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