1# Copyright 2015 gRPC authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""The Python implementation of the GRPC interoperability test client.""" 15 16import argparse 17import os 18 19from google import auth as google_auth 20from google.auth import jwt as google_auth_jwt 21import grpc 22from src.proto.grpc.testing import test_pb2_grpc 23 24from tests.interop import methods 25from tests.interop import resources 26 27 28def parse_interop_client_args(): 29 parser = argparse.ArgumentParser() 30 parser.add_argument('--server_host', 31 default="localhost", 32 type=str, 33 help='the host to which to connect') 34 parser.add_argument('--server_port', 35 type=int, 36 required=True, 37 help='the port to which to connect') 38 parser.add_argument('--test_case', 39 default='large_unary', 40 type=str, 41 help='the test case to execute') 42 parser.add_argument('--use_tls', 43 default=False, 44 type=resources.parse_bool, 45 help='require a secure connection') 46 parser.add_argument('--use_alts', 47 default=False, 48 type=resources.parse_bool, 49 help='require an ALTS secure connection') 50 parser.add_argument('--use_test_ca', 51 default=False, 52 type=resources.parse_bool, 53 help='replace platform root CAs with ca.pem') 54 parser.add_argument('--server_host_override', 55 type=str, 56 help='the server host to which to claim to connect') 57 parser.add_argument('--oauth_scope', 58 type=str, 59 help='scope for OAuth tokens') 60 parser.add_argument('--default_service_account', 61 type=str, 62 help='email address of the default service account') 63 return parser.parse_args() 64 65 66def _create_call_credentials(args): 67 if args.test_case == 'oauth2_auth_token': 68 google_credentials, unused_project_id = google_auth.default( 69 scopes=[args.oauth_scope]) 70 google_credentials.refresh(google_auth.transport.requests.Request()) 71 return grpc.access_token_call_credentials(google_credentials.token) 72 elif args.test_case == 'compute_engine_creds': 73 google_credentials, unused_project_id = google_auth.default( 74 scopes=[args.oauth_scope]) 75 return grpc.metadata_call_credentials( 76 google_auth.transport.grpc.AuthMetadataPlugin( 77 credentials=google_credentials, 78 request=google_auth.transport.requests.Request())) 79 elif args.test_case == 'jwt_token_creds': 80 google_credentials = google_auth_jwt.OnDemandCredentials.from_service_account_file( 81 os.environ[google_auth.environment_vars.CREDENTIALS]) 82 return grpc.metadata_call_credentials( 83 google_auth.transport.grpc.AuthMetadataPlugin( 84 credentials=google_credentials, request=None)) 85 else: 86 return None 87 88 89def get_secure_channel_parameters(args): 90 call_credentials = _create_call_credentials(args) 91 92 channel_opts = None 93 if args.use_tls: 94 if args.use_test_ca: 95 root_certificates = resources.test_root_certificates() 96 else: 97 root_certificates = None # will load default roots. 98 99 channel_credentials = grpc.ssl_channel_credentials(root_certificates) 100 if call_credentials is not None: 101 channel_credentials = grpc.composite_channel_credentials( 102 channel_credentials, call_credentials) 103 104 if args.server_host_override: 105 channel_opts = (( 106 'grpc.ssl_target_name_override', 107 args.server_host_override, 108 ),) 109 elif args.use_alts: 110 channel_credentials = grpc.alts_channel_credentials() 111 112 return channel_credentials, channel_opts 113 114 115def _create_channel(args): 116 target = '{}:{}'.format(args.server_host, args.server_port) 117 118 if args.use_tls or args.use_alts: 119 channel_credentials, options = get_secure_channel_parameters(args) 120 return grpc.secure_channel(target, channel_credentials, options) 121 else: 122 return grpc.insecure_channel(target) 123 124 125def create_stub(channel, args): 126 if args.test_case == "unimplemented_service": 127 return test_pb2_grpc.UnimplementedServiceStub(channel) 128 else: 129 return test_pb2_grpc.TestServiceStub(channel) 130 131 132def _test_case_from_arg(test_case_arg): 133 for test_case in methods.TestCase: 134 if test_case_arg == test_case.value: 135 return test_case 136 else: 137 raise ValueError('No test case "%s"!' % test_case_arg) 138 139 140def test_interoperability(): 141 args = parse_interop_client_args() 142 channel = _create_channel(args) 143 stub = create_stub(channel, args) 144 test_case = _test_case_from_arg(args.test_case) 145 test_case.test_interoperability(stub, args) 146 147 148if __name__ == '__main__': 149 test_interoperability() 150