From 9c79e8de96c168c40691bebf8db18c6acd3e813b Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Mon, 19 Sep 2016 14:33:18 +0200
Subject: add matrix run script

---
 tools/run_tests/run_tests_matrix.py | 239 ++++++++++++++++++++++++++++++++++++
 1 file changed, 239 insertions(+)
 create mode 100755 tools/run_tests/run_tests_matrix.py

(limited to 'tools/run_tests/run_tests_matrix.py')

diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
new file mode 100755
index 0000000000..2344e2f9fd
--- /dev/null
+++ b/tools/run_tests/run_tests_matrix.py
@@ -0,0 +1,239 @@
+#!/usr/bin/env python2.7
+# 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.
+
+"""Run test matrix."""
+
+import argparse
+import jobset
+import os
+import report_utils
+import sys
+
+_ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
+os.chdir(_ROOT)
+
+# TODO(jtattermusch): this is not going to be enough for sanitizers.
+_RUNTESTS_TIMEOUT = 30*60
+
+
+def _docker_jobspec(name, runtests_args=[]):
+  """Run a single instance of run_tests.py in a docker container"""
+  # TODO: fix copying report files from inside docker....
+  test_job = jobset.JobSpec(
+          cmdline=['python', 'tools/run_tests/run_tests.py',
+                   '--use_docker',
+                   '-t',
+                   '-j', '3',
+                   '-x', 'report_%s.xml' % name] + runtests_args,
+          shortname='run_tests_%s' % name,
+          timeout_seconds=_RUNTESTS_TIMEOUT)
+  return test_job
+
+
+def _workspace_jobspec(name, runtests_args=[], workspace_name=None):
+  """Run a single instance of run_tests.py in a separate workspace"""
+  env = {'WORKSPACE_NAME': workspace_name}
+  test_job = jobset.JobSpec(
+          cmdline=['tools/run_tests/run_tests_in_workspace.sh',
+                   '-t',
+                   '-j', '3',
+                   '-x', '../report_%s.xml' % name] + runtests_args,
+          environ=env,
+          shortname='run_tests_%s' % name,
+          timeout_seconds=_RUNTESTS_TIMEOUT)
+  return test_job
+
+
+def _generate_jobs(languages, configs, platforms,
+                  arch=None, compiler=None,
+                  labels=[]):
+  result = []
+  for language in languages:
+    for platform in platforms:
+      for config in configs:
+        name = '%s_%s_%s' % (language, platform, config)
+        runtests_args = ['-l', language,
+                         '-c', config]
+        if arch or compiler:
+          name += '_%s_%s' % (arch, compiler)
+          runtests_args += ['--arch', arch,
+                            '--compiler', compiler]
+
+        if platform == 'linux':
+          job = _docker_jobspec(name=name, runtests_args=runtests_args)
+        else:
+          job = _workspace_jobspec(name=name, runtests_args=runtests_args)
+
+        job.labels = [platform, config, language] + labels
+        result.append(job)
+  return result
+
+
+def _create_test_jobs():
+  test_jobs = []
+  # supported on linux only
+  test_jobs += _generate_jobs(languages=['sanity', 'php7'],
+                             configs=['dbg', 'opt'],
+                             platforms=['linux'],
+                             labels=['basictests'])
+  
+  # supported on all platforms.
+  test_jobs += _generate_jobs(languages=['c', 'csharp', 'node', 'python'],
+                            configs=['dbg', 'opt'],
+                            platforms=['linux', 'macos', 'windows'],
+                            labels=['basictests'])
+  
+  # supported on linux and mac.
+  test_jobs += _generate_jobs(languages=['c++', 'ruby', 'php'],
+                             configs=['dbg', 'opt'],
+                             platforms=['linux', 'macos'],
+                             labels=['basictests'])
+  
+  # supported on mac only.
+  test_jobs += _generate_jobs(languages=['objc'],
+                              configs=['dbg', 'opt'],
+                              platforms=['macos'],
+                              labels=['basictests'])
+  
+  # sanitizers
+  test_jobs += _generate_jobs(languages=['c'],
+                              configs=['msan', 'asan', 'tsan'],
+                              platforms=['linux'],
+                              labels=['sanitizers'])
+  test_jobs += _generate_jobs(languages=['c++'],
+                              configs=['asan', 'tsan'],
+                              platforms=['linux'],
+                              labels=['sanitizers'])
+  return test_jobs
+
+  
+def _create_portability_test_jobs():
+  test_jobs = []
+  # portability C x86
+  test_jobs += _generate_jobs(languages=['c'],
+                              configs=['dbg'],
+                              platforms=['linux'],
+                              arch='x86',
+                              compiler='default',
+                              labels=['portability'])
+  
+  # portability C and C++ on x64
+  for compiler in ['gcc4.4', 'gcc4.6', 'gcc5.3',
+                   'clang3.5', 'clang3.6', 'clang3.7']:
+    test_jobs += _generate_jobs(languages=['c', 'c++'],
+                                configs=['dbg'],
+                                platforms=['linux'],
+                                arch='x64',
+                                compiler=compiler,
+                                labels=['portability'])
+  
+  # portability C on Windows
+  for arch in ['x86', 'x64']:
+    for compiler in ['vs2013', 'vs2015']:
+      test_jobs += _generate_jobs(languages=['c'],
+                                  configs=['dbg'],
+                                  platforms=['windows'],
+                                  arch=arch,
+                                  compiler=compiler,
+                                  labels=['portability'])
+  
+  test_jobs += _generate_jobs(languages=['python'],
+                              configs=['dbg'],
+                              platforms=['linux'],
+                              arch='default',
+                              compiler='python3.4',
+                              labels=['portability'])
+  
+  test_jobs += _generate_jobs(languages=['csharp'],
+                              configs=['dbg'],
+                              platforms=['linux'],
+                              arch='default',
+                              compiler='coreclr',
+                              labels=['portability'])
+  
+  for compiler in ['node5', 'node6', 'node0.12']:
+    test_jobs += _generate_jobs(languages=['node'],
+                               configs=['dbg'],
+                               platforms=['linux'],
+                               arch='default',
+                               compiler=compiler,
+                               labels=['portability'])
+  return test_jobs  
+
+
+all_jobs = _create_test_jobs() + _create_portability_test_jobs()
+
+all_labels = set()
+for job in all_jobs:
+  for label in job.labels:
+    all_labels.add(label)
+
+argp = argparse.ArgumentParser(description='Run a matrix of run_tests.py tests.')
+argp.add_argument('-f', '--filter',
+                  choices=sorted(all_labels),
+                  nargs='+',
+                  default=[],
+                  help='Filter targets to run by label with AND semantics.')
+args = argp.parse_args()
+
+jobs = []
+for job in all_jobs:
+  if not args.filter or all(filter in job.labels for filter in args.filter):
+    jobs.append(job)
+
+if not jobs:
+  jobset.message('FAILED', 'No test suites match given criteria.',
+                 do_newline=True)
+  sys.exit(1)
+  
+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 or into subworkspaces.')
+
+print 
+print 'Will run these tests:'
+for job in jobs:
+  print '  %s' % job.shortname
+print
+
+jobset.message('START', 'Running test matrix.', do_newline=True)
+num_failures, resultset = jobset.run(jobs,
+                                     newline_on_success=True,
+                                     travis=True,
+                                     maxjobs=2)
+report_utils.render_junit_xml_report(resultset, 'report.xml')
+
+if num_failures == 0:
+  jobset.message('SUCCESS', 'All run_tests.py instance finished successfully.',
+                 do_newline=True)
+else:
+  jobset.message('FAILED', 'Some run_tests.py instance have failed.',
+                 do_newline=True)
+  sys.exit(1)
-- 
cgit v1.2.3


