3 # Copyright 2012 the V8 project authors. All rights reserved.
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following
12 # disclaimer in the documentation and/or other materials provided
13 # with the distribution.
14 # * Neither the name of Google Inc. nor the names of its
15 # contributors may be used to endorse or promote products derived
16 # from this software without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 import multiprocessing
35 from os.path import join
42 from testrunner.local import execution
43 from testrunner.local import progress
44 from testrunner.local import testsuite
45 from testrunner.local import utils
46 from testrunner.local import verbose
47 from testrunner.network import network_execution
48 from testrunner.objects import context
51 ARCH_GUESS = utils.DefaultArch()
52 DEFAULT_TESTS = ["mjsunit", "cctest", "message", "preparser"]
54 TIMEOUT_SCALEFACTOR = {"debug" : 4,
57 # Use this to run several variants of the tests.
60 "stress": ["--stress-opt", "--always-opt"],
61 "nocrankshaft": ["--nocrankshaft"]}
63 VARIANTS = ["default", "stress", "nocrankshaft"]
66 "debug" : ["--nobreak-on-abort", "--nodead-code-elimination",
67 "--nofold-constants", "--enable-slow-asserts",
68 "--debug-code", "--verify-heap"],
69 "release" : ["--nobreak-on-abort", "--nodead-code-elimination",
70 "--nofold-constants"]}
72 GC_STRESS_FLAGS = ["--gc-interval=500", "--stress-compaction",
73 "--concurrent-recompilation-queue-length=64",
74 "--concurrent-recompilation-delay=500",
75 "--concurrent-recompilation"]
77 SUPPORTED_ARCHS = ["android_arm",
85 # Double the timeout for these:
86 SLOW_ARCHS = ["android_arm",
95 result = optparse.OptionParser()
96 result.add_option("--arch",
97 help=("The architecture to run tests for, "
98 "'auto' or 'native' for auto-detect"),
99 default="ia32,x64,arm")
100 result.add_option("--arch-and-mode",
101 help="Architecture and mode in the format 'arch.mode'",
103 result.add_option("--asan",
104 help="Regard test expectations for ASAN",
105 default=False, action="store_true")
106 result.add_option("--buildbot",
107 help="Adapt to path structure used on buildbots",
108 default=False, action="store_true")
109 result.add_option("--cat", help="Print the source of the tests",
110 default=False, action="store_true")
111 result.add_option("--flaky-tests",
112 help="Regard tests marked as flaky (run|skip|dontcare)",
114 result.add_option("--slow-tests",
115 help="Regard slow tests (run|skip|dontcare)",
117 result.add_option("--pass-fail-tests",
118 help="Regard pass|fail tests (run|skip|dontcare)",
120 result.add_option("--gc-stress",
121 help="Switch on GC stress mode",
122 default=False, action="store_true")
123 result.add_option("--command-prefix",
124 help="Prepended to each shell command used to run a test",
126 result.add_option("--download-data", help="Download missing test suite data",
127 default=False, action="store_true")
128 result.add_option("--extra-flags",
129 help="Additional flags to pass to each test command",
131 result.add_option("--isolates", help="Whether to test isolates",
132 default=False, action="store_true")
133 result.add_option("-j", help="The number of parallel tasks to run",
134 default=0, type="int")
135 result.add_option("-m", "--mode",
136 help="The test modes in which to run (comma-separated)",
137 default="release,debug")
138 result.add_option("--no-i18n", "--noi18n",
139 help="Skip internationalization tests",
140 default=False, action="store_true")
141 result.add_option("--no-network", "--nonetwork",
142 help="Don't distribute tests on the network",
143 default=(utils.GuessOS() != "linux"),
144 dest="no_network", action="store_true")
145 result.add_option("--no-presubmit", "--nopresubmit",
146 help='Skip presubmit checks',
147 default=False, dest="no_presubmit", action="store_true")
148 result.add_option("--no-stress", "--nostress",
149 help="Don't run crankshaft --always-opt --stress-op test",
150 default=False, dest="no_stress", action="store_true")
151 result.add_option("--no-variants", "--novariants",
152 help="Don't run any testing variants",
153 default=False, dest="no_variants", action="store_true")
154 result.add_option("--variants",
155 help="Comma-separated list of testing variants")
156 result.add_option("--outdir", help="Base directory with compile output",
158 result.add_option("-p", "--progress",
159 help=("The style of progress indicator"
160 " (verbose, dots, color, mono)"),
161 choices=progress.PROGRESS_INDICATORS.keys(), default="mono")
162 result.add_option("--quickcheck", default=False, action="store_true",
163 help=("Quick check mode (skip slow/flaky tests)"))
164 result.add_option("--report", help="Print a summary of the tests to be run",
165 default=False, action="store_true")
166 result.add_option("--shard-count",
167 help="Split testsuites into this number of shards",
168 default=1, type="int")
169 result.add_option("--shard-run",
170 help="Run this shard from the split up tests.",
171 default=1, type="int")
172 result.add_option("--shell", help="DEPRECATED! use --shell-dir", default="")
173 result.add_option("--shell-dir", help="Directory containing executables",
175 result.add_option("--stress-only",
176 help="Only run tests with --always-opt --stress-opt",
177 default=False, action="store_true")
178 result.add_option("--time", help="Print timing information after running",
179 default=False, action="store_true")
180 result.add_option("-t", "--timeout", help="Timeout in seconds",
181 default= -1, type="int")
182 result.add_option("-v", "--verbose", help="Verbose output",
183 default=False, action="store_true")
184 result.add_option("--valgrind", help="Run tests through valgrind",
185 default=False, action="store_true")
186 result.add_option("--warn-unused", help="Report unused rules",
187 default=False, action="store_true")
188 result.add_option("--junitout", help="File name of the JUnit output")
189 result.add_option("--junittestsuite",
190 help="The testsuite name in the JUnit output file",
195 def ProcessOptions(options):
199 # Architecture and mode related stuff.
200 if options.arch_and_mode:
201 options.arch_and_mode = [arch_and_mode.split(".")
202 for arch_and_mode in options.arch_and_mode.split(",")]
203 options.arch = ",".join([tokens[0] for tokens in options.arch_and_mode])
204 options.mode = ",".join([tokens[1] for tokens in options.arch_and_mode])
205 options.mode = options.mode.split(",")
206 for mode in options.mode:
207 if not mode.lower() in ["debug", "release", "optdebug"]:
208 print "Unknown mode %s" % mode
210 if options.arch in ["auto", "native"]:
211 options.arch = ARCH_GUESS
212 options.arch = options.arch.split(",")
213 for arch in options.arch:
214 if not arch in SUPPORTED_ARCHS:
215 print "Unknown architecture %s" % arch
218 # Store the final configuration in arch_and_mode list. Don't overwrite
219 # predefined arch_and_mode since it is more expressive than arch and mode.
220 if not options.arch_and_mode:
221 options.arch_and_mode = itertools.product(options.arch, options.mode)
223 # Special processing of other options, sorted alphabetically.
226 # Buildbots run presubmit tests as a separate step.
227 options.no_presubmit = True
228 options.no_network = True
229 if options.command_prefix:
230 print("Specifying --command-prefix disables network distribution, "
231 "running tests locally.")
232 options.no_network = True
233 options.command_prefix = shlex.split(options.command_prefix)
234 options.extra_flags = shlex.split(options.extra_flags)
236 if options.gc_stress:
237 options.extra_flags += GC_STRESS_FLAGS
240 options.j = multiprocessing.cpu_count()
243 """Returns true if zero or one of multiple arguments are true."""
244 return reduce(lambda x, y: x + y, args) <= 1
246 if not excl(options.no_stress, options.stress_only, options.no_variants,
247 bool(options.variants), options.quickcheck):
248 print("Use only one of --no-stress, --stress-only, --no-variants, "
249 "--variants, or --quickcheck.")
251 if options.no_stress:
252 VARIANTS = ["default", "nocrankshaft"]
253 if options.no_variants:
254 VARIANTS = ["default"]
255 if options.stress_only:
256 VARIANTS = ["stress"]
258 VARIANTS = options.variants.split(",")
259 if not set(VARIANTS).issubset(VARIANT_FLAGS.keys()):
260 print "All variants must be in %s" % str(VARIANT_FLAGS.keys())
262 if options.quickcheck:
263 VARIANTS = ["default", "stress"]
264 options.flaky_tests = "skip"
265 options.slow_tests = "skip"
266 options.pass_fail_tests = "skip"
268 if not options.shell_dir:
270 print "Warning: --shell is deprecated, use --shell-dir instead."
271 options.shell_dir = os.path.dirname(options.shell)
273 run_valgrind = os.path.join("tools", "run-valgrind.py")
274 # This is OK for distributed running, so we don't need to set no_network.
275 options.command_prefix = (["python", "-u", run_valgrind] +
276 options.command_prefix)
277 def CheckTestMode(name, option):
278 if not option in ["run", "skip", "dontcare"]:
279 print "Unknown %s mode %s" % (name, option)
282 if not CheckTestMode("flaky test", options.flaky_tests):
284 if not CheckTestMode("slow test", options.slow_tests):
286 if not CheckTestMode("pass|fail test", options.pass_fail_tests):
288 if not options.no_i18n:
289 DEFAULT_TESTS.append("intl")
293 def ShardTests(tests, shard_count, shard_run):
296 if shard_run < 1 or shard_run > shard_count:
297 print "shard-run not a valid number, should be in [1:shard-count]"
298 print "defaulting back to running all tests"
303 if count % shard_count == shard_run - 1:
310 parser = BuildOptions()
311 (options, args) = parser.parse_args()
312 if not ProcessOptions(options):
317 workspace = os.path.abspath(join(os.path.dirname(sys.argv[0]), ".."))
318 if not options.no_presubmit:
319 print ">>> running presubmit tests"
320 code = subprocess.call(
321 [sys.executable, join(workspace, "tools", "presubmit.py")])
324 suite_paths = utils.GetSuitePaths(join(workspace, "test"))
327 suite_paths = [ s for s in DEFAULT_TESTS if s in suite_paths ]
331 suite = arg.split(os.path.sep)[0]
332 if not suite in args_suites:
333 args_suites.add(suite)
334 suite_paths = [ s for s in args_suites if s in suite_paths ]
337 for root in suite_paths:
338 suite = testsuite.TestSuite.LoadTestSuite(
339 os.path.join(workspace, "test", root))
343 if options.download_data:
347 for (arch, mode) in options.arch_and_mode:
349 code = Execute(arch, mode, args, options, suites, workspace)
350 except KeyboardInterrupt:
352 exit_code = exit_code or code
356 def Execute(arch, mode, args, options, suites, workspace):
357 print(">>> Running tests for %s.%s" % (arch, mode))
359 shell_dir = options.shell_dir
362 shell_dir = os.path.join(workspace, options.outdir, mode)
365 shell_dir = os.path.join(workspace, options.outdir,
366 "%s.%s" % (arch, mode))
367 shell_dir = os.path.relpath(shell_dir)
369 if mode == "optdebug":
370 mode = "debug" # "optdebug" is just an alias.
372 # Populate context object.
373 mode_flags = MODE_FLAGS[mode]
374 timeout = options.timeout
376 # Simulators are slow, therefore allow a longer default timeout.
377 if arch in SLOW_ARCHS:
378 timeout = 2 * TIMEOUT_DEFAULT;
380 timeout = TIMEOUT_DEFAULT;
382 timeout *= TIMEOUT_SCALEFACTOR[mode]
383 ctx = context.Context(arch, mode, shell_dir,
384 mode_flags, options.verbose,
385 timeout, options.isolates,
386 options.command_prefix,
390 # Find available test suites and read test cases from them.
393 "asan": options.asan,
394 "deopt_fuzzer": False,
395 "gc_stress": options.gc_stress,
396 "isolates": options.isolates,
398 "no_i18n": options.no_i18n,
399 "simulator": utils.UseSimulator(arch),
400 "system": utils.GuessOS(),
406 s.ReadStatusFile(variables)
409 s.FilterTestCasesByArgs(args)
411 s.FilterTestCasesByStatus(options.warn_unused, options.flaky_tests,
412 options.slow_tests, options.pass_fail_tests)
414 verbose.PrintTestSource(s.tests)
416 variant_flags = [VARIANT_FLAGS[var] for var in VARIANTS]
417 s.tests = [ t.CopyAddingFlags(v)
419 for v in s.VariantFlags(t, variant_flags) ]
420 s.tests = ShardTests(s.tests, options.shard_count, options.shard_run)
421 num_tests += len(s.tests)
427 return 0 # We're done here.
430 verbose.PrintReport(all_tests)
433 print "No tests to run."
436 # Run the tests, either locally or distributed on the network.
438 start_time = time.time()
439 progress_indicator = progress.PROGRESS_INDICATORS[options.progress]()
441 progress_indicator = progress.JUnitTestProgressIndicator(
442 progress_indicator, options.junitout, options.junittestsuite)
444 run_networked = not options.no_network
445 if not run_networked:
446 print("Network distribution disabled, running tests locally.")
447 elif utils.GuessOS() != "linux":
448 print("Network distribution is only supported on Linux, sorry!")
449 run_networked = False
452 peers = network_execution.GetPeers()
454 print("No connection to distribution server; running tests locally.")
455 run_networked = False
456 elif len(peers) == 1:
457 print("No other peers on the network; running tests locally.")
458 run_networked = False
459 elif num_tests <= 100:
460 print("Less than 100 tests, running them locally.")
461 run_networked = False
464 runner = network_execution.NetworkedRunner(suites, progress_indicator,
465 ctx, peers, workspace)
467 runner = execution.Runner(suites, progress_indicator, ctx)
469 exit_code = runner.Run(options.j)
472 overall_duration = time.time() - start_time
473 except KeyboardInterrupt:
477 verbose.PrintTestDurations(suites, overall_duration)
481 if __name__ == "__main__":