From 1191b7202d86f01857f74d0709792fb74eac5a37 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 8 Feb 2017 11:56:52 -0800 Subject: Improve Node and libuv testing and test coverage Allow Node tests to run with or without UV, change default version to 7, add some portability tests. Also make some more core tests work with libuv --- tools/run_tests/generated/sources_and_headers.json | 51 ++++++++++++++ tools/run_tests/generated/tests.json | 80 ++++++++++++++++++++-- tools/run_tests/helper_scripts/build_node.bat | 4 +- tools/run_tests/helper_scripts/build_node.sh | 9 ++- tools/run_tests/performance/run_worker_node.sh | 2 +- tools/run_tests/run_tests.py | 21 ++++-- tools/run_tests/run_tests_matrix.py | 47 ++++++++++--- 7 files changed, 192 insertions(+), 22 deletions(-) (limited to 'tools') diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 9bc82486d2..5763532faa 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -938,6 +938,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "grpc_completion_queue_threading_test", + "src": [ + "test/core/surface/completion_queue_threading_test.c" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -2017,6 +2034,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "tcp_client_uv_test", + "src": [ + "test/core/iomgr/tcp_client_uv_test.c" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -2051,6 +2085,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "tcp_server_uv_test", + "src": [ + "test/core/iomgr/tcp_server_uv_test.c" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 2c7b0a6c82..a273e3f120 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -1101,6 +1101,28 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "grpc_completion_queue_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ @@ -1117,7 +1139,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "grpc_completion_queue_test", + "name": "grpc_completion_queue_threading_test", "platforms": [ "linux", "mac", @@ -1240,7 +1262,9 @@ ], "cpu_cost": 1.0, "exclude_configs": [], - "exclude_iomgrs": [], + "exclude_iomgrs": [ + "uv" + ], "flaky": false, "gtest": false, "language": "c", @@ -1727,9 +1751,7 @@ ], "cpu_cost": 1.0, "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], + "exclude_iomgrs": [], "flaky": false, "gtest": false, "language": "c", @@ -2055,6 +2077,30 @@ "posix" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 0.5, + "exclude_configs": [], + "exclude_iomgrs": [ + "native" + ], + "flaky": false, + "gtest": false, + "language": "c", + "name": "tcp_client_uv_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ @@ -2099,6 +2145,30 @@ "posix" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "native" + ], + "flaky": false, + "gtest": false, + "language": "c", + "name": "tcp_server_uv_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ diff --git a/tools/run_tests/helper_scripts/build_node.bat b/tools/run_tests/helper_scripts/build_node.bat index 82e8208348..233dacd3fb 100644 --- a/tools/run_tests/helper_scripts/build_node.bat +++ b/tools/run_tests/helper_scripts/build_node.bat @@ -38,5 +38,7 @@ for /f "delims=v" %%v in ('node --version') do ( rmdir "%USERPROFILE%\.node-gyp\%%v\include\node\openssl" /S /Q ) + + @rem rebuild, because it probably failed the first time -call npm install --build-from-source \ No newline at end of file +call npm install --build-from-source %1 %2 diff --git a/tools/run_tests/helper_scripts/build_node.sh b/tools/run_tests/helper_scripts/build_node.sh index 8a928bb762..df3acdac2b 100755 --- a/tools/run_tests/helper_scripts/build_node.sh +++ b/tools/run_tests/helper_scripts/build_node.sh @@ -40,4 +40,11 @@ CONFIG=${CONFIG:-opt} # change to grpc repo root cd $(dirname $0)/../../.. -npm install --unsafe-perm --build-from-source +case "$CONFIG" in + 'dbg') config_flag='--debug' ;; + *) config_flag='--release' ;; +esac + +uv_flag=$2 + +npm install --unsafe-perm --build-from-source $uv_flag $config_flag diff --git a/tools/run_tests/performance/run_worker_node.sh b/tools/run_tests/performance/run_worker_node.sh index 9a53a311f4..7e24b326a4 100755 --- a/tools/run_tests/performance/run_worker_node.sh +++ b/tools/run_tests/performance/run_worker_node.sh @@ -29,7 +29,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. source ~/.nvm/nvm.sh -nvm use 4 +nvm use 7 set -ex diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 5aae3432e1..d0ab5b2e7c 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -376,9 +376,13 @@ class NodeLanguage(object): _check_compiler(self.args.compiler, ['default', 'node0.12', 'node4', 'node5', 'node6', 'node7', 'electron1.3']) + if args.iomgr_platform == "uv": + self.use_uv = True + else: + self.use_uv = False if self.args.compiler == 'default': self.runtime = 'node' - self.node_version = '4' + self.node_version = '7' else: if self.args.compiler.startswith('electron'): self.runtime = 'electron' @@ -407,7 +411,8 @@ class NodeLanguage(object): build_script = 'pre_build_node' if self.runtime == 'electron': build_script += '_electron' - return [['tools/run_tests/helper_scripts/{}.sh'.format(build_script), self.node_version]] + return [['tools/run_tests/helper_scripts/{}.sh'.format(build_script), + self.node_version]] def make_targets(self): return [] @@ -417,14 +422,22 @@ class NodeLanguage(object): def build_steps(self): if self.platform == 'windows': - return [['tools\\run_tests\\helper_scripts\\build_node.bat']] + if config == 'dbg': + config_flag = '--debug' + else: + config_flag = '--release' + return [['tools\\run_tests\\helper_scripts\\build_node.bat', + '--grpc_uv={}'.format('true' if self.use_uv else 'false'), + config_flag]] else: build_script = 'build_node' if self.runtime == 'electron': build_script += '_electron' # building for electron requires a patch version self.node_version += '.0' - return [['tools/run_tests/helper_scripts/{}.sh'.format(build_script), self.node_version]] + return [['tools/run_tests/helper_scripts/{}.sh'.format(build_script), + self.node_version, + '--grpc_uv={}'.format('true' if self.use_uv else 'false')]] def post_tests_steps(self): return [] diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index 8f70a6d2ea..5a109bd1a1 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -81,7 +81,7 @@ def _workspace_jobspec(name, runtests_args=[], workspace_name=None, inner_jobs=_ return test_job -def _generate_jobs(languages, configs, platforms, +def _generate_jobs(languages, configs, platforms, iomgr_platform = 'native', arch=None, compiler=None, labels=[], extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS): @@ -89,7 +89,7 @@ def _generate_jobs(languages, configs, platforms, for language in languages: for platform in platforms: for config in configs: - name = '%s_%s_%s' % (language, platform, config) + name = '%s_%s_%s_%s' % (language, platform, config, iomgr_platform) runtests_args = ['-l', language, '-c', config] if arch or compiler: @@ -156,14 +156,6 @@ def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS): extra_args=extra_args, inner_jobs=inner_jobs) - # libuv tests - test_jobs += _generate_jobs(languages=['c'], - configs=['dbg', 'opt'], - platforms=['linux'], - labels=['libuv'], - extra_args=extra_args + ['--iomgr_platform=uv'], - inner_jobs=inner_jobs) - return test_jobs @@ -232,6 +224,14 @@ def _create_portability_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS) extra_args=extra_args, inner_jobs=inner_jobs) + test_jobs += _generate_jobs(languages=['c'], + configs=['dbg'], + platforms=['linux'], + iomgr_platform='uv', + labels=['portability'], + extra_args=extra_args, + inner_jobs=inner_jobs) + test_jobs += _generate_jobs(languages=['node'], configs=['dbg'], platforms=['linux'], @@ -240,6 +240,33 @@ def _create_portability_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS) labels=['portability'], extra_args=extra_args, inner_jobs=inner_jobs) + + test_jobs += _generate_jobs(languages=['node'], + configs=['dbg'], + platforms=['linux'], + iomgr_platform='uv', + labels=['portability'], + extra_args=extra_args, + inner_jobs=inner_jobs) + + test_jobs += _generate_jobs(languages=['node'], + configs=['dbg'], + platforms=['linux'], + arch='default', + compiler='node4', + labels=['portability'], + extra_args=extra_args, + inner_jobs=inner_jobs) + + test_jobs += _generate_jobs(languages=['node'], + configs=['dbg'], + platforms=['linux'], + arch='default', + compiler='node6', + labels=['portability'], + extra_args=extra_args, + inner_jobs=inner_jobs) + return test_jobs -- cgit v1.2.3 From 88113f7b61c494f0873f50de14fc9f224bf7437f Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 21 Feb 2017 10:04:29 -0800 Subject: Minor fixes to tests --- tools/run_tests/helper_scripts/pre_build_node.sh | 2 +- tools/run_tests/run_tests.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/run_tests/helper_scripts/pre_build_node.sh b/tools/run_tests/helper_scripts/pre_build_node.sh index e63be9da52..083cb2bc77 100755 --- a/tools/run_tests/helper_scripts/pre_build_node.sh +++ b/tools/run_tests/helper_scripts/pre_build_node.sh @@ -32,7 +32,7 @@ NODE_VERSION=$1 source ~/.nvm/nvm.sh -nvm use $NODE_VERSION +nvm install $NODE_VERSION set -ex export GRPC_CONFIG=${CONFIG:-opt} diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index d0ab5b2e7c..0558360a98 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -422,7 +422,7 @@ class NodeLanguage(object): def build_steps(self): if self.platform == 'windows': - if config == 'dbg': + if self.config == 'dbg': config_flag = '--debug' else: config_flag = '--release' -- cgit v1.2.3 From 009c85983250e5ec0f3dc8ef43a25a1596fead1d Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 21 Feb 2017 18:15:37 -0800 Subject: Generalize build_node.bat argument propagation --- tools/run_tests/helper_scripts/build_node.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/run_tests/helper_scripts/build_node.bat b/tools/run_tests/helper_scripts/build_node.bat index 233dacd3fb..7a67769516 100644 --- a/tools/run_tests/helper_scripts/build_node.bat +++ b/tools/run_tests/helper_scripts/build_node.bat @@ -41,4 +41,4 @@ for /f "delims=v" %%v in ('node --version') do ( @rem rebuild, because it probably failed the first time -call npm install --build-from-source %1 %2 +call npm install --build-from-source %* -- cgit v1.2.3 From 626fb455acb45f200a1b933fb63d610b42fb198b Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Fri, 17 Feb 2017 22:52:27 -0800 Subject: Add Python3.6 to build artifacts --- .../grpc_artifact_python_manylinux_x64/Dockerfile | 1 + .../grpc_artifact_python_manylinux_x86/Dockerfile | 1 + tools/run_tests/artifacts/artifact_targets.py | 14 ++++++++++++-- tools/run_tests/dockerize/build_and_run_docker.sh | 7 +++++++ 4 files changed, 21 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile index 69e624aa41..7109862911 100644 --- a/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile @@ -53,6 +53,7 @@ RUN /opt/python/cp27-cp27m/bin/pip install cython RUN /opt/python/cp27-cp27mu/bin/pip install cython RUN /opt/python/cp34-cp34m/bin/pip install cython RUN /opt/python/cp35-cp35m/bin/pip install cython +RUN /opt/python/cp36-cp36m/bin/pip install cython #################################################### # Install auditwheel with fix for namespace packages diff --git a/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile index 9af80078ed..36286bca53 100644 --- a/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile @@ -53,6 +53,7 @@ RUN /opt/python/cp27-cp27m/bin/pip install cython RUN /opt/python/cp27-cp27mu/bin/pip install cython RUN /opt/python/cp34-cp34m/bin/pip install cython RUN /opt/python/cp35-cp35m/bin/pip install cython +RUN /opt/python/cp36-cp36m/bin/pip install cython #################################################### # Install auditwheel with fix for namespace packages diff --git a/tools/run_tests/artifacts/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py index 005d99790a..8648ceb1f3 100644 --- a/tools/run_tests/artifacts/artifact_targets.py +++ b/tools/run_tests/artifacts/artifact_targets.py @@ -40,7 +40,8 @@ import python_utils.jobset as jobset def create_docker_jobspec(name, dockerfile_dir, shell_command, environ={}, - flake_retries=0, timeout_retries=0, timeout_seconds=30*60): + flake_retries=0, timeout_retries=0, timeout_seconds=30*60, + docker_base_image=None): """Creates jobspec for a task running under docker.""" environ = environ.copy() environ['RUN_COMMAND'] = shell_command @@ -51,6 +52,9 @@ def create_docker_jobspec(name, dockerfile_dir, shell_command, environ={}, docker_env = {'DOCKERFILE_DIR': dockerfile_dir, 'DOCKER_RUN_SCRIPT': 'tools/run_tests/dockerize/docker_run.sh', 'OUTPUT_DIR': 'artifacts'} + + if docker_base_image is not None: + docker_env['DOCKER_BASE_IMAGE'] = docker_base_image jobspec = jobset.JobSpec( cmdline=['tools/run_tests/dockerize/build_and_run_docker.sh'] + docker_args, environ=docker_env, @@ -116,7 +120,8 @@ class PythonArtifact: 'tools/dockerfile/grpc_artifact_python_manylinux_%s' % self.arch, 'tools/run_tests/artifacts/build_artifact_python.sh', environ=environ, - timeout_seconds=60*60) + timeout_seconds=60*60, + docker_base_image='quay.io/pypa/manylinux1_i686' if self.arch == 'x86' else 'quay.io/pypa/manylinux1_x86_64') elif self.platform == 'windows': if 'Python27' in self.py_version or 'Python34' in self.py_version: environ['EXT_COMPILER'] = 'mingw32' @@ -336,19 +341,24 @@ def targets(): PythonArtifact('linux', 'x86', 'cp27-cp27mu'), PythonArtifact('linux', 'x86', 'cp34-cp34m'), PythonArtifact('linux', 'x86', 'cp35-cp35m'), + PythonArtifact('linux', 'x86', 'cp36-cp36m'), PythonArtifact('linux', 'x64', 'cp27-cp27m'), PythonArtifact('linux', 'x64', 'cp27-cp27mu'), PythonArtifact('linux', 'x64', 'cp34-cp34m'), PythonArtifact('linux', 'x64', 'cp35-cp35m'), + PythonArtifact('linux', 'x64', 'cp36-cp36m'), PythonArtifact('macos', 'x64', 'python2.7'), PythonArtifact('macos', 'x64', 'python3.4'), PythonArtifact('macos', 'x64', 'python3.5'), + PythonArtifact('macos', 'x64', 'python3.6'), PythonArtifact('windows', 'x86', 'Python27_32bits'), PythonArtifact('windows', 'x86', 'Python34_32bits'), PythonArtifact('windows', 'x86', 'Python35_32bits'), + PythonArtifact('windows', 'x86', 'Python36_32bits'), PythonArtifact('windows', 'x64', 'Python27'), PythonArtifact('windows', 'x64', 'Python34'), PythonArtifact('windows', 'x64', 'Python35'), + PythonArtifact('windows', 'x64', 'Python36'), RubyArtifact('linux', 'x86'), RubyArtifact('linux', 'x64'), RubyArtifact('macos', 'x64'), diff --git a/tools/run_tests/dockerize/build_and_run_docker.sh b/tools/run_tests/dockerize/build_and_run_docker.sh index f52f16ebd6..8c25c861c1 100755 --- a/tools/run_tests/dockerize/build_and_run_docker.sh +++ b/tools/run_tests/dockerize/build_and_run_docker.sh @@ -42,11 +42,18 @@ cd - # DOCKER_RUN_SCRIPT - Script to run under docker (relative to grpc repo root) # OUTPUT_DIR - Directory that will be copied from inside docker after finishing. # DOCKERHUB_ORGANIZATION - If set, pull a prebuilt image from given dockerhub org. +# DOCKER_BASE_IMAGE - If set, pull the latest base image. # $@ - Extra args to pass to docker run # Use image name based on Dockerfile location checksum DOCKER_IMAGE_NAME=$(basename $DOCKERFILE_DIR)_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ ) +# Pull the base image to force an update +if [ "$DOCKER_BASE_IMAGE" != "" ] +then + docker pull $DOCKER_BASE_IMAGE +fi + if [ "$DOCKERHUB_ORGANIZATION" != "" ] then DOCKER_IMAGE_NAME=$DOCKERHUB_ORGANIZATION/$DOCKER_IMAGE_NAME -- cgit v1.2.3 From 990d9fe1460d0f274857a5aaa8fe28f4b3852d9b Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Sun, 26 Feb 2017 16:54:18 -0800 Subject: Client-side keepalive ping Based on soltanmm-google's #9114 --- CMakeLists.txt | 2 + Makefile | 2 + include/grpc/impl/codegen/grpc_types.h | 10 + .../transport/chttp2/transport/chttp2_transport.c | 140 +++++ src/core/ext/transport/chttp2/transport/internal.h | 23 + test/core/end2end/end2end_nosec_tests.c | 8 + test/core/end2end/end2end_tests.c | 8 + test/core/end2end/gen_build_yaml.py | 1 + test/core/end2end/generate_tests.bzl | 1 + test/core/end2end/tests/keepalive_timeout.c | 240 ++++++++ tools/run_tests/generated/sources_and_headers.json | 2 + tools/run_tests/generated/tests.json | 666 ++++++++++++++++++++- .../end2end_nosec_tests.vcxproj | 2 + .../end2end_nosec_tests.vcxproj.filters | 3 + .../tests/end2end_tests/end2end_tests.vcxproj | 2 + .../end2end_tests/end2end_tests.vcxproj.filters | 3 + 16 files changed, 1104 insertions(+), 9 deletions(-) create mode 100644 test/core/end2end/tests/keepalive_timeout.c (limited to 'tools') diff --git a/CMakeLists.txt b/CMakeLists.txt index 383d575a34..483a3db058 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3788,6 +3788,7 @@ add_library(end2end_tests test/core/end2end/tests/hpack_size.c test/core/end2end/tests/idempotent_request.c test/core/end2end/tests/invoke_large_request.c + test/core/end2end/tests/keepalive_timeout.c test/core/end2end/tests/large_metadata.c test/core/end2end/tests/load_reporting_hook.c test/core/end2end/tests/max_concurrent_streams.c @@ -3877,6 +3878,7 @@ add_library(end2end_nosec_tests test/core/end2end/tests/hpack_size.c test/core/end2end/tests/idempotent_request.c test/core/end2end/tests/invoke_large_request.c + test/core/end2end/tests/keepalive_timeout.c test/core/end2end/tests/large_metadata.c test/core/end2end/tests/load_reporting_hook.c test/core/end2end/tests/max_concurrent_streams.c diff --git a/Makefile b/Makefile index 0e1bcd2c37..50625f1fe0 100644 --- a/Makefile +++ b/Makefile @@ -7692,6 +7692,7 @@ LIBEND2END_TESTS_SRC = \ test/core/end2end/tests/hpack_size.c \ test/core/end2end/tests/idempotent_request.c \ test/core/end2end/tests/invoke_large_request.c \ + test/core/end2end/tests/keepalive_timeout.c \ test/core/end2end/tests/large_metadata.c \ test/core/end2end/tests/load_reporting_hook.c \ test/core/end2end/tests/max_concurrent_streams.c \ @@ -7780,6 +7781,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \ test/core/end2end/tests/hpack_size.c \ test/core/end2end/tests/idempotent_request.c \ test/core/end2end/tests/invoke_large_request.c \ + test/core/end2end/tests/keepalive_timeout.c \ test/core/end2end/tests/large_metadata.c \ test/core/end2end/tests/load_reporting_hook.c \ test/core/end2end/tests/max_concurrent_streams.c \ diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index da936bf028..e5c731304c 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -193,6 +193,16 @@ typedef struct { /** How much data are we willing to queue up per stream if GRPC_WRITE_BUFFER_HINT is set? This is an upper bound */ #define GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE "grpc.http2.write_buffer_size" +/** After a duration of this time the client pings the server to see if the + transport is still alive. Int valued, seconds. */ +#define GRPC_ARG_HTTP2_KEEPALIVE_TIME "grpc.http2.keepalive_time" +/** After waiting for a duration of this time, if the client does not receive + the ping ack, it will close the transport. Int valued, seconds. */ +#define GRPC_ARG_HTTP2_KEEPALIVE_TIMEOUT "grpc.http2.keepalive_timeout" +/** Is it permissible to send keepalive pings without any outstanding streams. + Int valued, 0(false)/1(true). */ +#define GRPC_ARG_HTTP2_KEEPALIVE_PERMIT_WITHOUT_CALLS \ + "grpc.http2.keepalive_permit_without_calls" /** Default authority to pass if none specified on call construction. A string. * */ #define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority" diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 28a3166832..10dc6e6ff6 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -48,16 +48,19 @@ #include "src/core/ext/transport/chttp2/transport/varint.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/http/parser.h" +#include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/workqueue.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/support/env.h" #include "src/core/lib/support/string.h" #include "src/core/lib/transport/error_utils.h" #include "src/core/lib/transport/http2_errors.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_conversion.h" #include "src/core/lib/transport/timeout_encoding.h" +#include "src/core/lib/transport/transport.h" #include "src/core/lib/transport/transport_impl.h" #define DEFAULT_WINDOW 65535 @@ -66,6 +69,10 @@ #define MAX_WRITE_BUFFER_SIZE (64 * 1024 * 1024) #define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024) +#define DEFAULT_KEEPALIVE_TIME_SECOND INT_MAX +#define DEFAULT_KEEPALIVE_TIMEOUT_SECOND 20 +#define DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS false + #define MAX_CLIENT_STREAM_ID 0x7fffffffu int grpc_http_trace = 0; int grpc_flowctl_trace = 0; @@ -139,6 +146,14 @@ static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, #define DEFAULT_MIN_TIME_BETWEEN_PINGS_MS 0 #define DEFAULT_MAX_PINGS_BETWEEN_DATA 3 +/** keepalive-relevant functions */ +static void keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error); +static void keepalive_ping_ack_locked(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error); +static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error); + /******************************************************************************* * CONSTRUCTION/DESTRUCTION/REFCOUNTING */ @@ -209,6 +224,73 @@ void grpc_chttp2_unref_transport(grpc_exec_ctx *exec_ctx, void grpc_chttp2_ref_transport(grpc_chttp2_transport *t) { gpr_ref(&t->refs); } #endif +static void keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { + grpc_chttp2_transport *t = arg; + GPR_ASSERT(t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING); + if (error == GRPC_ERROR_NONE && !(t->destroying || t->closed)) { + t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_PINGING; + GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive ping end"); + t->keepalive_ping_id = send_ping_locked( + exec_ctx, t, + grpc_closure_create(keepalive_ping_ack_locked, t, + grpc_combiner_scheduler(t->combiner, false))); + if (t->keepalive_permit_without_calls || t->stream_map.count > 0) + GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive watchdog"); + grpc_timer_init( + exec_ctx, &t->keepalive_watchdog_timer, + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_timeout), + grpc_closure_create(keepalive_watchdog_fired_locked, t, + grpc_combiner_scheduler(t->combiner, false)), + gpr_now(GPR_CLOCK_MONOTONIC)); + } + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keepalive ping"); +} + +static void keepalive_ping_ack_locked(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { + grpc_chttp2_transport *t = arg; + if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { + if (error == GRPC_ERROR_NONE) { + t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_WAITING; + t->keepalive_ping_id = NULL; + grpc_timer_cancel(exec_ctx, &t->keepalive_watchdog_timer); + GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive ping"); + grpc_timer_init( + exec_ctx, &t->keepalive_ping_timer, + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time), + grpc_closure_create(keepalive_ping_locked, t, + grpc_combiner_scheduler(t->combiner, false)), + gpr_now(GPR_CLOCK_MONOTONIC)); + } + } else { + GPR_ASSERT(t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_DYING); + } + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keepalive ping end"); +} + +static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { + grpc_chttp2_transport *t = arg; + if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { + if (error == GRPC_ERROR_NONE) { + t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; + if (t->keepalive_ping_id != NULL) { + grpc_chttp2_ack_ping(exec_ctx, t, t->keepalive_ping_id); + } + close_transport_locked(exec_ctx, t, + GRPC_ERROR_CREATE("keepalive watchdog timeout")); + } + } else { + // GRPC_LOG_IF_ERROR("keepalive_watchdog", error); + if (error != GRPC_ERROR_CANCELLED) { + gpr_log(GPR_ERROR, "keepalive_ping_end state error: %d (expect: %d)", + t->keepalive_state, GRPC_CHTTP2_KEEPALIVE_STATE_PINGING); + } + } + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keepalive watchdog"); +} + static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, const grpc_channel_args *channel_args, grpc_endpoint *ep, bool is_client) { @@ -316,6 +398,13 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_time_from_millis(DEFAULT_MIN_TIME_BETWEEN_PINGS_MS, GPR_TIMESPAN), }; + /* client-side keepalive setting */ + t->keepalive_time = + gpr_time_from_seconds(DEFAULT_KEEPALIVE_TIME_SECOND, GPR_TIMESPAN); + t->keepalive_timeout = + gpr_time_from_seconds(DEFAULT_KEEPALIVE_TIMEOUT_SECOND, GPR_TIMESPAN); + t->keepalive_permit_without_calls = DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS; + if (channel_args) { for (i = 0; i < channel_args->num_args; i++) { if (0 == strcmp(channel_args->args[i].key, @@ -363,6 +452,29 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, strcmp(channel_args->args[i].key, GRPC_ARG_HTTP2_BDP_PROBE)) { t->enable_bdp_probe = grpc_channel_arg_get_integer( &channel_args->args[i], (grpc_integer_options){1, 0, 1}); + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_KEEPALIVE_TIME)) { + const int value = grpc_channel_arg_get_integer( + &channel_args->args[i], + (grpc_integer_options){DEFAULT_KEEPALIVE_TIME_SECOND, 1, INT_MAX}); + t->keepalive_time = value == INT_MAX + ? gpr_inf_future(GPR_TIMESPAN) + : gpr_time_from_seconds(value, GPR_TIMESPAN); + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_KEEPALIVE_TIMEOUT)) { + const int value = grpc_channel_arg_get_integer( + &channel_args->args[i], + (grpc_integer_options){DEFAULT_KEEPALIVE_TIMEOUT_SECOND, 0, + INT_MAX}); + t->keepalive_timeout = value == INT_MAX + ? gpr_inf_future(GPR_TIMESPAN) + : gpr_time_from_seconds(value, GPR_TIMESPAN); + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_KEEPALIVE_PERMIT_WITHOUT_CALLS)) { + t->keepalive_permit_without_calls = + (uint32_t)grpc_channel_arg_get_integer( + &channel_args->args[i], + (grpc_integer_options){0, 0, MAX_WRITE_BUFFER_SIZE}); } else { static const struct { const char *channel_arg_name; @@ -414,6 +526,18 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, t->ping_state.pings_before_data_required = t->ping_policy.max_pings_without_data; + // Start client-side keepalive pings + if (t->is_client) { + t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_WAITING; + GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive ping"); + grpc_timer_init( + exec_ctx, &t->keepalive_ping_timer, + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), t->keepalive_time), + grpc_closure_create(keepalive_ping_locked, t, + grpc_combiner_scheduler(t->combiner, false)), + gpr_now(GPR_CLOCK_MONOTONIC)); + } + grpc_chttp2_initiate_write(exec_ctx, t, false, "init"); post_benign_reclaimer(exec_ctx, t); } @@ -458,6 +582,22 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx, connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), "close_transport"); grpc_endpoint_shutdown(exec_ctx, t->ep, GRPC_ERROR_REF(error)); + if (t->is_client) { + switch (t->keepalive_state) { + case GRPC_CHTTP2_KEEPALIVE_STATE_WAITING: { + grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer); + break; + } + case GRPC_CHTTP2_KEEPALIVE_STATE_PINGING: { + grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer); + grpc_timer_cancel(exec_ctx, &t->keepalive_watchdog_timer); + break; + } + case GRPC_CHTTP2_KEEPALIVE_STATE_DYING: { + break; + } + } + } /* flush writable stream list to avoid dangling references */ grpc_chttp2_stream *s; diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 5d41f4bfda..7fcab0a722 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -50,6 +50,7 @@ #include "src/core/ext/transport/chttp2/transport/stream_map.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/timer.h" #include "src/core/lib/transport/bdp_estimator.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/pid_controller.h" @@ -208,6 +209,12 @@ struct grpc_chttp2_incoming_byte_stream { grpc_closure finished_action; }; +typedef enum { + GRPC_CHTTP2_KEEPALIVE_STATE_WAITING, + GRPC_CHTTP2_KEEPALIVE_STATE_PINGING, + GRPC_CHTTP2_KEEPALIVE_STATE_DYING, +} grpc_chttp2_keepalive_state; + struct grpc_chttp2_transport { grpc_transport base; /* must be first */ gpr_refcount refs; @@ -382,6 +389,22 @@ struct grpc_chttp2_transport { grpc_closure benign_reclaimer_locked; /** destructive cleanup closure */ grpc_closure destructive_reclaimer_locked; + + /* keep-alive ping support */ + /** timer to initiate ping events */ + grpc_timer keepalive_ping_timer; + /** watchdog to kill the transport when waiting for the keepalive ping */ + grpc_timer keepalive_watchdog_timer; + /** time duration in between pings */ + gpr_timespec keepalive_time; + /** grace period for a ping to complete before watchdog kicks in */ + gpr_timespec keepalive_timeout; + /** if keepalive pings are allowed when there's no outstanding streams */ + bool keepalive_permit_without_calls; + /** keep-alive state machine state */ + grpc_chttp2_keepalive_state keepalive_state; + + uint8_t *keepalive_ping_id; }; typedef enum { diff --git a/test/core/end2end/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c index fdfa31b5fb..b351bdee27 100644 --- a/test/core/end2end/end2end_nosec_tests.c +++ b/test/core/end2end/end2end_nosec_tests.c @@ -89,6 +89,8 @@ extern void idempotent_request(grpc_end2end_test_config config); extern void idempotent_request_pre_init(void); extern void invoke_large_request(grpc_end2end_test_config config); extern void invoke_large_request_pre_init(void); +extern void keepalive_timeout(grpc_end2end_test_config config); +extern void keepalive_timeout_pre_init(void); extern void large_metadata(grpc_end2end_test_config config); extern void large_metadata_pre_init(void); extern void load_reporting_hook(grpc_end2end_test_config config); @@ -168,6 +170,7 @@ void grpc_end2end_tests_pre_init(void) { hpack_size_pre_init(); idempotent_request_pre_init(); invoke_large_request_pre_init(); + keepalive_timeout_pre_init(); large_metadata_pre_init(); load_reporting_hook_pre_init(); max_concurrent_streams_pre_init(); @@ -225,6 +228,7 @@ void grpc_end2end_tests(int argc, char **argv, hpack_size(config); idempotent_request(config); invoke_large_request(config); + keepalive_timeout(config); large_metadata(config); load_reporting_hook(config); max_concurrent_streams(config); @@ -343,6 +347,10 @@ void grpc_end2end_tests(int argc, char **argv, invoke_large_request(config); continue; } + if (0 == strcmp("keepalive_timeout", argv[i])) { + keepalive_timeout(config); + continue; + } if (0 == strcmp("large_metadata", argv[i])) { large_metadata(config); continue; diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c index f529d6a899..199c09ec96 100644 --- a/test/core/end2end/end2end_tests.c +++ b/test/core/end2end/end2end_tests.c @@ -91,6 +91,8 @@ extern void idempotent_request(grpc_end2end_test_config config); extern void idempotent_request_pre_init(void); extern void invoke_large_request(grpc_end2end_test_config config); extern void invoke_large_request_pre_init(void); +extern void keepalive_timeout(grpc_end2end_test_config config); +extern void keepalive_timeout_pre_init(void); extern void large_metadata(grpc_end2end_test_config config); extern void large_metadata_pre_init(void); extern void load_reporting_hook(grpc_end2end_test_config config); @@ -171,6 +173,7 @@ void grpc_end2end_tests_pre_init(void) { hpack_size_pre_init(); idempotent_request_pre_init(); invoke_large_request_pre_init(); + keepalive_timeout_pre_init(); large_metadata_pre_init(); load_reporting_hook_pre_init(); max_concurrent_streams_pre_init(); @@ -229,6 +232,7 @@ void grpc_end2end_tests(int argc, char **argv, hpack_size(config); idempotent_request(config); invoke_large_request(config); + keepalive_timeout(config); large_metadata(config); load_reporting_hook(config); max_concurrent_streams(config); @@ -351,6 +355,10 @@ void grpc_end2end_tests(int argc, char **argv, invoke_large_request(config); continue; } + if (0 == strcmp("keepalive_timeout", argv[i])) { + keepalive_timeout(config); + continue; + } if (0 == strcmp("large_metadata", argv[i])) { large_metadata(config); continue; diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 5071299545..0c749537e6 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -119,6 +119,7 @@ END2END_TESTS = { 'high_initial_seqno': default_test_options, 'idempotent_request': default_test_options, 'invoke_large_request': default_test_options, + 'keepalive_timeout': default_test_options._replace(proxyable=False), 'large_metadata': default_test_options, 'max_concurrent_streams': default_test_options._replace(proxyable=False), 'max_message_length': default_test_options, diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 95c06de73f..431c6995ba 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -106,6 +106,7 @@ END2END_TESTS = { 'high_initial_seqno': test_options(), 'idempotent_request': test_options(), 'invoke_large_request': test_options(), + 'keepalive_timeout': test_options(proxyable=False), 'large_metadata': test_options(), 'max_concurrent_streams': test_options(proxyable=False), 'max_message_length': test_options(), diff --git a/test/core/end2end/tests/keepalive_timeout.c b/test/core/end2end/tests/keepalive_timeout.c new file mode 100644 index 0000000000..40a6bb3db5 --- /dev/null +++ b/test/core/end2end/tests/keepalive_timeout.c @@ -0,0 +1,240 @@ +/* + * + * Copyright 2016, 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. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include +#include + +#include +#include +#include +#include +#include +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/support/env.h" +#include "test/core/end2end/cq_verifier.h" + +static void *tag(intptr_t t) { return (void *)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char *test_name, + grpc_channel_args *client_args, + grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "%s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_time(int n) { + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); +} + +static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } + +static void drain_cq(grpc_completion_queue *cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture *f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = NULL; +} + +static void shutdown_client(grpc_end2end_test_fixture *f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = NULL; +} + +static void end_test(grpc_end2end_test_fixture *f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); +} + +/* Client sends a request, server replies with a payload, then waits for the + keepalive watchdog timeouts before returning status. */ +static void test_keepalive_timeout(grpc_end2end_test_config config) { + grpc_call *c; + grpc_call *s; + grpc_slice response_payload_slice = + grpc_slice_from_copied_string("hello world"); + grpc_byte_buffer *response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + gpr_timespec deadline = five_seconds_time(); + + grpc_arg keepalive_args[2]; + keepalive_args[0].type = GRPC_ARG_INTEGER; + keepalive_args[0].key = GRPC_ARG_HTTP2_KEEPALIVE_TIME; + keepalive_args[0].value.integer = 2; + keepalive_args[1].type = GRPC_ARG_INTEGER; + keepalive_args[1].key = GRPC_ARG_HTTP2_KEEPALIVE_TIMEOUT; + keepalive_args[1].value.integer = 0; + + grpc_channel_args *client_args = NULL; + client_args = grpc_channel_args_copy_and_add(client_args, keepalive_args, 2); + + grpc_end2end_test_fixture f = + begin_test(config, "keepalive_timeout", client_args, NULL); + cq_verifier *cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op *op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_byte_buffer *response_payload_recv = NULL; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + + c = grpc_channel_create_call( + f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), + get_host_override_slice("foo.test.google.fr:1234", config), deadline, + NULL); + GPR_ASSERT(c); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( + f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101))); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response_payload; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + cq_verify(cqv); + + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + cq_verify(cqv); + + char *details_str = grpc_slice_to_c_string(details); + char *method_str = grpc_slice_to_c_string(call_details.method); + GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "keepalive watchdog timeout")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); + validate_host_override_string("foo.test.google.fr:1234", call_details.host, + config); + + gpr_free(details_str); + gpr_free(method_str); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_destroy(c); + grpc_call_destroy(s); + + cq_verifier_destroy(cqv); + + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(response_payload_recv); + + if (client_args != NULL) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_channel_args_destroy(&exec_ctx, client_args); + grpc_exec_ctx_finish(&exec_ctx); + } + + end_test(&f); + config.tear_down_data(&f); +} + +void keepalive_timeout(grpc_end2end_test_config config) { + test_keepalive_timeout(config); +} + +void keepalive_timeout_pre_init(void) {} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8cf282a389..7dc0b3b258 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -6807,6 +6807,7 @@ "test/core/end2end/tests/hpack_size.c", "test/core/end2end/tests/idempotent_request.c", "test/core/end2end/tests/invoke_large_request.c", + "test/core/end2end/tests/keepalive_timeout.c", "test/core/end2end/tests/large_metadata.c", "test/core/end2end/tests/load_reporting_hook.c", "test/core/end2end/tests/max_concurrent_streams.c", @@ -6878,6 +6879,7 @@ "test/core/end2end/tests/hpack_size.c", "test/core/end2end/tests/idempotent_request.c", "test/core/end2end/tests/invoke_large_request.c", + "test/core/end2end/tests/keepalive_timeout.c", "test/core/end2end/tests/large_metadata.c", "test/core/end2end/tests/load_reporting_hook.c", "test/core/end2end/tests/max_concurrent_streams.c", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 8e843d07c0..35e5863904 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -5881,6 +5881,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_census_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -7010,6 +7033,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_compress_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -8116,6 +8162,28 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_fakesec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -9148,6 +9216,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_fd_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -10231,6 +10322,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_full_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -11266,6 +11380,25 @@ "linux" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_full+pipe_test", + "platforms": [ + "linux" + ] + }, { "args": [ "large_metadata" @@ -12268,6 +12401,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_full+trace_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -13395,6 +13551,30 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_http_proxy_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -14550,6 +14730,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_load_reporting_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -15700,6 +15903,30 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_oauth2_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -17812,6 +18039,30 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -18846,7 +19097,7 @@ }, { "args": [ - "large_metadata" + "keepalive_timeout" ], "ci_platforms": [ "windows", @@ -18870,7 +19121,7 @@ }, { "args": [ - "load_reporting_hook" + "large_metadata" ], "ci_platforms": [ "windows", @@ -18894,7 +19145,7 @@ }, { "args": [ - "max_concurrent_streams" + "load_reporting_hook" ], "ci_platforms": [ "windows", @@ -18918,7 +19169,7 @@ }, { "args": [ - "max_message_length" + "max_concurrent_streams" ], "ci_platforms": [ "windows", @@ -18942,7 +19193,7 @@ }, { "args": [ - "negative_deadline" + "max_message_length" ], "ci_platforms": [ "windows", @@ -18966,7 +19217,7 @@ }, { "args": [ - "network_status_change" + "negative_deadline" ], "ci_platforms": [ "windows", @@ -18990,7 +19241,7 @@ }, { "args": [ - "no_op" + "network_status_change" ], "ci_platforms": [ "windows", @@ -19014,7 +19265,7 @@ }, { "args": [ - "payload" + "no_op" ], "ci_platforms": [ "windows", @@ -19038,7 +19289,31 @@ }, { "args": [ - "ping_pong_streaming" + "payload" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair+trace_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping_pong_streaming" ], "ci_platforms": [ "windows", @@ -19892,6 +20167,32 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [ + "msan" + ], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_1byte_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -21021,6 +21322,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -22150,6 +22474,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cert_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -24262,6 +24609,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -25368,6 +25738,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_census_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -26474,6 +26867,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_compress_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -27509,6 +27925,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_fd_nosec_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -28569,6 +29008,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_full_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -29585,6 +30047,25 @@ "linux" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_full+pipe_nosec_test", + "platforms": [ + "linux" + ] + }, { "args": [ "large_metadata" @@ -30564,6 +31045,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_full+trace_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -31667,6 +32171,30 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_http_proxy_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -32799,6 +33327,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_load_reporting_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -34837,6 +35388,30 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -35845,6 +36420,30 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair+trace_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -36867,6 +37466,32 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [ + "msan" + ], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_1byte_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" @@ -37948,6 +38573,29 @@ "posix" ] }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_uds_nosec_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "large_metadata" diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj index 6506f24d1b..08b3acd03c 100644 --- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj +++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj @@ -199,6 +199,8 @@ + + diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters index 77e5ebf8b1..3a8670c1fa 100644 --- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters +++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters @@ -73,6 +73,9 @@ test\core\end2end\tests + + test\core\end2end\tests + test\core\end2end\tests diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj index 176e8f7197..96418c3ca5 100644 --- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj +++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj @@ -201,6 +201,8 @@ + + diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters index fa70267933..cf40abef43 100644 --- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters +++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters @@ -76,6 +76,9 @@ test\core\end2end\tests + + test\core\end2end\tests + test\core\end2end\tests -- cgit v1.2.3 From 28b0f2a0d18533f236c194015a395c22dfb51b3d Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Mon, 27 Feb 2017 00:52:47 -0800 Subject: Add tools/internal_ci/ to test filter --- tools/run_tests/python_utils/filter_pull_request_tests.py | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/run_tests/python_utils/filter_pull_request_tests.py b/tools/run_tests/python_utils/filter_pull_request_tests.py index ca1d6d4eb5..3734f025d5 100644 --- a/tools/run_tests/python_utils/filter_pull_request_tests.py +++ b/tools/run_tests/python_utils/filter_pull_request_tests.py @@ -98,6 +98,7 @@ _WHITELIST_DICT = { '^test/distrib/php/': [_PHP_TEST_SUITE], '^test/distrib/python/': [_PYTHON_TEST_SUITE], '^test/distrib/ruby/': [_RUBY_TEST_SUITE], + '^tools/internal_ci/': [], '^vsprojects/': [_WINDOWS_TEST_SUITE], 'binding\.gyp$': [_NODE_TEST_SUITE], 'composer\.json$': [_PHP_TEST_SUITE], -- cgit v1.2.3 From 70e353bf28b080af40539079b798b6e78b09e106 Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Mon, 27 Feb 2017 00:54:27 -0800 Subject: Make portability tests pull Docker images from Dockerhub --- tools/internal_ci/linux/grpc_portability_build_only.sh | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/internal_ci/linux/grpc_portability_build_only.sh b/tools/internal_ci/linux/grpc_portability_build_only.sh index 9fac5bcac0..ebdc0e82d7 100644 --- a/tools/internal_ci/linux/grpc_portability_build_only.sh +++ b/tools/internal_ci/linux/grpc_portability_build_only.sh @@ -35,4 +35,7 @@ cd $(dirname $0)/../../.. git submodule update --init +# download docker images from dockerhub +export DOCKERHUB_ORGANIZATION=grpctesting + tools/jenkins/run_jenkins_matrix.sh -f portability linux --build_only -- cgit v1.2.3