From a1906d5ea7b445c465ce368b7f8c0c8f396279a3 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Mon, 19 Sep 2016 18:37:17 +0200
Subject: run matrix improvements

---
 tools/run_tests/dockerize/build_docker_and_run_tests.sh | 12 ++++++------
 tools/run_tests/run_tests_in_workspace.sh               |  2 ++
 tools/run_tests/run_tests_matrix.py                     | 17 ++++++++++++++---
 3 files changed, 22 insertions(+), 9 deletions(-)

(limited to 'tools/run_tests/run_tests_matrix.py')

diff --git a/tools/run_tests/dockerize/build_docker_and_run_tests.sh b/tools/run_tests/dockerize/build_docker_and_run_tests.sh
index c2ea6f2c6e..b4b172ddef 100755
--- a/tools/run_tests/dockerize/build_docker_and_run_tests.sh
+++ b/tools/run_tests/dockerize/build_docker_and_run_tests.sh
@@ -44,9 +44,6 @@ mkdir -p /tmp/ccache
 # its cache location now that --download-cache is deprecated).
 mkdir -p /tmp/xdg-cache-home
 
-# Create a local branch so the child Docker script won't complain
-git branch -f jenkins-docker
-
 # Inputs
 # DOCKERFILE_DIR - Directory in which Dockerfile file is located.
 # DOCKER_RUN_SCRIPT - Script to run under docker (relative to grpc repo root)
