From 18cc842d6fab8a485461a9cfc6f33dc6048f14d1 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi <soltanmm@users.noreply.github.com> Date: Fri, 9 Oct 2015 17:55:45 -0700 Subject: [PATCH] Add Python support to run_interop_tests.py --- tools/jenkins/grpc_interop_python/Dockerfile | 80 +++++++++++++++++++ .../grpc_interop_python/build_interop.sh | 47 +++++++++++ tools/run_tests/run_interop_tests.py | 64 ++++++++++++++- 3 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 tools/jenkins/grpc_interop_python/Dockerfile create mode 100755 tools/jenkins/grpc_interop_python/build_interop.sh diff --git a/tools/jenkins/grpc_interop_python/Dockerfile b/tools/jenkins/grpc_interop_python/Dockerfile new file mode 100644 index 00000000000..5850f5f321e --- /dev/null +++ b/tools/jenkins/grpc_interop_python/Dockerfile @@ -0,0 +1,80 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# A work-in-progress Dockerfile that allows running gRPC test suites +# inside a docker container. + +FROM debian:jessie + +# Install Git. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + gcc \ + gcc-multilib \ + git \ + gyp \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + strace \ + python-dev \ + python-pip \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +# Prepare ccache +RUN ln -s /usr/bin/ccache /usr/local/bin/gcc +RUN ln -s /usr/bin/ccache /usr/local/bin/g++ +RUN ln -s /usr/bin/ccache /usr/local/bin/cc +RUN ln -s /usr/bin/ccache /usr/local/bin/c++ +RUN ln -s /usr/bin/ccache /usr/local/bin/clang +RUN ln -s /usr/bin/ccache /usr/local/bin/clang++ + + +##################### +# Python dependencies + +# Install Python requisites +RUN /bin/bash -l -c "pip install --upgrade pip" +RUN /bin/bash -l -c "pip install virtualenv" + +# Define the default command. +CMD ["bash"] diff --git a/tools/jenkins/grpc_interop_python/build_interop.sh b/tools/jenkins/grpc_interop_python/build_interop.sh new file mode 100755 index 00000000000..8f5bfd11e20 --- /dev/null +++ b/tools/jenkins/grpc_interop_python/build_interop.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Builds Python interop server and client in a base image. +set -e + +mkdir -p /var/local/git +git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc + +# copy service account keys if available +cp -r /var/local/jenkins/service_account $HOME || true + +cd /var/local/git/grpc + +make install-certs +make + +# build Python interop client and server +CONFIG=opt ./tools/run_tests/build_python.sh 2.7 + diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 6daa967bba4..33ebcbcc41f 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -56,7 +56,7 @@ _CLOUD_TO_PROD_BASE_ARGS = [ _CLOUD_TO_CLOUD_BASE_ARGS = [ '--server_host_override=foo.test.google.fr'] -# TOOD(jtattermusch) wrapped languages use this variable for location +# TOOD(jtattermusch) wrapped languages use this variable for location # of roots.pem. We might want to use GRPC_DEFAULT_SSL_ROOTS_FILE_PATH # supported by C core SslCredentials instead. _SSL_CERT_ENV = { 'SSL_CERT_FILE':'/usr/local/share/grpc/roots.pem' } @@ -87,6 +87,9 @@ class CXXLanguage: def server_args(self): return ['bins/opt/interop_server', '--use_tls=true'] + def global_env(self): + return {} + def __str__(self): return 'c++' @@ -113,6 +116,9 @@ class CSharpLanguage: def server_args(self): return ['mono', 'Grpc.IntegrationTesting.Server.exe', '--use_tls=true'] + def global_env(self): + return {} + def __str__(self): return 'csharp' @@ -139,6 +145,9 @@ class JavaLanguage: def server_args(self): return ['./run-test-server.sh', '--use_tls=true'] + def global_env(self): + return {} + def __str__(self): return 'java' @@ -166,6 +175,9 @@ class GoLanguage: def server_args(self): return ['go', 'run', 'server.go', '--use_tls=true'] + def global_env(self): + return {} + def __str__(self): return 'go' @@ -192,6 +204,9 @@ class NodeLanguage: def server_args(self): return ['node', 'src/node/interop/interop_server.js', '--use_tls=true'] + def global_env(self): + return {} + def __str__(self): return 'node' @@ -214,6 +229,9 @@ class PHPLanguage: def cloud_to_prod_env(self): return _SSL_CERT_ENV + def global_env(self): + return {} + def __str__(self): return 'php' @@ -240,11 +258,42 @@ class RubyLanguage: def server_args(self): return ['ruby', 'src/ruby/bin/interop/interop_server.rb', '--use_tls'] + def global_env(self): + return {} + def __str__(self): return 'ruby' -# TODO(jtattermusch): python once we get it working +class PythonLanguage: + + def __init__(self): + self.client_cmdline_base = ['python2.7_virtual_environment/bin/python', '-m', 'grpc_interop.client'] + 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 + + ['--use_tls']) + + def cloud_to_cloud_args(self): + return (self.client_cmdline_base + _CLOUD_TO_CLOUD_BASE_ARGS + + ['--use_tls', '--use_test_ca']) + + def cloud_to_prod_env(self): + return _SSL_CERT_ENV + + def server_args(self): + return ['python2.7_virtual_environment/bin/python', '-m', 'grpc_interop.server', '--use_tls'] + + def global_env(self): + return {'LD_LIBRARY_PATH': 'libs/opt'} + + def __str__(self): + return 'python' + + _LANGUAGES = { 'c++' : CXXLanguage(), 'csharp' : CSharpLanguage(), @@ -253,10 +302,11 @@ _LANGUAGES = { 'node' : NodeLanguage(), 'php' : PHPLanguage(), 'ruby' : RubyLanguage(), + 'python' : PythonLanguage(), } # languages supported as cloud_to_cloud servers -_SERVERS = ['c++', 'node', 'csharp', 'java', 'go', 'ruby'] +_SERVERS = ['c++', 'node', 'csharp', 'java', 'go', 'ruby', 'python'] # TODO(jtattermusch): add timeout_on_sleeping_server once java starts supporting it. _TEST_CASES = ['large_unary', 'empty_unary', 'ping_pong', @@ -335,7 +385,7 @@ def cloud_to_prod_jobspec(language, test_case, docker_image=None, auth=False): """Creates jobspec for cloud-to-prod interop test""" cmdline = language.cloud_to_prod_args() + ['--test_case=%s' % test_case] cwd = language.client_cwd - environ = language.cloud_to_prod_env() + environ = dict(language.cloud_to_prod_env(), **language.global_env()) container_name = None if auth: cmdline, environ = add_auth_options(language, test_case, cmdline, environ) @@ -374,10 +424,12 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host, '--server_host=%s' % server_host, '--server_port=%s' % server_port ]) cwd = language.client_cwd + environ = language.global_env() if docker_image: 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', container_name]) @@ -386,6 +438,7 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host, 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=2*60, @@ -401,13 +454,16 @@ def server_jobspec(language, docker_image): container_name = dockerjob.random_name('interop_server_%s' % language.safename) cmdline = bash_login_cmdline(language.server_args() + ['--port=%s' % _DEFAULT_SERVER_PORT]) + environ = language.global_env() docker_cmdline = docker_run_cmdline(cmdline, image=docker_image, cwd=language.server_cwd, + environ=environ, docker_args=['-p', str(_DEFAULT_SERVER_PORT), '--name', container_name]) server_job = jobset.JobSpec( cmdline=docker_cmdline, + environ=environ, shortname="interop_server_%s" % language, timeout_seconds=30*60) server_job.container_name = container_name