1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import unittest
6
7from telemetry.core import util
8from telemetry.unittest import options_for_unittests
9
10
11class ProgressReporter(object):
12  def __init__(self, output_stream):
13    self._output_stream = output_stream
14
15  def StartTest(self, test):
16    pass
17
18  def StartTestSuite(self, suite):
19    pass
20
21  def StartTestRun(self):
22    pass
23
24  def StopTest(self, test):
25    pass
26
27  def StopTestSuite(self, suite):
28    pass
29
30  def StopTestRun(self, result):
31    pass
32
33  def Error(self, test, err):
34    pass
35
36  def Failure(self, test, err):
37    pass
38
39  def Success(self, test):
40    pass
41
42  def Skip(self, test, reason):
43    pass
44
45
46class TestSuite(unittest.TestSuite):
47  """TestSuite that can delegate start and stop calls to a TestResult object."""
48  def run(self, result):  # pylint: disable=W0221
49    if hasattr(result, 'startTestSuite'):
50      result.startTestSuite(self)
51    result = super(TestSuite, self).run(result)
52    if hasattr(result, 'stopTestSuite'):
53      result.stopTestSuite(self)
54    return result
55
56
57class TestRunner(object):
58  def run(self, test, progress_reporters, repeat_count, args):
59    util.AddDirToPythonPath(util.GetUnittestDataDir())
60    result = TestResult(progress_reporters)
61    result.startTestRun()
62    try:
63      options_for_unittests.Push(args)
64      for _ in xrange(repeat_count):
65        test(result)
66    finally:
67      options_for_unittests.Pop()
68      result.stopTestRun()
69
70    return result
71
72
73class TestResult(unittest.TestResult):
74  def __init__(self, progress_reporters):
75    super(TestResult, self).__init__()
76    self.successes = []
77    self._progress_reporters = progress_reporters
78
79  @property
80  def failures_and_errors(self):
81    return self.failures + self.errors
82
83  def startTest(self, test):
84    super(TestResult, self).startTest(test)
85    for progress_reporter in self._progress_reporters:
86      progress_reporter.StartTest(test)
87
88  def startTestSuite(self, suite):
89    for progress_reporter in self._progress_reporters:
90      progress_reporter.StartTestSuite(suite)
91
92  def startTestRun(self):
93    super(TestResult, self).startTestRun()
94    for progress_reporter in self._progress_reporters:
95      progress_reporter.StartTestRun()
96
97  def stopTest(self, test):
98    super(TestResult, self).stopTest(test)
99    for progress_reporter in self._progress_reporters:
100      progress_reporter.StopTest(test)
101
102  def stopTestSuite(self, suite):
103    for progress_reporter in self._progress_reporters:
104      progress_reporter.StopTestSuite(suite)
105
106  def stopTestRun(self):
107    super(TestResult, self).stopTestRun()
108    for progress_reporter in self._progress_reporters:
109      progress_reporter.StopTestRun(self)
110
111  def addError(self, test, err):
112    super(TestResult, self).addError(test, err)
113    for progress_reporter in self._progress_reporters:
114      progress_reporter.Error(test, err)
115
116  def addFailure(self, test, err):
117    super(TestResult, self).addFailure(test, err)
118    for progress_reporter in self._progress_reporters:
119      progress_reporter.Failure(test, err)
120
121  def addSuccess(self, test):
122    super(TestResult, self).addSuccess(test)
123    self.successes.append(test)
124    for progress_reporter in self._progress_reporters:
125      progress_reporter.Success(test)
126
127  def addSkip(self, test, reason):
128    super(TestResult, self).addSkip(test, reason)
129    for progress_reporter in self._progress_reporters:
130      progress_reporter.Skip(test, reason)
131