@@ -86,9 +83,12 @@ docker run \
   $DOCKER_IMAGE_NAME \
   bash -l "/var/local/jenkins/grpc/$DOCKER_RUN_SCRIPT" || DOCKER_FAILED="true"
 
-docker cp "$CONTAINER_NAME:/var/local/git/grpc/reports.zip" $git_root || true
-unzip -o $git_root/reports.zip -d $git_root || true
-rm -f reports.zip
+# use unique name for reports.zip to prevent clash between concurrent
+# run_tests.py runs 
+TEMP_REPORTS_ZIP=`mktemp`
+docker cp "$CONTAINER_NAME:/var/local/git/grpc/reports.zip" ${TEMP_REPORTS_ZIP} || true
+unzip -o ${TEMP_REPORTS_ZIP} -d $git_root || true
+rm -f ${TEMP_REPORTS_ZIP}
 
 # remove the container, possibly killing it first
 docker rm -f $CONTAINER_NAME || true
diff --git a/tools/run_tests/run_tests_in_workspace.sh b/tools/run_tests/run_tests_in_workspace.sh
index 0e7604dbc5..b0c9ad05f7 100755
--- a/tools/run_tests/run_tests_in_workspace.sh
+++ b/tools/run_tests/run_tests_in_workspace.sh
@@ -37,6 +37,8 @@ set -ex
 cd $(dirname $0)/../..
 
 rm -rf "${WORKSPACE_NAME}"
+# TODO(jtattermusch): clone --recursive fetches the submodules from github.
+# Try avoiding that to save time and network capacity.
 git clone --recursive . "${WORKSPACE_NAME}"
 
 echo "Running run_tests.py in workspace ${WORKSPACE_NAME}" 
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index 2344e2f9fd..bc2e37abd8 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -32,6 +32,7 @@
 
 import argparse
 import jobset
+import multiprocessing
 import os
 import report_utils
 import sys
@@ -40,8 +41,12 @@ _ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
 os.chdir(_ROOT)
 
 # TODO(jtattermusch): this is not going to be enough for sanitizers.
+# TODO(jtattermusch): this is not going to be enough for rebuilding clang docker.
 _RUNTESTS_TIMEOUT = 30*60
 
+# Number of jobs assigned to each run_tests.py instance
+_INNER_JOBS = 2
+
 
 def _docker_jobspec(name, runtests_args=[]):
   """Run a single instance of run_tests.py in a docker container"""
@@ -50,7 +55,7 @@ def _docker_jobspec(name, runtests_args=[]):
           cmdline=['python', 'tools/run_tests/run_tests.py',
                    '--use_docker',
                    '-t',
-                   '-j', '3',
+                   '-j', str(_INNER_JOBS),
                    '-x', 'report_%s.xml' % name] + runtests_args,
           shortname='run_tests_%s' % name,
           timeout_seconds=_RUNTESTS_TIMEOUT)
@@ -59,11 +64,13 @@ def _docker_jobspec(name, runtests_args=[]):
 
 def _workspace_jobspec(name, runtests_args=[], workspace_name=None):
   """Run a single instance of run_tests.py in a separate workspace"""
