| Index: tools/testrunner/local/execution.py
|
| diff --git a/tools/testrunner/local/execution.py b/tools/testrunner/local/execution.py
|
| index 79f856c7d7da21a4319edbd5424af557623336ec..939995cd8f112b917953d25ce4c7800b968e5150 100644
|
| --- a/tools/testrunner/local/execution.py
|
| +++ b/tools/testrunner/local/execution.py
|
| @@ -81,6 +81,7 @@ class Runner(object):
|
| self.remaining = num_tests
|
| self.failed = []
|
| self.crashed = 0
|
| + self.reran_tests = 0
|
|
|
| def _RunPerfSafe(self, fun):
|
| try:
|
| @@ -89,6 +90,42 @@ class Runner(object):
|
| print("PerfData exception: %s" % e)
|
| self.perf_failures = True
|
|
|
| + def _GetJob(self, test):
|
| + command = self.GetCommand(test)
|
| + timeout = self.context.timeout
|
| + if ("--stress-opt" in test.flags or
|
| + "--stress-opt" in self.context.mode_flags or
|
| + "--stress-opt" in self.context.extra_flags):
|
| + timeout *= 4
|
| + if test.dependency is not None:
|
| + dep_command = [ c.replace(test.path, test.dependency) for c in command ]
|
| + else:
|
| + dep_command = None
|
| + return Job(command, dep_command, test.id, timeout, self.context.verbose)
|
| +
|
| + def _MaybeRerun(self, pool, test):
|
| + if test.run <= self.context.rerun_failures_count:
|
| + # Possibly rerun this test if its run count is below the maximum per
|
| + # test.
|
| + if test.run == 1:
|
| + # Count the overall number of reran tests on the first rerun.
|
| + if self.reran_tests < self.context.rerun_failures_max:
|
| + self.reran_tests += 1
|
| + else:
|
| + # Don't rerun this if the overall number of rerun tests has been
|
| + # reached.
|
| + return
|
| + if test.run >= 2 and test.duration > self.context.timeout / 20:
|
| + # Rerun slow tests at most once.
|
| + return
|
| +
|
| + # Rerun this test.
|
| + test.duration = None
|
| + test.output = None
|
| + test.run += 1
|
| + pool.add([self._GetJob(test)])
|
| + self.remaining += 1
|
| +
|
| def Run(self, jobs):
|
| self.indicator.Starting()
|
| self._RunInternal(jobs)
|
| @@ -109,23 +146,12 @@ class Runner(object):
|
| assert test.id >= 0
|
| test_map[test.id] = test
|
| try:
|
| - command = self.GetCommand(test)
|
| + queue.append([self._GetJob(test)])
|
| except Exception, e:
|
| # If this failed, save the exception and re-raise it later (after
|
| # all other tests have had a chance to run).
|
| queued_exception = e
|
| continue
|
| - timeout = self.context.timeout
|
| - if ("--stress-opt" in test.flags or
|
| - "--stress-opt" in self.context.mode_flags or
|
| - "--stress-opt" in self.context.extra_flags):
|
| - timeout *= 4
|
| - if test.dependency is not None:
|
| - dep_command = [ c.replace(test.path, test.dependency) for c in command ]
|
| - else:
|
| - dep_command = None
|
| - job = Job(command, dep_command, test.id, timeout, self.context.verbose)
|
| - queue.append([job])
|
| try:
|
| it = pool.imap_unordered(RunTest, queue)
|
| for result in it:
|
| @@ -143,6 +169,9 @@ class Runner(object):
|
| self.succeeded += 1
|
| self.remaining -= 1
|
| self.indicator.HasRun(test, has_unexpected_output)
|
| + if has_unexpected_output:
|
| + # Rerun test failures after the indicator has processed the results.
|
| + self._MaybeRerun(pool, test)
|
| finally:
|
| pool.terminate()
|
| self._RunPerfSafe(lambda: self.perf_data_manager.close())
|
|
|