| Index: tools/testrunner/local/execution.py
|
| diff --git a/tools/testrunner/local/execution.py b/tools/testrunner/local/execution.py
|
| index 43d11ebe8aad687f50cee76e5f2c3db4036ebefc..d2d086c111e3c086054d7a31f97ce97a980bdd32 100644
|
| --- a/tools/testrunner/local/execution.py
|
| +++ b/tools/testrunner/local/execution.py
|
| @@ -126,6 +126,63 @@ class Runner(object):
|
| pool.add([self._GetJob(test)])
|
| self.remaining += 1
|
|
|
| + def _ProcessTestNormal(self, test, result, pool):
|
| + self.indicator.AboutToRun(test)
|
| + test.output = result[1]
|
| + test.duration = result[2]
|
| + has_unexpected_output = test.suite.HasUnexpectedOutput(test)
|
| + if has_unexpected_output:
|
| + self.failed.append(test)
|
| + if test.output.HasCrashed():
|
| + self.crashed += 1
|
| + else:
|
| + 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)
|
| + # Update the perf database if the test succeeded.
|
| + return not has_unexpected_output
|
| +
|
| + def _ProcessTestPredictable(self, test, result, pool):
|
| + # Always pass the test duration for the database update.
|
| + test.duration = result[2]
|
| + if test.run == 1 and result[1].HasTimedOut():
|
| + # If we get a timeout in the first run, we are already in an
|
| + # unpredictable state. Just report it as a failure and don't rerun.
|
| + self.indicator.AboutToRun(test)
|
| + test.output = result[1]
|
| + self.remaining -= 1
|
| + self.failed.append(test)
|
| + self.indicator.HasRun(test, True)
|
| + if test.run > 1 and test.output != result[1]:
|
| + # From the second run on, check for differences. If a difference is
|
| + # found, call the indicator twice to report both tests. All runs of each
|
| + # test are counted as one for the statistic.
|
| + self.indicator.AboutToRun(test)
|
| + self.remaining -= 1
|
| + self.failed.append(test)
|
| + self.indicator.HasRun(test, True)
|
| + self.indicator.AboutToRun(test)
|
| + test.output = result[1]
|
| + self.indicator.HasRun(test, True)
|
| + elif test.run >= 3:
|
| + # No difference on the third run -> report a success.
|
| + self.indicator.AboutToRun(test)
|
| + self.remaining -= 1
|
| + self.succeeded += 1
|
| + test.output = result[1]
|
| + self.indicator.HasRun(test, False)
|
| + else:
|
| + # No difference yet and less than three runs -> add another run and
|
| + # remember the output for comparison.
|
| + test.run += 1
|
| + test.output = result[1]
|
| + pool.add([self._GetJob(test)])
|
| + # Always update the perf database.
|
| + return True
|
| +
|
| def Run(self, jobs):
|
| self.indicator.Starting()
|
| self._RunInternal(jobs)
|
| @@ -156,22 +213,12 @@ class Runner(object):
|
| it = pool.imap_unordered(RunTest, queue)
|
| for result in it:
|
| test = test_map[result[0]]
|
| - self.indicator.AboutToRun(test)
|
| - test.output = result[1]
|
| - test.duration = result[2]
|
| - has_unexpected_output = test.suite.HasUnexpectedOutput(test)
|
| - if has_unexpected_output:
|
| - self.failed.append(test)
|
| - if test.output.HasCrashed():
|
| - self.crashed += 1
|
| + if self.context.predictable:
|
| + update_perf = self._ProcessTestPredictable(test, result, pool)
|
| else:
|
| + update_perf = self._ProcessTestNormal(test, result, pool)
|
| + if update_perf:
|
| self._RunPerfSafe(lambda: self.perfdata.UpdatePerfData(test))
|
| - 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())
|
|
|