blob: 588784353a943dc822981814105bf1951e1dff33 [file] [log] [blame]
Tsuyoshi Ozawa4e0238d2016-09-20 05:56:10 +09001#!/usr/bin/env python
Jan Tattermusch7897ae92017-06-07 22:57:36 +02002# Copyright 2015 gRPC authors.
Craig Tillerc2c79212015-02-16 12:00:01 -08003#
Jan Tattermusch7897ae92017-06-07 22:57:36 +02004# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
Craig Tillerc2c79212015-02-16 12:00:01 -08007#
Jan Tattermusch7897ae92017-06-07 22:57:36 +02008# http://www.apache.org/licenses/LICENSE-2.0
Craig Tillerc2c79212015-02-16 12:00:01 -08009#
Jan Tattermusch7897ae92017-06-07 22:57:36 +020010# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
Craig Tillerc2c79212015-02-16 12:00:01 -080015
Nicolas Nobleddef2462015-01-06 18:08:25 -080016"""Run tests in parallel."""
17
siddharthshukla0589e532016-07-07 16:08:01 +020018from __future__ import print_function
19
Nicolas Nobleddef2462015-01-06 18:08:25 -080020import argparse
Craig Tiller9279ac22016-01-20 17:05:23 -080021import ast
Masood Malekghassemi3b5b2062016-06-02 20:27:20 -070022import collections
Nicolas Nobleddef2462015-01-06 18:08:25 -080023import glob
24import itertools
Craig Tiller261dd982015-01-16 16:41:45 -080025import json
David Garcia Quintas0727c102017-02-21 10:48:35 -080026import logging
Nicolas Nobleddef2462015-01-06 18:08:25 -080027import multiprocessing
Craig Tiller1cc11db2015-01-15 22:50:50 -080028import os
Masood Malekghassemi3b5b2062016-06-02 20:27:20 -070029import os.path
Craig Tiller38fb8de2016-07-13 08:23:32 -070030import pipes
David Garcia Quintas79e389f2015-06-02 17:49:42 -070031import platform
32import random
Craig Tillerfe406ec2015-02-24 13:55:12 -080033import re
Craig Tiller82875232015-09-25 13:57:34 -070034import socket
David Garcia Quintas79e389f2015-06-02 17:49:42 -070035import subprocess
Nicolas Nobleddef2462015-01-06 18:08:25 -080036import sys
Craig Tillerf0a293e2015-10-12 10:05:50 -070037import tempfile
38import traceback
ctiller3040cb72015-01-07 12:13:17 -080039import time
siddharthshukla0589e532016-07-07 16:08:01 +020040from six.moves import urllib
Jan Tattermusch03c01062015-12-11 14:28:56 -080041import uuid
Siddharth Shuklad194f592017-03-11 19:12:43 +010042import six
Nicolas Nobleddef2462015-01-06 18:08:25 -080043
Jan Tattermusch5c79a312016-12-20 11:02:50 +010044import python_utils.jobset as jobset
45import python_utils.report_utils as report_utils
46import python_utils.watch_dirs as watch_dirs
Craig Tiller7dc4ea62017-02-02 16:08:05 -080047import python_utils.start_port_server as start_port_server
Matt Kwong52ff9862017-04-17 13:56:51 -070048try:
49 from python_utils.upload_test_results import upload_results_to_bq
50except (ImportError):
51 pass # It's ok to not import because this is only necessary to upload results to BQ.
Craig Tillerb361b4e2016-01-06 11:44:17 -080052
David Garcia Quintasfaafa4d2017-06-06 14:52:17 -070053gcp_utils_dir = os.path.abspath(os.path.join(
54 os.path.dirname(__file__), '../gcp/utils'))
55sys.path.append(gcp_utils_dir)
David Garcia Quintasfaafa4d2017-06-06 14:52:17 -070056
Jan Tattermusch3b5121b2016-02-22 17:41:05 -080057_ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
58os.chdir(_ROOT)
Craig Tiller2cc2b842015-02-27 11:38:31 -080059
60
Craig Tiller8f18ee62016-07-18 08:00:33 -070061_FORCE_ENVIRON_FOR_WRAPPERS = {
62 'GRPC_VERBOSITY': 'DEBUG',
63}
Craig Tiller06805272015-06-11 14:46:47 -070064
Craig Tiller123f1372016-06-15 15:06:14 -070065_POLLING_STRATEGIES = {
Sree Kuchibhotlafc58bd82017-07-26 00:02:41 -070066 'linux': ['epollsig', 'epoll1', 'poll', 'poll-cv'],
67# TODO(ctiller, sreecha): enable epollex, epoll-thread-pool
Vijay Paiadb76ee2017-05-16 08:50:55 -070068 'mac': ['poll'],
Craig Tiller123f1372016-06-15 15:06:14 -070069}
70
71
Craig Tiller9992bdb2017-09-06 15:00:31 -070072BigQueryTestData = collections.namedtuple('BigQueryTestData', 'name flaky cpu')
73
74
75def get_bqtest_data(limit=None):
Craig Tillerd16abf82017-06-07 08:58:55 -070076 import big_query_utils
77
78 bq = big_query_utils.create_big_query()
David Garcia Quintasfaafa4d2017-06-06 14:52:17 -070079 query = """
David Garcia Quintas48623592017-08-02 18:15:22 -070080SELECT
81 filtered_test_name,
Craig Tiller120d4fd2017-09-07 12:25:25 -070082 SUM(result != 'PASSED' AND result != 'SKIPPED') > 0 as flaky,
Craig Tillerf7617bb2017-09-13 09:47:28 -070083 MAX(cpu_measured) + 0.01 as cpu
David Garcia Quintas48623592017-08-02 18:15:22 -070084 FROM (
85 SELECT
86 REGEXP_REPLACE(test_name, r'/\d+', '') AS filtered_test_name,
Craig Tiller9992bdb2017-09-06 15:00:31 -070087 result, cpu_measured
David Garcia Quintas48623592017-08-02 18:15:22 -070088 FROM
89 [grpc-testing:jenkins_test_results.aggregate_results]
90 WHERE
91 timestamp >= DATE_ADD(CURRENT_DATE(), -1, "WEEK")
Jan Tattermuschfb7c9a42017-08-14 10:46:43 +020092 AND platform = '"""+platform_string()+"""'
David Garcia Quintas48623592017-08-02 18:15:22 -070093 AND NOT REGEXP_MATCH(job_name, '.*portability.*') )
94GROUP BY
Craig Tillerf7617bb2017-09-13 09:47:28 -070095 filtered_test_name"""
David Garcia Quintasfaafa4d2017-06-06 14:52:17 -070096 if limit:
97 query += " limit {}".format(limit)
Craig Tillerd16abf82017-06-07 08:58:55 -070098 query_job = big_query_utils.sync_query_job(bq, 'grpc-testing', query)
David Garcia Quintasfaafa4d2017-06-06 14:52:17 -070099 page = bq.jobs().getQueryResults(
100 pageToken=None,
101 **query_job['jobReference']).execute(num_retries=3)
Craig Tiller9992bdb2017-09-06 15:00:31 -0700102 test_data = [BigQueryTestData(row['f'][0]['v'], row['f'][1]['v'] == 'true', float(row['f'][2]['v'])) for row in page['rows']]
103 return test_data
David Garcia Quintasfaafa4d2017-06-06 14:52:17 -0700104
105
Craig Tillerd50993d2015-08-05 08:04:36 -0700106def platform_string():
Nicolas "Pixel" Noblef72d7b52015-12-03 03:07:43 +0100107 return jobset.platform_string()
Craig Tillerd50993d2015-08-05 08:04:36 -0700108
109
Craig Tiller38fb8de2016-07-13 08:23:32 -0700110_DEFAULT_TIMEOUT_SECONDS = 5 * 60
111
David Garcia Quintas03920252017-02-15 12:51:21 -0800112def run_shell_command(cmd, env=None, cwd=None):
113 try:
114 subprocess.check_output(cmd, shell=True, env=env, cwd=cwd)
115 except subprocess.CalledProcessError as e:
David Garcia Quintas0727c102017-02-21 10:48:35 -0800116 logging.exception("Error while running command '%s'. Exit status %d. Output:\n%s",
117 e.cmd, e.returncode, e.output)
David Garcia Quintas03920252017-02-15 12:51:21 -0800118 raise
Craig Tiller38fb8de2016-07-13 08:23:32 -0700119
Alexander Polcyndbfcd452017-10-01 15:34:29 -0700120def max_parallel_tests_for_current_platform():
121 # Too much test parallelization has only been seen to be a problem
122 # so far on windows.
123 if jobset.platform_string() == 'windows':
124 return 64
Craig Tillere544ff02017-10-14 03:52:03 +0000125 return 1024
Alexander Polcyndbfcd452017-10-01 15:34:29 -0700126
Craig Tiller738c3342015-01-12 14:28:33 -0800127# SimpleConfig: just compile with CONFIG=config, and run the binary to test
Craig Tillera0f85172016-01-20 15:56:06 -0800128class Config(object):
Craig Tillerb50d1662015-01-15 17:28:21 -0800129
murgatroid99c36f6ea2016-10-03 09:24:09 -0700130 def __init__(self, config, environ=None, timeout_multiplier=1, tool_prefix=[], iomgr_platform='native'):
murgatroid99132ce6a2015-03-04 17:29:14 -0800131 if environ is None:
132 environ = {}
Craig Tiller738c3342015-01-12 14:28:33 -0800133 self.build_config = config
Craig Tiller547db2b2015-01-30 14:08:39 -0800134 self.environ = environ
murgatroid99132ce6a2015-03-04 17:29:14 -0800135 self.environ['CONFIG'] = config
Craig Tillera0f85172016-01-20 15:56:06 -0800136 self.tool_prefix = tool_prefix
Masood Malekghassemi26ea9e22015-10-09 15:19:17 -0700137 self.timeout_multiplier = timeout_multiplier
murgatroid99c36f6ea2016-10-03 09:24:09 -0700138 self.iomgr_platform = iomgr_platform
Craig Tiller738c3342015-01-12 14:28:33 -0800139
Craig Tiller38fb8de2016-07-13 08:23:32 -0700140 def job_spec(self, cmdline, timeout_seconds=_DEFAULT_TIMEOUT_SECONDS,
Craig Tillerde7edf82016-03-20 09:12:16 -0700141 shortname=None, environ={}, cpu_cost=1.0, flaky=False):
Craig Tiller49f61322015-03-03 13:02:11 -0800142 """Construct a jobset.JobSpec for a test under this config
143
144 Args:
145 cmdline: a list of strings specifying the command line the test
146 would like to run
Craig Tiller49f61322015-03-03 13:02:11 -0800147 """
Craig Tiller4fc90032015-05-21 10:39:52 -0700148 actual_environ = self.environ.copy()
siddharthshukla0589e532016-07-07 16:08:01 +0200149 for k, v in environ.items():
Craig Tiller4fc90032015-05-21 10:39:52 -0700150 actual_environ[k] = v
Craig Tiller336c21e2017-06-06 15:23:10 -0700151 if not flaky and shortname and shortname in flaky_tests:
Craig Tiller336c21e2017-06-06 15:23:10 -0700152 flaky = True
Craig Tiller0b86d032017-09-07 13:47:45 -0700153 if shortname in shortname_to_cpu:
Craig Tiller0b86d032017-09-07 13:47:45 -0700154 cpu_cost = shortname_to_cpu[shortname]
Craig Tillera0f85172016-01-20 15:56:06 -0800155 return jobset.JobSpec(cmdline=self.tool_prefix + cmdline,
Jan Tattermusch9a7d30c2015-04-23 16:12:55 -0700156 shortname=shortname,
Craig Tiller4fc90032015-05-21 10:39:52 -0700157 environ=actual_environ,
Craig Tiller56c6b6a2016-01-20 08:27:37 -0800158 cpu_cost=cpu_cost,
Craig Tiller94d04a52016-01-20 10:58:23 -0800159 timeout_seconds=(self.timeout_multiplier * timeout_seconds if timeout_seconds else None),
Jan Tattermusch376dc342017-10-16 16:00:35 +0200160 flake_retries=4 if flaky or args.allow_flakes else 0,
161 timeout_retries=1 if flaky or args.allow_flakes else 0)
Craig Tiller738c3342015-01-12 14:28:33 -0800162
163
murgatroid99cf08daf2015-09-21 15:33:16 -0700164def get_c_tests(travis, test_lang) :
165 out = []
166 platforms_str = 'ci_platforms' if travis else 'platforms'
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100167 with open('tools/run_tests/generated/tests.json') as f:
murgatroid9989899b12015-09-22 09:14:48 -0700168 js = json.load(f)
murgatroid99a3e244f2015-09-22 11:25:53 -0700169 return [tgt
170 for tgt in js
171 if tgt['language'] == test_lang and
172 platform_string() in tgt[platforms_str] and
173 not (travis and tgt['flaky'])]
murgatroid99cf08daf2015-09-21 15:33:16 -0700174
murgatroid99fafeeb32015-09-22 09:13:03 -0700175
Jan Tattermusch77db4322016-02-20 20:19:35 -0800176def _check_compiler(compiler, supported_compilers):
177 if compiler not in supported_compilers:
Jan Tattermuschb2531e22016-03-25 16:14:41 -0700178 raise Exception('Compiler %s not supported (on this platform).' % compiler)
179
180
181def _check_arch(arch, supported_archs):
182 if arch not in supported_archs:
183 raise Exception('Architecture %s not supported.' % arch)
Jan Tattermusch77db4322016-02-20 20:19:35 -0800184
185
Jan Tattermuschc4cbe392016-02-22 19:29:38 -0800186def _is_use_docker_child():
187 """Returns True if running running as a --use_docker child."""
188 return True if os.getenv('RUN_TESTS_COMMAND') else False
189
190
siddharthshukla2135a1b2016-08-04 02:11:53 +0200191_PythonConfigVars = collections.namedtuple(
192 '_ConfigVars', ['shell', 'builder', 'builder_prefix_arguments',
193 'venv_relative_python', 'toolchain', 'runner'])
194
195
196def _python_config_generator(name, major, minor, bits, config_vars):
197 return PythonConfig(
198 name,
199 config_vars.shell + config_vars.builder + config_vars.builder_prefix_arguments + [
200 _python_pattern_function(major=major, minor=minor, bits=bits)] + [
201 name] + config_vars.venv_relative_python + config_vars.toolchain,
202 config_vars.shell + config_vars.runner + [
203 os.path.join(name, config_vars.venv_relative_python[0])])
204
205
206def _pypy_config_generator(name, major, config_vars):
207 return PythonConfig(
208 name,
209 config_vars.shell + config_vars.builder + config_vars.builder_prefix_arguments + [
210 _pypy_pattern_function(major=major)] + [
211 name] + config_vars.venv_relative_python + config_vars.toolchain,
212 config_vars.shell + config_vars.runner + [
213 os.path.join(name, config_vars.venv_relative_python[0])])
214
215
216def _python_pattern_function(major, minor, bits):
217 # Bit-ness is handled by the test machine's environment
218 if os.name == "nt":
219 if bits == "64":
220 return '/c/Python{major}{minor}/python.exe'.format(
221 major=major, minor=minor, bits=bits)
222 else:
223 return '/c/Python{major}{minor}_{bits}bits/python.exe'.format(
224 major=major, minor=minor, bits=bits)
225 else:
226 return 'python{major}.{minor}'.format(major=major, minor=minor)
227
228
229def _pypy_pattern_function(major):
230 if major == '2':
231 return 'pypy'
232 elif major == '3':
233 return 'pypy3'
234 else:
235 raise ValueError("Unknown PyPy major version")
236
237
Craig Tillerc7449162015-01-16 14:42:10 -0800238class CLanguage(object):
239
Craig Tillere9c959d2015-01-18 10:23:26 -0800240 def __init__(self, make_target, test_lang):
Craig Tillerc7449162015-01-16 14:42:10 -0800241 self.make_target = make_target
Craig Tillerd50993d2015-08-05 08:04:36 -0700242 self.platform = platform_string()
Craig Tiller711bbe62015-08-19 12:35:16 -0700243 self.test_lang = test_lang
Craig Tillerc7449162015-01-16 14:42:10 -0800244
Jan Tattermusch77db4322016-02-20 20:19:35 -0800245 def configure(self, config, args):
246 self.config = config
247 self.args = args
Jan Tattermusch6521c502017-06-26 15:16:48 +0200248 if self.platform == 'windows':
Jan Tattermusch52ff56d2017-08-23 15:32:06 +0200249 _check_compiler(self.args.compiler, ['default', 'cmake', 'cmake_vs2015',
250 'cmake_vs2017'])
Jan Tattermusch6521c502017-06-26 15:16:48 +0200251 _check_arch(self.args.arch, ['default', 'x64', 'x86'])
Jan Tattermusch52ff56d2017-08-23 15:32:06 +0200252 self._cmake_generator_option = 'Visual Studio 15 2017' if self.args.compiler == 'cmake_vs2017' else 'Visual Studio 14 2015'
Jan Tattermusch6521c502017-06-26 15:16:48 +0200253 self._cmake_arch_option = 'x64' if self.args.arch == 'x64' else 'Win32'
254 self._use_cmake = True
255 self._make_options = []
256 elif self.args.compiler == 'cmake':
Jan Tattermuschc98bde62017-01-25 19:12:11 +0100257 _check_arch(self.args.arch, ['default'])
258 self._use_cmake = True
259 self._docker_distro = 'jessie'
260 self._make_options = []
Jan Tattermusch77db4322016-02-20 20:19:35 -0800261 else:
Jan Tattermuschc98bde62017-01-25 19:12:11 +0100262 self._use_cmake = False
Jan Tattermuschd4726c12016-02-23 16:57:36 -0800263 self._docker_distro, self._make_options = self._compiler_options(self.args.use_docker,
264 self.args.compiler)
murgatroid99c36f6ea2016-10-03 09:24:09 -0700265 if args.iomgr_platform == "uv":
murgatroid99b8e07ad2017-07-18 13:20:55 -0700266 cflags = '-DGRPC_UV -DGRPC_UV_THREAD_CHECK'
murgatroid99c36f6ea2016-10-03 09:24:09 -0700267 try:
268 cflags += subprocess.check_output(['pkg-config', '--cflags', 'libuv']).strip() + ' '
murgatroid991687cab2016-10-11 11:42:01 -0700269 except (subprocess.CalledProcessError, OSError):
murgatroid99c36f6ea2016-10-03 09:24:09 -0700270 pass
271 try:
272 ldflags = subprocess.check_output(['pkg-config', '--libs', 'libuv']).strip() + ' '
murgatroid991687cab2016-10-11 11:42:01 -0700273 except (subprocess.CalledProcessError, OSError):
murgatroid99c36f6ea2016-10-03 09:24:09 -0700274 ldflags = '-luv '
275 self._make_options += ['EXTRA_CPPFLAGS={}'.format(cflags),
276 'EXTRA_LDLIBS={}'.format(ldflags)]
Jan Tattermusch77db4322016-02-20 20:19:35 -0800277
278 def test_specs(self):
Craig Tiller547db2b2015-01-30 14:08:39 -0800279 out = []
Jan Tattermusch77db4322016-02-20 20:19:35 -0800280 binaries = get_c_tests(self.args.travis, self.test_lang)
Craig Tiller946ce7a2016-04-06 10:35:58 -0700281 for target in binaries:
Jan Tattermuschc98bde62017-01-25 19:12:11 +0100282 if self._use_cmake and target.get('boringssl', False):
283 # cmake doesn't build boringssl tests
284 continue
Jan Tattermusch46b34ca2017-10-10 12:30:24 +0200285 auto_timeout_scaling = target.get('auto_timeout_scaling', True)
Craig Tiller123f1372016-06-15 15:06:14 -0700286 polling_strategies = (_POLLING_STRATEGIES.get(self.platform, ['all'])
Craig Tiller946ce7a2016-04-06 10:35:58 -0700287 if target.get('uses_polling', True)
Vijay Pai1ba53702017-10-11 10:10:23 -0700288 else ['none'])
murgatroid992c287ca2016-10-07 09:55:35 -0700289 if self.args.iomgr_platform == 'uv':
290 polling_strategies = ['all']
Craig Tiller946ce7a2016-04-06 10:35:58 -0700291 for polling_strategy in polling_strategies:
292 env={'GRPC_DEFAULT_SSL_ROOTS_FILE_PATH':
Craig Tillerb29f1fe2017-03-28 15:49:23 -0700293 _ROOT + '/src/core/tsi/test_creds/ca.pem',
Craig Tiller8f18ee62016-07-18 08:00:33 -0700294 'GRPC_POLL_STRATEGY': polling_strategy,
295 'GRPC_VERBOSITY': 'DEBUG'}
Yuchen Zengfdae4bd2016-11-07 17:46:16 -0800296 resolver = os.environ.get('GRPC_DNS_RESOLVER', None);
297 if resolver:
298 env['GRPC_DNS_RESOLVER'] = resolver
Craig Tiller38fb8de2016-07-13 08:23:32 -0700299 shortname_ext = '' if polling_strategy=='all' else ' GRPC_POLL_STRATEGY=%s' % polling_strategy
Craig Tillerbc28cd62016-12-02 13:52:21 -0800300 timeout_scaling = 1
Jan Tattermusch46b34ca2017-10-10 12:30:24 +0200301
302 if auto_timeout_scaling and polling_strategy == 'poll-cv':
Craig Tillerbc28cd62016-12-02 13:52:21 -0800303 timeout_scaling *= 5
Robbie Shadeca7effc2017-01-17 09:14:29 -0500304
Sree Kuchibhotla70d9ca42017-01-27 10:54:05 -0800305 if polling_strategy in target.get('excluded_poll_engines', []):
Sree Kuchibhotlab5517dd2017-01-27 14:18:18 -0800306 continue
Sree Kuchibhotla03370d32017-02-01 08:33:33 -0800307
Robbie Shadeca7effc2017-01-17 09:14:29 -0500308 # Scale overall test timeout if running under various sanitizers.
309 config = self.args.config
Jan Tattermusch46b34ca2017-10-10 12:30:24 +0200310 if auto_timeout_scaling and ('asan' in config
311 or config == 'msan'
312 or config == 'tsan'
313 or config == 'ubsan'
314 or config == 'helgrind'
315 or config == 'memcheck'):
Robbie Shadeca7effc2017-01-17 09:14:29 -0500316 timeout_scaling *= 20
317
Craig Tillerb38197e2016-02-26 10:14:54 -0800318 if self.config.build_config in target['exclude_configs']:
319 continue
murgatroid99c36f6ea2016-10-03 09:24:09 -0700320 if self.args.iomgr_platform in target.get('exclude_iomgrs', []):
321 continue
Craig Tillerb38197e2016-02-26 10:14:54 -0800322 if self.platform == 'windows':
Jan Tattermusch6521c502017-06-26 15:16:48 +0200323 binary = 'cmake/build/%s/%s.exe' % (_MSBUILD_CONFIG[self.config.build_config], target['name'])
Craig Tillerca62ff02016-02-24 22:22:57 -0800324 else:
Jan Tattermuschc98bde62017-01-25 19:12:11 +0100325 if self._use_cmake:
326 binary = 'cmake/build/%s' % target['name']
327 else:
328 binary = 'bins/%s/%s' % (self.config.build_config, target['name'])
Craig Tillerab34b122016-11-28 13:19:12 -0800329 cpu_cost = target['cpu_cost']
330 if cpu_cost == 'capacity':
331 cpu_cost = multiprocessing.cpu_count()
Craig Tillerb38197e2016-02-26 10:14:54 -0800332 if os.path.isfile(binary):
ncteisen7839d822017-09-12 09:46:22 -0700333 list_test_command = None
334 filter_test_command = None
ncteisend439b4e2017-09-11 17:57:18 -0700335
ncteisen7839d822017-09-12 09:46:22 -0700336 # these are the flag defined by gtest and benchmark framework to list
337 # and filter test runs. We use them to split each individual test
338 # into its own JobSpec, and thus into its own process.
ncteisen128bbc72017-09-20 14:14:29 -0400339 if 'benchmark' in target and target['benchmark']:
Craig Tiller77013002017-10-16 16:11:37 -0700340 with open(os.devnull, 'w') as fnull:
341 tests = subprocess.check_output([binary, '--benchmark_list_tests'],
342 stderr=fnull)
343 base = None
344 for line in tests.split('\n'):
345 test = line.strip()
346 cmdline = [binary, '--benchmark_filter=%s$' % test] + target['args']
347 out.append(self.config.job_spec(cmdline,
348 shortname='%s:%s %s' % (binary, test, shortname_ext),
349 cpu_cost=cpu_cost,
350 timeout_seconds=_DEFAULT_TIMEOUT_SECONDS * timeout_scaling,
351 environ=env))
ncteisen128bbc72017-09-20 14:14:29 -0400352 elif 'gtest' in target and target['gtest']:
Craig Tiller77013002017-10-16 16:11:37 -0700353 # here we parse the output of --gtest_list_tests to build up a complete
354 # list of the tests contained in a binary for each test, we then
ncteisend439b4e2017-09-11 17:57:18 -0700355 # add a job to run, filtering for just that test.
Craig Tillerb38197e2016-02-26 10:14:54 -0800356 with open(os.devnull, 'w') as fnull:
Craig Tiller77013002017-10-16 16:11:37 -0700357 tests = subprocess.check_output([binary, '--gtest_list_tests'],
Craig Tillerb38197e2016-02-26 10:14:54 -0800358 stderr=fnull)
359 base = None
360 for line in tests.split('\n'):
361 i = line.find('#')
362 if i >= 0: line = line[:i]
363 if not line: continue
364 if line[0] != ' ':
365 base = line.strip()
366 else:
367 assert base is not None
368 assert line[1] == ' '
369 test = base + line.strip()
Craig Tiller77013002017-10-16 16:11:37 -0700370 cmdline = [binary, '--gtest_filter=%s' % test] + target['args']
Craig Tiller38fb8de2016-07-13 08:23:32 -0700371 out.append(self.config.job_spec(cmdline,
David Garcia Quintas947e5302017-02-17 16:44:45 -0800372 shortname='%s %s' % (' '.join(cmdline), shortname_ext),
Craig Tillerab34b122016-11-28 13:19:12 -0800373 cpu_cost=cpu_cost,
Craig Tillerbc28cd62016-12-02 13:52:21 -0800374 timeout_seconds=_DEFAULT_TIMEOUT_SECONDS * timeout_scaling,
Craig Tillerb38197e2016-02-26 10:14:54 -0800375 environ=env))
376 else:
377 cmdline = [binary] + target['args']
Craig Tiller0f7dc4f2017-09-19 12:17:25 -0700378 shortname = target.get('shortname', ' '.join(
379 pipes.quote(arg)
380 for arg in cmdline))
381 shortname += shortname_ext
Craig Tiller38fb8de2016-07-13 08:23:32 -0700382 out.append(self.config.job_spec(cmdline,
Craig Tiller0f7dc4f2017-09-19 12:17:25 -0700383 shortname=shortname,
Craig Tillerab34b122016-11-28 13:19:12 -0800384 cpu_cost=cpu_cost,
Craig Tillerc2278152016-03-21 08:59:54 -0700385 flaky=target.get('flaky', False),
Craig Tillerbc28cd62016-12-02 13:52:21 -0800386 timeout_seconds=target.get('timeout_seconds', _DEFAULT_TIMEOUT_SECONDS) * timeout_scaling,
Craig Tillerb38197e2016-02-26 10:14:54 -0800387 environ=env))
388 elif self.args.regex == '.*' or self.platform == 'windows':
siddharthshukla0589e532016-07-07 16:08:01 +0200389 print('\nWARNING: binary not found, skipping', binary)
Nicolas Noblee1445362015-05-11 17:40:26 -0700390 return sorted(out)
Craig Tillerc7449162015-01-16 14:42:10 -0800391
Jan Tattermusch77db4322016-02-20 20:19:35 -0800392 def make_targets(self):
Jan Tattermusch77db4322016-02-20 20:19:35 -0800393 if self.platform == 'windows':
Craig Tiller7bb3efd2015-09-01 08:04:03 -0700394 # don't build tools on windows just yet
395 return ['buildtests_%s' % self.make_target]
David Garcia Quintas8ff30322017-05-11 16:13:37 -0700396 return ['buildtests_%s' % self.make_target, 'tools_%s' % self.make_target,
397 'check_epollexclusive']
Craig Tillerc7449162015-01-16 14:42:10 -0800398
Jan Tattermuschc895fe02016-01-20 09:13:09 -0800399 def make_options(self):
Jan Tattermuschec3338d2017-08-23 15:26:18 +0200400 return self._make_options
Jan Tattermuschc895fe02016-01-20 09:13:09 -0800401
murgatroid99256d3df2015-09-21 16:58:02 -0700402 def pre_build_steps(self):
Jan Tattermusch6521c502017-06-26 15:16:48 +0200403 if self.platform == 'windows':
Jan Tattermuschec3338d2017-08-23 15:26:18 +0200404 return [['tools\\run_tests\\helper_scripts\\pre_build_cmake.bat',
405 self._cmake_generator_option,
406 self._cmake_arch_option]]
Jan Tattermusch6521c502017-06-26 15:16:48 +0200407 elif self._use_cmake:
408 return [['tools/run_tests/helper_scripts/pre_build_cmake.sh']]
Jan Tattermusch874aec02015-10-07 19:26:19 -0700409 else:
Jan Tattermusch6521c502017-06-26 15:16:48 +0200410 return []
murgatroid99256d3df2015-09-21 16:58:02 -0700411
Craig Tillerc7449162015-01-16 14:42:10 -0800412 def build_steps(self):
413 return []
414
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +0200415 def post_tests_steps(self):
416 if self.platform == 'windows':
417 return []
418 else:
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100419 return [['tools/run_tests/helper_scripts/post_tests_c.sh']]
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +0200420
murgatroid99a3e244f2015-09-22 11:25:53 -0700421 def makefile_name(self):
Jan Tattermuschc98bde62017-01-25 19:12:11 +0100422 if self._use_cmake:
423 return 'cmake/build/Makefile'
424 else:
425 return 'Makefile'
murgatroid99a3e244f2015-09-22 11:25:53 -0700426
Jan Tattermusch6d258c52016-06-10 09:36:51 -0700427 def _clang_make_options(self, version_suffix=''):
428 return ['CC=clang%s' % version_suffix,
429 'CXX=clang++%s' % version_suffix,
430 'LD=clang%s' % version_suffix,
431 'LDXX=clang++%s' % version_suffix]
Jan Tattermuschd4726c12016-02-23 16:57:36 -0800432
Jan Tattermusch6d258c52016-06-10 09:36:51 -0700433 def _gcc_make_options(self, version_suffix):
434 return ['CC=gcc%s' % version_suffix,
435 'CXX=g++%s' % version_suffix,
436 'LD=gcc%s' % version_suffix,
437 'LDXX=g++%s' % version_suffix]
Jan Tattermusch9bb70622016-03-18 10:28:54 -0700438
Jan Tattermuschd4726c12016-02-23 16:57:36 -0800439 def _compiler_options(self, use_docker, compiler):
440 """Returns docker distro and make options to use for given compiler."""
Jan Tattermuschfd3857b2016-06-03 12:24:03 -0700441 if not use_docker and not _is_use_docker_child():
Jan Tattermuschc4cbe392016-02-22 19:29:38 -0800442 _check_compiler(compiler, ['default'])
443
444 if compiler == 'gcc4.9' or compiler == 'default':
Jan Tattermuschd4726c12016-02-23 16:57:36 -0800445 return ('jessie', [])
Matt Kwong029ed102016-11-01 18:04:47 -0700446 elif compiler == 'gcc4.8':
Matt Kwong1347e402016-11-02 18:07:40 -0700447 return ('jessie', self._gcc_make_options(version_suffix='-4.8'))
Jan Tattermuschc4cbe392016-02-22 19:29:38 -0800448 elif compiler == 'gcc5.3':
Jan Tattermuschd4726c12016-02-23 16:57:36 -0800449 return ('ubuntu1604', [])
Ken Payson975b5102017-03-30 17:38:40 -0700450 elif compiler == 'gcc_musl':
451 return ('alpine', [])
Jan Tattermuschd4726c12016-02-23 16:57:36 -0800452 elif compiler == 'clang3.4':
Jan Tattermusch6d258c52016-06-10 09:36:51 -0700453 # on ubuntu1404, clang-3.4 alias doesn't exist, just use 'clang'
Jan Tattermuschd4726c12016-02-23 16:57:36 -0800454 return ('ubuntu1404', self._clang_make_options())
Jan Tattermusch6d258c52016-06-10 09:36:51 -0700455 elif compiler == 'clang3.5':
456 return ('jessie', self._clang_make_options(version_suffix='-3.5'))
Jan Tattermuschd4726c12016-02-23 16:57:36 -0800457 elif compiler == 'clang3.6':
Jan Tattermusch6d258c52016-06-10 09:36:51 -0700458 return ('ubuntu1604', self._clang_make_options(version_suffix='-3.6'))
459 elif compiler == 'clang3.7':
460 return ('ubuntu1604', self._clang_make_options(version_suffix='-3.7'))
Jan Tattermuschc4cbe392016-02-22 19:29:38 -0800461 else:
462 raise Exception('Compiler %s not supported.' % compiler)
463
Jan Tattermusch77db4322016-02-20 20:19:35 -0800464 def dockerfile_dir(self):
Jan Tattermuschc4cbe392016-02-22 19:29:38 -0800465 return 'tools/dockerfile/test/cxx_%s_%s' % (self._docker_distro,
466 _docker_arch_suffix(self.args.arch))
Jan Tattermusch788ee232016-01-26 12:19:44 -0800467
murgatroid99132ce6a2015-03-04 17:29:14 -0800468 def __str__(self):
469 return self.make_target
470
Craig Tillercc0535d2015-12-08 15:14:47 -0800471
Matt Kwonge2e7cf42017-09-15 11:17:04 -0700472# This tests Node on grpc/grpc-node and will become the standard for Node testing
473class RemoteNodeLanguage(object):
474
475 def __init__(self):
476 self.platform = platform_string()
477
478 def configure(self, config, args):
479 self.config = config
480 self.args = args
481 # Note: electron ABI only depends on major and minor version, so that's all
482 # we should specify in the compiler argument
483 _check_compiler(self.args.compiler, ['default', 'node0.12',
484 'node4', 'node5', 'node6',
485 'node7', 'node8',
486 'electron1.3', 'electron1.6'])
487 if self.args.compiler == 'default':
488 self.runtime = 'node'
489 self.node_version = '8'
490 else:
491 if self.args.compiler.startswith('electron'):
492 self.runtime = 'electron'
493 self.node_version = self.args.compiler[8:]
494 else:
495 self.runtime = 'node'
496 # Take off the word "node"
497 self.node_version = self.args.compiler[4:]
498
499 # TODO: update with Windows/electron scripts when available for grpc/grpc-node
500 def test_specs(self):
501 if self.platform == 'windows':
502 return [self.config.job_spec(['tools\\run_tests\\helper_scripts\\run_node.bat'])]
503 else:
504 return [self.config.job_spec(['tools/run_tests/helper_scripts/run_grpc-node.sh'],
505 None,
506 environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
507
508 def pre_build_steps(self):
509 return []
510
511 def make_targets(self):
512 return []
513
514 def make_options(self):
515 return []
516
517 def build_steps(self):
518 return []
519
520 def post_tests_steps(self):
521 return []
522
523 def makefile_name(self):
524 return 'Makefile'
525
526 def dockerfile_dir(self):
527 return 'tools/dockerfile/test/node_jessie_%s' % _docker_arch_suffix(self.args.arch)
528
529 def __str__(self):
530 return 'grpc-node'
531
532
murgatroid992c8d5162015-01-26 10:41:21 -0800533class NodeLanguage(object):
534
Jan Tattermusche477b842016-02-06 22:19:01 -0800535 def __init__(self):
Michael Lumishaaa876a2016-02-10 15:27:58 -0800536 self.platform = platform_string()
Jan Tattermusche477b842016-02-06 22:19:01 -0800537
Jan Tattermusch77db4322016-02-20 20:19:35 -0800538 def configure(self, config, args):
539 self.config = config
540 self.args = args
murgatroid99eaf79642016-11-01 11:05:02 -0700541 # Note: electron ABI only depends on major and minor version, so that's all
542 # we should specify in the compiler argument
murgatroid999fab4382016-04-29 15:05:00 -0700543 _check_compiler(self.args.compiler, ['default', 'node0.12',
murgatroid99eaf79642016-11-01 11:05:02 -0700544 'node4', 'node5', 'node6',
murgatroid994bea5b92017-05-30 17:37:02 -0700545 'node7', 'node8',
546 'electron1.3', 'electron1.6'])
murgatroid999fab4382016-04-29 15:05:00 -0700547 if self.args.compiler == 'default':
murgatroid99c5181982017-01-12 12:40:11 -0800548 self.runtime = 'node'
murgatroid994bea5b92017-05-30 17:37:02 -0700549 self.node_version = '8'
murgatroid999fab4382016-04-29 15:05:00 -0700550 else:
murgatroid99eaf79642016-11-01 11:05:02 -0700551 if self.args.compiler.startswith('electron'):
552 self.runtime = 'electron'
553 self.node_version = self.args.compiler[8:]
554 else:
555 self.runtime = 'node'
556 # Take off the word "node"
557 self.node_version = self.args.compiler[4:]
Jan Tattermusch77db4322016-02-20 20:19:35 -0800558
559 def test_specs(self):
Michael Lumishaaa876a2016-02-10 15:27:58 -0800560 if self.platform == 'windows':
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100561 return [self.config.job_spec(['tools\\run_tests\\helper_scripts\\run_node.bat'])]
Michael Lumishaaa876a2016-02-10 15:27:58 -0800562 else:
murgatroid99eaf79642016-11-01 11:05:02 -0700563 run_script = 'run_node'
564 if self.runtime == 'electron':
565 run_script += '_electron'
murgatroid99c34cac22017-01-04 15:43:02 -0800566 return [self.config.job_spec(['tools/run_tests/helper_scripts/{}.sh'.format(run_script),
murgatroid99eaf79642016-11-01 11:05:02 -0700567 self.node_version],
Jan Tattermusch77db4322016-02-20 20:19:35 -0800568 None,
569 environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
murgatroid992c8d5162015-01-26 10:41:21 -0800570
murgatroid99256d3df2015-09-21 16:58:02 -0700571 def pre_build_steps(self):
Michael Lumishaaa876a2016-02-10 15:27:58 -0800572 if self.platform == 'windows':
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100573 return [['tools\\run_tests\\helper_scripts\\pre_build_node.bat']]
Michael Lumishaaa876a2016-02-10 15:27:58 -0800574 else:
murgatroid99eaf79642016-11-01 11:05:02 -0700575 build_script = 'pre_build_node'
576 if self.runtime == 'electron':
577 build_script += '_electron'
murgatroid991191b722017-02-08 11:56:52 -0800578 return [['tools/run_tests/helper_scripts/{}.sh'.format(build_script),
579 self.node_version]]
murgatroid99256d3df2015-09-21 16:58:02 -0700580
Jan Tattermusch77db4322016-02-20 20:19:35 -0800581 def make_targets(self):
murgatroid99db5b1602015-10-01 13:20:11 -0700582 return []
murgatroid992c8d5162015-01-26 10:41:21 -0800583
Jan Tattermuschc895fe02016-01-20 09:13:09 -0800584 def make_options(self):
585 return []
586
murgatroid992c8d5162015-01-26 10:41:21 -0800587 def build_steps(self):
Michael Lumishaaa876a2016-02-10 15:27:58 -0800588 if self.platform == 'windows':
murgatroid9988113f72017-02-21 10:04:29 -0800589 if self.config == 'dbg':
murgatroid991191b722017-02-08 11:56:52 -0800590 config_flag = '--debug'
591 else:
592 config_flag = '--release'
593 return [['tools\\run_tests\\helper_scripts\\build_node.bat',
murgatroid991191b722017-02-08 11:56:52 -0800594 config_flag]]
Michael Lumishaaa876a2016-02-10 15:27:58 -0800595 else:
murgatroid99eaf79642016-11-01 11:05:02 -0700596 build_script = 'build_node'
597 if self.runtime == 'electron':
598 build_script += '_electron'
599 # building for electron requires a patch version
600 self.node_version += '.0'
murgatroid991191b722017-02-08 11:56:52 -0800601 return [['tools/run_tests/helper_scripts/{}.sh'.format(build_script),
murgatroid99f94f64f2017-04-24 13:35:21 -0700602 self.node_version]]
Craig Tillerc7449162015-01-16 14:42:10 -0800603
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +0200604 def post_tests_steps(self):
605 return []
606
murgatroid99a3e244f2015-09-22 11:25:53 -0700607 def makefile_name(self):
608 return 'Makefile'
609
Jan Tattermusch77db4322016-02-20 20:19:35 -0800610 def dockerfile_dir(self):
611 return 'tools/dockerfile/test/node_jessie_%s' % _docker_arch_suffix(self.args.arch)
Jan Tattermusch788ee232016-01-26 12:19:44 -0800612
murgatroid99132ce6a2015-03-04 17:29:14 -0800613 def __str__(self):
614 return 'node'
615
Craig Tiller99775822015-01-30 13:07:16 -0800616
Craig Tillerc7449162015-01-16 14:42:10 -0800617class PhpLanguage(object):
618
Jan Tattermusch77db4322016-02-20 20:19:35 -0800619 def configure(self, config, args):
620 self.config = config
621 self.args = args
622 _check_compiler(self.args.compiler, ['default'])
ZhouyihaiDinge4260e52017-09-11 16:11:02 -0700623 self._make_options = ['EMBED_OPENSSL=true', 'EMBED_ZLIB=true']
Jan Tattermusch77db4322016-02-20 20:19:35 -0800624
625 def test_specs(self):
Jan Tattermuschfffb2672016-12-19 15:24:45 +0100626 return [self.config.job_spec(['src/php/bin/run_tests.sh'],
Jan Tattermusch77db4322016-02-20 20:19:35 -0800627 environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
Craig Tillerc7449162015-01-16 14:42:10 -0800628
murgatroid99256d3df2015-09-21 16:58:02 -0700629 def pre_build_steps(self):
630 return []
631
Jan Tattermusch77db4322016-02-20 20:19:35 -0800632 def make_targets(self):
Craig Tilleraf7cf542015-05-22 10:07:34 -0700633 return ['static_c', 'shared_c']
Craig Tillerc7449162015-01-16 14:42:10 -0800634
Jan Tattermuschc895fe02016-01-20 09:13:09 -0800635 def make_options(self):
ZhouyihaiDinge4260e52017-09-11 16:11:02 -0700636 return self._make_options;
Jan Tattermuschc895fe02016-01-20 09:13:09 -0800637
Craig Tillerc7449162015-01-16 14:42:10 -0800638 def build_steps(self):
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100639 return [['tools/run_tests/helper_scripts/build_php.sh']]
Craig Tillerc7449162015-01-16 14:42:10 -0800640
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +0200641 def post_tests_steps(self):
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100642 return [['tools/run_tests/helper_scripts/post_tests_php.sh']]
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +0200643
murgatroid99a3e244f2015-09-22 11:25:53 -0700644 def makefile_name(self):
645 return 'Makefile'
646
Jan Tattermusch77db4322016-02-20 20:19:35 -0800647 def dockerfile_dir(self):
648 return 'tools/dockerfile/test/php_jessie_%s' % _docker_arch_suffix(self.args.arch)
Jan Tattermusch788ee232016-01-26 12:19:44 -0800649
murgatroid99132ce6a2015-03-04 17:29:14 -0800650 def __str__(self):
651 return 'php'
652
Craig Tillerc7449162015-01-16 14:42:10 -0800653
Stanley Cheung2e2cdff2016-07-23 19:07:36 -0700654class Php7Language(object):
655
656 def configure(self, config, args):
657 self.config = config
658 self.args = args
659 _check_compiler(self.args.compiler, ['default'])
ZhouyihaiDinge4260e52017-09-11 16:11:02 -0700660 self._make_options = ['EMBED_OPENSSL=true', 'EMBED_ZLIB=true']
Stanley Cheung2e2cdff2016-07-23 19:07:36 -0700661
662 def test_specs(self):
Jan Tattermuschfffb2672016-12-19 15:24:45 +0100663 return [self.config.job_spec(['src/php/bin/run_tests.sh'],
Stanley Cheung2e2cdff2016-07-23 19:07:36 -0700664 environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
665
666 def pre_build_steps(self):
667 return []
668
669 def make_targets(self):
670 return ['static_c', 'shared_c']
671
672 def make_options(self):
ZhouyihaiDinge4260e52017-09-11 16:11:02 -0700673 return self._make_options;
Stanley Cheung2e2cdff2016-07-23 19:07:36 -0700674
675 def build_steps(self):
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100676 return [['tools/run_tests/helper_scripts/build_php.sh']]
Stanley Cheung2e2cdff2016-07-23 19:07:36 -0700677
678 def post_tests_steps(self):
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100679 return [['tools/run_tests/helper_scripts/post_tests_php.sh']]
Stanley Cheung2e2cdff2016-07-23 19:07:36 -0700680
681 def makefile_name(self):
682 return 'Makefile'
683
684 def dockerfile_dir(self):
685 return 'tools/dockerfile/test/php7_jessie_%s' % _docker_arch_suffix(self.args.arch)
686
687 def __str__(self):
688 return 'php7'
689
690
Masood Malekghassemi3b5b2062016-06-02 20:27:20 -0700691class PythonConfig(collections.namedtuple('PythonConfig', [
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700692 'name', 'build', 'run'])):
693 """Tuple of commands (named s.t. 'what it says on the tin' applies)"""
Masood Malekghassemi3b5b2062016-06-02 20:27:20 -0700694
Nathaniel Manista840615e2015-01-22 20:31:47 +0000695class PythonLanguage(object):
696
Jan Tattermusch77db4322016-02-20 20:19:35 -0800697 def configure(self, config, args):
698 self.config = config
699 self.args = args
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700700 self.pythons = self._get_pythons(self.args)
Jan Tattermusch77db4322016-02-20 20:19:35 -0800701
702 def test_specs(self):
Jan Tattermusch072ebaa2016-03-01 18:33:12 -0800703 # load list of known test suites
Masood Malekghassemi1ff429d2016-06-02 16:39:20 -0700704 with open('src/python/grpcio_tests/tests/tests.json') as tests_json_file:
Jan Tattermusch072ebaa2016-03-01 18:33:12 -0800705 tests_json = json.load(tests_json_file)
Masood Malekghassemi2b841622015-07-28 17:39:02 -0700706 environment = dict(_FORCE_ENVIRON_FOR_WRAPPERS)
Masood Malekghassemi1c062bd2016-06-13 18:41:36 -0700707 return [self.config.job_spec(
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700708 config.run,
Masood Malekghassemie6a23e22016-06-28 13:58:42 -0700709 timeout_seconds=5*60,
siddharthshukla0589e532016-07-07 16:08:01 +0200710 environ=dict(list(environment.items()) +
Masood Malekghassemic4f5a2e2016-12-05 15:54:56 -0800711 [('GRPC_PYTHON_TESTRUNNER_FILTER', str(suite_name))]),
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700712 shortname='%s.test.%s' % (config.name, suite_name),)
Masood Malekghassemi1c062bd2016-06-13 18:41:36 -0700713 for suite_name in tests_json
714 for config in self.pythons]
Nathaniel Manista840615e2015-01-22 20:31:47 +0000715
murgatroid99256d3df2015-09-21 16:58:02 -0700716 def pre_build_steps(self):
717 return []
718
Jan Tattermusch77db4322016-02-20 20:19:35 -0800719 def make_targets(self):
Masood Malekghassemi3b5b2062016-06-02 20:27:20 -0700720 return []
Nathaniel Manista840615e2015-01-22 20:31:47 +0000721
Jan Tattermuschc895fe02016-01-20 09:13:09 -0800722 def make_options(self):
723 return []
724
Nathaniel Manista840615e2015-01-22 20:31:47 +0000725 def build_steps(self):
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700726 return [config.build for config in self.pythons]
Nathaniel Manista840615e2015-01-22 20:31:47 +0000727
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +0200728 def post_tests_steps(self):
Matt Kwongc1113412017-09-22 11:25:34 -0700729 if self.config.build_config != 'gcov':
Matt Kwong0ff19572017-03-30 18:22:21 -0700730 return []
731 else:
732 return [['tools/run_tests/helper_scripts/post_tests_python.sh']]
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +0200733
murgatroid99a3e244f2015-09-22 11:25:53 -0700734 def makefile_name(self):
735 return 'Makefile'
736
Jan Tattermusch77db4322016-02-20 20:19:35 -0800737 def dockerfile_dir(self):
siddharthshuklac4782142016-06-28 18:48:47 +0200738 return 'tools/dockerfile/test/python_%s_%s' % (self.python_manager_name(), _docker_arch_suffix(self.args.arch))
739
740 def python_manager_name(self):
Ken Payson975b5102017-03-30 17:38:40 -0700741 if self.args.compiler in ['python3.5', 'python3.6']:
742 return 'pyenv'
743 elif self.args.compiler == 'python_alpine':
744 return 'alpine'
745 else:
746 return 'jessie'
Jan Tattermusch788ee232016-01-26 12:19:44 -0800747
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700748 def _get_pythons(self, args):
749 if args.arch == 'x86':
750 bits = '32'
Masood Malekghassemi3b5b2062016-06-02 20:27:20 -0700751 else:
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700752 bits = '64'
siddharthshukla2135a1b2016-08-04 02:11:53 +0200753
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700754 if os.name == 'nt':
755 shell = ['bash']
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100756 builder = [os.path.abspath('tools/run_tests/helper_scripts/build_python_msys2.sh')]
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700757 builder_prefix_arguments = ['MINGW{}'.format(bits)]
758 venv_relative_python = ['Scripts/python.exe']
759 toolchain = ['mingw32']
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700760 else:
761 shell = []
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100762 builder = [os.path.abspath('tools/run_tests/helper_scripts/build_python.sh')]
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700763 builder_prefix_arguments = []
764 venv_relative_python = ['bin/python']
765 toolchain = ['unix']
siddharthshukla2135a1b2016-08-04 02:11:53 +0200766
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100767 runner = [os.path.abspath('tools/run_tests/helper_scripts/run_python.sh')]
siddharthshukla2135a1b2016-08-04 02:11:53 +0200768 config_vars = _PythonConfigVars(shell, builder, builder_prefix_arguments,
769 venv_relative_python, toolchain, runner)
770 python27_config = _python_config_generator(name='py27', major='2',
771 minor='7', bits=bits,
772 config_vars=config_vars)
773 python34_config = _python_config_generator(name='py34', major='3',
774 minor='4', bits=bits,
775 config_vars=config_vars)
776 python35_config = _python_config_generator(name='py35', major='3',
777 minor='5', bits=bits,
778 config_vars=config_vars)
779 python36_config = _python_config_generator(name='py36', major='3',
780 minor='6', bits=bits,
781 config_vars=config_vars)
782 pypy27_config = _pypy_config_generator(name='pypy', major='2',
783 config_vars=config_vars)
784 pypy32_config = _pypy_config_generator(name='pypy3', major='3',
785 config_vars=config_vars)
786
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700787 if args.compiler == 'default':
788 if os.name == 'nt':
Ken Payson631862f2017-06-01 14:27:52 -0700789 return (python35_config,)
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700790 else:
791 return (python27_config, python34_config,)
792 elif args.compiler == 'python2.7':
Masood Malekghassemi3b5b2062016-06-02 20:27:20 -0700793 return (python27_config,)
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700794 elif args.compiler == 'python3.4':
Masood Malekghassemi3b5b2062016-06-02 20:27:20 -0700795 return (python34_config,)
siddharthshuklac4782142016-06-28 18:48:47 +0200796 elif args.compiler == 'python3.5':
797 return (python35_config,)
798 elif args.compiler == 'python3.6':
799 return (python36_config,)
siddharthshukla2135a1b2016-08-04 02:11:53 +0200800 elif args.compiler == 'pypy':
801 return (pypy27_config,)
802 elif args.compiler == 'pypy3':
803 return (pypy32_config,)
Ken Payson975b5102017-03-30 17:38:40 -0700804 elif args.compiler == 'python_alpine':
805 return (python27_config,)
Nathaniel Manistaa0109e52017-09-16 23:49:52 +0000806 elif args.compiler == 'all_the_cpythons':
807 return (python27_config, python34_config, python35_config,
808 python36_config,)
Jan Tattermusch825471c2016-04-25 16:52:25 -0700809 else:
Masood Malekghassemicab9d4f2016-06-28 09:09:31 -0700810 raise Exception('Compiler %s not supported.' % args.compiler)
Jan Tattermusch825471c2016-04-25 16:52:25 -0700811
murgatroid99132ce6a2015-03-04 17:29:14 -0800812 def __str__(self):
813 return 'python'
814
Craig Tillerd625d812015-04-08 15:52:35 -0700815
murgatroid996a4c4fa2015-02-27 12:08:57 -0800816class RubyLanguage(object):
817
Jan Tattermusch77db4322016-02-20 20:19:35 -0800818 def configure(self, config, args):
819 self.config = config
820 self.args = args
821 _check_compiler(self.args.compiler, ['default'])
822
823 def test_specs(self):
Alexander Polcync44c16e2017-03-14 17:44:21 -0700824 tests = [self.config.job_spec(['tools/run_tests/helper_scripts/run_ruby.sh'],
825 timeout_seconds=10*60,
826 environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
Alexander Polcync44c16e2017-03-14 17:44:21 -0700827 tests.append(self.config.job_spec(['tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh'],
828 timeout_seconds=10*60,
829 environ=_FORCE_ENVIRON_FOR_WRAPPERS))
830 return tests
murgatroid996a4c4fa2015-02-27 12:08:57 -0800831
murgatroid99256d3df2015-09-21 16:58:02 -0700832 def pre_build_steps(self):
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100833 return [['tools/run_tests/helper_scripts/pre_build_ruby.sh']]
murgatroid99256d3df2015-09-21 16:58:02 -0700834
Jan Tattermusch4651bef2016-02-23 08:31:25 -0800835 def make_targets(self):
murgatroid997d243df2016-02-18 09:58:05 -0800836 return []
murgatroid996a4c4fa2015-02-27 12:08:57 -0800837
Jan Tattermuschc895fe02016-01-20 09:13:09 -0800838 def make_options(self):
839 return []
840
murgatroid996a4c4fa2015-02-27 12:08:57 -0800841 def build_steps(self):
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100842 return [['tools/run_tests/helper_scripts/build_ruby.sh']]
murgatroid996a4c4fa2015-02-27 12:08:57 -0800843
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +0200844 def post_tests_steps(self):
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100845 return [['tools/run_tests/helper_scripts/post_tests_ruby.sh']]
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +0200846
murgatroid99a3e244f2015-09-22 11:25:53 -0700847 def makefile_name(self):
848 return 'Makefile'
849
Jan Tattermusch77db4322016-02-20 20:19:35 -0800850 def dockerfile_dir(self):
851 return 'tools/dockerfile/test/ruby_jessie_%s' % _docker_arch_suffix(self.args.arch)
Jan Tattermusch788ee232016-01-26 12:19:44 -0800852
murgatroid99132ce6a2015-03-04 17:29:14 -0800853 def __str__(self):
854 return 'ruby'
855
Craig Tillerd625d812015-04-08 15:52:35 -0700856
Jan Tattermusch1970a5b2015-03-03 15:17:25 -0800857class CSharpLanguage(object):
Jan Tattermusch77db4322016-02-20 20:19:35 -0800858
Jan Tattermuschb00aa672015-06-01 15:48:03 -0700859 def __init__(self):
Craig Tillerd50993d2015-08-05 08:04:36 -0700860 self.platform = platform_string()
Jan Tattermuschb00aa672015-06-01 15:48:03 -0700861
Jan Tattermusch77db4322016-02-20 20:19:35 -0800862 def configure(self, config, args):
863 self.config = config
864 self.args = args
Jan Tattermusch6d28d352016-03-25 15:07:22 -0700865 if self.platform == 'windows':
Jan Tattermusche7f0b852017-02-08 19:06:10 -0800866 _check_compiler(self.args.compiler, ['coreclr', 'default'])
Jan Tattermuschb2531e22016-03-25 16:14:41 -0700867 _check_arch(self.args.arch, ['default'])
Jan Tattermusch3c344d22017-04-04 16:49:06 +0200868 self._cmake_arch_option = 'x64'
Jan Tattermusche7f0b852017-02-08 19:06:10 -0800869 self._make_options = []
Jan Tattermusch6d28d352016-03-25 15:07:22 -0700870 else:
Jan Tattermuschbc98af12016-06-17 18:38:27 -0700871 _check_compiler(self.args.compiler, ['default', 'coreclr'])
Jan Tattermusch3c344d22017-04-04 16:49:06 +0200872 self._docker_distro = 'jessie'
Jan Tattermusch76511a52016-06-17 14:00:57 -0700873
Jan Tattermusch6d28d352016-03-25 15:07:22 -0700874 if self.platform == 'mac':
Jan Tattermusch2a322c22016-03-30 13:55:07 -0700875 # TODO(jtattermusch): EMBED_ZLIB=true currently breaks the mac build
Jan Tattermusch6d082202016-06-21 10:03:38 -0700876 self._make_options = ['EMBED_OPENSSL=true']
877 if self.args.compiler != 'coreclr':
878 # On Mac, official distribution of mono is 32bit.
Craig Tiller90ce7232017-04-12 06:53:09 -0700879 self._make_options += ['ARCH_FLAGS=-m32', 'LDFLAGS=-m32']
Jan Tattermusch6d28d352016-03-25 15:07:22 -0700880 else:
881 self._make_options = ['EMBED_OPENSSL=true', 'EMBED_ZLIB=true']
Jan Tattermusch77db4322016-02-20 20:19:35 -0800882
883 def test_specs(self):
Jan Tattermusch03c01062015-12-11 14:28:56 -0800884 with open('src/csharp/tests.json') as f:
Jan Tattermusch38ed2cf2016-04-09 16:24:16 -0700885 tests_by_assembly = json.load(f)
Jan Tattermusch03c01062015-12-11 14:28:56 -0800886
Jan Tattermuscha2d964c2016-02-22 17:33:09 -0800887 msbuild_config = _MSBUILD_CONFIG[self.config.build_config]
Jan Tattermusch78cb9312017-04-11 11:04:42 +0200888 nunit_args = ['--labels=All', '--noresult', '--workers=1']
Jan Tattermusch76511a52016-06-17 14:00:57 -0700889 assembly_subdir = 'bin/%s' % msbuild_config
890 assembly_extension = '.exe'
891
892 if self.args.compiler == 'coreclr':
Jan Tattermusch1f7ce192016-09-08 16:21:16 +0200893 assembly_subdir += '/netcoreapp1.0'
894 runtime_cmd = ['dotnet', 'exec']
895 assembly_extension = '.dll'
Jan Tattermuschb00aa672015-06-01 15:48:03 -0700896 else:
Jan Tattermusch3c344d22017-04-04 16:49:06 +0200897 assembly_subdir += '/net45'
Jan Tattermuschbc98af12016-06-17 18:38:27 -0700898 if self.platform == 'windows':
899 runtime_cmd = []
900 else:
901 runtime_cmd = ['mono']
Jan Tattermuschbf3b1532015-10-26 10:24:42 -0700902
Jan Tattermusch38ed2cf2016-04-09 16:24:16 -0700903 specs = []
Siddharth Shuklad194f592017-03-11 19:12:43 +0100904 for assembly in six.iterkeys(tests_by_assembly):
Jan Tattermusch76511a52016-06-17 14:00:57 -0700905 assembly_file = 'src/csharp/%s/%s/%s%s' % (assembly,
906 assembly_subdir,
907 assembly,
908 assembly_extension)
Jan Tattermuscha5f1f122016-04-11 15:49:56 -0700909 if self.config.build_config != 'gcov' or self.platform != 'windows':
Jan Tattermusch38ed2cf2016-04-09 16:24:16 -0700910 # normally, run each test as a separate process
911 for test in tests_by_assembly[assembly]:
912 cmdline = runtime_cmd + [assembly_file, '--test=%s' % test] + nunit_args
913 specs.append(self.config.job_spec(cmdline,
Jan Tattermusch38ed2cf2016-04-09 16:24:16 -0700914 shortname='csharp.%s' % test,
915 environ=_FORCE_ENVIRON_FOR_WRAPPERS))
916 else:
Jan Tattermuscha5f1f122016-04-11 15:49:56 -0700917 # For C# test coverage, run all tests from the same assembly at once
918 # using OpenCover.Console (only works on Windows).
919 cmdline = ['src\\csharp\\packages\\OpenCover.4.6.519\\tools\\OpenCover.Console.exe',
920 '-target:%s' % assembly_file,
921 '-targetdir:src\\csharp',
922 '-targetargs:%s' % ' '.join(nunit_args),
923 '-filter:+[Grpc.Core]*',
924 '-register:user',
925 '-output:src\\csharp\\coverage_csharp_%s.xml' % assembly]
Jan Tattermusch38ed2cf2016-04-09 16:24:16 -0700926
Jan Tattermuscha5f1f122016-04-11 15:49:56 -0700927 # set really high cpu_cost to make sure instances of OpenCover.Console run exclusively
928 # to prevent problems with registering the profiler.
929 run_exclusive = 1000000
Jan Tattermusch35e608f2016-04-09 16:35:06 -0700930 specs.append(self.config.job_spec(cmdline,
Jan Tattermusch38ed2cf2016-04-09 16:24:16 -0700931 shortname='csharp.coverage.%s' % assembly,
Jan Tattermuscha5f1f122016-04-11 15:49:56 -0700932 cpu_cost=run_exclusive,
Jan Tattermusch77db4322016-02-20 20:19:35 -0800933 environ=_FORCE_ENVIRON_FOR_WRAPPERS))
Jan Tattermusch38ed2cf2016-04-09 16:24:16 -0700934 return specs
Jan Tattermusch1970a5b2015-03-03 15:17:25 -0800935
murgatroid99256d3df2015-09-21 16:58:02 -0700936 def pre_build_steps(self):
Jan Tattermusch48423fc2015-10-07 18:59:16 -0700937 if self.platform == 'windows':
Jan Tattermusche7f0b852017-02-08 19:06:10 -0800938 return [['tools\\run_tests\\helper_scripts\\pre_build_csharp.bat', self._cmake_arch_option]]
Jan Tattermusch48423fc2015-10-07 18:59:16 -0700939 else:
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100940 return [['tools/run_tests/helper_scripts/pre_build_csharp.sh']]
murgatroid99256d3df2015-09-21 16:58:02 -0700941
Jan Tattermusch77db4322016-02-20 20:19:35 -0800942 def make_targets(self):
Jan Tattermusch6d28d352016-03-25 15:07:22 -0700943 return ['grpc_csharp_ext']
Jan Tattermusch1970a5b2015-03-03 15:17:25 -0800944
Jan Tattermuschc895fe02016-01-20 09:13:09 -0800945 def make_options(self):
Jan Tattermusch6d28d352016-03-25 15:07:22 -0700946 return self._make_options;
Jan Tattermuschc895fe02016-01-20 09:13:09 -0800947
Jan Tattermusch1970a5b2015-03-03 15:17:25 -0800948 def build_steps(self):
Jan Tattermusch3c344d22017-04-04 16:49:06 +0200949 if self.platform == 'windows':
950 return [['tools\\run_tests\\helper_scripts\\build_csharp.bat']]
Jan Tattermuschb00aa672015-06-01 15:48:03 -0700951 else:
Jan Tattermusch3c344d22017-04-04 16:49:06 +0200952 return [['tools/run_tests/helper_scripts/build_csharp.sh']]
Nathaniel Manista840615e2015-01-22 20:31:47 +0000953
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +0200954 def post_tests_steps(self):
Jan Tattermusch38ed2cf2016-04-09 16:24:16 -0700955 if self.platform == 'windows':
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100956 return [['tools\\run_tests\\helper_scripts\\post_tests_csharp.bat']]
Jan Tattermusch38ed2cf2016-04-09 16:24:16 -0700957 else:
Jan Tattermusch5c79a312016-12-20 11:02:50 +0100958 return [['tools/run_tests/helper_scripts/post_tests_csharp.sh']]
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +0200959
murgatroid99a3e244f2015-09-22 11:25:53 -0700960 def makefile_name(self):
Jan Tattermusche7f0b852017-02-08 19:06:10 -0800961 if self.platform == 'windows':
962 return 'cmake/build/%s/Makefile' % self._cmake_arch_option
963 else:
964 return 'Makefile'
murgatroid99a3e244f2015-09-22 11:25:53 -0700965
Jan Tattermusch77db4322016-02-20 20:19:35 -0800966 def dockerfile_dir(self):
Jan Tattermusch76511a52016-06-17 14:00:57 -0700967 return 'tools/dockerfile/test/csharp_%s_%s' % (self._docker_distro,
968 _docker_arch_suffix(self.args.arch))
Jan Tattermusch788ee232016-01-26 12:19:44 -0800969
murgatroid99132ce6a2015-03-04 17:29:14 -0800970 def __str__(self):
971 return 'csharp'
972
Craig Tillerd625d812015-04-08 15:52:35 -0700973
Jorge Canizalesa0b3bfa2015-07-30 19:25:52 -0700974class ObjCLanguage(object):
975
Jan Tattermusch77db4322016-02-20 20:19:35 -0800976 def configure(self, config, args):
977 self.config = config
978 self.args = args
979 _check_compiler(self.args.compiler, ['default'])
980
981 def test_specs(self):
Jorge Canizales8a9fe2a2016-07-29 15:44:47 -0700982 return [
983 self.config.job_spec(['src/objective-c/tests/run_tests.sh'],
Jan Tattermuschfffb2672016-12-19 15:24:45 +0100984 timeout_seconds=60*60,
Jorge Canizales8a9fe2a2016-07-29 15:44:47 -0700985 shortname='objc-tests',
Jan Tattermusch0557f6c2017-08-09 19:31:52 +0200986 cpu_cost=1e6,
Jorge Canizales8a9fe2a2016-07-29 15:44:47 -0700987 environ=_FORCE_ENVIRON_FOR_WRAPPERS),
Jan Tattermusch9359e502017-08-02 10:10:52 +0200988 self.config.job_spec(['src/objective-c/tests/run_plugin_tests.sh'],
989 timeout_seconds=60*60,
990 shortname='objc-plugin-tests',
Jan Tattermusch0557f6c2017-08-09 19:31:52 +0200991 cpu_cost=1e6,
Jorge Canizales8a9fe2a2016-07-29 15:44:47 -0700992 environ=_FORCE_ENVIRON_FOR_WRAPPERS),
Jan Tattermusch9359e502017-08-02 10:10:52 +0200993 self.config.job_spec(['src/objective-c/tests/build_one_example.sh'],
994 timeout_seconds=10*60,
995 shortname='objc-build-example-helloworld',
Jan Tattermusch0557f6c2017-08-09 19:31:52 +0200996 cpu_cost=1e6,
Jan Tattermusch9359e502017-08-02 10:10:52 +0200997 environ={'SCHEME': 'HelloWorld',
998 'EXAMPLE_PATH': 'examples/objective-c/helloworld'}),
999 self.config.job_spec(['src/objective-c/tests/build_one_example.sh'],
1000 timeout_seconds=10*60,
1001 shortname='objc-build-example-routeguide',
Jan Tattermusch0557f6c2017-08-09 19:31:52 +02001002 cpu_cost=1e6,
Jan Tattermusch9359e502017-08-02 10:10:52 +02001003 environ={'SCHEME': 'RouteGuideClient',
1004 'EXAMPLE_PATH': 'examples/objective-c/route_guide'}),
1005 self.config.job_spec(['src/objective-c/tests/build_one_example.sh'],
1006 timeout_seconds=10*60,
1007 shortname='objc-build-example-authsample',
Jan Tattermusch0557f6c2017-08-09 19:31:52 +02001008 cpu_cost=1e6,
Jan Tattermusch9359e502017-08-02 10:10:52 +02001009 environ={'SCHEME': 'AuthSample',
1010 'EXAMPLE_PATH': 'examples/objective-c/auth_sample'}),
1011 self.config.job_spec(['src/objective-c/tests/build_one_example.sh'],
1012 timeout_seconds=10*60,
1013 shortname='objc-build-example-sample',
Jan Tattermusch0557f6c2017-08-09 19:31:52 +02001014 cpu_cost=1e6,
Jan Tattermusch9359e502017-08-02 10:10:52 +02001015 environ={'SCHEME': 'Sample',
1016 'EXAMPLE_PATH': 'src/objective-c/examples/Sample'}),
1017 self.config.job_spec(['src/objective-c/tests/build_one_example.sh'],
1018 timeout_seconds=10*60,
1019 shortname='objc-build-example-sample-frameworks',
Jan Tattermusch0557f6c2017-08-09 19:31:52 +02001020 cpu_cost=1e6,
Jan Tattermusch9359e502017-08-02 10:10:52 +02001021 environ={'SCHEME': 'Sample',
1022 'EXAMPLE_PATH': 'src/objective-c/examples/Sample',
1023 'FRAMEWORKS': 'YES'}),
1024 self.config.job_spec(['src/objective-c/tests/build_one_example.sh'],
1025 timeout_seconds=10*60,
1026 shortname='objc-build-example-switftsample',
Jan Tattermusch0557f6c2017-08-09 19:31:52 +02001027 cpu_cost=1e6,
Jan Tattermusch9359e502017-08-02 10:10:52 +02001028 environ={'SCHEME': 'SwiftSample',
1029 'EXAMPLE_PATH': 'src/objective-c/examples/SwiftSample'}),
Jorge Canizales8a9fe2a2016-07-29 15:44:47 -07001030 ]
Jorge Canizalesa0b3bfa2015-07-30 19:25:52 -07001031
murgatroid99256d3df2015-09-21 16:58:02 -07001032 def pre_build_steps(self):
1033 return []
1034
Jan Tattermusch77db4322016-02-20 20:19:35 -08001035 def make_targets(self):
Jorge Canizales6eade6d2016-07-11 00:34:14 -07001036 return ['interop_server']
Jorge Canizalesa0b3bfa2015-07-30 19:25:52 -07001037
Jan Tattermuschc895fe02016-01-20 09:13:09 -08001038 def make_options(self):
1039 return []
1040
Jorge Canizalesa0b3bfa2015-07-30 19:25:52 -07001041 def build_steps(self):
Jorge Canizalesd0b32e92015-07-30 23:08:43 -07001042 return [['src/objective-c/tests/build_tests.sh']]
Jorge Canizalesa0b3bfa2015-07-30 19:25:52 -07001043
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +02001044 def post_tests_steps(self):
1045 return []
1046
murgatroid99a3e244f2015-09-22 11:25:53 -07001047 def makefile_name(self):
1048 return 'Makefile'
1049
Jan Tattermusch77db4322016-02-20 20:19:35 -08001050 def dockerfile_dir(self):
Jan Tattermusch788ee232016-01-26 12:19:44 -08001051 return None
1052
Jorge Canizalesa0b3bfa2015-07-30 19:25:52 -07001053 def __str__(self):
1054 return 'objc'
1055
1056
Nicolas "Pixel" Noble9f728642015-03-24 18:50:30 +01001057class Sanity(object):
1058
Jan Tattermusch77db4322016-02-20 20:19:35 -08001059 def configure(self, config, args):
1060 self.config = config
1061 self.args = args
1062 _check_compiler(self.args.compiler, ['default'])
1063
1064 def test_specs(self):
Craig Tiller94d04a52016-01-20 10:58:23 -08001065 import yaml
Jan Tattermusch788ee232016-01-26 12:19:44 -08001066 with open('tools/run_tests/sanity/sanity_tests.yaml', 'r') as f:
Jan Tattermusch7dd2cc62016-12-20 17:15:39 +01001067 environ={'TEST': 'true'}
1068 if _is_use_docker_child():
1069 environ['CLANG_FORMAT_SKIP_DOCKER'] = 'true'
Craig Tiller34226af2016-06-24 16:46:25 -07001070 return [self.config.job_spec(cmd['script'].split(),
Jan Tattermusch7dd2cc62016-12-20 17:15:39 +01001071 timeout_seconds=30*60,
1072 environ=environ,
Jan Tattermusch77db4322016-02-20 20:19:35 -08001073 cpu_cost=cmd.get('cpu_cost', 1))
Craig Tiller94d04a52016-01-20 10:58:23 -08001074 for cmd in yaml.load(f)]
Nicolas "Pixel" Noble9f728642015-03-24 18:50:30 +01001075
murgatroid99256d3df2015-09-21 16:58:02 -07001076 def pre_build_steps(self):
1077 return []
1078
Jan Tattermusch77db4322016-02-20 20:19:35 -08001079 def make_targets(self):
Nicolas "Pixel" Noble9f728642015-03-24 18:50:30 +01001080 return ['run_dep_checks']
1081
Jan Tattermuschc895fe02016-01-20 09:13:09 -08001082 def make_options(self):
1083 return []
1084
Nicolas "Pixel" Noble9f728642015-03-24 18:50:30 +01001085 def build_steps(self):
1086 return []
1087
Nicolas "Pixel" Noble87879b32015-10-12 23:28:53 +02001088 def post_tests_steps(self):
1089 return []
1090
murgatroid99a3e244f2015-09-22 11:25:53 -07001091 def makefile_name(self):
1092 return 'Makefile'
1093
Jan Tattermusch77db4322016-02-20 20:19:35 -08001094 def dockerfile_dir(self):
Jan Tattermusche70b3c52016-02-07 20:21:02 -08001095 return 'tools/dockerfile/test/sanity'
Jan Tattermusch788ee232016-01-26 12:19:44 -08001096
Nicolas "Pixel" Noble9f728642015-03-24 18:50:30 +01001097 def __str__(self):
1098 return 'sanity'
1099
murgatroid99b53e5d12016-10-18 09:55:28 -07001100class NodeExpressLanguage(object):
1101 """Dummy Node express test target to enable running express performance
1102 benchmarks"""
1103
1104 def __init__(self):
1105 self.platform = platform_string()
1106
1107 def configure(self, config, args):
1108 self.config = config
1109 self.args = args
1110 _check_compiler(self.args.compiler, ['default', 'node0.12',
1111 'node4', 'node5', 'node6'])
1112 if self.args.compiler == 'default':
1113 self.node_version = '4'
1114 else:
1115 # Take off the word "node"
1116 self.node_version = self.args.compiler[4:]
1117
1118 def test_specs(self):
1119 return []
1120
1121 def pre_build_steps(self):
1122 if self.platform == 'windows':
Jan Tattermusch5c79a312016-12-20 11:02:50 +01001123 return [['tools\\run_tests\\helper_scripts\\pre_build_node.bat']]
murgatroid99b53e5d12016-10-18 09:55:28 -07001124 else:
Jan Tattermusch5c79a312016-12-20 11:02:50 +01001125 return [['tools/run_tests/helper_scripts/pre_build_node.sh', self.node_version]]
murgatroid99b53e5d12016-10-18 09:55:28 -07001126
1127 def make_targets(self):
1128 return []
1129
1130 def make_options(self):
1131 return []
1132
1133 def build_steps(self):
1134 return []
1135
1136 def post_tests_steps(self):
1137 return []
1138
1139 def makefile_name(self):
1140 return 'Makefile'
1141
1142 def dockerfile_dir(self):
1143 return 'tools/dockerfile/test/node_jessie_%s' % _docker_arch_suffix(self.args.arch)
1144
1145 def __str__(self):
1146 return 'node_express'
Nicolas "Pixel" Noblee55cd7f2015-04-14 17:59:13 +02001147
Craig Tiller738c3342015-01-12 14:28:33 -08001148# different configurations we can run under
Jan Tattermusch5c79a312016-12-20 11:02:50 +01001149with open('tools/run_tests/generated/configs.json') as f:
Craig Tiller1dce9062016-01-20 17:01:56 -08001150 _CONFIGS = dict((cfg['config'], Config(**cfg)) for cfg in ast.literal_eval(f.read()))
Craig Tiller738c3342015-01-12 14:28:33 -08001151
1152
Craig Tillerc7449162015-01-16 14:42:10 -08001153_LANGUAGES = {
Craig Tillere9c959d2015-01-18 10:23:26 -08001154 'c++': CLanguage('cxx', 'c++'),
1155 'c': CLanguage('c', 'c'),
Matt Kwonge2e7cf42017-09-15 11:17:04 -07001156 'grpc-node': RemoteNodeLanguage(),
murgatroid992c8d5162015-01-26 10:41:21 -08001157 'node': NodeLanguage(),
murgatroid99b53e5d12016-10-18 09:55:28 -07001158 'node_express': NodeExpressLanguage(),
Nathaniel Manista840615e2015-01-22 20:31:47 +00001159 'php': PhpLanguage(),
Stanley Cheung2e2cdff2016-07-23 19:07:36 -07001160 'php7': Php7Language(),
Nathaniel Manista840615e2015-01-22 20:31:47 +00001161 'python': PythonLanguage(),
Jan Tattermusch1970a5b2015-03-03 15:17:25 -08001162 'ruby': RubyLanguage(),
Nicolas "Pixel" Noble9f728642015-03-24 18:50:30 +01001163 'csharp': CSharpLanguage(),
Jorge Canizalesa0b3bfa2015-07-30 19:25:52 -07001164 'objc' : ObjCLanguage(),
Jan Tattermusch70a57e42016-02-20 18:50:27 -08001165 'sanity': Sanity()
Craig Tillereb272bc2015-01-30 13:13:14 -08001166 }
Nicolas Nobleddef2462015-01-06 18:08:25 -08001167
Jan Tattermusch77db4322016-02-20 20:19:35 -08001168
Jan Tattermuscha2d964c2016-02-22 17:33:09 -08001169_MSBUILD_CONFIG = {
Craig Tiller7bb3efd2015-09-01 08:04:03 -07001170 'dbg': 'Debug',
1171 'opt': 'Release',
Jan Tattermusche4a69182015-12-15 09:53:01 -08001172 'gcov': 'Debug',
Craig Tiller7bb3efd2015-09-01 08:04:03 -07001173 }
1174
David Garcia Quintase90cd372015-05-31 18:15:26 -07001175
Jan Tattermusch2dd156e2015-12-04 18:26:17 -08001176def _windows_arch_option(arch):
1177 """Returns msbuild cmdline option for selected architecture."""
Jan Tattermusch9be594f2016-01-25 18:08:47 -08001178 if arch == 'default' or arch == 'x86':
Jan Tattermusch2dd156e2015-12-04 18:26:17 -08001179 return '/p:Platform=Win32'
Jan Tattermusch9be594f2016-01-25 18:08:47 -08001180 elif arch == 'x64':
Jan Tattermusch2dd156e2015-12-04 18:26:17 -08001181 return '/p:Platform=x64'
1182 else:
siddharthshukla0589e532016-07-07 16:08:01 +02001183 print('Architecture %s not supported.' % arch)
Jan Tattermusch2dd156e2015-12-04 18:26:17 -08001184 sys.exit(1)
Jan Tattermusch788ee232016-01-26 12:19:44 -08001185
Jan Tattermuschf08018a2016-01-26 08:22:09 -08001186
1187def _check_arch_option(arch):
1188 """Checks that architecture option is valid."""
1189 if platform_string() == 'windows':
1190 _windows_arch_option(arch)
1191 elif platform_string() == 'linux':
1192 # On linux, we need to be running under docker with the right architecture.
Jan Tattermusch07fb0422016-01-26 10:46:56 -08001193 runtime_arch = platform.architecture()[0]
Jan Tattermuschf08018a2016-01-26 08:22:09 -08001194 if arch == 'default':
1195 return
1196 elif runtime_arch == '64bit' and arch == 'x64':
1197 return
1198 elif runtime_arch == '32bit' and arch == 'x86':
1199 return
1200 else:
siddharthshukla0589e532016-07-07 16:08:01 +02001201 print('Architecture %s does not match current runtime architecture.' % arch)
Jan Tattermuschf08018a2016-01-26 08:22:09 -08001202 sys.exit(1)
1203 else:
1204 if args.arch != 'default':
siddharthshukla0589e532016-07-07 16:08:01 +02001205 print('Architecture %s not supported on current platform.' % args.arch)
Jan Tattermuschf08018a2016-01-26 08:22:09 -08001206 sys.exit(1)
Jan Tattermusch2dd156e2015-12-04 18:26:17 -08001207
Jan Tattermusch4dc9e722016-01-25 17:00:54 -08001208
Jan Tattermusche70b3c52016-02-07 20:21:02 -08001209def _docker_arch_suffix(arch):
1210 """Returns suffix to dockerfile dir to use."""
1211 if arch == 'default' or arch == 'x64':
1212 return 'x64'
1213 elif arch == 'x86':
1214 return 'x86'
1215 else:
siddharthshukla0589e532016-07-07 16:08:01 +02001216 print('Architecture %s not supported with current settings.' % arch)
Jan Tattermusche70b3c52016-02-07 20:21:02 -08001217 sys.exit(1)
1218
1219
David Garcia Quintase90cd372015-05-31 18:15:26 -07001220def runs_per_test_type(arg_str):
1221 """Auxilary function to parse the "runs_per_test" flag.
1222
1223 Returns:
1224 A positive integer or 0, the latter indicating an infinite number of
1225 runs.
1226
1227 Raises:
1228 argparse.ArgumentTypeError: Upon invalid input.
1229 """
1230 if arg_str == 'inf':
1231 return 0
1232 try:
1233 n = int(arg_str)
1234 if n <= 0: raise ValueError
Craig Tiller50e53e22015-06-01 20:18:21 -07001235 return n
David Garcia Quintase90cd372015-05-31 18:15:26 -07001236 except:
Adele Zhoue4c35612015-10-16 15:34:23 -07001237 msg = '\'{}\' is not a positive integer or \'inf\''.format(arg_str)
David Garcia Quintase90cd372015-05-31 18:15:26 -07001238 raise argparse.ArgumentTypeError(msg)
Jan Tattermuschc95eead2015-09-18 13:03:50 -07001239
siddharthshukla2135a1b2016-08-04 02:11:53 +02001240
David Garcia Quintas95b37b72017-02-15 16:49:49 -08001241def percent_type(arg_str):
1242 pct = float(arg_str)
1243 if pct > 100 or pct < 0:
1244 raise argparse.ArgumentTypeError(
1245 "'%f' is not a valid percentage in the [0, 100] range" % pct)
1246 return pct
1247
1248# This is math.isclose in python >= 3.5
1249def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
1250 return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
1251
1252
Jan Tattermuschc95eead2015-09-18 13:03:50 -07001253# parse command line
1254argp = argparse.ArgumentParser(description='Run grpc tests.')
1255argp.add_argument('-c', '--config',
Jan Tattermusch77db4322016-02-20 20:19:35 -08001256 choices=sorted(_CONFIGS.keys()),
1257 default='opt')
David Garcia Quintase90cd372015-05-31 18:15:26 -07001258argp.add_argument('-n', '--runs_per_test', default=1, type=runs_per_test_type,
1259 help='A positive integer or "inf". If "inf", all tests will run in an '
1260 'infinite loop. Especially useful in combination with "-f"')
Craig Tillerfe406ec2015-02-24 13:55:12 -08001261argp.add_argument('-r', '--regex', default='.*', type=str)
Vijay Pai488fd0e2016-06-13 12:37:12 -07001262argp.add_argument('--regex_exclude', default='', type=str)
Craig Tiller5f735a62016-01-20 09:31:15 -08001263argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int)
Craig Tiller8451e872015-02-27 09:25:51 -08001264argp.add_argument('-s', '--slowdown', default=1.0, type=float)
David Garcia Quintas95b37b72017-02-15 16:49:49 -08001265argp.add_argument('-p', '--sample_percent', default=100.0, type=percent_type,
1266 help='Run a random sample with that percentage of tests')
ctiller3040cb72015-01-07 12:13:17 -08001267argp.add_argument('-f', '--forever',
1268 default=False,
1269 action='store_const',
1270 const=True)
Nicolas "Pixel" Noblea7df3f92015-02-26 22:07:04 +01001271argp.add_argument('-t', '--travis',
1272 default=False,
1273 action='store_const',
1274 const=True)
Nicolas Noble044db742015-01-14 16:57:24 -08001275argp.add_argument('--newline_on_success',
1276 default=False,
1277 action='store_const',
1278 const=True)
Craig Tiller686fb262015-01-15 07:39:09 -08001279argp.add_argument('-l', '--language',
Craig Tiller60f15e62015-05-13 09:05:17 -07001280 choices=['all'] + sorted(_LANGUAGES.keys()),
Craig Tiller686fb262015-01-15 07:39:09 -08001281 nargs='+',
Craig Tiller60f15e62015-05-13 09:05:17 -07001282 default=['all'])
Craig Tillercd43da82015-05-29 08:41:29 -07001283argp.add_argument('-S', '--stop_on_failure',
1284 default=False,
1285 action='store_const',
1286 const=True)
Jan Tattermuschc95eead2015-09-18 13:03:50 -07001287argp.add_argument('--use_docker',
1288 default=False,
1289 action='store_const',
1290 const=True,
Adele Zhoue4c35612015-10-16 15:34:23 -07001291 help='Run all the tests under docker. That provides ' +
1292 'additional isolation and prevents the need to install ' +
1293 'language specific prerequisites. Only available on Linux.')
Craig Tillerd4509a12015-09-28 09:18:40 -07001294argp.add_argument('--allow_flakes',
1295 default=False,
1296 action='store_const',
1297 const=True,
Adele Zhoue4c35612015-10-16 15:34:23 -07001298 help='Allow flaky tests to show as passing (re-runs failed tests up to five times)')
Jan Tattermusch2dd156e2015-12-04 18:26:17 -08001299argp.add_argument('--arch',
Jan Tattermusch9be594f2016-01-25 18:08:47 -08001300 choices=['default', 'x86', 'x64'],
Jan Tattermusch2dd156e2015-12-04 18:26:17 -08001301 default='default',
1302 help='Selects architecture to target. For some platforms "default" is the only supported choice.')
1303argp.add_argument('--compiler',
Jan Tattermuschc4cbe392016-02-22 19:29:38 -08001304 choices=['default',
Ken Payson975b5102017-03-30 17:38:40 -07001305 'gcc4.4', 'gcc4.6', 'gcc4.8', 'gcc4.9', 'gcc5.3', 'gcc_musl',
Jan Tattermusch6d258c52016-06-10 09:36:51 -07001306 'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7',
Nathaniel Manistaa0109e52017-09-16 23:49:52 +00001307 'python2.7', 'python3.4', 'python3.5', 'python3.6', 'pypy', 'pypy3', 'python_alpine', 'all_the_cpythons',
murgatroid994bea5b92017-05-30 17:37:02 -07001308 'node0.12', 'node4', 'node5', 'node6', 'node7', 'node8',
murgatroid99f25f5052017-04-13 17:22:32 -07001309 'electron1.3', 'electron1.6',
Jan Tattermuschc98bde62017-01-25 19:12:11 +01001310 'coreclr',
Jan Tattermusch52ff56d2017-08-23 15:32:06 +02001311 'cmake', 'cmake_vs2015', 'cmake_vs2017'],
Jan Tattermusch2dd156e2015-12-04 18:26:17 -08001312 default='default',
Jan Tattermusch77db4322016-02-20 20:19:35 -08001313 help='Selects compiler to use. Allowed values depend on the platform and language.')
murgatroid99c36f6ea2016-10-03 09:24:09 -07001314argp.add_argument('--iomgr_platform',
1315 choices=['native', 'uv'],
1316 default='native',
1317 help='Selects iomgr platform to build on')
Jan Tattermusch2dd156e2015-12-04 18:26:17 -08001318argp.add_argument('--build_only',
1319 default=False,
1320 action='store_const',
1321 const=True,
Matt Kwong52ff9862017-04-17 13:56:51 -07001322 help='Perform all the build steps but don\'t run any tests.')
Craig Tiller5f735a62016-01-20 09:31:15 -08001323argp.add_argument('--measure_cpu_costs', default=False, action='store_const', const=True,
1324 help='Measure the cpu costs of tests')
Craig Tiller1676f912016-01-05 10:49:44 -08001325argp.add_argument('--update_submodules', default=[], nargs='*',
1326 help='Update some submodules before building. If any are updated, also run generate_projects. ' +
1327 'Submodules are specified as SUBMODULE_NAME:BRANCH; if BRANCH is omitted, master is assumed.')
Craig Tiller234b6e72015-05-23 10:12:40 -07001328argp.add_argument('-a', '--antagonists', default=0, type=int)
Nicolas "Pixel" Noble5937b5b2015-06-26 02:04:12 +02001329argp.add_argument('-x', '--xml_report', default=None, type=str,
1330 help='Generates a JUnit-compatible XML report')
Jan Tattermuschcfcc0752016-10-09 17:02:34 +02001331argp.add_argument('--report_suite_name', default='tests', type=str,
1332 help='Test suite name to use in generated JUnit XML report')
Jan Tattermusch68e27bf2016-12-16 14:09:03 +01001333argp.add_argument('--quiet_success',
1334 default=False,
1335 action='store_const',
1336 const=True,
Matt Kwong52ff9862017-04-17 13:56:51 -07001337 help='Don\'t print anything when a test passes. Passing tests also will not be reported in XML report. ' +
Jan Tattermusch68e27bf2016-12-16 14:09:03 +01001338 'Useful when running many iterations of each test (argument -n).')
Craig Tiller123f1372016-06-15 15:06:14 -07001339argp.add_argument('--force_default_poller', default=False, action='store_const', const=True,
Matt Kwong52ff9862017-04-17 13:56:51 -07001340 help='Don\'t try to iterate over many polling strategies when they exist')
Sree Kuchibhotla15d91642017-08-15 14:00:23 -07001341argp.add_argument('--force_use_pollers', default=None, type=str,
1342 help='Only use the specified comma-delimited list of polling engines. '
1343 'Example: --force_use_pollers epollsig,poll '
1344 ' (This flag has no effect if --force_default_poller flag is also used)')
Craig Tillera1ac2a12017-04-21 07:20:38 -07001345argp.add_argument('--max_time', default=-1, type=int, help='Maximum test runtime in seconds')
Matt Kwong52ff9862017-04-17 13:56:51 -07001346argp.add_argument('--bq_result_table',
1347 default='',
1348 type=str,
1349 nargs='?',
1350 help='Upload test results to a specified BQ table.')
Matt Kwongc5fd8902017-08-10 13:39:21 -07001351argp.add_argument('--disable_auto_set_flakes', default=False, const=True, action='store_const',
1352 help='Disable rerunning historically flaky tests')
Nicolas Nobleddef2462015-01-06 18:08:25 -08001353args = argp.parse_args()
1354
Craig Tillerd16abf82017-06-07 08:58:55 -07001355flaky_tests = set()
Craig Tiller0b86d032017-09-07 13:47:45 -07001356shortname_to_cpu = {}
Matt Kwongc5fd8902017-08-10 13:39:21 -07001357if not args.disable_auto_set_flakes:
Craig Tillerd16abf82017-06-07 08:58:55 -07001358 try:
Craig Tiller9992bdb2017-09-06 15:00:31 -07001359 for test in get_bqtest_data():
1360 if test.flaky: flaky_tests.add(test.name)
Craig Tiller0b86d032017-09-07 13:47:45 -07001361 if test.cpu > 0: shortname_to_cpu[test.name] = test.cpu
Craig Tillerd16abf82017-06-07 08:58:55 -07001362 except:
1363 print("Unexpected error getting flaky tests:", sys.exc_info()[0])
David Garcia Quintasfaafa4d2017-06-06 14:52:17 -07001364
Craig Tiller123f1372016-06-15 15:06:14 -07001365if args.force_default_poller:
1366 _POLLING_STRATEGIES = {}
Sree Kuchibhotla15d91642017-08-15 14:00:23 -07001367elif args.force_use_pollers:
1368 _POLLING_STRATEGIES[platform_string()] = args.force_use_pollers.split(',')
Craig Tiller123f1372016-06-15 15:06:14 -07001369
Craig Tiller5f735a62016-01-20 09:31:15 -08001370jobset.measure_cpu_costs = args.measure_cpu_costs
1371
Craig Tiller1676f912016-01-05 10:49:44 -08001372# update submodules if necessary
Craig Tillerb361b4e2016-01-06 11:44:17 -08001373need_to_regenerate_projects = False
1374for spec in args.update_submodules:
1375 spec = spec.split(':', 1)
1376 if len(spec) == 1:
1377 submodule = spec[0]
1378 branch = 'master'
1379 elif len(spec) == 2:
1380 submodule = spec[0]
1381 branch = spec[1]
1382 cwd = 'third_party/%s' % submodule
1383 def git(cmd, cwd=cwd):
siddharthshukla0589e532016-07-07 16:08:01 +02001384 print('in %s: git %s' % (cwd, cmd))
David Garcia Quintas03920252017-02-15 12:51:21 -08001385 run_shell_command('git %s' % cmd, cwd=cwd)
Craig Tillerb361b4e2016-01-06 11:44:17 -08001386 git('fetch')
1387 git('checkout %s' % branch)
1388 git('pull origin %s' % branch)
1389 if os.path.exists('src/%s/gen_build_yaml.py' % submodule):
1390 need_to_regenerate_projects = True
1391if need_to_regenerate_projects:
1392 if jobset.platform_string() == 'linux':
David Garcia Quintas03920252017-02-15 12:51:21 -08001393 run_shell_command('tools/buildgen/generate_projects.sh')
Craig Tillerb361b4e2016-01-06 11:44:17 -08001394 else:
siddharthshukla0589e532016-07-07 16:08:01 +02001395 print('WARNING: may need to regenerate projects, but since we are not on')
1396 print(' Linux this step is being skipped. Compilation MAY fail.')
Craig Tiller1676f912016-01-05 10:49:44 -08001397
1398
Nicolas Nobleddef2462015-01-06 18:08:25 -08001399# grab config
Jan Tattermusch77db4322016-02-20 20:19:35 -08001400run_config = _CONFIGS[args.config]
1401build_config = run_config.build_config
Craig Tillerf1973b02015-01-16 12:32:13 -08001402
Craig Tiller06805272015-06-11 14:46:47 -07001403if args.travis:
murgatroid99d3b5b7f2015-10-06 17:02:03 -07001404 _FORCE_ENVIRON_FOR_WRAPPERS = {'GRPC_TRACE': 'api'}
Craig Tiller06805272015-06-11 14:46:47 -07001405
Adele Zhou6b9527c2015-11-20 15:56:35 -08001406if 'all' in args.language:
Craig Tiller1676f912016-01-05 10:49:44 -08001407 lang_list = _LANGUAGES.keys()
Adele Zhou6b9527c2015-11-20 15:56:35 -08001408else:
1409 lang_list = args.language
Craig Tiller16900662016-01-07 19:30:54 -08001410# We don't support code coverage on some languages
1411if 'gcov' in args.config:
Jan Tattermusch3b5121b2016-02-22 17:41:05 -08001412 for bad in ['objc', 'sanity']:
Craig Tiller16900662016-01-07 19:30:54 -08001413 if bad in lang_list:
1414 lang_list.remove(bad)
Adele Zhou6b9527c2015-11-20 15:56:35 -08001415
1416languages = set(_LANGUAGES[l] for l in lang_list)
Jan Tattermusch77db4322016-02-20 20:19:35 -08001417for l in languages:
1418 l.configure(run_config, args)
murgatroid99132ce6a2015-03-04 17:29:14 -08001419
Jan Tattermuschc895fe02016-01-20 09:13:09 -08001420language_make_options=[]
1421if any(language.make_options() for language in languages):
Adele Zhou3b6ab812016-05-18 17:04:20 -07001422 if not 'gcov' in args.config and len(languages) != 1:
siddharthshukla0589e532016-07-07 16:08:01 +02001423 print('languages with custom make options cannot be built simultaneously with other languages')
Jan Tattermuschc895fe02016-01-20 09:13:09 -08001424 sys.exit(1)
1425 else:
Matt Kwong0ff19572017-03-30 18:22:21 -07001426 # Combining make options is not clean and just happens to work. It allows C/C++ and C# to build
1427 # together, and is only used under gcov. All other configs should build languages individually.
1428 language_make_options = list(set([make_option for lang in languages for make_option in lang.make_options()]))
Jan Tattermuschc895fe02016-01-20 09:13:09 -08001429
Jan Tattermusch4dc9e722016-01-25 17:00:54 -08001430if args.use_docker:
1431 if not args.travis:
siddharthshukla0589e532016-07-07 16:08:01 +02001432 print('Seen --use_docker flag, will run tests under docker.')
1433 print('')
1434 print('IMPORTANT: The changes you are testing need to be locally committed')
1435 print('because only the committed changes in the current branch will be')
1436 print('copied to the docker environment.')
Jan Tattermusch4dc9e722016-01-25 17:00:54 -08001437 time.sleep(5)
1438
Jan Tattermusch3b5121b2016-02-22 17:41:05 -08001439 dockerfile_dirs = set([l.dockerfile_dir() for l in languages])
1440 if len(dockerfile_dirs) > 1:
Adele Zhou9506ef22016-03-02 13:53:34 -08001441 if 'gcov' in args.config:
1442 dockerfile_dir = 'tools/dockerfile/test/multilang_jessie_x64'
1443 print ('Using multilang_jessie_x64 docker image for code coverage for '
1444 'all languages.')
1445 else:
1446 print ('Languages to be tested require running under different docker '
1447 'images.')
1448 sys.exit(1)
1449 else:
1450 dockerfile_dir = next(iter(dockerfile_dirs))
Craig Tillerde7edf82016-03-20 09:12:16 -07001451
Jan Tattermusch4dc9e722016-01-25 17:00:54 -08001452 child_argv = [ arg for arg in sys.argv if not arg == '--use_docker' ]
Jan Tattermusched342b12016-01-26 14:40:31 -08001453 run_tests_cmd = 'python tools/run_tests/run_tests.py %s' % ' '.join(child_argv[1:])
Jan Tattermusch4dc9e722016-01-25 17:00:54 -08001454
Jan Tattermusch4dc9e722016-01-25 17:00:54 -08001455 env = os.environ.copy()
1456 env['RUN_TESTS_COMMAND'] = run_tests_cmd
Jan Tattermusch3b5121b2016-02-22 17:41:05 -08001457 env['DOCKERFILE_DIR'] = dockerfile_dir
Jan Tattermusch9835d4b2016-04-29 15:05:05 -07001458 env['DOCKER_RUN_SCRIPT'] = 'tools/run_tests/dockerize/docker_run_tests.sh'
Jan Tattermusch4dc9e722016-01-25 17:00:54 -08001459 if args.xml_report:
1460 env['XML_REPORT'] = args.xml_report
1461 if not args.travis:
1462 env['TTY_FLAG'] = '-t' # enables Ctrl-C when not on Jenkins.
1463
Jan Tattermusch3464f702017-03-08 20:50:57 +01001464 subprocess.check_call('tools/run_tests/dockerize/build_docker_and_run_tests.sh',
1465 shell=True,
1466 env=env)
Jan Tattermusch4dc9e722016-01-25 17:00:54 -08001467 sys.exit(0)
Jan Tattermusch788ee232016-01-26 12:19:44 -08001468
Jan Tattermuschf08018a2016-01-26 08:22:09 -08001469_check_arch_option(args.arch)
Jan Tattermusch4dc9e722016-01-25 17:00:54 -08001470
Jan Tattermuschfba65302016-01-25 18:21:14 -08001471def make_jobspec(cfg, targets, makefile='Makefile'):
1472 if platform_string() == 'windows':
Jan Tattermusch91eeb792017-08-23 15:11:30 +02001473 return [jobset.JobSpec(['cmake', '--build', '.',
1474 '--target', '%s' % target,
1475 '--config', _MSBUILD_CONFIG[cfg]],
1476 cwd=os.path.dirname(makefile),
1477 timeout_seconds=None) for target in targets]
Jan Tattermuschfba65302016-01-25 18:21:14 -08001478 else:
Jan Tattermuschc98bde62017-01-25 19:12:11 +01001479 if targets and makefile.startswith('cmake/build/'):
1480 # With cmake, we've passed all the build configuration in the pre-build step already
1481 return [jobset.JobSpec([os.getenv('MAKE', 'make'),
1482 '-j', '%d' % args.jobs] +
1483 targets,
1484 cwd='cmake/build',
1485 timeout_seconds=None)]
murgatroid998ae409f2015-10-26 16:39:00 -07001486 if targets:
1487 return [jobset.JobSpec([os.getenv('MAKE', 'make'),
1488 '-f', makefile,
Craig Tillerdd6f7ed2016-01-21 12:54:42 -08001489 '-j', '%d' % args.jobs,
Craig Tiller71a86042016-01-15 14:59:58 -08001490 'EXTRA_DEFINES=GRPC_TEST_SLOWDOWN_MACHINE_FACTOR=%f' % args.slowdown,
Craig Tiller90ce7232017-04-12 06:53:09 -07001491 'CONFIG=%s' % cfg,
1492 'Q='] +
Jan Tattermuschc895fe02016-01-20 09:13:09 -08001493 language_make_options +
Craig Tiller71a86042016-01-15 14:59:58 -08001494 ([] if not args.travis else ['JENKINS_BUILD=1']) +
1495 targets,
Craig Tiller590105a2016-01-19 13:03:46 -08001496 timeout_seconds=None)]
murgatroid998ae409f2015-10-26 16:39:00 -07001497 else:
1498 return []
Jan Tattermuschfba65302016-01-25 18:21:14 -08001499
murgatroid99a3e244f2015-09-22 11:25:53 -07001500make_targets = {}
1501for l in languages:
1502 makefile = l.makefile_name()
1503 make_targets[makefile] = make_targets.get(makefile, set()).union(
Jan Tattermusch77db4322016-02-20 20:19:35 -08001504 set(l.make_targets()))
Craig Tiller5058c692015-04-08 09:42:04 -07001505
Jan Tattermusche4a69182015-12-15 09:53:01 -08001506def build_step_environ(cfg):
1507 environ = {'CONFIG': cfg}
Jan Tattermuscha2d964c2016-02-22 17:33:09 -08001508 msbuild_cfg = _MSBUILD_CONFIG.get(cfg)
Jan Tattermusche4a69182015-12-15 09:53:01 -08001509 if msbuild_cfg:
1510 environ['MSBUILD_CONFIG'] = msbuild_cfg
1511 return environ
1512
murgatroid99fddac962015-09-22 09:20:11 -07001513build_steps = list(set(
Jan Tattermusch376dc342017-10-16 16:00:35 +02001514 jobset.JobSpec(cmdline, environ=build_step_environ(build_config), flake_retries=2)
murgatroid99256d3df2015-09-21 16:58:02 -07001515 for l in languages
1516 for cmdline in l.pre_build_steps()))
Craig Tillerbd4e3782015-09-01 06:48:55 -07001517if make_targets:
siddharthshukla0589e532016-07-07 16:08:01 +02001518 make_commands = itertools.chain.from_iterable(make_jobspec(build_config, list(targets), makefile) for (makefile, targets) in make_targets.items())
Craig Tiller6fd23842015-09-01 07:36:31 -07001519 build_steps.extend(set(make_commands))
Craig Tiller5058c692015-04-08 09:42:04 -07001520build_steps.extend(set(
Jan Tattermusch77db4322016-02-20 20:19:35 -08001521 jobset.JobSpec(cmdline, environ=build_step_environ(build_config), timeout_seconds=None)
Craig Tiller547db2b2015-01-30 14:08:39 -08001522 for l in languages
Craig Tiller533b1a22015-05-29 08:41:29 -07001523 for cmdline in l.build_steps()))
Craig Tillerf1973b02015-01-16 12:32:13 -08001524
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +02001525post_tests_steps = list(set(
Jan Tattermusch77db4322016-02-20 20:19:35 -08001526 jobset.JobSpec(cmdline, environ=build_step_environ(build_config))
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +02001527 for l in languages
1528 for cmdline in l.post_tests_steps()))
Nicolas Nobleddef2462015-01-06 18:08:25 -08001529runs_per_test = args.runs_per_test
ctiller3040cb72015-01-07 12:13:17 -08001530forever = args.forever
Nicolas Nobleddef2462015-01-06 18:08:25 -08001531
Nicolas Nobleddef2462015-01-06 18:08:25 -08001532
Ken Paysonfa51de52016-06-30 23:50:48 -07001533def _shut_down_legacy_server(legacy_server_port):
1534 try:
siddharthshukla0589e532016-07-07 16:08:01 +02001535 version = int(urllib.request.urlopen(
Ken Paysonfa51de52016-06-30 23:50:48 -07001536 'http://localhost:%d/version_number' % legacy_server_port,
1537 timeout=10).read())
1538 except:
1539 pass
1540 else:
siddharthshukla0589e532016-07-07 16:08:01 +02001541 urllib.request.urlopen(
Ken Paysonfa51de52016-06-30 23:50:48 -07001542 'http://localhost:%d/quitquitquit' % legacy_server_port).read()
1543
1544
Adele Zhoud5fffa52015-10-23 15:51:42 -07001545def _calculate_num_runs_failures(list_of_results):
1546 """Caculate number of runs and failures for a particular test.
1547
1548 Args:
1549 list_of_results: (List) of JobResult object.
1550 Returns:
1551 A tuple of total number of runs and failures.
1552 """
1553 num_runs = len(list_of_results) # By default, there is 1 run per JobResult.
1554 num_failures = 0
1555 for jobresult in list_of_results:
1556 if jobresult.retries > 0:
1557 num_runs += jobresult.retries
1558 if jobresult.num_failures > 0:
1559 num_failures += jobresult.num_failures
1560 return num_runs, num_failures
1561
Adele Zhou6b9527c2015-11-20 15:56:35 -08001562
Craig Tillereb9de8b2016-01-08 08:57:41 -08001563# _build_and_run results
1564class BuildAndRunError(object):
1565
1566 BUILD = object()
1567 TEST = object()
1568 POST_TEST = object()
1569
1570
Craig Tiller819cd882017-04-25 13:18:22 -07001571def _has_epollexclusive():
Craig Tiller909a9842017-05-11 16:32:58 -07001572 binary = 'bins/%s/check_epollexclusive' % args.config
1573 if not os.path.exists(binary):
1574 return False
Craig Tiller819cd882017-04-25 13:18:22 -07001575 try:
Craig Tiller909a9842017-05-11 16:32:58 -07001576 subprocess.check_call(binary)
Craig Tiller819cd882017-04-25 13:18:22 -07001577 return True
1578 except subprocess.CalledProcessError, e:
1579 return False
Jan Tattermusch9883e0b2017-05-18 11:00:27 +02001580 except OSError, e:
1581 # For languages other than C and Windows the binary won't exist
1582 return False
Craig Tiller819cd882017-04-25 13:18:22 -07001583
1584
Craig Tillereb9de8b2016-01-08 08:57:41 -08001585# returns a list of things that failed (or an empty list on success)
Craig Tillerf53d9c82015-08-04 14:19:43 -07001586def _build_and_run(
Craig Tiller74189cd2016-06-23 15:39:06 -07001587 check_cancelled, newline_on_success, xml_report=None, build_only=False):
ctiller3040cb72015-01-07 12:13:17 -08001588 """Do one pass of building & running tests."""
murgatroid99666450e2015-01-26 13:03:31 -08001589 # build latest sequentially
Jan Tattermuschaab1e512016-01-28 09:30:44 -08001590 num_failures, resultset = jobset.run(
Adele Zhoue4c35612015-10-16 15:34:23 -07001591 build_steps, maxjobs=1, stop_on_failure=True,
Craig Tiller883064c2015-11-04 10:06:10 -08001592 newline_on_success=newline_on_success, travis=args.travis)
Adele Zhoue4c35612015-10-16 15:34:23 -07001593 if num_failures:
Craig Tillereb9de8b2016-01-08 08:57:41 -08001594 return [BuildAndRunError.BUILD]
Craig Tillerb361b4e2016-01-06 11:44:17 -08001595
Jan Tattermusch2dd156e2015-12-04 18:26:17 -08001596 if build_only:
Jan Tattermuschaab1e512016-01-28 09:30:44 -08001597 if xml_report:
Jan Tattermuschcfcc0752016-10-09 17:02:34 +02001598 report_utils.render_junit_xml_report(resultset, xml_report,
1599 suite_name=args.report_suite_name)
Craig Tillereb9de8b2016-01-08 08:57:41 -08001600 return []
ctiller3040cb72015-01-07 12:13:17 -08001601
Craig Tillerb2574bf2017-05-17 09:01:28 -07001602 if not args.travis and not _has_epollexclusive() and platform_string() in _POLLING_STRATEGIES and 'epollex' in _POLLING_STRATEGIES[platform_string()]:
Craig Tiller819cd882017-04-25 13:18:22 -07001603 print('\n\nOmitting EPOLLEXCLUSIVE tests\n\n')
1604 _POLLING_STRATEGIES[platform_string()].remove('epollex')
1605
Craig Tiller234b6e72015-05-23 10:12:40 -07001606 # start antagonists
Jan Tattermusch5c79a312016-12-20 11:02:50 +01001607 antagonists = [subprocess.Popen(['tools/run_tests/python_utils/antagonist.py'])
Craig Tiller234b6e72015-05-23 10:12:40 -07001608 for _ in range(0, args.antagonists)]
Craig Tillercba864b2017-02-17 10:27:56 -08001609 start_port_server.start_port_server()
Adele Zhou7cf72112015-11-04 11:18:43 -08001610 resultset = None
Adele Zhou803af152015-11-30 15:16:16 -08001611 num_test_failures = 0
Craig Tiller234b6e72015-05-23 10:12:40 -07001612 try:
David Garcia Quintase90cd372015-05-31 18:15:26 -07001613 infinite_runs = runs_per_test == 0
yang-g6c1fdc62015-08-18 11:57:42 -07001614 one_run = set(
1615 spec
yang-g6c1fdc62015-08-18 11:57:42 -07001616 for language in languages
Jan Tattermusch77db4322016-02-20 20:19:35 -08001617 for spec in language.test_specs()
Vijay Pai488fd0e2016-06-13 12:37:12 -07001618 if (re.search(args.regex, spec.shortname) and
1619 (args.regex_exclude == '' or
1620 not re.search(args.regex_exclude, spec.shortname))))
David Garcia Quintas79e389f2015-06-02 17:49:42 -07001621 # When running on travis, we want out test runs to be as similar as possible
1622 # for reproducibility purposes.
Craig Tillera1ac2a12017-04-21 07:20:38 -07001623 if args.travis and args.max_time <= 0:
Craig Tiller8d0fef22017-09-07 13:59:47 -07001624 massaged_one_run = sorted(one_run, key=lambda x: x.cpu_cost)
David Garcia Quintas79e389f2015-06-02 17:49:42 -07001625 else:
1626 # whereas otherwise, we want to shuffle things up to give all tests a
1627 # chance to run.
David Garcia Quintas95b37b72017-02-15 16:49:49 -08001628 massaged_one_run = list(one_run) # random.sample needs an indexable seq.
1629 num_jobs = len(massaged_one_run)
1630 # for a random sample, get as many as indicated by the 'sample_percent'
1631 # argument. By default this arg is 100, resulting in a shuffle of all
1632 # jobs.
1633 sample_size = int(num_jobs * args.sample_percent/100.0)
1634 massaged_one_run = random.sample(massaged_one_run, sample_size)
1635 if not isclose(args.sample_percent, 100.0):
David Garcia Quintase2bdbfe2017-03-08 11:55:07 -08001636 assert args.runs_per_test == 1, "Can't do sampling (-p) over multiple runs (-n)."
David Garcia Quintas95b37b72017-02-15 16:49:49 -08001637 print("Running %d tests out of %d (~%d%%)" %
1638 (sample_size, num_jobs, args.sample_percent))
Craig Tillerf7b7c892015-06-22 14:33:25 -07001639 if infinite_runs:
1640 assert len(massaged_one_run) > 0, 'Must have at least one test for a -n inf run'
David Garcia Quintas79e389f2015-06-02 17:49:42 -07001641 runs_sequence = (itertools.repeat(massaged_one_run) if infinite_runs
1642 else itertools.repeat(massaged_one_run, runs_per_test))
David Garcia Quintase90cd372015-05-31 18:15:26 -07001643 all_runs = itertools.chain.from_iterable(runs_sequence)
Nicolas "Pixel" Noble5937b5b2015-06-26 02:04:12 +02001644
Jan Tattermusch68e27bf2016-12-16 14:09:03 +01001645 if args.quiet_success:
1646 jobset.message('START', 'Running tests quietly, only failing tests will be reported', do_newline=True)
Adele Zhou803af152015-11-30 15:16:16 -08001647 num_test_failures, resultset = jobset.run(
Adele Zhou2271ab52015-10-28 13:59:14 -07001648 all_runs, check_cancelled, newline_on_success=newline_on_success,
Alexander Polcyndbfcd452017-10-01 15:34:29 -07001649 travis=args.travis, maxjobs=args.jobs, maxjobs_cpu_agnostic=max_parallel_tests_for_current_platform(),
murgatroid998ae409f2015-10-26 16:39:00 -07001650 stop_on_failure=args.stop_on_failure,
Craig Tillera1ac2a12017-04-21 07:20:38 -07001651 quiet_success=args.quiet_success, max_time=args.max_time)
Adele Zhoud5fffa52015-10-23 15:51:42 -07001652 if resultset:
Craig Tiller2b59dbc2016-05-13 15:59:09 -07001653 for k, v in sorted(resultset.items()):
Adele Zhoud5fffa52015-10-23 15:51:42 -07001654 num_runs, num_failures = _calculate_num_runs_failures(v)
Jan Tattermusch68e27bf2016-12-16 14:09:03 +01001655 if num_failures > 0:
1656 if num_failures == num_runs: # what about infinite_runs???
1657 jobset.message('FAILED', k, do_newline=True)
1658 else:
1659 jobset.message(
1660 'FLAKE', '%s [%d/%d runs flaked]' % (k, num_failures, num_runs),
1661 do_newline=True)
Craig Tiller234b6e72015-05-23 10:12:40 -07001662 finally:
1663 for antagonist in antagonists:
1664 antagonist.kill()
Matt Kwong52ff9862017-04-17 13:56:51 -07001665 if args.bq_result_table and resultset:
1666 upload_results_to_bq(resultset, args.bq_result_table, args, platform_string())
Adele Zhou7cf72112015-11-04 11:18:43 -08001667 if xml_report and resultset:
Jan Tattermuschcfcc0752016-10-09 17:02:34 +02001668 report_utils.render_junit_xml_report(resultset, xml_report,
1669 suite_name=args.report_suite_name)
Craig Tillerd86a3942015-01-14 12:48:54 -08001670
Adele Zhouf2ca7bc2015-10-23 15:38:00 -07001671 number_failures, _ = jobset.run(
Matt Kwong316855e2017-09-27 14:26:41 -07001672 post_tests_steps, maxjobs=1, stop_on_failure=False,
Craig Tiller883064c2015-11-04 10:06:10 -08001673 newline_on_success=newline_on_success, travis=args.travis)
Craig Tillereb9de8b2016-01-08 08:57:41 -08001674
1675 out = []
1676 if number_failures:
1677 out.append(BuildAndRunError.POST_TEST)
1678 if num_test_failures:
1679 out.append(BuildAndRunError.TEST)
Nicolas "Pixel" Noble3fcd3bf2015-10-10 02:30:38 +02001680
Craig Tillereb9de8b2016-01-08 08:57:41 -08001681 return out
ctiller3040cb72015-01-07 12:13:17 -08001682
1683
1684if forever:
Nicolas Noble044db742015-01-14 16:57:24 -08001685 success = True
ctiller3040cb72015-01-07 12:13:17 -08001686 while True:
Craig Tiller42bc87c2015-02-23 08:50:19 -08001687 dw = watch_dirs.DirWatcher(['src', 'include', 'test', 'examples'])
ctiller3040cb72015-01-07 12:13:17 -08001688 initial_time = dw.most_recent_change()
1689 have_files_changed = lambda: dw.most_recent_change() != initial_time
Nicolas Noble044db742015-01-14 16:57:24 -08001690 previous_success = success
Craig Tillereb9de8b2016-01-08 08:57:41 -08001691 errors = _build_and_run(check_cancelled=have_files_changed,
1692 newline_on_success=False,
Craig Tillereb9de8b2016-01-08 08:57:41 -08001693 build_only=args.build_only) == 0
1694 if not previous_success and not errors:
Nicolas Nobleb09078f2015-01-14 18:06:05 -08001695 jobset.message('SUCCESS',
1696 'All tests are now passing properly',
1697 do_newline=True)
Nicolas Noble044db742015-01-14 16:57:24 -08001698 jobset.message('IDLE', 'No change detected')
ctiller3040cb72015-01-07 12:13:17 -08001699 while not have_files_changed():
1700 time.sleep(1)
1701else:
Craig Tillereb9de8b2016-01-08 08:57:41 -08001702 errors = _build_and_run(check_cancelled=lambda: False,
Craig Tiller71735182015-01-15 17:07:13 -08001703 newline_on_success=args.newline_on_success,
Jan Tattermusch2dd156e2015-12-04 18:26:17 -08001704 xml_report=args.xml_report,
1705 build_only=args.build_only)
Craig Tillereb9de8b2016-01-08 08:57:41 -08001706 if not errors:
Nicolas Nobleb09078f2015-01-14 18:06:05 -08001707 jobset.message('SUCCESS', 'All tests passed', do_newline=True)
1708 else:
1709 jobset.message('FAILED', 'Some tests failed', do_newline=True)
Craig Tillereb9de8b2016-01-08 08:57:41 -08001710 exit_code = 0
1711 if BuildAndRunError.BUILD in errors:
1712 exit_code |= 1
Jan Tattermusche480a6a2016-10-07 12:59:08 +02001713 if BuildAndRunError.TEST in errors:
Craig Tillereb9de8b2016-01-08 08:57:41 -08001714 exit_code |= 2
Craig Tiller4f2be362016-01-08 08:59:20 -08001715 if BuildAndRunError.POST_TEST in errors:
1716 exit_code |= 4
Craig Tillereb9de8b2016-01-08 08:57:41 -08001717 sys.exit(exit_code)