diff options
Diffstat (limited to 'tools/run_tests/run_interop_tests.py')
-rwxr-xr-x | tools/run_tests/run_interop_tests.py | 232 |
1 files changed, 158 insertions, 74 deletions
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 4a9c282d23..aa58107ced 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -385,6 +385,36 @@ class NodeLanguage: return 'node' +class NodePureJSLanguage: + + def __init__(self): + self.client_cwd = '../grpc-node' + self.server_cwd = '../grpc-node' + self.safename = str(self) + + def client_cmd(self, args): + return [ + 'packages/grpc-native-core/deps/grpc/tools/run_tests/interop/with_nvm.sh', + 'node', '--require', './test/fixtures/js_js', + 'test/interop/interop_client.js' + ] + args + + def cloud_to_prod_env(self): + return {} + + def global_env(self): + return {} + + def unimplemented_test_cases(self): + return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + + def unimplemented_test_cases_server(self): + return [] + + def __str__(self): + return 'nodepurejs' + + class PHPLanguage: def __init__(self): @@ -515,13 +545,13 @@ class PythonLanguage: def client_cmd(self, args): return [ - 'py27/bin/python', 'src/python/grpcio_tests/setup.py', + 'py27_native/bin/python', 'src/python/grpcio_tests/setup.py', 'run_interop', '--client', '--args="{}"'.format(' '.join(args)) ] def client_cmd_http2interop(self, args): return [ - 'py27/bin/python', + 'py27_native/bin/python', 'src/python/grpcio_tests/tests/http2/negative_http2_client.py', ] + args @@ -530,7 +560,7 @@ class PythonLanguage: def server_cmd(self, args): return [ - 'py27/bin/python', 'src/python/grpcio_tests/setup.py', + 'py27_native/bin/python', 'src/python/grpcio_tests/setup.py', 'run_interop', '--server', '--args="{}"'.format(' '.join(args)) ] @@ -559,6 +589,7 @@ _LANGUAGES = { 'java': JavaLanguage(), 'javaokhttp': JavaOkHttpClient(), 'node': NodeLanguage(), + 'nodepurejs': NodePureJSLanguage(), 'php': PHPLanguage(), 'php7': PHP7Language(), 'objc': ObjcLanguage(), @@ -606,6 +637,14 @@ _LANGUAGES_WITH_HTTP2_CLIENTS_FOR_HTTP2_SERVER_TEST_CASES = [ 'java', 'go', 'python', 'c++' ] +#TODO: Add c++ when c++ ALTS interop client is ready. +_LANGUAGES_FOR_ALTS_TEST_CASES = ['java', 'go', 'c++'] + +#TODO: Add c++ when c++ ALTS interop server is ready. +_SERVERS_FOR_ALTS_TEST_CASES = ['java', 'go', 'c++'] + +_TRANSPORT_SECURITY_OPTIONS = ['tls', 'alts', 'insecure'] + DOCKER_WORKDIR_ROOT = '/var/local/git/grpc' @@ -660,25 +699,37 @@ def bash_cmdline(cmdline): return ['bash', '-c', ' '.join(cmdline)] -def auth_options(language, test_case): +def compute_engine_creds_required(language, test_case): + """Returns True if given test requires access to compute engine creds.""" + language = str(language) + if test_case == 'compute_engine_creds': + return True + if test_case == 'oauth2_auth_token' and language == 'c++': + # C++ oauth2 test uses GCE creds because C++ only supports JWT + return True + return False + + +def auth_options(language, test_case, service_account_key_file=None): """Returns (cmdline, env) tuple with cloud_to_prod_auth test options.""" language = str(language) cmdargs = [] env = {} - # TODO(jtattermusch): this file path only works inside docker - key_filepath = '/root/service_account/GrpcTesting-726eb1347f15.json' + if not service_account_key_file: + # this file path only works inside docker + service_account_key_file = '/root/service_account/GrpcTesting-726eb1347f15.json' oauth_scope_arg = '--oauth_scope=https://www.googleapis.com/auth/xapi.zoo' - key_file_arg = '--service_account_key_file=%s' % key_filepath + key_file_arg = '--service_account_key_file=%s' % service_account_key_file default_account_arg = '--default_service_account=830293263384-compute@developer.gserviceaccount.com' if test_case in ['jwt_token_creds', 'per_rpc_creds', 'oauth2_auth_token']: if language in [ 'csharp', 'csharpcoreclr', 'node', 'php', 'php7', 'python', - 'ruby' + 'ruby', 'nodepurejs' ]: - env['GOOGLE_APPLICATION_CREDENTIALS'] = key_filepath + env['GOOGLE_APPLICATION_CREDENTIALS'] = service_account_key_file else: cmdargs += [key_file_arg] @@ -707,22 +758,24 @@ def _job_kill_handler(job): def cloud_to_prod_jobspec(language, test_case, - server_host_name, - server_host_detail, + server_host_nickname, + server_host, docker_image=None, auth=False, - manual_cmd_log=None): + manual_cmd_log=None, + service_account_key_file=None): """Creates jobspec for cloud-to-prod interop test""" container_name = None cmdargs = [ - '--server_host=%s' % server_host_detail[0], - '--server_host_override=%s' % server_host_detail[1], - '--server_port=443', '--use_tls=true', + '--server_host=%s' % server_host, + '--server_host_override=%s' % server_host, '--server_port=443', + '--use_tls=true', '--test_case=%s' % test_case ] environ = dict(language.cloud_to_prod_env(), **language.global_env()) if auth: - auth_cmdargs, auth_env = auth_options(language, test_case) + auth_cmdargs, auth_env = auth_options(language, test_case, + service_account_key_file) cmdargs += auth_cmdargs environ.update(auth_env) cmdline = bash_cmdline(language.client_cmd(cmdargs)) @@ -751,7 +804,7 @@ def cloud_to_prod_jobspec(language, cmdline=cmdline, cwd=cwd, environ=environ, - shortname='%s:%s:%s:%s' % (suite_name, language, server_host_name, + shortname='%s:%s:%s:%s' % (suite_name, language, server_host_nickname, test_case), timeout_seconds=_TEST_TIMEOUT, flake_retries=4 if args.allow_flakes else 0, @@ -768,14 +821,22 @@ def cloud_to_cloud_jobspec(language, server_host, server_port, docker_image=None, - insecure=False, + transport_security='tls', manual_cmd_log=None): """Creates jobspec for cloud-to-cloud interop test""" interop_only_options = [ '--server_host_override=foo.test.google.fr', - '--use_tls=%s' % ('false' if insecure else 'true'), '--use_test_ca=true', ] + if transport_security == 'tls': + interop_only_options += ['--use_tls=true'] + elif transport_security == 'alts': + interop_only_options += ['--use_tls=false', '--use_alts=true'] + elif transport_security == 'insecure': + interop_only_options += ['--use_tls=false'] + else: + print('Invalid transport security option.') + sys.exit(1) client_test_case = test_case if test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS: @@ -840,15 +901,24 @@ def cloud_to_cloud_jobspec(language, return test_job -def server_jobspec(language, docker_image, insecure=False, manual_cmd_log=None): +def server_jobspec(language, + docker_image, + transport_security='tls', + manual_cmd_log=None): """Create jobspec for running a server""" container_name = dockerjob.random_name( 'interop_server_%s' % language.safename) - cmdline = bash_cmdline( - language.server_cmd([ - '--port=%s' % _DEFAULT_SERVER_PORT, - '--use_tls=%s' % ('false' if insecure else 'true') - ])) + server_cmd = ['--port=%s' % _DEFAULT_SERVER_PORT] + if transport_security == 'tls': + server_cmd += ['--use_tls=true'] + elif transport_security == 'alts': + server_cmd += ['--use_tls=false', '--use_alts=true'] + elif transport_security == 'insecure': + server_cmd += ['--use_tls=false'] + else: + print('Invalid transport security option.') + sys.exit(1) + cmdline = bash_cmdline(language.server_cmd(server_cmd)) environ = language.global_env() docker_args = ['--name=%s' % container_name] if language.safename == 'http2': @@ -953,19 +1023,9 @@ def aggregate_http2_results(stdout): # A dictionary of prod servers to test. -# Format: server_name: (server_host, server_host_override, errors_allowed) -# TODO(adelez): implement logic for errors_allowed where if the indicated tests -# fail, they don't impact the overall test result. prod_servers = { - 'default': ('216.239.32.254', 'grpc-test.sandbox.googleapis.com', False), - 'gateway_v2': ('216.239.32.254', 'grpc-test2.sandbox.googleapis.com', True), - 'cloud_gateway': ('216.239.32.255', 'grpc-test.sandbox.googleapis.com', - False), - 'cloud_gateway_v2': ('216.239.32.255', 'grpc-test2.sandbox.googleapis.com', - True), - 'gateway_v4': ('216.239.32.254', 'grpc-test4.sandbox.googleapis.com', True), - 'cloud_gateway_v4': ('216.239.32.255', 'grpc-test4.sandbox.googleapis.com', - True), + 'default': 'grpc-test.sandbox.googleapis.com', + 'gateway_v4': 'grpc-test4.sandbox.googleapis.com', } argp = argparse.ArgumentParser(description='Run interop tests.') @@ -1013,6 +1073,12 @@ argp.add_argument( 'Use servername=HOST:PORT to explicitly specify a server. E.g. csharp=localhost:50000', default=[]) argp.add_argument( + '--service_account_key_file', + type=str, + help= + 'Override the default service account key file to use for auth interop tests.', + default=None) +argp.add_argument( '-t', '--travis', default=False, action='store_const', const=True) argp.add_argument( '-v', '--verbose', default=False, action='store_const', const=True) @@ -1055,11 +1121,19 @@ argp.add_argument( 'Enable HTTP/2 server edge case testing. (Includes positive and negative tests' ) argp.add_argument( - '--insecure', + '--transport_security', + choices=_TRANSPORT_SECURITY_OPTIONS, + default='tls', + type=str, + nargs='?', + const=True, + help='Which transport security mechanism to use.') +argp.add_argument( + '--skip_compute_engine_creds', default=False, action='store_const', const=True, - help='Whether to use secure channel.') + help='Skip auth tests requiring access to compute engine credentials.') argp.add_argument( '--internal_ci', default=False, @@ -1079,6 +1153,9 @@ servers = set( s for s in itertools.chain.from_iterable( _SERVERS if x == 'all' else [x] for x in args.server)) +# ALTS servers are only available for certain languages. +if args.transport_security == 'alts': + servers = servers.intersection(_SERVERS_FOR_ALTS_TEST_CASES) if args.use_docker: if not args.travis: @@ -1108,6 +1185,10 @@ all_but_objc = set(six.iterkeys(_LANGUAGES)) - set(['objc']) languages = set(_LANGUAGES[l] for l in itertools.chain.from_iterable( all_but_objc if x == 'all' else [x] for x in args.language)) +# ALTS interop clients are only available for certain languages. +if args.transport_security == 'alts': + alts_languages = set(_LANGUAGES[l] for l in _LANGUAGES_FOR_ALTS_TEST_CASES) + languages = languages.intersection(alts_languages) languages_http2_clients_for_http2_server_interop = set() if args.http2_server_interop: @@ -1176,7 +1257,7 @@ try: spec = server_jobspec( _LANGUAGES[lang], docker_images.get(lang), - args.insecure, + args.transport_security, manual_cmd_log=server_manual_cmd_log) if not args.manual_run: job = dockerjob.DockerJob(spec) @@ -1204,9 +1285,9 @@ try: jobs = [] if args.cloud_to_prod: - if args.insecure: + if args.transport_security != 'tls': print('TLS is always enabled for cloud_to_prod scenarios.') - for server_host_name in args.prod_servers: + for server_host_nickname in args.prod_servers: for language in languages: for test_case in _TEST_CASES: if not test_case in language.unimplemented_test_cases(): @@ -1214,10 +1295,12 @@ try: test_job = cloud_to_prod_jobspec( language, test_case, - server_host_name, - prod_servers[server_host_name], + server_host_nickname, + prod_servers[server_host_nickname], docker_image=docker_images.get(str(language)), - manual_cmd_log=client_manual_cmd_log) + manual_cmd_log=client_manual_cmd_log, + service_account_key_file=args. + service_account_key_file) jobs.append(test_job) if args.http2_interop: @@ -1225,28 +1308,34 @@ try: test_job = cloud_to_prod_jobspec( http2Interop, test_case, - server_host_name, - prod_servers[server_host_name], + server_host_nickname, + prod_servers[server_host_nickname], docker_image=docker_images.get(str(http2Interop)), - manual_cmd_log=client_manual_cmd_log) + manual_cmd_log=client_manual_cmd_log, + service_account_key_file=args.service_account_key_file) jobs.append(test_job) if args.cloud_to_prod_auth: - if args.insecure: + if args.transport_security != 'tls': print('TLS is always enabled for cloud_to_prod scenarios.') - for server_host_name in args.prod_servers: + for server_host_nickname in args.prod_servers: for language in languages: for test_case in _AUTH_TEST_CASES: - if not test_case in language.unimplemented_test_cases(): - test_job = cloud_to_prod_jobspec( - language, - test_case, - server_host_name, - prod_servers[server_host_name], - docker_image=docker_images.get(str(language)), - auth=True, - manual_cmd_log=client_manual_cmd_log) - jobs.append(test_job) + if (not args.skip_compute_engine_creds or + not compute_engine_creds_required( + language, test_case)): + if not test_case in language.unimplemented_test_cases(): + test_job = cloud_to_prod_jobspec( + language, + test_case, + server_host_nickname, + prod_servers[server_host_nickname], + docker_image=docker_images.get(str(language)), + auth=True, + manual_cmd_log=client_manual_cmd_log, + service_account_key_file=args. + service_account_key_file) + jobs.append(test_job) for server in args.override_server: server_name = server[0] @@ -1270,7 +1359,7 @@ try: server_host, server_port, docker_image=docker_images.get(str(language)), - insecure=args.insecure, + transport_security=args.transport_security, manual_cmd_log=client_manual_cmd_log) jobs.append(test_job) @@ -1286,7 +1375,7 @@ try: server_host, server_port, docker_image=docker_images.get(str(http2Interop)), - insecure=args.insecure, + transport_security=args.transport_security, manual_cmd_log=client_manual_cmd_log) jobs.append(test_job) @@ -1322,11 +1411,12 @@ try: server_port = _DEFAULT_SERVER_PORT + offset if not args.manual_run: server_port = http2_server_job.mapped_port(server_port) - if not args.insecure: - print(( - 'Creating grpc cient to http2 server test case with insecure connection, even though' - ' args.insecure is False. Http2 test server only supports insecure connections.' - )) + if args.transport_security != 'insecure': + print( + ('Creating grpc client to http2 server test case ' + 'with insecure connection, even though ' + 'args.transport_security is not insecure. Http2 ' + 'test server only supports insecure connections.')) test_job = cloud_to_cloud_jobspec( language, test_case, @@ -1334,7 +1424,7 @@ try: 'localhost', server_port, docker_image=docker_images.get(str(language)), - insecure=True, + transport_security='insecure', manual_cmd_log=client_manual_cmd_log) jobs.append(test_job) @@ -1377,12 +1467,6 @@ try: http2_server_test_cases = (_HTTP2_SERVER_TEST_CASES if args.http2_server_interop else []) - report_utils.render_interop_html_report( - set([str(l) for l in languages]), servers, _TEST_CASES, - _AUTH_TEST_CASES, _HTTP2_TEST_CASES, http2_server_test_cases, resultset, - num_failures, args.cloud_to_prod_auth or args.cloud_to_prod, - args.prod_servers, args.http2_interop) - if num_failures: sys.exit(1) else: |