+  if not workspace_name:
+    workspace_name = 'workspace_%s' % name
   env = {'WORKSPACE_NAME': workspace_name}
   test_job = jobset.JobSpec(
           cmdline=['tools/run_tests/run_tests_in_workspace.sh',
                    '-t',
-                   '-j', '3',
+                   '-j', str(_INNER_JOBS),
                    '-x', '../report_%s.xml' % name] + runtests_args,
           environ=env,
           shortname='run_tests_%s' % name,
@@ -196,6 +203,10 @@ for job in all_jobs:
     all_labels.add(label)
 
 argp = argparse.ArgumentParser(description='Run a matrix of run_tests.py tests.')
+argp.add_argument('-j', '--jobs',
+                  default=multiprocessing.cpu_count()/_INNER_JOBS,
+                  type=int,
+                  help='Number of concurrent run_tests.py instances.')
 argp.add_argument('-f', '--filter',
                   choices=sorted(all_labels),
                   nargs='+',
@@ -227,7 +238,7 @@ jobset.message('START', 'Running test matrix.', do_newline=True)
 num_failures, resultset = jobset.run(jobs,
                                      newline_on_success=True,
                                      travis=True,
-                                     maxjobs=2)
+                                     maxjobs=args.jobs)
 report_utils.render_junit_xml_report(resultset, 'report.xml')
 
 if num_failures == 0:
-- 
cgit v1.2.3


From 060eb8794a9064fd046952c16dba096ce364eeac Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Tue, 20 Sep 2016 16:06:13 +0200
Subject: address some TODOs

---
 tools/run_tests/run_tests_matrix.py | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

(limited to 'tools/run_tests/run_tests_matrix.py')

diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index bc2e37abd8..06ab02e32f 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -40,9 +40,9 @@ import sys
 _ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
 os.chdir(_ROOT)
 
-# TODO(jtattermusch): this is not going to be enough for sanitizers.
-# TODO(jtattermusch): this is not going to be enough for rebuilding clang docker.
-_RUNTESTS_TIMEOUT = 30*60
+# Set the timeout high to allow enough time for sanitizers and pre-building
+# clang docker.
+_RUNTESTS_TIMEOUT = 2*60*60
 
 # Number of jobs assigned to each run_tests.py instance
 _INNER_JOBS = 2
@@ -50,7 +50,6 @@ _INNER_JOBS = 2
 
 def _docker_jobspec(name, runtests_args=[]):
   """Run a single instance of run_tests.py in a docker container"""
-  # TODO: fix copying report files from inside docker....
   test_job = jobset.JobSpec(
           cmdline=['python', 'tools/run_tests/run_tests.py',
                    '--use_docker',
@@ -203,6 +202,8 @@ for job in all_jobs:
     all_labels.add(label)
 
 argp = argparse.ArgumentParser(description='Run a matrix of run_tests.py tests.')
+# TODO(jtattermusch): allow running tests with --build_only flag
+# TODO(jtattermusch): allow running tests with --force_default_poller flag.
 argp.add_argument('-j', '--jobs',
                   default=multiprocessing.cpu_count()/_INNER_JOBS,
                   type=int,
-- 
cgit v1.2.3


From 6d7c6ef332376def2d0666e4f721ae6fba7176a3 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Thu, 22 Sep 2016 13:40:48 +0200
Subject: support passing extra args to run_tests.py

---
 tools/run_tests/run_tests_matrix.py | 90 ++++++++++++++++++++++++-------------
 1 file changed, 59 insertions(+), 31 deletions(-)

(limited to 'tools/run_tests/run_tests_matrix.py')

diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index 06ab02e32f..ae7fdd84f9 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -79,7 +79,7 @@ def _workspace_jobspec(name, runtests_args=[], workspace_name=None):
 
 def _generate_jobs(languages, configs, platforms,
                   arch=None, compiler=None,
-                  labels=[]):
+                  labels=[], extra_args=[]):
   result = []
   for language in languages:
     for platform in platforms:
@@ -92,6 +92,7 @@ def _generate_jobs(languages, configs, platforms,
           runtests_args += ['--arch', arch,
                             '--compiler', compiler]
 
+        runtests_args += extra_args
         if platform == 'linux':
           job = _docker_jobspec(name=name, runtests_args=runtests_args)
         else:
@@ -102,45 +103,51 @@ def _generate_jobs(languages, configs, platforms,
   return result
 
 
-def _create_test_jobs():
+def _create_test_jobs(extra_args=[]):
   test_jobs = []
   # supported on linux only
   test_jobs += _generate_jobs(languages=['sanity', 'php7'],
                              configs=['dbg', 'opt'],
                              platforms=['linux'],
-                             labels=['basictests'])
+                             labels=['basictests'],
+                             extra_args=extra_args)
   
   # supported on all platforms.
   test_jobs += _generate_jobs(languages=['c', 'csharp', 'node', 'python'],
-                            configs=['dbg', 'opt'],
-                            platforms=['linux', 'macos', 'windows'],
-                            labels=['basictests'])
+                             configs=['dbg', 'opt'],
+                             platforms=['linux', 'macos', 'windows'],
+                             labels=['basictests'],
+                             extra_args=extra_args)
   
   # supported on linux and mac.
   test_jobs += _generate_jobs(languages=['c++', 'ruby', 'php'],
-                             configs=['dbg', 'opt'],
-                             platforms=['linux', 'macos'],
-                             labels=['basictests'])
+                              configs=['dbg', 'opt'],
+                              platforms=['linux', 'macos'],
+                              labels=['basictests'],
+                              extra_args=extra_args)
   
   # supported on mac only.
   test_jobs += _generate_jobs(languages=['objc'],
                               configs=['dbg', 'opt'],
                               platforms=['macos'],
-                              labels=['basictests'])
+                              labels=['basictests'],
+                              extra_args=extra_args)
   
   # sanitizers
   test_jobs += _generate_jobs(languages=['c'],
                               configs=['msan', 'asan', 'tsan'],
                               platforms=['linux'],
-                              labels=['sanitizers'])
+                              labels=['sanitizers'],
+                              extra_args=extra_args)
   test_jobs += _generate_jobs(languages=['c++'],
                               configs=['asan', 'tsan'],
                               platforms=['linux'],
-                              labels=['sanitizers'])
+                              labels=['sanitizers'],
+                              extra_args=extra_args)
   return test_jobs
 
   
