| Index: tools/run-tests.py
|
| diff --git a/tools/run-tests.py b/tools/run-tests.py
|
| index 5cf49049f48e2729985c9e03de8d1c98c1277d06..82b766bf4ab963d3986ff676cdc0aabe86fa6c29 100755
|
| --- a/tools/run-tests.py
|
| +++ b/tools/run-tests.py
|
| @@ -152,6 +152,8 @@ def BuildOptions():
|
| result.add_option("--no-presubmit", "--nopresubmit",
|
| help='Skip presubmit checks',
|
| default=False, dest="no_presubmit", action="store_true")
|
| + result.add_option("--no-repeat-failures", help="Don't rerun failed tests",
|
| + default=False, action="store_true")
|
| result.add_option("--no-snap", "--nosnap",
|
| help='Test a build compiled without snapshot.',
|
| default=False, dest="no_snap", action="store_true")
|
| @@ -372,6 +374,53 @@ def Main():
|
| return exit_code
|
|
|
|
|
| +def RunTests(suites, num_tests, ctx, options, workspace):
|
| + # Run the tests, either locally or distributed on the network.
|
| + try:
|
| + start_time = time.time()
|
| + progress_indicator = progress.PROGRESS_INDICATORS[options.progress]()
|
| + if options.junitout:
|
| + progress_indicator = progress.JUnitTestProgressIndicator(
|
| + progress_indicator, options.junitout, options.junittestsuite)
|
| +
|
| + run_networked = not options.no_network
|
| + if not run_networked:
|
| + print("Network distribution disabled, running tests locally.")
|
| + elif utils.GuessOS() != "linux":
|
| + print("Network distribution is only supported on Linux, sorry!")
|
| + run_networked = False
|
| + peers = []
|
| + if run_networked:
|
| + peers = network_execution.GetPeers()
|
| + if not peers:
|
| + print("No connection to distribution server; running tests locally.")
|
| + run_networked = False
|
| + elif len(peers) == 1:
|
| + print("No other peers on the network; running tests locally.")
|
| + run_networked = False
|
| + elif num_tests <= 100:
|
| + print("Less than 100 tests, running them locally.")
|
| + run_networked = False
|
| +
|
| + if run_networked:
|
| + runner = network_execution.NetworkedRunner(suites, progress_indicator,
|
| + ctx, peers, workspace)
|
| + else:
|
| + runner = execution.Runner(suites, progress_indicator, ctx)
|
| +
|
| + # TODO(machenbach): Maybe use single thread for reruns?
|
| + exit_code = runner.Run(options.j)
|
| + if runner.terminate:
|
| + return [], exit_code
|
| + overall_duration = time.time() - start_time
|
| + except KeyboardInterrupt:
|
| + raise
|
| +
|
| + if options.time:
|
| + verbose.PrintTestDurations(suites, overall_duration)
|
| + return runner.FailedTests(), exit_code
|
| +
|
| +
|
| def Execute(arch, mode, args, options, suites, workspace):
|
| print(">>> Running tests for %s.%s" % (arch, mode))
|
|
|
| @@ -458,48 +507,25 @@ def Execute(arch, mode, args, options, suites, workspace):
|
| print "No tests to run."
|
| return 0
|
|
|
| - # Run the tests, either locally or distributed on the network.
|
| - try:
|
| - start_time = time.time()
|
| - progress_indicator = progress.PROGRESS_INDICATORS[options.progress]()
|
| - if options.junitout:
|
| - progress_indicator = progress.JUnitTestProgressIndicator(
|
| - progress_indicator, options.junitout, options.junittestsuite)
|
| + failed_tests, exit_code = RunTests(
|
| + suites, num_tests, ctx, options, workspace)
|
| + if not failed_tests or options.no_repeat_failures:
|
| + return exit_code
|
|
|
| - run_networked = not options.no_network
|
| - if not run_networked:
|
| - print("Network distribution disabled, running tests locally.")
|
| - elif utils.GuessOS() != "linux":
|
| - print("Network distribution is only supported on Linux, sorry!")
|
| - run_networked = False
|
| - peers = []
|
| - if run_networked:
|
| - peers = network_execution.GetPeers()
|
| - if not peers:
|
| - print("No connection to distribution server; running tests locally.")
|
| - run_networked = False
|
| - elif len(peers) == 1:
|
| - print("No other peers on the network; running tests locally.")
|
| - run_networked = False
|
| - elif num_tests <= 100:
|
| - print("Less than 100 tests, running them locally.")
|
| - run_networked = False
|
| -
|
| - if run_networked:
|
| - runner = network_execution.NetworkedRunner(suites, progress_indicator,
|
| - ctx, peers, workspace)
|
| - else:
|
| - runner = execution.Runner(suites, progress_indicator, ctx)
|
| -
|
| - exit_code = runner.Run(options.j)
|
| - if runner.terminate:
|
| - return exit_code
|
| - overall_duration = time.time() - start_time
|
| - except KeyboardInterrupt:
|
| - raise
|
| + # TODO(machenbach): Additional features: Rerun count, max rerun test cases,
|
| + # rerun dependent on test timing (i.e. don't rerun very slow tests), group
|
| + # flakes, e.g. flaky crashes, flaky failures.
|
| + print(">>> Rerunning failures for %s.%s" % (arch, mode))
|
| + num_tests = 0
|
| + for s in suites:
|
| + s.tests = [t.Copy() for t in failed_tests if t in s.tests]
|
| + num_tests += len(s.tests)
|
|
|
| - if options.time:
|
| - verbose.PrintTestDurations(suites, overall_duration)
|
| + # TODO(machenbach): Use exit_code of final result as soon as flakes can be
|
| + # displayed as warnings. For now, the rerun is just FYI.
|
| + # TODO(machenbach): Never hide failures in gc-stress mode.
|
| + failed_tests, _ = RunTests(
|
| + suites, num_tests, ctx, options, workspace)
|
| return exit_code
|
|
|
|
|
|
|