diff options
author | 2017-12-11 18:00:40 -0800 | |
---|---|---|
committer | 2017-12-11 18:08:35 -0800 | |
commit | 888093c6ed0d24eed699173b5fb35235fe7a6069 (patch) | |
tree | ffbbc9fbfaacff17c3b94a2f2d780ece6abbfa36 /tools/run_tests/run_interop_tests.py | |
parent | a69c6901f9c4e375ad543cb4ee6ce747d953bf18 (diff) |
yapf run_tests
Diffstat (limited to 'tools/run_tests/run_interop_tests.py')
-rwxr-xr-x | tools/run_tests/run_interop_tests.py | 1988 |
1 files changed, 1044 insertions, 944 deletions
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 8f46ea99fd..99f4298813 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -12,7 +12,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - """Run interop (cross-language) tests in parallel.""" from __future__ import print_function @@ -37,9 +36,9 @@ import python_utils.jobset as jobset import python_utils.report_utils as report_utils # It's ok to not import because this is only necessary to upload results to BQ. try: - from python_utils.upload_test_results import upload_interop_results_to_bq + from python_utils.upload_test_results import upload_interop_results_to_bq except ImportError as e: - print(e) + print(e) # Docker doesn't clean up after itself, so we do it on exit. atexit.register(lambda: subprocess.call(['stty', 'echo'])) @@ -47,22 +46,24 @@ atexit.register(lambda: subprocess.call(['stty', 'echo'])) ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..')) os.chdir(ROOT) -_DEFAULT_SERVER_PORT=8080 +_DEFAULT_SERVER_PORT = 8080 -_SKIP_CLIENT_COMPRESSION = ['client_compressed_unary', - 'client_compressed_streaming'] +_SKIP_CLIENT_COMPRESSION = [ + 'client_compressed_unary', 'client_compressed_streaming' +] -_SKIP_SERVER_COMPRESSION = ['server_compressed_unary', - 'server_compressed_streaming'] +_SKIP_SERVER_COMPRESSION = [ + 'server_compressed_unary', 'server_compressed_streaming' +] _SKIP_COMPRESSION = _SKIP_CLIENT_COMPRESSION + _SKIP_SERVER_COMPRESSION -_SKIP_ADVANCED = ['status_code_and_message', - 'custom_metadata', - 'unimplemented_method', - 'unimplemented_service'] +_SKIP_ADVANCED = [ + 'status_code_and_message', 'custom_metadata', 'unimplemented_method', + 'unimplemented_service' +] -_TEST_TIMEOUT = 3*60 +_TEST_TIMEOUT = 3 * 60 # disable this test on core-based languages, # see https://github.com/grpc/grpc/issues/9779 @@ -77,977 +78,1054 @@ _XML_REPORT = 'report.xml' class CXXLanguage: - def __init__(self): - self.client_cwd = None - self.server_cwd = None - self.http2_cwd = None - self.safename = 'cxx' + def __init__(self): + self.client_cwd = None + self.server_cwd = None + self.http2_cwd = None + self.safename = 'cxx' - def client_cmd(self, args): - return ['bins/opt/interop_client'] + args + def client_cmd(self, args): + return ['bins/opt/interop_client'] + args - def client_cmd_http2interop(self, args): - return ['bins/opt/http2_client'] + args + def client_cmd_http2interop(self, args): + return ['bins/opt/http2_client'] + args - def cloud_to_prod_env(self): - return {} + def cloud_to_prod_env(self): + return {} - def server_cmd(self, args): - return ['bins/opt/interop_server'] + args + def server_cmd(self, args): + return ['bins/opt/interop_server'] + args - def global_env(self): - return {} + def global_env(self): + return {} - def unimplemented_test_cases(self): - return _SKIP_DATA_FRAME_PADDING + def unimplemented_test_cases(self): + return _SKIP_DATA_FRAME_PADDING - def unimplemented_test_cases_server(self): - return [] + def unimplemented_test_cases_server(self): + return [] - def __str__(self): - return 'c++' + def __str__(self): + return 'c++' class CSharpLanguage: - def __init__(self): - self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45' - self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/net45' - self.safename = str(self) + def __init__(self): + self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45' + self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/net45' + self.safename = str(self) - def client_cmd(self, args): - return ['mono', 'Grpc.IntegrationTesting.Client.exe'] + args + def client_cmd(self, args): + return ['mono', 'Grpc.IntegrationTesting.Client.exe'] + args - def cloud_to_prod_env(self): - return {} + def cloud_to_prod_env(self): + return {} - def server_cmd(self, args): - return ['mono', 'Grpc.IntegrationTesting.Server.exe'] + args + def server_cmd(self, args): + return ['mono', 'Grpc.IntegrationTesting.Server.exe'] + args - def global_env(self): - return {} + def global_env(self): + return {} - def unimplemented_test_cases(self): - return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + def unimplemented_test_cases(self): + return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING - def unimplemented_test_cases_server(self): - return _SKIP_COMPRESSION + def unimplemented_test_cases_server(self): + return _SKIP_COMPRESSION - def __str__(self): - return 'csharp' + def __str__(self): + return 'csharp' class CSharpCoreCLRLanguage: - def __init__(self): - self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0' - self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/netcoreapp1.0' - self.safename = str(self) + def __init__(self): + self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0' + self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/netcoreapp1.0' + self.safename = str(self) - def client_cmd(self, args): - return ['dotnet', 'exec', 'Grpc.IntegrationTesting.Client.dll'] + args + def client_cmd(self, args): + return ['dotnet', 'exec', 'Grpc.IntegrationTesting.Client.dll'] + args - def cloud_to_prod_env(self): - return {} + def cloud_to_prod_env(self): + return {} - def server_cmd(self, args): - return ['dotnet', 'exec', 'Grpc.IntegrationTesting.Server.dll'] + args + def server_cmd(self, args): + return ['dotnet', 'exec', 'Grpc.IntegrationTesting.Server.dll'] + args - def global_env(self): - return {} + def global_env(self): + return {} - def unimplemented_test_cases(self): - return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + def unimplemented_test_cases(self): + return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING - def unimplemented_test_cases_server(self): - return _SKIP_COMPRESSION + def unimplemented_test_cases_server(self): + return _SKIP_COMPRESSION - def __str__(self): - return 'csharpcoreclr' + def __str__(self): + return 'csharpcoreclr' class JavaLanguage: - def __init__(self): - self.client_cwd = '../grpc-java' - self.server_cwd = '../grpc-java' - self.http2_cwd = '../grpc-java' - self.safename = str(self) + def __init__(self): + self.client_cwd = '../grpc-java' + self.server_cwd = '../grpc-java' + self.http2_cwd = '../grpc-java' + self.safename = str(self) - def client_cmd(self, args): - return ['./run-test-client.sh'] + args + def client_cmd(self, args): + return ['./run-test-client.sh'] + args - def client_cmd_http2interop(self, args): - return ['./interop-testing/build/install/grpc-interop-testing/bin/http2-client'] + args + def client_cmd_http2interop(self, args): + return [ + './interop-testing/build/install/grpc-interop-testing/bin/http2-client' + ] + args - def cloud_to_prod_env(self): - return {} + def cloud_to_prod_env(self): + return {} - def server_cmd(self, args): - return ['./run-test-server.sh'] + args + def server_cmd(self, args): + return ['./run-test-server.sh'] + args - def global_env(self): - return {} + def global_env(self): + return {} - def unimplemented_test_cases(self): - return [] + def unimplemented_test_cases(self): + return [] - def unimplemented_test_cases_server(self): - return _SKIP_COMPRESSION + def unimplemented_test_cases_server(self): + return _SKIP_COMPRESSION - def __str__(self): - return 'java' + def __str__(self): + return 'java' class JavaOkHttpClient: - def __init__(self): - self.client_cwd = '../grpc-java' - self.safename = 'java' + def __init__(self): + self.client_cwd = '../grpc-java' + self.safename = 'java' - def client_cmd(self, args): - return ['./run-test-client.sh', '--use_okhttp=true'] + args + def client_cmd(self, args): + return ['./run-test-client.sh', '--use_okhttp=true'] + args - def cloud_to_prod_env(self): - return {} + def cloud_to_prod_env(self): + return {} - def global_env(self): - return {} + def global_env(self): + return {} - def unimplemented_test_cases(self): - return _SKIP_DATA_FRAME_PADDING + def unimplemented_test_cases(self): + return _SKIP_DATA_FRAME_PADDING - def __str__(self): - return 'javaokhttp' + def __str__(self): + return 'javaokhttp' class GoLanguage: - def __init__(self): - # TODO: this relies on running inside docker - self.client_cwd = '/go/src/google.golang.org/grpc/interop/client' - self.server_cwd = '/go/src/google.golang.org/grpc/interop/server' - self.http2_cwd = '/go/src/google.golang.org/grpc/interop/http2' - self.safename = str(self) + def __init__(self): + # TODO: this relies on running inside docker + self.client_cwd = '/go/src/google.golang.org/grpc/interop/client' + self.server_cwd = '/go/src/google.golang.org/grpc/interop/server' + self.http2_cwd = '/go/src/google.golang.org/grpc/interop/http2' + self.safename = str(self) + + def client_cmd(self, args): + return ['go', 'run', 'client.go'] + args - def client_cmd(self, args): - return ['go', 'run', 'client.go'] + args + def client_cmd_http2interop(self, args): + return ['go', 'run', 'negative_http2_client.go'] + args - def client_cmd_http2interop(self, args): - return ['go', 'run', 'negative_http2_client.go'] + args + def cloud_to_prod_env(self): + return {} - def cloud_to_prod_env(self): - return {} + def server_cmd(self, args): + return ['go', 'run', 'server.go'] + args - def server_cmd(self, args): - return ['go', 'run', 'server.go'] + args + def global_env(self): + return {} - def global_env(self): - return {} + def unimplemented_test_cases(self): + return _SKIP_COMPRESSION - def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + def unimplemented_test_cases_server(self): + return _SKIP_COMPRESSION - def unimplemented_test_cases_server(self): - return _SKIP_COMPRESSION + def __str__(self): + return 'go' - def __str__(self): - return 'go' class Http2Server: - """Represents the HTTP/2 Interop Test server + """Represents the HTTP/2 Interop Test server This pretends to be a language in order to be built and run, but really it isn't. """ - def __init__(self): - self.server_cwd = None - self.safename = str(self) - def server_cmd(self, args): - return ['python test/http2_test/http2_test_server.py'] + def __init__(self): + self.server_cwd = None + self.safename = str(self) + + def server_cmd(self, args): + return ['python test/http2_test/http2_test_server.py'] + + def cloud_to_prod_env(self): + return {} - def cloud_to_prod_env(self): - return {} + def global_env(self): + return {} - def global_env(self): - return {} + def unimplemented_test_cases(self): + return _TEST_CASES + _SKIP_DATA_FRAME_PADDING - def unimplemented_test_cases(self): - return _TEST_CASES + _SKIP_DATA_FRAME_PADDING + def unimplemented_test_cases_server(self): + return _TEST_CASES - def unimplemented_test_cases_server(self): - return _TEST_CASES + def __str__(self): + return 'http2' - def __str__(self): - return 'http2' class Http2Client: - """Represents the HTTP/2 Interop Test + """Represents the HTTP/2 Interop Test This pretends to be a language in order to be built and run, but really it isn't. """ - def __init__(self): - self.client_cwd = None - self.safename = str(self) - def client_cmd(self, args): - return ['tools/http2_interop/http2_interop.test', '-test.v'] + args + def __init__(self): + self.client_cwd = None + self.safename = str(self) - def cloud_to_prod_env(self): - return {} + def client_cmd(self, args): + return ['tools/http2_interop/http2_interop.test', '-test.v'] + args - def global_env(self): - return {} + def cloud_to_prod_env(self): + return {} - def unimplemented_test_cases(self): - return _TEST_CASES + def global_env(self): + return {} - def unimplemented_test_cases_server(self): - return _TEST_CASES + def unimplemented_test_cases(self): + return _TEST_CASES + + def unimplemented_test_cases_server(self): + return _TEST_CASES + + def __str__(self): + return 'http2' - def __str__(self): - return 'http2' class NodeLanguage: - def __init__(self): - self.client_cwd = '../grpc-node' - self.server_cwd = '../grpc-node' - self.safename = str(self) + 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', + def client_cmd(self, args): + return [ + 'packages/grpc-native-core/deps/grpc/tools/run_tests/interop/with_nvm.sh', 'node', '--require', './test/fixtures/native_native', - 'test/interop/interop_client.js'] + args + 'test/interop/interop_client.js' + ] + args - def cloud_to_prod_env(self): - return {} + def cloud_to_prod_env(self): + return {} - def server_cmd(self, args): - return ['packages/grpc-native-core/deps/grpc/tools/run_tests/interop/with_nvm.sh', + def server_cmd(self, args): + return [ + 'packages/grpc-native-core/deps/grpc/tools/run_tests/interop/with_nvm.sh', 'node', '--require', './test/fixtures/native_native', - 'test/interop/interop_server.js'] + args + 'test/interop/interop_server.js' + ] + args - def global_env(self): - return {} + def global_env(self): + return {} - def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + def unimplemented_test_cases(self): + return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING - def unimplemented_test_cases_server(self): - return _SKIP_COMPRESSION + def unimplemented_test_cases_server(self): + return _SKIP_COMPRESSION - def __str__(self): - return 'node' + def __str__(self): + return 'node' class PHPLanguage: - def __init__(self): - self.client_cwd = None - self.safename = str(self) + def __init__(self): + self.client_cwd = None + self.safename = str(self) - def client_cmd(self, args): - return ['src/php/bin/interop_client.sh'] + args + def client_cmd(self, args): + return ['src/php/bin/interop_client.sh'] + args - def cloud_to_prod_env(self): - return {} + def cloud_to_prod_env(self): + return {} - def global_env(self): - return {} + def global_env(self): + return {} - def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + def unimplemented_test_cases(self): + return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING - def unimplemented_test_cases_server(self): - return [] + def unimplemented_test_cases_server(self): + return [] - def __str__(self): - return 'php' + def __str__(self): + return 'php' class PHP7Language: - def __init__(self): - self.client_cwd = None - self.safename = str(self) + def __init__(self): + self.client_cwd = None + self.safename = str(self) - def client_cmd(self, args): - return ['src/php/bin/interop_client.sh'] + args + def client_cmd(self, args): + return ['src/php/bin/interop_client.sh'] + args - def cloud_to_prod_env(self): - return {} + def cloud_to_prod_env(self): + return {} - def global_env(self): - return {} + def global_env(self): + return {} - def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + def unimplemented_test_cases(self): + return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING - def unimplemented_test_cases_server(self): - return [] + def unimplemented_test_cases_server(self): + return [] + + def __str__(self): + return 'php7' - def __str__(self): - return 'php7' class ObjcLanguage: - def __init__(self): - self.client_cwd = 'src/objective-c/tests' - self.safename = str(self) + def __init__(self): + self.client_cwd = 'src/objective-c/tests' + self.safename = str(self) + + def client_cmd(self, args): + # from args, extract the server port and craft xcodebuild command out of it + for arg in args: + port = re.search('--server_port=(\d+)', arg) + if port: + portnum = port.group(1) + cmdline = 'pod install && xcodebuild -workspace Tests.xcworkspace -scheme InteropTestsLocalSSL -destination name="iPhone 6" HOST_PORT_LOCALSSL=localhost:%s test' % portnum + return [cmdline] - def client_cmd(self, args): - # from args, extract the server port and craft xcodebuild command out of it - for arg in args: - port = re.search('--server_port=(\d+)', arg) - if port: - portnum = port.group(1) - cmdline = 'pod install && xcodebuild -workspace Tests.xcworkspace -scheme InteropTestsLocalSSL -destination name="iPhone 6" HOST_PORT_LOCALSSL=localhost:%s test'%portnum - return [cmdline] + def cloud_to_prod_env(self): + return {} - def cloud_to_prod_env(self): - return {} + def global_env(self): + return {} - def global_env(self): - return {} + def unimplemented_test_cases(self): + # ObjC test runs all cases with the same command. It ignores the testcase + # cmdline argument. Here we return all but one test cases as unimplemented, + # and depend upon ObjC test's behavior that it runs all cases even when + # we tell it to run just one. + return _TEST_CASES[1:] + _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING - def unimplemented_test_cases(self): - # ObjC test runs all cases with the same command. It ignores the testcase - # cmdline argument. Here we return all but one test cases as unimplemented, - # and depend upon ObjC test's behavior that it runs all cases even when - # we tell it to run just one. - return _TEST_CASES[1:] + _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + def unimplemented_test_cases_server(self): + return _SKIP_COMPRESSION - def unimplemented_test_cases_server(self): - return _SKIP_COMPRESSION + def __str__(self): + return 'objc' - def __str__(self): - return 'objc' class RubyLanguage: - def __init__(self): - self.client_cwd = None - self.server_cwd = None - self.safename = str(self) + def __init__(self): + self.client_cwd = None + self.server_cwd = None + self.safename = str(self) - def client_cmd(self, args): - return ['tools/run_tests/interop/with_rvm.sh', - 'ruby', 'src/ruby/pb/test/client.rb'] + args + def client_cmd(self, args): + return [ + 'tools/run_tests/interop/with_rvm.sh', 'ruby', + 'src/ruby/pb/test/client.rb' + ] + args - def cloud_to_prod_env(self): - return {} + def cloud_to_prod_env(self): + return {} - def server_cmd(self, args): - return ['tools/run_tests/interop/with_rvm.sh', - 'ruby', 'src/ruby/pb/test/server.rb'] + args + def server_cmd(self, args): + return [ + 'tools/run_tests/interop/with_rvm.sh', 'ruby', + 'src/ruby/pb/test/server.rb' + ] + args - def global_env(self): - return {} + def global_env(self): + return {} - def unimplemented_test_cases(self): - return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + def unimplemented_test_cases(self): + return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING - def unimplemented_test_cases_server(self): - return _SKIP_COMPRESSION + def unimplemented_test_cases_server(self): + return _SKIP_COMPRESSION + + def __str__(self): + return 'ruby' - def __str__(self): - return 'ruby' class PythonLanguage: - def __init__(self): - self.client_cwd = None - self.server_cwd = None - self.http2_cwd = None - self.safename = str(self) - - def client_cmd(self, args): - return [ - 'py27/bin/python', - 'src/python/grpcio_tests/setup.py', - 'run_interop', - '--client', - '--args="{}"'.format(' '.join(args)) - ] + def __init__(self): + self.client_cwd = None + self.server_cwd = None + self.http2_cwd = None + self.safename = str(self) - def client_cmd_http2interop(self, args): - return [ 'py27/bin/python', - 'src/python/grpcio_tests/tests/http2/negative_http2_client.py', - ] + args - - def cloud_to_prod_env(self): - return {} - - def server_cmd(self, args): - return [ - 'py27/bin/python', - 'src/python/grpcio_tests/setup.py', - 'run_interop', - '--server', - '--args="{}"'.format(' '.join(args)) - ] + def client_cmd(self, args): + return [ + 'py27/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', + 'src/python/grpcio_tests/tests/http2/negative_http2_client.py', + ] + args - def global_env(self): - return {'LD_LIBRARY_PATH': '{}/libs/opt'.format(DOCKER_WORKDIR_ROOT), - 'PYTHONPATH': '{}/src/python/gens'.format(DOCKER_WORKDIR_ROOT)} + def cloud_to_prod_env(self): + return {} - def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + def server_cmd(self, args): + return [ + 'py27/bin/python', 'src/python/grpcio_tests/setup.py', + 'run_interop', '--server', '--args="{}"'.format(' '.join(args)) + ] - def unimplemented_test_cases_server(self): - return _SKIP_COMPRESSION + def global_env(self): + return { + 'LD_LIBRARY_PATH': '{}/libs/opt'.format(DOCKER_WORKDIR_ROOT), + 'PYTHONPATH': '{}/src/python/gens'.format(DOCKER_WORKDIR_ROOT) + } - def __str__(self): - return 'python' + def unimplemented_test_cases(self): + return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + + def unimplemented_test_cases_server(self): + return _SKIP_COMPRESSION + + def __str__(self): + return 'python' _LANGUAGES = { - 'c++' : CXXLanguage(), - 'csharp' : CSharpLanguage(), - 'csharpcoreclr' : CSharpCoreCLRLanguage(), - 'go' : GoLanguage(), - 'java' : JavaLanguage(), - 'javaokhttp' : JavaOkHttpClient(), - 'node' : NodeLanguage(), - 'php' : PHPLanguage(), - 'php7' : PHP7Language(), - 'objc' : ObjcLanguage(), - 'ruby' : RubyLanguage(), - 'python' : PythonLanguage(), + 'c++': CXXLanguage(), + 'csharp': CSharpLanguage(), + 'csharpcoreclr': CSharpCoreCLRLanguage(), + 'go': GoLanguage(), + 'java': JavaLanguage(), + 'javaokhttp': JavaOkHttpClient(), + 'node': NodeLanguage(), + 'php': PHPLanguage(), + 'php7': PHP7Language(), + 'objc': ObjcLanguage(), + 'ruby': RubyLanguage(), + 'python': PythonLanguage(), } # languages supported as cloud_to_cloud servers -_SERVERS = ['c++', 'node', 'csharp', 'csharpcoreclr', 'java', 'go', 'ruby', 'python'] - -_TEST_CASES = ['large_unary', 'empty_unary', 'ping_pong', - 'empty_stream', 'client_streaming', 'server_streaming', - 'cancel_after_begin', 'cancel_after_first_response', - 'timeout_on_sleeping_server', 'custom_metadata', - 'status_code_and_message', 'unimplemented_method', - 'client_compressed_unary', 'server_compressed_unary', - 'client_compressed_streaming', 'server_compressed_streaming', - 'unimplemented_service'] - -_AUTH_TEST_CASES = ['compute_engine_creds', 'jwt_token_creds', - 'oauth2_auth_token', 'per_rpc_creds'] +_SERVERS = [ + 'c++', 'node', 'csharp', 'csharpcoreclr', 'java', 'go', 'ruby', 'python' +] + +_TEST_CASES = [ + 'large_unary', 'empty_unary', 'ping_pong', 'empty_stream', + 'client_streaming', 'server_streaming', 'cancel_after_begin', + 'cancel_after_first_response', 'timeout_on_sleeping_server', + 'custom_metadata', 'status_code_and_message', 'unimplemented_method', + 'client_compressed_unary', 'server_compressed_unary', + 'client_compressed_streaming', 'server_compressed_streaming', + 'unimplemented_service' +] + +_AUTH_TEST_CASES = [ + 'compute_engine_creds', 'jwt_token_creds', 'oauth2_auth_token', + 'per_rpc_creds' +] _HTTP2_TEST_CASES = ['tls', 'framing'] -_HTTP2_SERVER_TEST_CASES = ['rst_after_header', 'rst_after_data', 'rst_during_data', - 'goaway', 'ping', 'max_streams', 'data_frame_padding', 'no_df_padding_sanity_test'] +_HTTP2_SERVER_TEST_CASES = [ + 'rst_after_header', 'rst_after_data', 'rst_during_data', 'goaway', 'ping', + 'max_streams', 'data_frame_padding', 'no_df_padding_sanity_test' +] -_GRPC_CLIENT_TEST_CASES_FOR_HTTP2_SERVER_TEST_CASES = { 'data_frame_padding': 'large_unary', 'no_df_padding_sanity_test': 'large_unary' } +_GRPC_CLIENT_TEST_CASES_FOR_HTTP2_SERVER_TEST_CASES = { + 'data_frame_padding': 'large_unary', + 'no_df_padding_sanity_test': 'large_unary' +} -_HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS = _GRPC_CLIENT_TEST_CASES_FOR_HTTP2_SERVER_TEST_CASES.keys() +_HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS = _GRPC_CLIENT_TEST_CASES_FOR_HTTP2_SERVER_TEST_CASES.keys( +) -_LANGUAGES_WITH_HTTP2_CLIENTS_FOR_HTTP2_SERVER_TEST_CASES = ['java', 'go', 'python', 'c++'] +_LANGUAGES_WITH_HTTP2_CLIENTS_FOR_HTTP2_SERVER_TEST_CASES = [ + 'java', 'go', 'python', 'c++' +] DOCKER_WORKDIR_ROOT = '/var/local/git/grpc' + def docker_run_cmdline(cmdline, image, docker_args=[], cwd=None, environ=None): - """Wraps given cmdline array to create 'docker run' cmdline from it.""" - docker_cmdline = ['docker', 'run', '-i', '--rm=true'] + """Wraps given cmdline array to create 'docker run' cmdline from it.""" + docker_cmdline = ['docker', 'run', '-i', '--rm=true'] - # turn environ into -e docker args - if environ: - for k,v in environ.items(): - docker_cmdline += ['-e', '%s=%s' % (k,v)] + # turn environ into -e docker args + if environ: + for k, v in environ.items(): + docker_cmdline += ['-e', '%s=%s' % (k, v)] - # set working directory - workdir = DOCKER_WORKDIR_ROOT - if cwd: - workdir = os.path.join(workdir, cwd) - docker_cmdline += ['-w', workdir] + # set working directory + workdir = DOCKER_WORKDIR_ROOT + if cwd: + workdir = os.path.join(workdir, cwd) + docker_cmdline += ['-w', workdir] - docker_cmdline += docker_args + [image] + cmdline - return docker_cmdline + docker_cmdline += docker_args + [image] + cmdline + return docker_cmdline def manual_cmdline(docker_cmdline, docker_image): - """Returns docker cmdline adjusted for manual invocation.""" - print_cmdline = [] - for item in docker_cmdline: - if item.startswith('--name='): - continue - if item == docker_image: - item = "$docker_image" - item = item.replace('"', '\\"') - # add quotes when necessary - if any(character.isspace() for character in item): - item = "\"%s\"" % item - print_cmdline.append(item) - return ' '.join(print_cmdline) + """Returns docker cmdline adjusted for manual invocation.""" + print_cmdline = [] + for item in docker_cmdline: + if item.startswith('--name='): + continue + if item == docker_image: + item = "$docker_image" + item = item.replace('"', '\\"') + # add quotes when necessary + if any(character.isspace() for character in item): + item = "\"%s\"" % item + print_cmdline.append(item) + return ' '.join(print_cmdline) def write_cmdlog_maybe(cmdlog, filename): - """Returns docker cmdline adjusted for manual invocation.""" - if cmdlog: - with open(filename, 'w') as logfile: - logfile.write('#!/bin/bash\n') - logfile.writelines("%s\n" % line for line in cmdlog) - print('Command log written to file %s' % filename) + """Returns docker cmdline adjusted for manual invocation.""" + if cmdlog: + with open(filename, 'w') as logfile: + logfile.write('#!/bin/bash\n') + logfile.writelines("%s\n" % line for line in cmdlog) + print('Command log written to file %s' % filename) def bash_cmdline(cmdline): - """Creates bash -c cmdline from args list.""" - # Use login shell: - # * makes error messages clearer if executables are missing - return ['bash', '-c', ' '.join(cmdline)] + """Creates bash -c cmdline from args list.""" + # Use login shell: + # * makes error messages clearer if executables are missing + return ['bash', '-c', ' '.join(cmdline)] def auth_options(language, test_case): - """Returns (cmdline, env) tuple with cloud_to_prod_auth test options.""" + """Returns (cmdline, env) tuple with cloud_to_prod_auth test options.""" - language = str(language) - cmdargs = [] - env = {} + language = str(language) + cmdargs = [] + env = {} - # TODO(jtattermusch): this file path only works inside docker - key_filepath = '/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 - default_account_arg = '--default_service_account=830293263384-compute@developer.gserviceaccount.com' + # TODO(jtattermusch): this file path only works inside docker + key_filepath = '/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 + 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']: - env['GOOGLE_APPLICATION_CREDENTIALS'] = key_filepath - else: - cmdargs += [key_file_arg] + if test_case in ['jwt_token_creds', 'per_rpc_creds', 'oauth2_auth_token']: + if language in [ + 'csharp', 'csharpcoreclr', 'node', 'php', 'php7', 'python', + 'ruby' + ]: + env['GOOGLE_APPLICATION_CREDENTIALS'] = key_filepath + else: + cmdargs += [key_file_arg] - if test_case in ['per_rpc_creds', 'oauth2_auth_token']: - cmdargs += [oauth_scope_arg] + if test_case in ['per_rpc_creds', 'oauth2_auth_token']: + cmdargs += [oauth_scope_arg] - if test_case == 'oauth2_auth_token' and language == 'c++': - # C++ oauth2 test uses GCE creds and thus needs to know the default account - cmdargs += [default_account_arg] + if test_case == 'oauth2_auth_token' and language == 'c++': + # C++ oauth2 test uses GCE creds and thus needs to know the default account + cmdargs += [default_account_arg] - if test_case == 'compute_engine_creds': - cmdargs += [oauth_scope_arg, default_account_arg] + if test_case == 'compute_engine_creds': + cmdargs += [oauth_scope_arg, default_account_arg] - return (cmdargs, env) + return (cmdargs, env) def _job_kill_handler(job): - if job._spec.container_name: - dockerjob.docker_kill(job._spec.container_name) - # When the job times out and we decide to kill it, - # we need to wait a before restarting the job - # to prevent "container name already in use" error. - # TODO(jtattermusch): figure out a cleaner way to to this. - time.sleep(2) - - -def cloud_to_prod_jobspec(language, test_case, server_host_name, - server_host_detail, docker_image=None, auth=False, + if job._spec.container_name: + dockerjob.docker_kill(job._spec.container_name) + # When the job times out and we decide to kill it, + # we need to wait a before restarting the job + # to prevent "container name already in use" error. + # TODO(jtattermusch): figure out a cleaner way to to this. + time.sleep(2) + + +def cloud_to_prod_jobspec(language, + test_case, + server_host_name, + server_host_detail, + docker_image=None, + auth=False, manual_cmd_log=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', - '--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) - cmdargs += auth_cmdargs - environ.update(auth_env) - cmdline = bash_cmdline(language.client_cmd(cmdargs)) - cwd = language.client_cwd - - if docker_image: - container_name = dockerjob.random_name('interop_client_%s' % - language.safename) - cmdline = docker_run_cmdline(cmdline, - image=docker_image, - cwd=cwd, - environ=environ, - docker_args=['--net=host', - '--name=%s' % container_name]) - if manual_cmd_log is not None: - if manual_cmd_log == []: - manual_cmd_log.append('echo "Testing ${docker_image:=%s}"' % docker_image) - manual_cmd_log.append(manual_cmdline(cmdline, docker_image)) - cwd = None - environ = None - - suite_name='cloud_to_prod_auth' if auth else 'cloud_to_prod' - test_job = jobset.JobSpec( - cmdline=cmdline, - cwd=cwd, - environ=environ, - shortname='%s:%s:%s:%s' % (suite_name, language, server_host_name, - test_case), - timeout_seconds=_TEST_TIMEOUT, - flake_retries=4 if args.allow_flakes else 0, - timeout_retries=2 if args.allow_flakes else 0, - kill_handler=_job_kill_handler) - if docker_image: - test_job.container_name = container_name - return test_job - - -def cloud_to_cloud_jobspec(language, test_case, server_name, server_host, - server_port, docker_image=None, insecure=False, - 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', - ] - - client_test_case = test_case - if test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS: - client_test_case = _GRPC_CLIENT_TEST_CASES_FOR_HTTP2_SERVER_TEST_CASES[test_case] - if client_test_case in language.unimplemented_test_cases(): - print('asking client %s to run unimplemented test case %s' % (repr(language), client_test_case)) - sys.exit(1) + """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', '--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) + cmdargs += auth_cmdargs + environ.update(auth_env) + cmdline = bash_cmdline(language.client_cmd(cmdargs)) + cwd = language.client_cwd - common_options = [ - '--test_case=%s' % client_test_case, - '--server_host=%s' % server_host, - '--server_port=%s' % server_port, - ] + if docker_image: + container_name = dockerjob.random_name('interop_client_%s' % + language.safename) + cmdline = docker_run_cmdline( + cmdline, + image=docker_image, + cwd=cwd, + environ=environ, + docker_args=['--net=host', '--name=%s' % container_name]) + if manual_cmd_log is not None: + if manual_cmd_log == []: + manual_cmd_log.append('echo "Testing ${docker_image:=%s}"' % + docker_image) + manual_cmd_log.append(manual_cmdline(cmdline, docker_image)) + cwd = None + environ = None + + suite_name = 'cloud_to_prod_auth' if auth else 'cloud_to_prod' + test_job = jobset.JobSpec( + cmdline=cmdline, + cwd=cwd, + environ=environ, + shortname='%s:%s:%s:%s' % (suite_name, language, server_host_name, + test_case), + timeout_seconds=_TEST_TIMEOUT, + flake_retries=4 if args.allow_flakes else 0, + timeout_retries=2 if args.allow_flakes else 0, + kill_handler=_job_kill_handler) + if docker_image: + test_job.container_name = container_name + return test_job + + +def cloud_to_cloud_jobspec(language, + test_case, + server_name, + server_host, + server_port, + docker_image=None, + insecure=False, + 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 test_case in _HTTP2_SERVER_TEST_CASES: + client_test_case = test_case if test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS: - client_options = interop_only_options + common_options - cmdline = bash_cmdline(language.client_cmd(client_options)) - cwd = language.client_cwd - else: - cmdline = bash_cmdline(language.client_cmd_http2interop(common_options)) - cwd = language.http2_cwd - else: - cmdline = bash_cmdline(language.client_cmd(common_options+interop_only_options)) - cwd = language.client_cwd + client_test_case = _GRPC_CLIENT_TEST_CASES_FOR_HTTP2_SERVER_TEST_CASES[ + test_case] + if client_test_case in language.unimplemented_test_cases(): + print('asking client %s to run unimplemented test case %s' % + (repr(language), client_test_case)) + sys.exit(1) + + common_options = [ + '--test_case=%s' % client_test_case, + '--server_host=%s' % server_host, + '--server_port=%s' % server_port, + ] - environ = language.global_env() - if docker_image and language.safename != 'objc': - # we can't run client in docker for objc. - container_name = dockerjob.random_name('interop_client_%s' % language.safename) - cmdline = docker_run_cmdline(cmdline, - image=docker_image, - environ=environ, - cwd=cwd, - docker_args=['--net=host', - '--name=%s' % container_name]) - if manual_cmd_log is not None: - if manual_cmd_log == []: - manual_cmd_log.append('echo "Testing ${docker_image:=%s}"' % docker_image) - manual_cmd_log.append(manual_cmdline(cmdline, docker_image)) - cwd = None - - test_job = jobset.JobSpec( - cmdline=cmdline, - cwd=cwd, - environ=environ, - shortname='cloud_to_cloud:%s:%s_server:%s' % (language, server_name, - test_case), - timeout_seconds=_TEST_TIMEOUT, - flake_retries=4 if args.allow_flakes else 0, - timeout_retries=2 if args.allow_flakes else 0, - kill_handler=_job_kill_handler) - if docker_image: - test_job.container_name = container_name - return test_job + if test_case in _HTTP2_SERVER_TEST_CASES: + if test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS: + client_options = interop_only_options + common_options + cmdline = bash_cmdline(language.client_cmd(client_options)) + cwd = language.client_cwd + else: + cmdline = bash_cmdline( + language.client_cmd_http2interop(common_options)) + cwd = language.http2_cwd + else: + cmdline = bash_cmdline( + language.client_cmd(common_options + interop_only_options)) + cwd = language.client_cwd + + environ = language.global_env() + if docker_image and language.safename != 'objc': + # we can't run client in docker for objc. + container_name = dockerjob.random_name('interop_client_%s' % + language.safename) + cmdline = docker_run_cmdline( + cmdline, + image=docker_image, + environ=environ, + cwd=cwd, + docker_args=['--net=host', '--name=%s' % container_name]) + if manual_cmd_log is not None: + if manual_cmd_log == []: + manual_cmd_log.append('echo "Testing ${docker_image:=%s}"' % + docker_image) + manual_cmd_log.append(manual_cmdline(cmdline, docker_image)) + cwd = None + + test_job = jobset.JobSpec( + cmdline=cmdline, + cwd=cwd, + environ=environ, + shortname='cloud_to_cloud:%s:%s_server:%s' % (language, server_name, + test_case), + timeout_seconds=_TEST_TIMEOUT, + flake_retries=4 if args.allow_flakes else 0, + timeout_retries=2 if args.allow_flakes else 0, + kill_handler=_job_kill_handler) + if docker_image: + test_job.container_name = container_name + return test_job def server_jobspec(language, docker_image, insecure=False, 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')])) - environ = language.global_env() - docker_args = ['--name=%s' % container_name] - if language.safename == 'http2': - # we are running the http2 interop server. Open next N ports beginning - # with the server port. These ports are used for http2 interop test - # (one test case per port). - docker_args += list( - itertools.chain.from_iterable(('-p', str(_DEFAULT_SERVER_PORT + i)) - for i in range( - len(_HTTP2_SERVER_TEST_CASES)))) - # Enable docker's healthcheck mechanism. - # This runs a Python script inside the container every second. The script - # pings the http2 server to verify it is ready. The 'health-retries' flag - # specifies the number of consecutive failures before docker will report - # the container's status as 'unhealthy'. Prior to the first 'health_retries' - # failures or the first success, the status will be 'starting'. 'docker ps' - # or 'docker inspect' can be used to see the health of the container on the - # command line. - docker_args += [ - '--health-cmd=python test/http2_test/http2_server_health_check.py ' - '--server_host=%s --server_port=%d' - % ('localhost', _DEFAULT_SERVER_PORT), - '--health-interval=1s', - '--health-retries=5', - '--health-timeout=10s', - ] + """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') + ])) + environ = language.global_env() + docker_args = ['--name=%s' % container_name] + if language.safename == 'http2': + # we are running the http2 interop server. Open next N ports beginning + # with the server port. These ports are used for http2 interop test + # (one test case per port). + docker_args += list( + itertools.chain.from_iterable(('-p', str(_DEFAULT_SERVER_PORT + i)) + for i in range( + len(_HTTP2_SERVER_TEST_CASES)))) + # Enable docker's healthcheck mechanism. + # This runs a Python script inside the container every second. The script + # pings the http2 server to verify it is ready. The 'health-retries' flag + # specifies the number of consecutive failures before docker will report + # the container's status as 'unhealthy'. Prior to the first 'health_retries' + # failures or the first success, the status will be 'starting'. 'docker ps' + # or 'docker inspect' can be used to see the health of the container on the + # command line. + docker_args += [ + '--health-cmd=python test/http2_test/http2_server_health_check.py ' + '--server_host=%s --server_port=%d' % + ('localhost', _DEFAULT_SERVER_PORT), + '--health-interval=1s', + '--health-retries=5', + '--health-timeout=10s', + ] - else: - docker_args += ['-p', str(_DEFAULT_SERVER_PORT)] - - docker_cmdline = docker_run_cmdline(cmdline, - image=docker_image, - cwd=language.server_cwd, - environ=environ, - docker_args=docker_args) - if manual_cmd_log is not None: - if manual_cmd_log == []: - manual_cmd_log.append('echo "Testing ${docker_image:=%s}"' % docker_image) - manual_cmd_log.append(manual_cmdline(docker_cmdline, docker_image)) - server_job = jobset.JobSpec( - cmdline=docker_cmdline, - environ=environ, - shortname='interop_server_%s' % language, - timeout_seconds=30*60) - server_job.container_name = container_name - return server_job + else: + docker_args += ['-p', str(_DEFAULT_SERVER_PORT)] + + docker_cmdline = docker_run_cmdline( + cmdline, + image=docker_image, + cwd=language.server_cwd, + environ=environ, + docker_args=docker_args) + if manual_cmd_log is not None: + if manual_cmd_log == []: + manual_cmd_log.append('echo "Testing ${docker_image:=%s}"' % + docker_image) + manual_cmd_log.append(manual_cmdline(docker_cmdline, docker_image)) + server_job = jobset.JobSpec( + cmdline=docker_cmdline, + environ=environ, + shortname='interop_server_%s' % language, + timeout_seconds=30 * 60) + server_job.container_name = container_name + return server_job def build_interop_image_jobspec(language, tag=None): - """Creates jobspec for building interop docker image for a language""" - if not tag: - tag = 'grpc_interop_%s:%s' % (language.safename, uuid.uuid4()) - env = {'INTEROP_IMAGE': tag, - 'BASE_NAME': 'grpc_interop_%s' % language.safename} - if not args.travis: - env['TTY_FLAG'] = '-t' - # This env variable is used to get around the github rate limit - # error when running the PHP `composer install` command - host_file = '%s/.composer/auth.json' % os.environ['HOME'] - if language.safename == 'php' and os.path.exists(host_file): - env['BUILD_INTEROP_DOCKER_EXTRA_ARGS'] = \ - '-v %s:/root/.composer/auth.json:ro' % host_file - build_job = jobset.JobSpec( - cmdline=['tools/run_tests/dockerize/build_interop_image.sh'], - environ=env, - shortname='build_docker_%s' % (language), - timeout_seconds=30*60) - build_job.tag = tag - return build_job + """Creates jobspec for building interop docker image for a language""" + if not tag: + tag = 'grpc_interop_%s:%s' % (language.safename, uuid.uuid4()) + env = { + 'INTEROP_IMAGE': tag, + 'BASE_NAME': 'grpc_interop_%s' % language.safename + } + if not args.travis: + env['TTY_FLAG'] = '-t' + # This env variable is used to get around the github rate limit + # error when running the PHP `composer install` command + host_file = '%s/.composer/auth.json' % os.environ['HOME'] + if language.safename == 'php' and os.path.exists(host_file): + env['BUILD_INTEROP_DOCKER_EXTRA_ARGS'] = \ + '-v %s:/root/.composer/auth.json:ro' % host_file + build_job = jobset.JobSpec( + cmdline=['tools/run_tests/dockerize/build_interop_image.sh'], + environ=env, + shortname='build_docker_%s' % (language), + timeout_seconds=30 * 60) + build_job.tag = tag + return build_job def aggregate_http2_results(stdout): - match = re.search(r'\{"cases[^\]]*\]\}', stdout) - if not match: - return None - - results = json.loads(match.group(0)) - skipped = 0 - passed = 0 - failed = 0 - failed_cases = [] - for case in results['cases']: - if case.get('skipped', False): - skipped += 1 - else: - if case.get('passed', False): - passed += 1 - else: - failed += 1 - failed_cases.append(case.get('name', "NONAME")) - return { - 'passed': passed, - 'failed': failed, - 'skipped': skipped, - 'failed_cases': ', '.join(failed_cases), - 'percent': 1.0 * passed / (passed + failed) - } + match = re.search(r'\{"cases[^\]]*\]\}', stdout) + if not match: + return None + + results = json.loads(match.group(0)) + skipped = 0 + passed = 0 + failed = 0 + failed_cases = [] + for case in results['cases']: + if case.get('skipped', False): + skipped += 1 + else: + if case.get('passed', False): + passed += 1 + else: + failed += 1 + failed_cases.append(case.get('name', "NONAME")) + return { + 'passed': passed, + 'failed': failed, + 'skipped': skipped, + 'failed_cases': ', '.join(failed_cases), + 'percent': 1.0 * passed / (passed + failed) + } + # 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), + '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), + '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), } argp = argparse.ArgumentParser(description='Run interop tests.') -argp.add_argument('-l', '--language', - choices=['all'] + sorted(_LANGUAGES), - nargs='+', - default=['all'], - help='Clients to run. Objc client can be only run on OSX.') +argp.add_argument( + '-l', + '--language', + choices=['all'] + sorted(_LANGUAGES), + nargs='+', + default=['all'], + help='Clients to run. Objc client can be only run on OSX.') argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int) -argp.add_argument('--cloud_to_prod', - default=False, - action='store_const', - const=True, - help='Run cloud_to_prod tests.') -argp.add_argument('--cloud_to_prod_auth', - default=False, - action='store_const', - const=True, - help='Run cloud_to_prod_auth tests.') -argp.add_argument('--prod_servers', - choices=prod_servers.keys(), - default=['default'], - nargs='+', - help=('The servers to run cloud_to_prod and ' - 'cloud_to_prod_auth tests against.')) -argp.add_argument('-s', '--server', - choices=['all'] + sorted(_SERVERS), - nargs='+', - help='Run cloud_to_cloud servers in a separate docker ' + - 'image. Servers can only be started automatically if ' + - '--use_docker option is enabled.', - default=[]) -argp.add_argument('--override_server', - action='append', - type=lambda kv: kv.split('='), - help='Use servername=HOST:PORT to explicitly specify a server. E.g. csharp=localhost:50000', - default=[]) -argp.add_argument('-t', '--travis', - default=False, - action='store_const', - const=True) -argp.add_argument('-v', '--verbose', - default=False, - action='store_const', - const=True) -argp.add_argument('--use_docker', - default=False, - action='store_const', - const=True, - help='Run all the interop tests under docker. That provides ' + - 'additional isolation and prevents the need to install ' + - 'language specific prerequisites. Only available on Linux.') -argp.add_argument('--allow_flakes', - default=False, - action='store_const', - const=True, - help='Allow flaky tests to show as passing (re-runs failed tests up to five times)') -argp.add_argument('--manual_run', - default=False, - action='store_const', - const=True, - help='Prepare things for running interop tests manually. ' + - 'Preserve docker images after building them and skip ' - 'actually running the tests. Only print commands to run by ' + - 'hand.') -argp.add_argument('--http2_interop', - default=False, - action='store_const', - const=True, - help='Enable HTTP/2 client edge case testing. (Bad client, good server)') -argp.add_argument('--http2_server_interop', - default=False, - action='store_const', - const=True, - help='Enable HTTP/2 server edge case testing. (Includes positive and negative tests') -argp.add_argument('--insecure', - default=False, - action='store_const', - const=True, - help='Whether to use secure channel.') -argp.add_argument('--internal_ci', - default=False, - action='store_const', - const=True, - help=('Put reports into subdirectories to improve ' - 'presentation of results by Internal CI.')) -argp.add_argument('--bq_result_table', - default='', - type=str, - nargs='?', - help='Upload test results to a specified BQ table.') +argp.add_argument( + '--cloud_to_prod', + default=False, + action='store_const', + const=True, + help='Run cloud_to_prod tests.') +argp.add_argument( + '--cloud_to_prod_auth', + default=False, + action='store_const', + const=True, + help='Run cloud_to_prod_auth tests.') +argp.add_argument( + '--prod_servers', + choices=prod_servers.keys(), + default=['default'], + nargs='+', + help=('The servers to run cloud_to_prod and ' + 'cloud_to_prod_auth tests against.')) +argp.add_argument( + '-s', + '--server', + choices=['all'] + sorted(_SERVERS), + nargs='+', + help='Run cloud_to_cloud servers in a separate docker ' + + 'image. Servers can only be started automatically if ' + + '--use_docker option is enabled.', + default=[]) +argp.add_argument( + '--override_server', + action='append', + type=lambda kv: kv.split('='), + help='Use servername=HOST:PORT to explicitly specify a server. E.g. csharp=localhost:50000', + default=[]) +argp.add_argument( + '-t', '--travis', default=False, action='store_const', const=True) +argp.add_argument( + '-v', '--verbose', default=False, action='store_const', const=True) +argp.add_argument( + '--use_docker', + default=False, + action='store_const', + const=True, + help='Run all the interop tests under docker. That provides ' + + 'additional isolation and prevents the need to install ' + + 'language specific prerequisites. Only available on Linux.') +argp.add_argument( + '--allow_flakes', + default=False, + action='store_const', + const=True, + help='Allow flaky tests to show as passing (re-runs failed tests up to five times)' +) +argp.add_argument( + '--manual_run', + default=False, + action='store_const', + const=True, + help='Prepare things for running interop tests manually. ' + + 'Preserve docker images after building them and skip ' + 'actually running the tests. Only print commands to run by ' + 'hand.') +argp.add_argument( + '--http2_interop', + default=False, + action='store_const', + const=True, + help='Enable HTTP/2 client edge case testing. (Bad client, good server)') +argp.add_argument( + '--http2_server_interop', + default=False, + action='store_const', + const=True, + help='Enable HTTP/2 server edge case testing. (Includes positive and negative tests' +) +argp.add_argument( + '--insecure', + default=False, + action='store_const', + const=True, + help='Whether to use secure channel.') +argp.add_argument( + '--internal_ci', + default=False, + action='store_const', + const=True, + help=('Put reports into subdirectories to improve ' + 'presentation of results by Internal CI.')) +argp.add_argument( + '--bq_result_table', + default='', + type=str, + nargs='?', + help='Upload test results to a specified BQ table.') args = argp.parse_args() -servers = set(s for s in itertools.chain.from_iterable(_SERVERS - if x == 'all' else [x] - for x in args.server)) +servers = set( + s + for s in itertools.chain.from_iterable(_SERVERS if x == 'all' else [x] + for x in args.server)) if args.use_docker: - if not args.travis: - print('Seen --use_docker flag, will run interop tests under docker.') - print('') - print('IMPORTANT: The changes you are testing need to be locally committed') - print('because only the committed changes in the current branch will be') - print('copied to the docker environment.') - time.sleep(5) + if not args.travis: + print('Seen --use_docker flag, will run interop tests under docker.') + print('') + print( + 'IMPORTANT: The changes you are testing need to be locally committed' + ) + print( + 'because only the committed changes in the current branch will be') + print('copied to the docker environment.') + time.sleep(5) if args.manual_run and not args.use_docker: - print('--manual_run is only supported with --use_docker option enabled.') - sys.exit(1) + print('--manual_run is only supported with --use_docker option enabled.') + sys.exit(1) if not args.use_docker and servers: - print('Running interop servers is only supported with --use_docker option enabled.') - sys.exit(1) - + print( + 'Running interop servers is only supported with --use_docker option enabled.' + ) + sys.exit(1) # we want to include everything but objc in 'all' # because objc won't run on non-mac platforms 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)) +languages = set( + _LANGUAGES[l] + for l in itertools.chain.from_iterable(all_but_objc if x == 'all' else [x] + for x in args.language)) languages_http2_clients_for_http2_server_interop = set() if args.http2_server_interop: - languages_http2_clients_for_http2_server_interop = set( - _LANGUAGES[l] for l in _LANGUAGES_WITH_HTTP2_CLIENTS_FOR_HTTP2_SERVER_TEST_CASES - if 'all' in args.language or l in args.language) + languages_http2_clients_for_http2_server_interop = set( + _LANGUAGES[l] + for l in _LANGUAGES_WITH_HTTP2_CLIENTS_FOR_HTTP2_SERVER_TEST_CASES + if 'all' in args.language or l in args.language) http2Interop = Http2Client() if args.http2_interop else None http2InteropServer = Http2Server() if args.http2_server_interop else None -docker_images={} +docker_images = {} if args.use_docker: - # languages for which to build docker images - languages_to_build = set( - _LANGUAGES[k] for k in set([str(l) for l in languages] + [s for s in servers])) - languages_to_build = languages_to_build | languages_http2_clients_for_http2_server_interop - - if args.http2_interop: - languages_to_build.add(http2Interop) - - if args.http2_server_interop: - languages_to_build.add(http2InteropServer) - - build_jobs = [] - for l in languages_to_build: - if str(l) == 'objc': - # we don't need to build a docker image for objc - continue - job = build_interop_image_jobspec(l) - docker_images[str(l)] = job.tag - build_jobs.append(job) - - if build_jobs: - jobset.message('START', 'Building interop docker images.', do_newline=True) - if args.verbose: - print('Jobs to run: \n%s\n' % '\n'.join(str(j) for j in build_jobs)) + # languages for which to build docker images + languages_to_build = set( + _LANGUAGES[k] + for k in set([str(l) for l in languages] + [s for s in servers])) + languages_to_build = languages_to_build | languages_http2_clients_for_http2_server_interop - num_failures, _ = jobset.run( - build_jobs, newline_on_success=True, maxjobs=args.jobs) - if num_failures == 0: - jobset.message('SUCCESS', 'All docker images built successfully.', - do_newline=True) - else: - jobset.message('FAILED', 'Failed to build interop docker images.', - do_newline=True) - for image in six.itervalues(docker_images): - dockerjob.remove_image(image, skip_nonexistent=True) - sys.exit(1) + if args.http2_interop: + languages_to_build.add(http2Interop) + + if args.http2_server_interop: + languages_to_build.add(http2InteropServer) + + build_jobs = [] + for l in languages_to_build: + if str(l) == 'objc': + # we don't need to build a docker image for objc + continue + job = build_interop_image_jobspec(l) + docker_images[str(l)] = job.tag + build_jobs.append(job) + + if build_jobs: + jobset.message( + 'START', 'Building interop docker images.', do_newline=True) + if args.verbose: + print('Jobs to run: \n%s\n' % '\n'.join(str(j) for j in build_jobs)) + + num_failures, _ = jobset.run( + build_jobs, newline_on_success=True, maxjobs=args.jobs) + if num_failures == 0: + jobset.message( + 'SUCCESS', + 'All docker images built successfully.', + do_newline=True) + else: + jobset.message( + 'FAILED', + 'Failed to build interop docker images.', + do_newline=True) + for image in six.itervalues(docker_images): + dockerjob.remove_image(image, skip_nonexistent=True) + sys.exit(1) server_manual_cmd_log = [] if args.manual_run else None client_manual_cmd_log = [] if args.manual_run else None @@ -1056,214 +1134,236 @@ client_manual_cmd_log = [] if args.manual_run else None server_jobs = {} server_addresses = {} try: - for s in servers: - lang = str(s) - spec = server_jobspec(_LANGUAGES[lang], docker_images.get(lang), - args.insecure, manual_cmd_log=server_manual_cmd_log) - if not args.manual_run: - job = dockerjob.DockerJob(spec) - server_jobs[lang] = job - server_addresses[lang] = ('localhost', job.mapped_port(_DEFAULT_SERVER_PORT)) - else: - # don't run the server, set server port to a placeholder value - server_addresses[lang] = ('localhost', '${SERVER_PORT}') - - http2_server_job = None - if args.http2_server_interop: - # launch a HTTP2 server emulator that creates edge cases - lang = str(http2InteropServer) - spec = server_jobspec(http2InteropServer, docker_images.get(lang), - manual_cmd_log=server_manual_cmd_log) - if not args.manual_run: - http2_server_job = dockerjob.DockerJob(spec) - server_jobs[lang] = http2_server_job - else: - # don't run the server, set server port to a placeholder value - server_addresses[lang] = ('localhost', '${SERVER_PORT}') - - jobs = [] - if args.cloud_to_prod: - if args.insecure: - print('TLS is always enabled for cloud_to_prod scenarios.') - for server_host_name in args.prod_servers: - for language in languages: - for test_case in _TEST_CASES: - if not test_case in language.unimplemented_test_cases(): - if not test_case in _SKIP_ADVANCED + _SKIP_COMPRESSION: - test_job = cloud_to_prod_jobspec( - language, test_case, server_host_name, - prod_servers[server_host_name], - docker_image=docker_images.get(str(language)), - manual_cmd_log=client_manual_cmd_log) - jobs.append(test_job) - - if args.http2_interop: - for test_case in _HTTP2_TEST_CASES: - test_job = cloud_to_prod_jobspec( - http2Interop, test_case, server_host_name, - prod_servers[server_host_name], - docker_image=docker_images.get(str(http2Interop)), - manual_cmd_log=client_manual_cmd_log) - jobs.append(test_job) - - if args.cloud_to_prod_auth: - if args.insecure: - print('TLS is always enabled for cloud_to_prod scenarios.') - for server_host_name 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) - - for server in args.override_server: - server_name = server[0] - (server_host, server_port) = server[1].split(':') - server_addresses[server_name] = (server_host, server_port) - - for server_name, server_address in server_addresses.items(): - (server_host, server_port) = server_address - server_language = _LANGUAGES.get(server_name, None) - skip_server = [] # test cases unimplemented by server - if server_language: - skip_server = server_language.unimplemented_test_cases_server() - for language in languages: - for test_case in _TEST_CASES: - if not test_case in language.unimplemented_test_cases(): - if not test_case in skip_server: - test_job = cloud_to_cloud_jobspec(language, - test_case, - server_name, - server_host, - server_port, - docker_image=docker_images.get(str(language)), - insecure=args.insecure, - manual_cmd_log=client_manual_cmd_log) - jobs.append(test_job) - - if args.http2_interop: - for test_case in _HTTP2_TEST_CASES: - if server_name == "go": - # TODO(carl-mastrangelo): Reenable after https://github.com/grpc/grpc-go/issues/434 - continue - test_job = cloud_to_cloud_jobspec(http2Interop, - test_case, - server_name, - server_host, - server_port, - docker_image=docker_images.get(str(http2Interop)), - insecure=args.insecure, - manual_cmd_log=client_manual_cmd_log) - jobs.append(test_job) - - if args.http2_server_interop: - if not args.manual_run: - http2_server_job.wait_for_healthy(timeout_seconds=600) - for language in languages_http2_clients_for_http2_server_interop: - for test_case in set(_HTTP2_SERVER_TEST_CASES) - set(_HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS): - offset = sorted(_HTTP2_SERVER_TEST_CASES).index(test_case) - server_port = _DEFAULT_SERVER_PORT+offset + for s in servers: + lang = str(s) + spec = server_jobspec( + _LANGUAGES[lang], + docker_images.get(lang), + args.insecure, + manual_cmd_log=server_manual_cmd_log) if not args.manual_run: - server_port = http2_server_job.mapped_port(server_port) - test_job = cloud_to_cloud_jobspec(language, - test_case, - str(http2InteropServer), - 'localhost', - server_port, - docker_image=docker_images.get(str(language)), - manual_cmd_log=client_manual_cmd_log) - jobs.append(test_job) - for language in languages: - # HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS is a subset of - # HTTP_SERVER_TEST_CASES, in which clients use their gRPC interop clients rather - # than specialized http2 clients, reusing existing test implementations. - # For example, in the "data_frame_padding" test, use language's gRPC - # interop clients and make them think that theyre running "large_unary" - # test case. This avoids implementing a new test case in each language. - for test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS: - if test_case not in language.unimplemented_test_cases(): - offset = sorted(_HTTP2_SERVER_TEST_CASES).index(test_case) - 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.')) - test_job = cloud_to_cloud_jobspec(language, - test_case, - str(http2InteropServer), - 'localhost', - server_port, - docker_image=docker_images.get(str(language)), - insecure=True, - manual_cmd_log=client_manual_cmd_log) - jobs.append(test_job) - - if not jobs: - print('No jobs to run.') - for image in six.itervalues(docker_images): - dockerjob.remove_image(image, skip_nonexistent=True) - sys.exit(1) - - if args.manual_run: - print('All tests will skipped --manual_run option is active.') - - if args.verbose: - print('Jobs to run: \n%s\n' % '\n'.join(str(job) for job in jobs)) + job = dockerjob.DockerJob(spec) + server_jobs[lang] = job + server_addresses[lang] = ('localhost', + job.mapped_port(_DEFAULT_SERVER_PORT)) + else: + # don't run the server, set server port to a placeholder value + server_addresses[lang] = ('localhost', '${SERVER_PORT}') + + http2_server_job = None + if args.http2_server_interop: + # launch a HTTP2 server emulator that creates edge cases + lang = str(http2InteropServer) + spec = server_jobspec( + http2InteropServer, + docker_images.get(lang), + manual_cmd_log=server_manual_cmd_log) + if not args.manual_run: + http2_server_job = dockerjob.DockerJob(spec) + server_jobs[lang] = http2_server_job + else: + # don't run the server, set server port to a placeholder value + server_addresses[lang] = ('localhost', '${SERVER_PORT}') + + jobs = [] + if args.cloud_to_prod: + if args.insecure: + print('TLS is always enabled for cloud_to_prod scenarios.') + for server_host_name in args.prod_servers: + for language in languages: + for test_case in _TEST_CASES: + if not test_case in language.unimplemented_test_cases(): + if not test_case in _SKIP_ADVANCED + _SKIP_COMPRESSION: + test_job = cloud_to_prod_jobspec( + language, + test_case, + server_host_name, + prod_servers[server_host_name], + docker_image=docker_images.get(str(language)), + manual_cmd_log=client_manual_cmd_log) + jobs.append(test_job) + + if args.http2_interop: + for test_case in _HTTP2_TEST_CASES: + test_job = cloud_to_prod_jobspec( + http2Interop, + test_case, + server_host_name, + prod_servers[server_host_name], + docker_image=docker_images.get(str(http2Interop)), + manual_cmd_log=client_manual_cmd_log) + jobs.append(test_job) + + if args.cloud_to_prod_auth: + if args.insecure: + print('TLS is always enabled for cloud_to_prod scenarios.') + for server_host_name 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) + + for server in args.override_server: + server_name = server[0] + (server_host, server_port) = server[1].split(':') + server_addresses[server_name] = (server_host, server_port) + + for server_name, server_address in server_addresses.items(): + (server_host, server_port) = server_address + server_language = _LANGUAGES.get(server_name, None) + skip_server = [] # test cases unimplemented by server + if server_language: + skip_server = server_language.unimplemented_test_cases_server() + for language in languages: + for test_case in _TEST_CASES: + if not test_case in language.unimplemented_test_cases(): + if not test_case in skip_server: + test_job = cloud_to_cloud_jobspec( + language, + test_case, + server_name, + server_host, + server_port, + docker_image=docker_images.get(str(language)), + insecure=args.insecure, + manual_cmd_log=client_manual_cmd_log) + jobs.append(test_job) + + if args.http2_interop: + for test_case in _HTTP2_TEST_CASES: + if server_name == "go": + # TODO(carl-mastrangelo): Reenable after https://github.com/grpc/grpc-go/issues/434 + continue + test_job = cloud_to_cloud_jobspec( + http2Interop, + test_case, + server_name, + server_host, + server_port, + docker_image=docker_images.get(str(http2Interop)), + insecure=args.insecure, + manual_cmd_log=client_manual_cmd_log) + jobs.append(test_job) + + if args.http2_server_interop: + if not args.manual_run: + http2_server_job.wait_for_healthy(timeout_seconds=600) + for language in languages_http2_clients_for_http2_server_interop: + for test_case in set(_HTTP2_SERVER_TEST_CASES) - set( + _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS): + offset = sorted(_HTTP2_SERVER_TEST_CASES).index(test_case) + server_port = _DEFAULT_SERVER_PORT + offset + if not args.manual_run: + server_port = http2_server_job.mapped_port(server_port) + test_job = cloud_to_cloud_jobspec( + language, + test_case, + str(http2InteropServer), + 'localhost', + server_port, + docker_image=docker_images.get(str(language)), + manual_cmd_log=client_manual_cmd_log) + jobs.append(test_job) + for language in languages: + # HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS is a subset of + # HTTP_SERVER_TEST_CASES, in which clients use their gRPC interop clients rather + # than specialized http2 clients, reusing existing test implementations. + # For example, in the "data_frame_padding" test, use language's gRPC + # interop clients and make them think that theyre running "large_unary" + # test case. This avoids implementing a new test case in each language. + for test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS: + if test_case not in language.unimplemented_test_cases(): + offset = sorted(_HTTP2_SERVER_TEST_CASES).index(test_case) + 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.' + )) + test_job = cloud_to_cloud_jobspec( + language, + test_case, + str(http2InteropServer), + 'localhost', + server_port, + docker_image=docker_images.get(str(language)), + insecure=True, + manual_cmd_log=client_manual_cmd_log) + jobs.append(test_job) + + if not jobs: + print('No jobs to run.') + for image in six.itervalues(docker_images): + dockerjob.remove_image(image, skip_nonexistent=True) + sys.exit(1) + + if args.manual_run: + print('All tests will skipped --manual_run option is active.') - num_failures, resultset = jobset.run(jobs, newline_on_success=True, - maxjobs=args.jobs, - skip_jobs=args.manual_run) - if args.bq_result_table and resultset: - upload_interop_results_to_bq(resultset, args.bq_result_table, args) - if num_failures: - jobset.message('FAILED', 'Some tests failed', do_newline=True) - else: - jobset.message('SUCCESS', 'All tests passed', do_newline=True) + if args.verbose: + print('Jobs to run: \n%s\n' % '\n'.join(str(job) for job in jobs)) + + num_failures, resultset = jobset.run( + jobs, + newline_on_success=True, + maxjobs=args.jobs, + skip_jobs=args.manual_run) + if args.bq_result_table and resultset: + upload_interop_results_to_bq(resultset, args.bq_result_table, args) + if num_failures: + jobset.message('FAILED', 'Some tests failed', do_newline=True) + else: + jobset.message('SUCCESS', 'All tests passed', do_newline=True) - write_cmdlog_maybe(server_manual_cmd_log, 'interop_server_cmds.sh') - write_cmdlog_maybe(client_manual_cmd_log, 'interop_client_cmds.sh') + write_cmdlog_maybe(server_manual_cmd_log, 'interop_server_cmds.sh') + write_cmdlog_maybe(client_manual_cmd_log, 'interop_client_cmds.sh') - xml_report_name = _XML_REPORT - if args.internal_ci: - xml_report_name = _INTERNAL_CL_XML_REPORT - report_utils.render_junit_xml_report(resultset, xml_report_name) + xml_report_name = _XML_REPORT + if args.internal_ci: + xml_report_name = _INTERNAL_CL_XML_REPORT + report_utils.render_junit_xml_report(resultset, xml_report_name) - for name, job in resultset.items(): - if "http2" in name: - job[0].http2results = aggregate_http2_results(job[0].message) + for name, job in resultset.items(): + if "http2" in name: + job[0].http2results = aggregate_http2_results(job[0].message) - http2_server_test_cases = ( - _HTTP2_SERVER_TEST_CASES if args.http2_server_interop else []) + 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) + 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: - sys.exit(0) + if num_failures: + sys.exit(1) + else: + sys.exit(0) except Exception as e: - print('exception occurred:') - traceback.print_exc(file=sys.stdout) + print('exception occurred:') + traceback.print_exc(file=sys.stdout) finally: - # Check if servers are still running. - for server, job in server_jobs.items(): - if not job.is_running(): - print('Server "%s" has exited prematurely.' % server) + # Check if servers are still running. + for server, job in server_jobs.items(): + if not job.is_running(): + print('Server "%s" has exited prematurely.' % server) - dockerjob.finish_jobs([j for j in six.itervalues(server_jobs)]) + dockerjob.finish_jobs([j for j in six.itervalues(server_jobs)]) - for image in six.itervalues(docker_images): - if not args.manual_run: - print('Removing docker image %s' % image) - dockerjob.remove_image(image) - else: - print('Preserving docker image: %s' % image) + for image in six.itervalues(docker_images): + if not args.manual_run: + print('Removing docker image %s' % image) + dockerjob.remove_image(image) + else: + print('Preserving docker image: %s' % image) |