xref: /aosp_15_r20/external/autotest/tko/parsers/test/unittest_hotfix.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Lint as: python2, python3
2"""Monkey patch lame-o vanilla unittest with test skip feature.
3
4From the patch that was never applied (shameful!):
5http://bugs.python.org/issue1034053
6"""
7
8from __future__ import absolute_import
9from __future__ import division
10from __future__ import print_function
11import time, unittest
12from six.moves import map
13
14
15class SkipException(Exception):
16    pass
17
18
19def TestResult__init__(self):
20    self.failures = []
21    self.errors = []
22    self.skipped = []
23    self.testsRun = 0
24    self.shouldStop = 0
25
26unittest.TestResult.__init__ = TestResult__init__
27
28
29def TestResult_addSkipped(self, test, err):
30    """Called when a test is skipped.
31
32    'err' is a tuple of values as returned by sys.exc_info().
33    """
34    self.skipped.append((test, str(err[1])))
35
36unittest.TestResult.addSkipped = TestResult_addSkipped
37
38
39def TestResult__repr__(self):
40    return "<%s run=%i errors=%i failures=%i skipped=%i>" % (
41        unittest._strclass(self.__class__), self.testsRun,
42        len(self.errors), len(self.failures), len(self.skipped))
43
44unittest.TestResult.__repr__ = TestResult__repr__
45
46
47class TestCase(unittest.TestCase):
48    # Yuck, all of run has to be copied for this.
49    # I don't care about wrapping setUp atm.
50    def run(self, result=None):
51        if result is None: result = self.defaultTestResult()
52        result.startTest(self)
53        # Support variable naming differences between 2.4 and 2.6
54        # Yay for silly variable hiding
55        try:
56            testMethodName = self.__testMethodName
57            exc_info = self.__exc_info
58        except AttributeError:
59            testMethodName = self._testMethodName
60            exc_info = self._exc_info
61
62        testMethod = getattr(self, testMethodName)
63
64        try:
65            try:
66                self.setUp()
67            except KeyboardInterrupt:
68                raise
69            except:
70                result.addError(self, exc_info())
71                return
72
73            ok = False
74            try:
75                testMethod()
76                ok = True
77            except self.failureException:
78                result.addFailure(self, exc_info())
79            except SkipException:
80                result.addSkipped(self, exc_info())
81            except KeyboardInterrupt:
82                raise
83            except:
84                result.addError(self, exc_info())
85
86            try:
87                self.tearDown()
88            except KeyboardInterrupt:
89                raise
90            except:
91                result.addError(self, exc_info())
92                ok = False
93            if ok: result.addSuccess(self)
94        finally:
95            result.stopTest(self)
96
97
98    def skip(self, msg=None):
99        """Skip the test, with the given message."""
100        raise SkipException(msg)
101
102
103    def skipIf(self, expr, msg=None):
104        """Skip the test if the expression is true."""
105        if expr:
106            raise SkipException(msg)
107
108
109def _TextTestResult_addSkipped(self, test, err):
110    unittest.TestResult.addSkipped(self, test, err)
111    if self.showAll:
112        msg = str(err[1])
113        if msg:
114            msg = " (" + msg + ")"
115        self.stream.writeln("SKIPPED" + msg)
116    elif self.dots:
117        self.stream.write('S')
118
119unittest._TextTestResult.addSkipped = _TextTestResult_addSkipped
120
121
122# Bah
123def TextTestRunner_run(self, test):
124    "Run the given test case or test suite."
125    result = self._makeResult()
126    startTime = time.time()
127    test(result)
128    stopTime = time.time()
129    timeTaken = stopTime - startTime
130    result.printErrors()
131    self.stream.writeln(result.separator2)
132    run = result.testsRun
133    self.stream.writeln("Ran %d test%s in %.3fs" %
134                        (run, run != 1 and "s" or "", timeTaken))
135    self.stream.writeln()
136    if not result.wasSuccessful():
137        self.stream.write("FAILED (")
138        failed, errored, skipped = list(map(
139            len, (result.failures, result.errors, result.skipped)))
140        if failed:
141            self.stream.write("failures=%d" % failed)
142        if errored:
143            if failed: self.stream.write(", ")
144            self.stream.write("errors=%d" % errored)
145        if skipped:
146            self.stream.write(", skipped=%d" % skipped)
147        self.stream.writeln(")")
148    else:
149        if result.skipped:
150            self.stream.writeln(
151                "OK (skipped=%d)" % len(result.skipped))
152        else:
153            self.stream.writeln("OK")
154    return result
155
156unittest.TextTestRunner.run = TextTestRunner_run
157