blob: 87315fe7ddb444bfd0b28858b974e2e414590880 [file] [log] [blame]
armvixlad96eda2013-06-14 11:42:37 +01001#!/usr/bin/env python2.7
2
Alexandre Ramesb78f1392016-07-01 14:22:22 +01003# Copyright 2015, VIXL authors
armvixlad96eda2013-06-14 11:42:37 +01004# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are met:
8#
9# * Redistributions of source code must retain the above copyright notice,
10# this list of conditions and the following disclaimer.
11# * Redistributions in binary form must reproduce the above copyright notice,
12# this list of conditions and the following disclaimer in the documentation
13# and/or other materials provided with the distribution.
14# * Neither the name of ARM Limited nor the names of its contributors may be
15# used to endorse or promote products derived from this software without
16# specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
19# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
armvixlad96eda2013-06-14 11:42:37 +010029import argparse
armvixldb644342015-07-21 11:37:10 +010030import fcntl
31import git
32import itertools
armvixl4a102ba2014-07-14 09:02:40 +010033import multiprocessing
armvixldb644342015-07-21 11:37:10 +010034import os
35from os.path import join
36import platform
37import re
38import subprocess
39import sys
armvixlad96eda2013-06-14 11:42:37 +010040import time
armvixldb644342015-07-21 11:37:10 +010041
42import config
armvixl0f35e362016-05-10 13:57:58 +010043import clang_format
armvixldb644342015-07-21 11:37:10 +010044import lint
45import printer
46import test
47import threaded_tests
armvixlad96eda2013-06-14 11:42:37 +010048import util
49
50
armvixldb644342015-07-21 11:37:10 +010051dir_root = config.dir_root
52
53def Optionify(name):
54 return '--' + name
55
56
57# The options that can be tested are abstracted to provide an easy way to add
58# new ones.
59# Environment options influence the environment. They can be used for example to
60# set the compiler used.
61# Build options are options passed to scons, with a syntax like `scons opt=val`
62# Runtime options are options passed to the test program.
63# See the definition of `test_options` below.
64
65# 'all' is a special value for the options. If specified, all other values of
66# the option are tested.
67class TestOption(object):
68 type_environment = 'type_environment'
69 type_build = 'type_build'
70 type_run = 'type_run'
71
72 def __init__(self, option_type, name, help,
73 val_test_choices, val_test_default = None,
74 # If unset, the user can pass any value.
Pierre Langlois1c1488c2016-12-14 18:16:44 +000075 strict_choices = True, test_independently = False):
armvixldb644342015-07-21 11:37:10 +010076 self.name = name
77 self.option_type = option_type
78 self.help = help
79 self.val_test_choices = val_test_choices
80 self.strict_choices = strict_choices
Pierre Langlois1c1488c2016-12-14 18:16:44 +000081 self.test_independently = test_independently
armvixldb644342015-07-21 11:37:10 +010082 if val_test_default is not None:
83 self.val_test_default = val_test_default
84 else:
85 self.val_test_default = val_test_choices[0]
86
87 def ArgList(self, to_test):
88 res = []
89 if to_test == 'all':
90 for value in self.val_test_choices:
91 if value != 'all':
92 res.append(self.GetOptionString(value))
93 else:
94 for value in to_test:
95 res.append(self.GetOptionString(value))
96 return res
97
98class EnvironmentOption(TestOption):
99 option_type = TestOption.type_environment
100 def __init__(self, name, environment_variable_name, help,
101 val_test_choices, val_test_default = None,
102 strict_choices = True):
103 super(EnvironmentOption, self).__init__(EnvironmentOption.option_type,
104 name,
105 help,
106 val_test_choices,
107 val_test_default,
108 strict_choices = strict_choices)
109 self.environment_variable_name = environment_variable_name
110
111 def GetOptionString(self, value):
112 return self.environment_variable_name + '=' + value
113
114
115class BuildOption(TestOption):
116 option_type = TestOption.type_build
117 def __init__(self, name, help,
118 val_test_choices, val_test_default = None,
Pierre Langlois1c1488c2016-12-14 18:16:44 +0000119 strict_choices = True, test_independently = False):
armvixldb644342015-07-21 11:37:10 +0100120 super(BuildOption, self).__init__(BuildOption.option_type,
121 name,
122 help,
123 val_test_choices,
124 val_test_default,
Pierre Langlois1c1488c2016-12-14 18:16:44 +0000125 strict_choices = strict_choices,
126 test_independently = test_independently)
armvixldb644342015-07-21 11:37:10 +0100127 def GetOptionString(self, value):
128 return self.name + '=' + value
129
130
131class RuntimeOption(TestOption):
132 option_type = TestOption.type_run
133 def __init__(self, name, help,
134 val_test_choices, val_test_default = None):
135 super(RuntimeOption, self).__init__(RuntimeOption.option_type,
136 name,
137 help,
138 val_test_choices,
139 val_test_default)
140 def GetOptionString(self, value):
141 if value == 'on':
142 return Optionify(self.name)
143 else:
144 return None
145
146
147
148environment_option_compiler = \
149 EnvironmentOption('compiler', 'CXX', 'Test for the specified compilers.',
150 val_test_choices=['all'] + config.tested_compilers,
151 strict_choices = False)
152test_environment_options = [
153 environment_option_compiler
154]
155
156build_option_mode = \
157 BuildOption('mode', 'Test with the specified build modes.',
158 val_test_choices=['all'] + config.build_options_modes)
159build_option_standard = \
160 BuildOption('std', 'Test with the specified C++ standard.',
161 val_test_choices=['all'] + config.tested_cpp_standards,
162 strict_choices = False)
Rodolph Perfetta9a9331f2016-12-09 22:05:48 +0000163build_option_target = \
164 BuildOption('target', 'Test with the specified isa enabled.',
165 val_test_choices=['all'] + config.build_options_target,
Pierre Langlois1c1488c2016-12-14 18:16:44 +0000166 strict_choices = False, test_independently = True)
167build_option_negative_testing = \
168 BuildOption('negative_testing', 'Test with negative testing enabled.',
169 val_test_choices=['all'] + config.build_options_negative_testing,
170 strict_choices = False, test_independently = True)
armvixldb644342015-07-21 11:37:10 +0100171test_build_options = [
172 build_option_mode,
Pierre Langlois1c1488c2016-12-14 18:16:44 +0000173 build_option_standard,
Rodolph Perfetta9a9331f2016-12-09 22:05:48 +0000174 build_option_target,
Pierre Langlois1c1488c2016-12-14 18:16:44 +0000175 build_option_negative_testing
armvixldb644342015-07-21 11:37:10 +0100176]
177
Jacob Bramleyc919d872018-07-03 17:58:44 +0100178test_runtime_options = []
armvixldb644342015-07-21 11:37:10 +0100179
180test_options = \
Jacob Bramleyc919d872018-07-03 17:58:44 +0100181 test_environment_options + test_build_options + test_runtime_options
armvixl5799d6c2014-05-01 11:05:00 +0100182
183
armvixlad96eda2013-06-14 11:42:37 +0100184def BuildOptions():
armvixldb644342015-07-21 11:37:10 +0100185 args = argparse.ArgumentParser(
186 description =
armvixl0f35e362016-05-10 13:57:58 +0100187 '''This tool runs all tests matching the specified filters for multiple
armvixldb644342015-07-21 11:37:10 +0100188 environment, build options, and runtime options configurations.''',
189 # Print default values.
190 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
191
192 args.add_argument('filters', metavar='filter', nargs='*',
193 help='Run tests matching all of the (regexp) filters.')
194
195 # We automatically build the script options from the options to be tested.
196 test_arguments = args.add_argument_group(
197 'Test options',
198 'These options indicate what should be tested')
199 for option in test_options:
200 choices = option.val_test_choices if option.strict_choices else None
201 help = option.help
202 if not option.strict_choices:
203 help += ' Supported values: {' + ','.join(option.val_test_choices) + '}'
204 test_arguments.add_argument(Optionify(option.name),
205 nargs='+',
206 choices=choices,
207 default=option.val_test_default,
208 help=help,
209 action='store')
210
211 general_arguments = args.add_argument_group('General options')
212 general_arguments.add_argument('--fast', action='store_true',
armvixl0f35e362016-05-10 13:57:58 +0100213 help='''Skip the lint and clang-format tests,
214 and run only with one compiler, in one mode,
215 with one C++ standard, and with an appropriate
Alexandre Ramesdd7de862016-07-06 13:56:11 +0100216 default for runtime options.''')
Jacob Bramley59d74ae2017-01-18 15:27:45 +0000217 general_arguments.add_argument('--dry-run', action='store_true',
218 help='''Don't actually build or run anything,
219 but print the configurations that would be
220 tested.''')
armvixldb644342015-07-21 11:37:10 +0100221 general_arguments.add_argument(
222 '--jobs', '-j', metavar='N', type=int, nargs='?',
223 default=multiprocessing.cpu_count(),
224 const=multiprocessing.cpu_count(),
225 help='''Runs the tests using N jobs. If the option is set but no value is
226 provided, the script will use as many jobs as it thinks useful.''')
Pierre Langlois44096c42018-05-23 23:15:25 +0100227 general_arguments.add_argument('--clang-format',
228 default=clang_format.DEFAULT_CLANG_FORMAT,
229 help='Path to clang-format.')
armvixldb644342015-07-21 11:37:10 +0100230 general_arguments.add_argument('--nobench', action='store_true',
231 help='Do not run benchmarks.')
232 general_arguments.add_argument('--nolint', action='store_true',
233 help='Do not run the linter.')
armvixl0f35e362016-05-10 13:57:58 +0100234 general_arguments.add_argument('--noclang-format', action='store_true',
235 help='Do not run clang-format.')
armvixldb644342015-07-21 11:37:10 +0100236 general_arguments.add_argument('--notest', action='store_true',
237 help='Do not run tests.')
Alexandre Rames73064a22016-07-08 09:17:03 +0100238 general_arguments.add_argument('--fail-early', action='store_true',
239 help='Exit as soon as a test fails.')
Pierre Langloisa3b21462016-08-04 16:01:51 +0100240 sim_default = 'none' if platform.machine() == 'aarch64' else 'aarch64'
armvixldb644342015-07-21 11:37:10 +0100241 general_arguments.add_argument(
Pierre Langloisa3b21462016-08-04 16:01:51 +0100242 '--simulator', action='store', choices=['aarch64', 'none'],
armvixldb644342015-07-21 11:37:10 +0100243 default=sim_default,
244 help='Explicitly enable or disable the simulator.')
armvixl684cd2a2015-10-23 13:38:33 +0100245 general_arguments.add_argument(
246 '--under_valgrind', action='store_true',
247 help='''Run the test-runner commands under Valgrind.
248 Note that a few tests are known to fail because of
249 issues in Valgrind''')
armvixldb644342015-07-21 11:37:10 +0100250 return args.parse_args()
armvixlad96eda2013-06-14 11:42:37 +0100251
252
armvixldb644342015-07-21 11:37:10 +0100253def RunCommand(command, environment_options = None):
254 # Create a copy of the environment. We do not want to pollute the environment
255 # of future commands run.
256 environment = os.environ
257 # Configure the environment.
258 # TODO: We currently pass the options as strings, so we need to parse them. We
259 # should instead pass them as a data structure and build the string option
260 # later. `environment_options` looks like `['CXX=compiler', 'OPT=val']`.
261 if environment_options:
262 for option in environment_options:
263 opt, val = option.split('=')
264 environment[opt] = val
armvixlad96eda2013-06-14 11:42:37 +0100265
armvixldb644342015-07-21 11:37:10 +0100266 printable_command = ''
267 if environment_options:
268 printable_command += ' '.join(environment_options) + ' '
269 printable_command += ' '.join(command)
armvixlad96eda2013-06-14 11:42:37 +0100270
armvixldb644342015-07-21 11:37:10 +0100271 printable_command_orange = \
272 printer.COLOUR_ORANGE + printable_command + printer.NO_COLOUR
273 printer.PrintOverwritableLine(printable_command_orange)
274 sys.stdout.flush()
armvixlad96eda2013-06-14 11:42:37 +0100275
armvixldb644342015-07-21 11:37:10 +0100276 # Start a process for the command.
277 # Interleave `stderr` and `stdout`.
278 p = subprocess.Popen(command,
279 stdout=subprocess.PIPE,
280 stderr=subprocess.STDOUT,
281 env=environment)
armvixlad96eda2013-06-14 11:42:37 +0100282
armvixldb644342015-07-21 11:37:10 +0100283 # We want to be able to display a continuously updated 'work indicator' while
284 # the process is running. Since the process can hang if the `stdout` pipe is
285 # full, we need to pull from it regularly. We cannot do so via the
286 # `readline()` function because it is blocking, and would thus cause the
287 # indicator to not be updated properly. So use file control mechanisms
288 # instead.
289 indicator = ' (still working: %d seconds elapsed)'
armvixl5799d6c2014-05-01 11:05:00 +0100290
armvixldb644342015-07-21 11:37:10 +0100291 # Mark the process output as non-blocking.
292 flags = fcntl.fcntl(p.stdout, fcntl.F_GETFL)
293 fcntl.fcntl(p.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK)
armvixl5799d6c2014-05-01 11:05:00 +0100294
armvixldb644342015-07-21 11:37:10 +0100295 t_start = time.time()
296 t_last_indication = t_start
297 process_output = ''
armvixl5799d6c2014-05-01 11:05:00 +0100298
armvixldb644342015-07-21 11:37:10 +0100299 # Keep looping as long as the process is running.
300 while p.poll() is None:
301 # Avoid polling too often.
302 time.sleep(0.1)
303 # Update the progress indicator.
304 t_current = time.time()
305 if (t_current - t_start >= 2) and (t_current - t_last_indication >= 1):
306 printer.PrintOverwritableLine(
307 printable_command_orange + indicator % int(t_current - t_start))
308 sys.stdout.flush()
309 t_last_indication = t_current
310 # Pull from the process output.
311 while True:
312 try:
313 line = os.read(p.stdout.fileno(), 1024)
314 except OSError:
315 line = ''
316 break
317 if line == '': break
318 process_output += line
armvixlad96eda2013-06-14 11:42:37 +0100319
armvixldb644342015-07-21 11:37:10 +0100320 # The process has exited. Don't forget to retrieve the rest of its output.
321 out, err = p.communicate()
322 rc = p.poll()
323 process_output += out
armvixlad96eda2013-06-14 11:42:37 +0100324
Anthony Barbierb5f72392019-02-15 15:33:48 +0000325 printable_command += ' (took %d seconds)' % int(t_current - t_start)
armvixldb644342015-07-21 11:37:10 +0100326 if rc == 0:
327 printer.Print(printer.COLOUR_GREEN + printable_command + printer.NO_COLOUR)
armvixl4a102ba2014-07-14 09:02:40 +0100328 else:
armvixldb644342015-07-21 11:37:10 +0100329 printer.Print(printer.COLOUR_RED + printable_command + printer.NO_COLOUR)
330 printer.Print(process_output)
331 return rc
armvixl5799d6c2014-05-01 11:05:00 +0100332
333
armvixldb644342015-07-21 11:37:10 +0100334def RunLinter():
Alexandre Ramesb2746622016-07-11 16:12:39 +0100335 rc, default_tracked_files = lint.GetDefaultFilesToLint()
armvixldb644342015-07-21 11:37:10 +0100336 if rc:
337 return rc
Alexandre Ramesb2746622016-07-11 16:12:39 +0100338 return lint.RunLinter(map(lambda x: join(dir_root, x), default_tracked_files),
armvixldb644342015-07-21 11:37:10 +0100339 jobs = args.jobs, progress_prefix = 'cpp lint: ')
armvixlad96eda2013-06-14 11:42:37 +0100340
armvixlad96eda2013-06-14 11:42:37 +0100341
armvixl0f35e362016-05-10 13:57:58 +0100342def RunClangFormat():
343 return clang_format.ClangFormatFiles(clang_format.GetCppSourceFilesToFormat(),
Pierre Langlois44096c42018-05-23 23:15:25 +0100344 args.clang_format, jobs = args.jobs,
armvixl0f35e362016-05-10 13:57:58 +0100345 progress_prefix = 'clang-format: ')
346
347
armvixlad96eda2013-06-14 11:42:37 +0100348
armvixldb644342015-07-21 11:37:10 +0100349def BuildAll(build_options, jobs):
350 scons_command = ["scons", "-C", dir_root, 'all', '-j', str(jobs)]
351 scons_command += list(build_options)
352 return RunCommand(scons_command, list(environment_options))
armvixlad96eda2013-06-14 11:42:37 +0100353
armvixl4a102ba2014-07-14 09:02:40 +0100354
Rodolph Perfetta9a9331f2016-12-09 22:05:48 +0000355# Work out if the given options or args allow to run on the specified arch.
356# * arches is a list of ISA/architecture (a64, aarch32, etc)
357# * options are test.py's command line options if any.
358# * args are the arguments given to the build script.
359def CanRunOn(arches, options, args):
360 # First we check in the build specific options.
361 for option in options:
362 if 'target' in option:
363 # The option format is 'target=x,y,z'.
364 for target in (option.split('='))[1].split(','):
365 if target in arches:
366 return True
367
368 # There was a target build option but it didn't include the target arch.
369 return False
370
371 # No specific build option, check the script arguments.
372 # The meaning of 'all' will depend on the platform, e.g. 32-bit compilers
373 # cannot handle Aarch64 while 64-bit compiler can handle Aarch32. To avoid
374 # any issues no benchmarks are run for target='all'.
375 if args.target == 'all': return False
376
377 for target in args.target[0].split(','):
378 if target in arches:
379 return True
380
381 return False
382
383
384def CanRunAarch64(options, args):
385 return CanRunOn(['aarch64', 'a64'], options, args)
386
387
388def CanRunAarch32(options, args):
389 return CanRunOn(['aarch32', 'a32', 't32'], options, args)
390
391
392def RunBenchmarks(options, args):
armvixldb644342015-07-21 11:37:10 +0100393 rc = 0
Rodolph Perfetta9a9331f2016-12-09 22:05:48 +0000394 if CanRunAarch32(options, args):
Pierre Langlois1c1488c2016-12-14 18:16:44 +0000395 benchmark_names = util.ListCCFilesWithoutExt(config.dir_aarch32_benchmarks)
396 for bench in benchmark_names:
397 rc |= RunCommand(
398 [os.path.realpath(
Martyn Capewell9cd420f2017-05-12 20:30:23 +0100399 join(config.dir_build_latest, 'benchmarks/aarch32', bench)), '10'])
Rodolph Perfetta9a9331f2016-12-09 22:05:48 +0000400 if CanRunAarch64(options, args):
Pierre Langlois1c1488c2016-12-14 18:16:44 +0000401 benchmark_names = util.ListCCFilesWithoutExt(config.dir_aarch64_benchmarks)
402 for bench in benchmark_names:
403 rc |= RunCommand(
404 [util.relrealpath(
Martyn Capewell9cd420f2017-05-12 20:30:23 +0100405 join(config.dir_build_latest,
406 'benchmarks/aarch64', bench)), '10'])
armvixldb644342015-07-21 11:37:10 +0100407 return rc
armvixl4a102ba2014-07-14 09:02:40 +0100408
armvixl4a102ba2014-07-14 09:02:40 +0100409
armvixldb644342015-07-21 11:37:10 +0100410def PrintStatus(success):
411 printer.Print('\n$ ' + ' '.join(sys.argv))
412 if success:
413 printer.Print('SUCCESS')
414 else:
415 printer.Print('FAILURE')
armvixl4a102ba2014-07-14 09:02:40 +0100416
armvixlad96eda2013-06-14 11:42:37 +0100417
418
419if __name__ == '__main__':
armvixldb644342015-07-21 11:37:10 +0100420 util.require_program('scons')
421 rc = 0
armvixlad96eda2013-06-14 11:42:37 +0100422
armvixlad96eda2013-06-14 11:42:37 +0100423 args = BuildOptions()
armvixlad96eda2013-06-14 11:42:37 +0100424
Alexandre Rames73064a22016-07-08 09:17:03 +0100425 def MaybeExitEarly(rc):
426 if args.fail_early and rc != 0:
427 PrintStatus(rc == 0)
428 sys.exit(rc)
429
armvixl684cd2a2015-10-23 13:38:33 +0100430 if args.under_valgrind:
431 util.require_program('valgrind')
432
armvixldb644342015-07-21 11:37:10 +0100433 if args.fast:
434 def SetFast(option, specified, default):
435 option.val_test_choices = \
Alexandre Ramesdd7de862016-07-06 13:56:11 +0100436 [default if specified == 'all' else specified[0]]
437 # `g++` is very slow to compile a few aarch32 test files.
438 SetFast(environment_option_compiler, args.compiler, 'clang++')
439 SetFast(build_option_standard, args.std, 'c++98')
440 SetFast(build_option_mode, args.mode, 'debug')
armvixlad96eda2013-06-14 11:42:37 +0100441
Jacob Bramley59d74ae2017-01-18 15:27:45 +0000442 if not args.nolint and not (args.fast or args.dry_run):
armvixldb644342015-07-21 11:37:10 +0100443 rc |= RunLinter()
Alexandre Rames73064a22016-07-08 09:17:03 +0100444 MaybeExitEarly(rc)
445
Jacob Bramley59d74ae2017-01-18 15:27:45 +0000446 if not args.noclang_format and not (args.fast or args.dry_run):
armvixl0f35e362016-05-10 13:57:58 +0100447 rc |= RunClangFormat()
Alexandre Rames73064a22016-07-08 09:17:03 +0100448 MaybeExitEarly(rc)
armvixl5799d6c2014-05-01 11:05:00 +0100449
armvixldb644342015-07-21 11:37:10 +0100450 # List all combinations of options that will be tested.
451 def ListCombinations(args, options):
Pierre Langlois1c1488c2016-12-14 18:16:44 +0000452 opts_list = [
453 opt.ArgList(args.__dict__[opt.name])
454 for opt in options
455 if not opt.test_independently
456 ]
armvixldb644342015-07-21 11:37:10 +0100457 return list(itertools.product(*opts_list))
Pierre Langlois1c1488c2016-12-14 18:16:44 +0000458 # List combinations of options that should only be tested independently.
Jacob Bramleyd503ed22017-01-18 16:14:37 +0000459 def ListIndependentCombinations(args, options, base):
Pierre Langlois1c1488c2016-12-14 18:16:44 +0000460 n = []
461 for opt in options:
462 if opt.test_independently:
463 for o in opt.ArgList(args.__dict__[opt.name]):
Jacob Bramleyd503ed22017-01-18 16:14:37 +0000464 n.append(base + (o,))
Pierre Langlois1c1488c2016-12-14 18:16:44 +0000465 return n
Georgia Kouveli38d5d1b2016-11-16 11:58:41 +0000466 # TODO: We should refine the configurations we test by default, instead of
467 # always testing all possible combinations.
armvixldb644342015-07-21 11:37:10 +0100468 test_env_combinations = ListCombinations(args, test_environment_options)
469 test_build_combinations = ListCombinations(args, test_build_options)
Jacob Bramleyd503ed22017-01-18 16:14:37 +0000470 if not args.fast:
471 test_build_combinations.extend(
472 ListIndependentCombinations(args,
473 test_build_options,
474 test_build_combinations[0]))
armvixldb644342015-07-21 11:37:10 +0100475 test_runtime_combinations = ListCombinations(args, test_runtime_options)
armvixlad96eda2013-06-14 11:42:37 +0100476
Anthony Barbierb5f72392019-02-15 15:33:48 +0000477 tests = threaded_tests.TestQueue(args.under_valgrind)
armvixldb644342015-07-21 11:37:10 +0100478 for environment_options in test_env_combinations:
479 for build_options in test_build_combinations:
Jacob Bramley59d74ae2017-01-18 15:27:45 +0000480 if (args.dry_run):
481 for runtime_options in test_runtime_combinations:
482 print(' '.join(filter(None, environment_options)) + ', ' +
483 ' '.join(filter(None, build_options)) + ', ' +
484 ' '.join(filter(None, runtime_options)))
485 continue
486
armvixldb644342015-07-21 11:37:10 +0100487 # Avoid going through the build stage if we are not using the build
488 # result.
489 if not (args.notest and args.nobench):
490 build_rc = BuildAll(build_options, args.jobs)
491 # Don't run the tests for this configuration if the build failed.
492 if build_rc != 0:
493 rc |= build_rc
Alexandre Rames73064a22016-07-08 09:17:03 +0100494 MaybeExitEarly(rc)
armvixldb644342015-07-21 11:37:10 +0100495 continue
armvixlad96eda2013-06-14 11:42:37 +0100496
armvixldb644342015-07-21 11:37:10 +0100497 # Use the realpath of the test executable so that the commands printed
498 # can be copy-pasted and run.
Alexandre Rames81c76e62016-07-19 09:53:09 +0100499 test_executable = util.relrealpath(
armvixldb644342015-07-21 11:37:10 +0100500 join(config.dir_build_latest, 'test', 'test-runner'))
501
502 if not args.notest:
503 printer.Print(test_executable)
504
505 for runtime_options in test_runtime_combinations:
506 if not args.notest:
507 runtime_options = [x for x in runtime_options if x is not None]
508 prefix = ' ' + ' '.join(runtime_options) + ' '
Anthony Barbierb5f72392019-02-15 15:33:48 +0000509 tests.Add(test_executable,
510 args.filters,
511 list(runtime_options))
Alexandre Rames73064a22016-07-08 09:17:03 +0100512 MaybeExitEarly(rc)
armvixldb644342015-07-21 11:37:10 +0100513
514 if not args.nobench:
Rodolph Perfetta9a9331f2016-12-09 22:05:48 +0000515 rc |= RunBenchmarks(build_options, args)
Alexandre Rames73064a22016-07-08 09:17:03 +0100516 MaybeExitEarly(rc)
armvixldb644342015-07-21 11:37:10 +0100517
Anthony Barbierb5f72392019-02-15 15:33:48 +0000518 rc |= tests.Run(args.jobs)
Jacob Bramley59d74ae2017-01-18 15:27:45 +0000519 if not args.dry_run:
520 PrintStatus(rc == 0)
Alexandre Rames7c0ea8b2016-05-18 13:47:42 +0100521
522 sys.exit(rc)