diff --git a/tools/run_tests/dockerjob.py b/tools/run_tests/dockerjob.py index 266edd4375b3479b7b618921d7c8f1fbf52fd449..1d67fe3033e2d0880fedb512cc96ff0dbeaaf80f 100755 --- a/tools/run_tests/dockerjob.py +++ b/tools/run_tests/dockerjob.py @@ -46,13 +46,24 @@ def random_name(base_name): def docker_kill(cid): """Kills a docker container. Returns True if successful.""" - return subprocess.call(['docker','kill', str(cid)]) == 0 + return subprocess.call(['docker','kill', str(cid)], + stdout=_DEVNULL, + stderr=subprocess.STDOUT) == 0 -def docker_mapped_port(cid, port): +def docker_mapped_port(cid, port, timeout_seconds=15): """Get port mapped to internal given internal port for given container.""" - output = subprocess.check_output('docker port %s %s' % (cid, port), shell=True) - return int(output.split(':', 2)[1]) + started = time.time() + while time.time() - started < timeout_seconds: + try: + output = subprocess.check_output('docker port %s %s' % (cid, port), + stderr=_DEVNULL, + shell=True) + return int(output.split(':', 2)[1]) + except subprocess.CalledProcessError as e: + pass + raise Exception('Failed to get exposed port %s for container %s.' % + (port, cid)) def finish_jobs(jobs): @@ -68,7 +79,7 @@ def image_exists(image): """Returns True if given docker image exists.""" return subprocess.call(['docker','inspect', image], stdout=_DEVNULL, - stderr=_DEVNULL) == 0 + stderr=subprocess.STDOUT) == 0 def remove_image(image, skip_nonexistent=False, max_retries=10): @@ -76,7 +87,9 @@ def remove_image(image, skip_nonexistent=False, max_retries=10): if skip_nonexistent and not image_exists(image): return True for attempt in range(0, max_retries): - if subprocess.call(['docker','rmi', '-f', image]) == 0: + if subprocess.call(['docker','rmi', '-f', image], + stdout=_DEVNULL, + stderr=subprocess.STDOUT) == 0: return True time.sleep(2) print 'Failed to remove docker image %s' % image diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 4d09ae7fcdafc87b2294d19e95d044e31853a848..6daa967bba488f01f0e8a589a205aa72a3c079ce 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -71,6 +71,7 @@ class CXXLanguage: self.client_cmdline_base = ['bins/opt/interop_client'] self.client_cwd = None self.server_cwd = None + self.safename = 'cxx' def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -96,6 +97,7 @@ class CSharpLanguage: self.client_cmdline_base = ['mono', 'Grpc.IntegrationTesting.Client.exe'] self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug' self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug' + self.safename = str(self) def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -121,6 +123,7 @@ class JavaLanguage: self.client_cmdline_base = ['./run-test-client.sh'] self.client_cwd = '../grpc-java' self.server_cwd = '../grpc-java' + self.safename = str(self) def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -147,6 +150,7 @@ class GoLanguage: # 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.safename = str(self) def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -172,6 +176,7 @@ class NodeLanguage: self.client_cmdline_base = ['node', 'src/node/interop/interop_client.js'] self.client_cwd = None self.server_cwd = None + self.safename = str(self) def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -196,6 +201,7 @@ class PHPLanguage: def __init__(self): self.client_cmdline_base = ['src/php/bin/interop_client.sh'] self.client_cwd = None + self.safename = str(self) def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -218,6 +224,7 @@ class RubyLanguage: self.client_cmdline_base = ['ruby', 'src/ruby/bin/interop/interop_client.rb'] self.client_cwd = None self.server_cwd = None + self.safename = str(self) def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -251,11 +258,9 @@ _LANGUAGES = { # languages supported as cloud_to_cloud servers _SERVERS = ['c++', 'node', 'csharp', 'java', 'go', 'ruby'] -# TODO(jtattermusch): add empty_stream once PHP starts supporting it. # TODO(jtattermusch): add timeout_on_sleeping_server once java starts supporting it. -# TODO(jtattermusch): add support for auth tests. _TEST_CASES = ['large_unary', 'empty_unary', 'ping_pong', - 'client_streaming', 'server_streaming', + 'empty_stream', 'client_streaming', 'server_streaming', 'cancel_after_begin', 'cancel_after_first_response'] _AUTH_TEST_CASES = ['compute_engine_creds', 'jwt_token_creds', @@ -337,7 +342,7 @@ def cloud_to_prod_jobspec(language, test_case, docker_image=None, auth=False): cmdline = bash_login_cmdline(cmdline) if docker_image: - container_name = dockerjob.random_name('interop_client_%s' % language) + container_name = dockerjob.random_name('interop_client_%s' % language.safename) cmdline = docker_run_cmdline(cmdline, image=docker_image, cwd=cwd, @@ -370,7 +375,7 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host, '--server_port=%s' % server_port ]) cwd = language.client_cwd if docker_image: - container_name = dockerjob.random_name('interop_client_%s' % language) + container_name = dockerjob.random_name('interop_client_%s' % language.safename) cmdline = docker_run_cmdline(cmdline, image=docker_image, cwd=cwd, @@ -393,7 +398,7 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host, def server_jobspec(language, docker_image): """Create jobspec for running a server""" - container_name = dockerjob.random_name('interop_server_%s' % language) + container_name = dockerjob.random_name('interop_server_%s' % language.safename) cmdline = bash_login_cmdline(language.server_args() + ['--port=%s' % _DEFAULT_SERVER_PORT]) docker_cmdline = docker_run_cmdline(cmdline, @@ -411,10 +416,10 @@ def server_jobspec(language, docker_image): def build_interop_image_jobspec(language, tag=None): """Creates jobspec for building interop docker image for a language""" - safelang = str(language).replace("+", "x") if not tag: - tag = 'grpc_interop_%s:%s' % (safelang, uuid.uuid4()) - env = {'INTEROP_IMAGE': tag, 'BASE_NAME': 'grpc_interop_%s' % safelang} + 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' build_job = jobset.JobSpec(