blob: 191228e4db78771174696f3edc0f76b9c14fb4ba [file] [log] [blame]
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +02001#!/usr/bin/env python2.7
2# Copyright 2015, Google Inc.
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met:
8#
9# * Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# * Redistributions in binary form must reproduce the above
12# copyright notice, this list of conditions and the following disclaimer
13# in the documentation and/or other materials provided with the
14# distribution.
15# * Neither the name of Google Inc. nor the names of its
16# contributors may be used to endorse or promote products derived from
17# this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31"""Run test matrix."""
32
Siddharth Shuklad194f592017-03-11 19:12:43 +010033from __future__ import print_function
34
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020035import argparse
Jan Tattermuscha1906d52016-09-19 18:37:17 +020036import multiprocessing
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020037import os
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020038import sys
Jan Tattermusch5c79a312016-12-20 11:02:50 +010039
40import python_utils.jobset as jobset
41import python_utils.report_utils as report_utils
42from python_utils.filter_pull_request_tests import filter_tests
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020043
44_ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
45os.chdir(_ROOT)
46
Jan Tattermusch060eb872016-09-20 16:06:13 +020047# Set the timeout high to allow enough time for sanitizers and pre-building
48# clang docker.
Ken Payson97e69202016-10-17 09:11:49 -070049_RUNTESTS_TIMEOUT = 4*60*60
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020050
Jan Tattermuscha1906d52016-09-19 18:37:17 +020051# Number of jobs assigned to each run_tests.py instance
Matt Kwongfef98962016-10-27 10:45:47 -070052_DEFAULT_INNER_JOBS = 2
Jan Tattermuscha1906d52016-09-19 18:37:17 +020053
Jan Tattermusch5a59c432017-03-07 19:57:13 +010054# report suffix is important for reports to get picked up by internal CI
55_REPORT_SUFFIX = 'sponge_log.xml'
56
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020057
Matt Kwongfef98962016-10-27 10:45:47 -070058def _docker_jobspec(name, runtests_args=[], inner_jobs=_DEFAULT_INNER_JOBS):
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020059 """Run a single instance of run_tests.py in a docker container"""
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020060 test_job = jobset.JobSpec(
61 cmdline=['python', 'tools/run_tests/run_tests.py',
62 '--use_docker',
63 '-t',
Matt Kwongfef98962016-10-27 10:45:47 -070064 '-j', str(inner_jobs),
Jan Tattermusch5a59c432017-03-07 19:57:13 +010065 '-x', 'report_%s_%s' % (name, _REPORT_SUFFIX),
Jan Tattermuschcfcc0752016-10-09 17:02:34 +020066 '--report_suite_name', '%s' % name] + runtests_args,
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020067 shortname='run_tests_%s' % name,
68 timeout_seconds=_RUNTESTS_TIMEOUT)
69 return test_job
70
71
Matt Kwongfef98962016-10-27 10:45:47 -070072def _workspace_jobspec(name, runtests_args=[], workspace_name=None, inner_jobs=_DEFAULT_INNER_JOBS):
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020073 """Run a single instance of run_tests.py in a separate workspace"""
Jan Tattermuscha1906d52016-09-19 18:37:17 +020074 if not workspace_name:
75 workspace_name = 'workspace_%s' % name
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020076 env = {'WORKSPACE_NAME': workspace_name}
77 test_job = jobset.JobSpec(
Jan Tattermuschff61b8c2017-03-01 15:57:33 +010078 cmdline=['bash',
79 'tools/run_tests/helper_scripts/run_tests_in_workspace.sh',
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020080 '-t',
Matt Kwongfef98962016-10-27 10:45:47 -070081 '-j', str(inner_jobs),
Jan Tattermusch5a59c432017-03-07 19:57:13 +010082 '-x', '../report_%s_%s' % (name, _REPORT_SUFFIX),
Jan Tattermuschcfcc0752016-10-09 17:02:34 +020083 '--report_suite_name', '%s' % name] + runtests_args,
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020084 environ=env,
85 shortname='run_tests_%s' % name,
86 timeout_seconds=_RUNTESTS_TIMEOUT)
87 return test_job
88
89
murgatroid991191b722017-02-08 11:56:52 -080090def _generate_jobs(languages, configs, platforms, iomgr_platform = 'native',
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020091 arch=None, compiler=None,
Matt Kwongfef98962016-10-27 10:45:47 -070092 labels=[], extra_args=[],
93 inner_jobs=_DEFAULT_INNER_JOBS):
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020094 result = []
95 for language in languages:
96 for platform in platforms:
97 for config in configs:
murgatroid991191b722017-02-08 11:56:52 -080098 name = '%s_%s_%s_%s' % (language, platform, config, iomgr_platform)
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +020099 runtests_args = ['-l', language,
100 '-c', config]
101 if arch or compiler:
102 name += '_%s_%s' % (arch, compiler)
103 runtests_args += ['--arch', arch,
104 '--compiler', compiler]
105
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200106 runtests_args += extra_args
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200107 if platform == 'linux':
Matt Kwongfef98962016-10-27 10:45:47 -0700108 job = _docker_jobspec(name=name, runtests_args=runtests_args, inner_jobs=inner_jobs)
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200109 else:
Matt Kwongfef98962016-10-27 10:45:47 -0700110 job = _workspace_jobspec(name=name, runtests_args=runtests_args, inner_jobs=inner_jobs)
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200111
112 job.labels = [platform, config, language] + labels
113 result.append(job)
114 return result
115
116
Matt Kwongfef98962016-10-27 10:45:47 -0700117def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS):
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200118 test_jobs = []
119 # supported on linux only
120 test_jobs += _generate_jobs(languages=['sanity', 'php7'],
121 configs=['dbg', 'opt'],
122 platforms=['linux'],
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200123 labels=['basictests'],
Matt Kwongfef98962016-10-27 10:45:47 -0700124 extra_args=extra_args,
125 inner_jobs=inner_jobs)
murgatroid991687cab2016-10-11 11:42:01 -0700126
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200127 # supported on all platforms.
128 test_jobs += _generate_jobs(languages=['c', 'csharp', 'node', 'python'],
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200129 configs=['dbg', 'opt'],
130 platforms=['linux', 'macos', 'windows'],
131 labels=['basictests'],
Matt Kwongfef98962016-10-27 10:45:47 -0700132 extra_args=extra_args,
133 inner_jobs=inner_jobs)
murgatroid991687cab2016-10-11 11:42:01 -0700134
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200135 # supported on linux and mac.
136 test_jobs += _generate_jobs(languages=['c++', 'ruby', 'php'],
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200137 configs=['dbg', 'opt'],
138 platforms=['linux', 'macos'],
139 labels=['basictests'],
Matt Kwongfef98962016-10-27 10:45:47 -0700140 extra_args=extra_args,
141 inner_jobs=inner_jobs)
murgatroid991687cab2016-10-11 11:42:01 -0700142
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200143 # supported on mac only.
144 test_jobs += _generate_jobs(languages=['objc'],
145 configs=['dbg', 'opt'],
146 platforms=['macos'],
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200147 labels=['basictests'],
Matt Kwongfef98962016-10-27 10:45:47 -0700148 extra_args=extra_args,
149 inner_jobs=inner_jobs)
murgatroid991687cab2016-10-11 11:42:01 -0700150
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200151 # sanitizers
152 test_jobs += _generate_jobs(languages=['c'],
153 configs=['msan', 'asan', 'tsan'],
154 platforms=['linux'],
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200155 labels=['sanitizers'],
Matt Kwongfef98962016-10-27 10:45:47 -0700156 extra_args=extra_args,
157 inner_jobs=inner_jobs)
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200158 test_jobs += _generate_jobs(languages=['c++'],
159 configs=['asan', 'tsan'],
160 platforms=['linux'],
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200161 labels=['sanitizers'],
Matt Kwongfef98962016-10-27 10:45:47 -0700162 extra_args=extra_args,
163 inner_jobs=inner_jobs)
murgatroid991687cab2016-10-11 11:42:01 -0700164
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200165 return test_jobs
166
murgatroid991687cab2016-10-11 11:42:01 -0700167
Matt Kwongfef98962016-10-27 10:45:47 -0700168def _create_portability_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS):
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200169 test_jobs = []
170 # portability C x86
171 test_jobs += _generate_jobs(languages=['c'],
172 configs=['dbg'],
173 platforms=['linux'],
174 arch='x86',
175 compiler='default',
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200176 labels=['portability'],
Matt Kwongfef98962016-10-27 10:45:47 -0700177 extra_args=extra_args,
178 inner_jobs=inner_jobs)
murgatroid991687cab2016-10-11 11:42:01 -0700179
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200180 # portability C and C++ on x64
181 for compiler in ['gcc4.4', 'gcc4.6', 'gcc5.3',
182 'clang3.5', 'clang3.6', 'clang3.7']:
Matt Kwonge3beac92016-11-01 12:53:04 -0700183 test_jobs += _generate_jobs(languages=['c'],
184 configs=['dbg'],
185 platforms=['linux'],
186 arch='x64',
187 compiler=compiler,
188 labels=['portability'],
189 extra_args=extra_args,
190 inner_jobs=inner_jobs)
Jan Tattermusch8613e472016-11-22 11:15:53 +0100191
Matt Kwonge3beac92016-11-01 12:53:04 -0700192 for compiler in ['gcc4.8', 'gcc5.3',
193 'clang3.5', 'clang3.6', 'clang3.7']:
194 test_jobs += _generate_jobs(languages=['c++'],
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200195 configs=['dbg'],
196 platforms=['linux'],
197 arch='x64',
198 compiler=compiler,
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200199 labels=['portability'],
Matt Kwongfef98962016-10-27 10:45:47 -0700200 extra_args=extra_args,
201 inner_jobs=inner_jobs)
murgatroid991687cab2016-10-11 11:42:01 -0700202
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200203 # portability C on Windows
204 for arch in ['x86', 'x64']:
205 for compiler in ['vs2013', 'vs2015']:
206 test_jobs += _generate_jobs(languages=['c'],
207 configs=['dbg'],
208 platforms=['windows'],
209 arch=arch,
210 compiler=compiler,
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200211 labels=['portability'],
Matt Kwongfef98962016-10-27 10:45:47 -0700212 extra_args=extra_args,
213 inner_jobs=inner_jobs)
murgatroid991687cab2016-10-11 11:42:01 -0700214
Jan Tattermuschdfb03bb2017-01-25 19:27:58 +0100215 # cmake build for C and C++
216 # TODO(jtattermusch): some of the tests are failing, so we force --build_only
217 # to make sure it's buildable at least.
218 test_jobs += _generate_jobs(languages=['c', 'c++'],
219 configs=['dbg'],
220 platforms=['linux', 'windows'],
221 arch='default',
222 compiler='cmake',
223 labels=['portability'],
224 extra_args=extra_args + ['--build_only'],
225 inner_jobs=inner_jobs)
226
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200227 test_jobs += _generate_jobs(languages=['python'],
228 configs=['dbg'],
229 platforms=['linux'],
230 arch='default',
231 compiler='python3.4',
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200232 labels=['portability'],
Matt Kwongfef98962016-10-27 10:45:47 -0700233 extra_args=extra_args,
234 inner_jobs=inner_jobs)
murgatroid991687cab2016-10-11 11:42:01 -0700235
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200236 test_jobs += _generate_jobs(languages=['csharp'],
237 configs=['dbg'],
238 platforms=['linux'],
239 arch='default',
240 compiler='coreclr',
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200241 labels=['portability'],
Matt Kwongfef98962016-10-27 10:45:47 -0700242 extra_args=extra_args,
243 inner_jobs=inner_jobs)
murgatroid99804c9e92016-12-05 12:19:57 -0800244
murgatroid991191b722017-02-08 11:56:52 -0800245 test_jobs += _generate_jobs(languages=['c'],
246 configs=['dbg'],
247 platforms=['linux'],
248 iomgr_platform='uv',
249 labels=['portability'],
250 extra_args=extra_args,
251 inner_jobs=inner_jobs)
252
murgatroid99804c9e92016-12-05 12:19:57 -0800253 test_jobs += _generate_jobs(languages=['node'],
254 configs=['dbg'],
255 platforms=['linux'],
256 arch='default',
257 compiler='electron1.3',
258 labels=['portability'],
259 extra_args=extra_args,
260 inner_jobs=inner_jobs)
murgatroid991191b722017-02-08 11:56:52 -0800261
262 test_jobs += _generate_jobs(languages=['node'],
263 configs=['dbg'],
264 platforms=['linux'],
265 iomgr_platform='uv',
266 labels=['portability'],
267 extra_args=extra_args,
268 inner_jobs=inner_jobs)
269
270 test_jobs += _generate_jobs(languages=['node'],
271 configs=['dbg'],
272 platforms=['linux'],
273 arch='default',
274 compiler='node4',
275 labels=['portability'],
276 extra_args=extra_args,
277 inner_jobs=inner_jobs)
278
279 test_jobs += _generate_jobs(languages=['node'],
280 configs=['dbg'],
281 platforms=['linux'],
282 arch='default',
283 compiler='node6',
284 labels=['portability'],
285 extra_args=extra_args,
286 inner_jobs=inner_jobs)
287
murgatroid991687cab2016-10-11 11:42:01 -0700288 return test_jobs
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200289
290
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200291def _allowed_labels():
292 """Returns a list of existing job labels."""
293 all_labels = set()
294 for job in _create_test_jobs() + _create_portability_test_jobs():
295 for label in job.labels:
296 all_labels.add(label)
297 return sorted(all_labels)
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200298
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200299
Jan Tattermusch68e27bf2016-12-16 14:09:03 +0100300def _runs_per_test_type(arg_str):
Jan Tattermusch6a851292016-12-20 10:20:42 +0100301 """Auxiliary function to parse the "runs_per_test" flag."""
302 try:
303 n = int(arg_str)
304 if n <= 0: raise ValueError
305 return n
306 except:
307 msg = '\'{}\' is not a positive integer'.format(arg_str)
308 raise argparse.ArgumentTypeError(msg)
Jan Tattermusch68e27bf2016-12-16 14:09:03 +0100309
310
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700311if __name__ == "__main__":
312 argp = argparse.ArgumentParser(description='Run a matrix of run_tests.py tests.')
313 argp.add_argument('-j', '--jobs',
314 default=multiprocessing.cpu_count()/_DEFAULT_INNER_JOBS,
315 type=int,
316 help='Number of concurrent run_tests.py instances.')
317 argp.add_argument('-f', '--filter',
318 choices=_allowed_labels(),
319 nargs='+',
320 default=[],
321 help='Filter targets to run by label with AND semantics.')
Jan Tattermusch6a851292016-12-20 10:20:42 +0100322 argp.add_argument('--exclude',
323 choices=_allowed_labels(),
324 nargs='+',
325 default=[],
326 help='Exclude targets with any of given labels.')
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700327 argp.add_argument('--build_only',
328 default=False,
329 action='store_const',
330 const=True,
331 help='Pass --build_only flag to run_tests.py instances.')
332 argp.add_argument('--force_default_poller', default=False, action='store_const', const=True,
333 help='Pass --force_default_poller to run_tests.py instances.')
334 argp.add_argument('--dry_run',
335 default=False,
336 action='store_const',
337 const=True,
338 help='Only print what would be run.')
339 argp.add_argument('--filter_pr_tests',
340 default=False,
341 action='store_const',
342 const=True,
Jan Tattermusch68e27bf2016-12-16 14:09:03 +0100343 help='Filters out tests irrelevant to pull request changes.')
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700344 argp.add_argument('--base_branch',
345 default='origin/master',
346 type=str,
347 help='Branch that pull request is requesting to merge into')
348 argp.add_argument('--inner_jobs',
349 default=_DEFAULT_INNER_JOBS,
350 type=int,
351 help='Number of jobs in each run_tests.py instance')
Jan Tattermusch68e27bf2016-12-16 14:09:03 +0100352 argp.add_argument('-n', '--runs_per_test', default=1, type=_runs_per_test_type,
353 help='How many times to run each tests. >1 runs implies ' +
354 'omitting passing test from the output & reports.')
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700355 args = argp.parse_args()
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200356
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700357 extra_args = []
358 if args.build_only:
359 extra_args.append('--build_only')
360 if args.force_default_poller:
361 extra_args.append('--force_default_poller')
Jan Tattermusch68e27bf2016-12-16 14:09:03 +0100362 if args.runs_per_test > 1:
363 extra_args.append('-n')
364 extra_args.append('%s' % args.runs_per_test)
365 extra_args.append('--quiet_success')
Matt Kwongfef98962016-10-27 10:45:47 -0700366
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700367 all_jobs = _create_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs) + \
368 _create_portability_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs)
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200369
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700370 jobs = []
371 for job in all_jobs:
372 if not args.filter or all(filter in job.labels for filter in args.filter):
Jan Tattermusch6a851292016-12-20 10:20:42 +0100373 if not any(exclude_label in job.labels for exclude_label in args.exclude):
374 jobs.append(job)
Jan Tattermusch6d7c6ef2016-09-22 13:40:48 +0200375
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700376 if not jobs:
377 jobset.message('FAILED', 'No test suites match given criteria.',
378 do_newline=True)
379 sys.exit(1)
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200380
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700381 print('IMPORTANT: The changes you are testing need to be locally committed')
382 print('because only the committed changes in the current branch will be')
383 print('copied to the docker environment or into subworkspaces.')
murgatroid991687cab2016-10-11 11:42:01 -0700384
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700385 skipped_jobs = []
Jan Tattermusch9c79e8d2016-09-19 14:33:18 +0200386
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700387 if args.filter_pr_tests:
388 print('Looking for irrelevant tests to skip...')
389 relevant_jobs = filter_tests(jobs, args.base_branch)
390 if len(relevant_jobs) == len(jobs):
391 print('No tests will be skipped.')
392 else:
393 print('These tests will be skipped:')
Matt Kwongaa6c94c2016-11-09 15:53:23 -0800394 skipped_jobs = list(set(jobs) - set(relevant_jobs))
395 # Sort by shortnames to make printing of skipped tests consistent
396 skipped_jobs.sort(key=lambda job: job.shortname)
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700397 for job in list(skipped_jobs):
398 print(' %s' % job.shortname)
399 jobs = relevant_jobs
400
401 print('Will run these tests:')
402 for job in jobs:
403 if args.dry_run:
404 print(' %s: "%s"' % (job.shortname, ' '.join(job.cmdline)))
405 else:
406 print(' %s' % job.shortname)
Matt Kwong5c691c62016-10-20 17:11:18 -0700407 print
408
Jan Tattermusch7b9c21a2016-09-22 14:44:27 +0200409 if args.dry_run:
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700410 print('--dry_run was used, exiting')
411 sys.exit(1)
412
413 jobset.message('START', 'Running test matrix.', do_newline=True)
414 num_failures, resultset = jobset.run(jobs,
415 newline_on_success=True,
416 travis=True,
417 maxjobs=args.jobs)
418 # Merge skipped tests into results to show skipped tests on report.xml
419 if skipped_jobs:
420 skipped_results = jobset.run(skipped_jobs,
421 skip_jobs=True)
422 resultset.update(skipped_results)
Jan Tattermusch5a59c432017-03-07 19:57:13 +0100423 report_utils.render_junit_xml_report(resultset, 'report_%s' % _REPORT_SUFFIX,
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700424 suite_name='aggregate_tests')
425
426 if num_failures == 0:
427 jobset.message('SUCCESS', 'All run_tests.py instance finished successfully.',
428 do_newline=True)
Jan Tattermusch7b9c21a2016-09-22 14:44:27 +0200429 else:
Matt Kwong7e9bd6c2016-10-24 17:30:25 -0700430 jobset.message('FAILED', 'Some run_tests.py instance have failed.',
431 do_newline=True)
432 sys.exit(1)