-def _create_portability_test_jobs():
+def _create_portability_test_jobs(extra_args=[]):
   test_jobs = []
   # portability C x86
   test_jobs += _generate_jobs(languages=['c'],
@@ -148,7 +155,8 @@ def _create_portability_test_jobs():
                               platforms=['linux'],
                               arch='x86',
                               compiler='default',
-                              labels=['portability'])
+                              labels=['portability'],
+                              extra_args=extra_args)
   
   # portability C and C++ on x64
   for compiler in ['gcc4.4', 'gcc4.6', 'gcc5.3',
@@ -158,7 +166,8 @@ def _create_portability_test_jobs():
                                 platforms=['linux'],
                                 arch='x64',
                                 compiler=compiler,
-                                labels=['portability'])
+                                labels=['portability'],
+                                extra_args=extra_args)
   
   # portability C on Windows
   for arch in ['x86', 'x64']:
@@ -168,53 +177,72 @@ def _create_portability_test_jobs():
                                   platforms=['windows'],
                                   arch=arch,
                                   compiler=compiler,
-                                  labels=['portability'])
+                                  labels=['portability'],
+                                  extra_args=extra_args)
   
   test_jobs += _generate_jobs(languages=['python'],
                               configs=['dbg'],
                               platforms=['linux'],
                               arch='default',
                               compiler='python3.4',
-                              labels=['portability'])
+                              labels=['portability'],
+                              extra_args=extra_args)
   
   test_jobs += _generate_jobs(languages=['csharp'],
                               configs=['dbg'],
                               platforms=['linux'],
                               arch='default',
                               compiler='coreclr',
-                              labels=['portability'])
+                              labels=['portability'],
+                              extra_args=extra_args)
   
   for compiler in ['node5', 'node6', 'node0.12']:
     test_jobs += _generate_jobs(languages=['node'],
-                               configs=['dbg'],
-                               platforms=['linux'],
-                               arch='default',
-                               compiler=compiler,
-                               labels=['portability'])
+                                configs=['dbg'],
+                                platforms=['linux'],
+                                arch='default',
+                                compiler=compiler,
+                                labels=['portability'],
+                                extra_args=extra_args)
   return test_jobs  
 
 
-all_jobs = _create_test_jobs() + _create_portability_test_jobs()
+def _allowed_labels():
+  """Returns a list of existing job labels."""
+  all_labels = set()
+  for job in _create_test_jobs() + _create_portability_test_jobs():
+    for label in job.labels:
+      all_labels.add(label)
+  return sorted(all_labels)
 
-all_labels = set()
-for job in all_jobs:
-  for label in job.labels:
-    all_labels.add(label)
 
 argp = argparse.ArgumentParser(description='Run a matrix of run_tests.py tests.')
-# TODO(jtattermusch): allow running tests with --build_only flag
-# TODO(jtattermusch): allow running tests with --force_default_poller flag.
 argp.add_argument('-j', '--jobs',
                   default=multiprocessing.cpu_count()/_INNER_JOBS,
                   type=int,
                   help='Number of concurrent run_tests.py instances.')
 argp.add_argument('-f', '--filter',
-                  choices=sorted(all_labels),
+                  choices=_allowed_labels(),
                   nargs='+',
                   default=[],
                   help='Filter targets to run by label with AND semantics.')
+argp.add_argument('--build_only',
+                  default=False,
+                  action='store_const',
+                  const=True,
+                  help='Pass --build_only flag to run_tests.py instances.')
+argp.add_argument('--force_default_poller', default=False, action='store_const', const=True,
+                  help='Pass --force_default_poller to run_tests.py instances.')
 args = argp.parse_args()
 
+extra_args = []
+if args.build_only:
+  extra_args.append('--build_only')
+if args.force_default_poller:
+  extra_args.append('--force_default_poller')
+
+all_jobs = _create_test_jobs(extra_args=extra_args) + _create_portability_test_jobs(extra_args=extra_args)
+
 jobs = []
 for job in all_jobs:
   if not args.filter or all(filter in job.labels for filter in args.filter):
-- 
cgit v1.2.3


From 1c037a30441466ed06d9e11c7e56e749afc99bed Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Thu, 22 Sep 2016 14:28:07 +0200
Subject: node6 portability test not yet implemented

---
 tools/run_tests/run_tests_matrix.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'tools/run_tests/run_tests_matrix.py')

diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index ae7fdd84f9..d87632d889 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -196,7 +196,7 @@ def _create_portability_test_jobs(extra_args=[]):
                               labels=['portability'],
                               extra_args=extra_args)
   
-  for compiler in ['node5', 'node6', 'node0.12']:
+  for compiler in ['node5', 'node0.12']:
     test_jobs += _generate_jobs(languages=['node'],
                                 configs=['dbg'],
                                 platforms=['linux'],
-- 
cgit v1.2.3


From c1e44906f87fbd6552a5ed3cc372cce1ec170cbb Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Thu, 22 Sep 2016 14:31:10 +0200
Subject: support --dry_run flag

---
 tools/run_tests/run_tests_matrix.py | 9 +++++++++
 1 file changed, 9 insertions(+)

(limited to 'tools/run_tests/run_tests_matrix.py')

diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index d87632d889..a31b0dd917 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -233,6 +233,11 @@ argp.add_argument('--build_only',
                   help='Pass --build_only flag to run_tests.py instances.')
 argp.add_argument('--force_default_poller', default=False, action='store_const', const=True,
                   help='Pass --force_default_poller to run_tests.py instances.')
+argp.add_argument('--dry_run',
+                  default=False,
+                  action='store_const',
+                  const=True,
+                  help='Only print what would be run.')
 args = argp.parse_args()
 
 extra_args = []
@@ -263,6 +268,10 @@ for job in jobs:
   print '  %s' % job.shortname
 print
 
+if args.dry_run:
+  print '--dry_run was used, exiting'
+  sys.exit(1)
+
 jobset.message('START', 'Running test matrix.', do_newline=True)
 num_failures, resultset = jobset.run(jobs,
                                      newline_on_success=True,
-- 
cgit v1.2.3


From 7b9c21ab2c467df62ab3c871e6544cfb70a23a44 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Thu, 22 Sep 2016 14:44:27 +0200
Subject: better --dry_run printouts

---
 tools/run_tests/run_tests_matrix.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'tools/run_tests/run_tests_matrix.py')

diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index a31b0dd917..d5f9047825 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -265,7 +265,10 @@ print('copied to the docker environment or into subworkspaces.')
 print 
 print 'Will run these tests:'
 for job in jobs:
-  print '  %s' % job.shortname
+  if args.dry_run:
+    print '  %s: "%s"' % (job.shortname, ' '.join(job.cmdline))
+  else:
+    print '  %s' % job.shortname
 print
 
 if args.dry_run:
-- 
cgit v1.2.3