1*cda5da8dSAndroid Build Coastguard Worker"""TestSuite""" 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard Workerimport sys 4*cda5da8dSAndroid Build Coastguard Worker 5*cda5da8dSAndroid Build Coastguard Workerfrom . import case 6*cda5da8dSAndroid Build Coastguard Workerfrom . import util 7*cda5da8dSAndroid Build Coastguard Worker 8*cda5da8dSAndroid Build Coastguard Worker__unittest = True 9*cda5da8dSAndroid Build Coastguard Worker 10*cda5da8dSAndroid Build Coastguard Worker 11*cda5da8dSAndroid Build Coastguard Workerdef _call_if_exists(parent, attr): 12*cda5da8dSAndroid Build Coastguard Worker func = getattr(parent, attr, lambda: None) 13*cda5da8dSAndroid Build Coastguard Worker func() 14*cda5da8dSAndroid Build Coastguard Worker 15*cda5da8dSAndroid Build Coastguard Worker 16*cda5da8dSAndroid Build Coastguard Workerclass BaseTestSuite(object): 17*cda5da8dSAndroid Build Coastguard Worker """A simple test suite that doesn't provide class or module shared fixtures. 18*cda5da8dSAndroid Build Coastguard Worker """ 19*cda5da8dSAndroid Build Coastguard Worker _cleanup = True 20*cda5da8dSAndroid Build Coastguard Worker 21*cda5da8dSAndroid Build Coastguard Worker def __init__(self, tests=()): 22*cda5da8dSAndroid Build Coastguard Worker self._tests = [] 23*cda5da8dSAndroid Build Coastguard Worker self._removed_tests = 0 24*cda5da8dSAndroid Build Coastguard Worker self.addTests(tests) 25*cda5da8dSAndroid Build Coastguard Worker 26*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 27*cda5da8dSAndroid Build Coastguard Worker return "<%s tests=%s>" % (util.strclass(self.__class__), list(self)) 28*cda5da8dSAndroid Build Coastguard Worker 29*cda5da8dSAndroid Build Coastguard Worker def __eq__(self, other): 30*cda5da8dSAndroid Build Coastguard Worker if not isinstance(other, self.__class__): 31*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 32*cda5da8dSAndroid Build Coastguard Worker return list(self) == list(other) 33*cda5da8dSAndroid Build Coastguard Worker 34*cda5da8dSAndroid Build Coastguard Worker def __iter__(self): 35*cda5da8dSAndroid Build Coastguard Worker return iter(self._tests) 36*cda5da8dSAndroid Build Coastguard Worker 37*cda5da8dSAndroid Build Coastguard Worker def countTestCases(self): 38*cda5da8dSAndroid Build Coastguard Worker cases = self._removed_tests 39*cda5da8dSAndroid Build Coastguard Worker for test in self: 40*cda5da8dSAndroid Build Coastguard Worker if test: 41*cda5da8dSAndroid Build Coastguard Worker cases += test.countTestCases() 42*cda5da8dSAndroid Build Coastguard Worker return cases 43*cda5da8dSAndroid Build Coastguard Worker 44*cda5da8dSAndroid Build Coastguard Worker def addTest(self, test): 45*cda5da8dSAndroid Build Coastguard Worker # sanity checks 46*cda5da8dSAndroid Build Coastguard Worker if not callable(test): 47*cda5da8dSAndroid Build Coastguard Worker raise TypeError("{} is not callable".format(repr(test))) 48*cda5da8dSAndroid Build Coastguard Worker if isinstance(test, type) and issubclass(test, 49*cda5da8dSAndroid Build Coastguard Worker (case.TestCase, TestSuite)): 50*cda5da8dSAndroid Build Coastguard Worker raise TypeError("TestCases and TestSuites must be instantiated " 51*cda5da8dSAndroid Build Coastguard Worker "before passing them to addTest()") 52*cda5da8dSAndroid Build Coastguard Worker self._tests.append(test) 53*cda5da8dSAndroid Build Coastguard Worker 54*cda5da8dSAndroid Build Coastguard Worker def addTests(self, tests): 55*cda5da8dSAndroid Build Coastguard Worker if isinstance(tests, str): 56*cda5da8dSAndroid Build Coastguard Worker raise TypeError("tests must be an iterable of tests, not a string") 57*cda5da8dSAndroid Build Coastguard Worker for test in tests: 58*cda5da8dSAndroid Build Coastguard Worker self.addTest(test) 59*cda5da8dSAndroid Build Coastguard Worker 60*cda5da8dSAndroid Build Coastguard Worker def run(self, result): 61*cda5da8dSAndroid Build Coastguard Worker for index, test in enumerate(self): 62*cda5da8dSAndroid Build Coastguard Worker if result.shouldStop: 63*cda5da8dSAndroid Build Coastguard Worker break 64*cda5da8dSAndroid Build Coastguard Worker test(result) 65*cda5da8dSAndroid Build Coastguard Worker if self._cleanup: 66*cda5da8dSAndroid Build Coastguard Worker self._removeTestAtIndex(index) 67*cda5da8dSAndroid Build Coastguard Worker return result 68*cda5da8dSAndroid Build Coastguard Worker 69*cda5da8dSAndroid Build Coastguard Worker def _removeTestAtIndex(self, index): 70*cda5da8dSAndroid Build Coastguard Worker """Stop holding a reference to the TestCase at index.""" 71*cda5da8dSAndroid Build Coastguard Worker try: 72*cda5da8dSAndroid Build Coastguard Worker test = self._tests[index] 73*cda5da8dSAndroid Build Coastguard Worker except TypeError: 74*cda5da8dSAndroid Build Coastguard Worker # support for suite implementations that have overridden self._tests 75*cda5da8dSAndroid Build Coastguard Worker pass 76*cda5da8dSAndroid Build Coastguard Worker else: 77*cda5da8dSAndroid Build Coastguard Worker # Some unittest tests add non TestCase/TestSuite objects to 78*cda5da8dSAndroid Build Coastguard Worker # the suite. 79*cda5da8dSAndroid Build Coastguard Worker if hasattr(test, 'countTestCases'): 80*cda5da8dSAndroid Build Coastguard Worker self._removed_tests += test.countTestCases() 81*cda5da8dSAndroid Build Coastguard Worker self._tests[index] = None 82*cda5da8dSAndroid Build Coastguard Worker 83*cda5da8dSAndroid Build Coastguard Worker def __call__(self, *args, **kwds): 84*cda5da8dSAndroid Build Coastguard Worker return self.run(*args, **kwds) 85*cda5da8dSAndroid Build Coastguard Worker 86*cda5da8dSAndroid Build Coastguard Worker def debug(self): 87*cda5da8dSAndroid Build Coastguard Worker """Run the tests without collecting errors in a TestResult""" 88*cda5da8dSAndroid Build Coastguard Worker for test in self: 89*cda5da8dSAndroid Build Coastguard Worker test.debug() 90*cda5da8dSAndroid Build Coastguard Worker 91*cda5da8dSAndroid Build Coastguard Worker 92*cda5da8dSAndroid Build Coastguard Workerclass TestSuite(BaseTestSuite): 93*cda5da8dSAndroid Build Coastguard Worker """A test suite is a composite test consisting of a number of TestCases. 94*cda5da8dSAndroid Build Coastguard Worker 95*cda5da8dSAndroid Build Coastguard Worker For use, create an instance of TestSuite, then add test case instances. 96*cda5da8dSAndroid Build Coastguard Worker When all tests have been added, the suite can be passed to a test 97*cda5da8dSAndroid Build Coastguard Worker runner, such as TextTestRunner. It will run the individual test cases 98*cda5da8dSAndroid Build Coastguard Worker in the order in which they were added, aggregating the results. When 99*cda5da8dSAndroid Build Coastguard Worker subclassing, do not forget to call the base class constructor. 100*cda5da8dSAndroid Build Coastguard Worker """ 101*cda5da8dSAndroid Build Coastguard Worker 102*cda5da8dSAndroid Build Coastguard Worker def run(self, result, debug=False): 103*cda5da8dSAndroid Build Coastguard Worker topLevel = False 104*cda5da8dSAndroid Build Coastguard Worker if getattr(result, '_testRunEntered', False) is False: 105*cda5da8dSAndroid Build Coastguard Worker result._testRunEntered = topLevel = True 106*cda5da8dSAndroid Build Coastguard Worker 107*cda5da8dSAndroid Build Coastguard Worker for index, test in enumerate(self): 108*cda5da8dSAndroid Build Coastguard Worker if result.shouldStop: 109*cda5da8dSAndroid Build Coastguard Worker break 110*cda5da8dSAndroid Build Coastguard Worker 111*cda5da8dSAndroid Build Coastguard Worker if _isnotsuite(test): 112*cda5da8dSAndroid Build Coastguard Worker self._tearDownPreviousClass(test, result) 113*cda5da8dSAndroid Build Coastguard Worker self._handleModuleFixture(test, result) 114*cda5da8dSAndroid Build Coastguard Worker self._handleClassSetUp(test, result) 115*cda5da8dSAndroid Build Coastguard Worker result._previousTestClass = test.__class__ 116*cda5da8dSAndroid Build Coastguard Worker 117*cda5da8dSAndroid Build Coastguard Worker if (getattr(test.__class__, '_classSetupFailed', False) or 118*cda5da8dSAndroid Build Coastguard Worker getattr(result, '_moduleSetUpFailed', False)): 119*cda5da8dSAndroid Build Coastguard Worker continue 120*cda5da8dSAndroid Build Coastguard Worker 121*cda5da8dSAndroid Build Coastguard Worker if not debug: 122*cda5da8dSAndroid Build Coastguard Worker test(result) 123*cda5da8dSAndroid Build Coastguard Worker else: 124*cda5da8dSAndroid Build Coastguard Worker test.debug() 125*cda5da8dSAndroid Build Coastguard Worker 126*cda5da8dSAndroid Build Coastguard Worker if self._cleanup: 127*cda5da8dSAndroid Build Coastguard Worker self._removeTestAtIndex(index) 128*cda5da8dSAndroid Build Coastguard Worker 129*cda5da8dSAndroid Build Coastguard Worker if topLevel: 130*cda5da8dSAndroid Build Coastguard Worker self._tearDownPreviousClass(None, result) 131*cda5da8dSAndroid Build Coastguard Worker self._handleModuleTearDown(result) 132*cda5da8dSAndroid Build Coastguard Worker result._testRunEntered = False 133*cda5da8dSAndroid Build Coastguard Worker return result 134*cda5da8dSAndroid Build Coastguard Worker 135*cda5da8dSAndroid Build Coastguard Worker def debug(self): 136*cda5da8dSAndroid Build Coastguard Worker """Run the tests without collecting errors in a TestResult""" 137*cda5da8dSAndroid Build Coastguard Worker debug = _DebugResult() 138*cda5da8dSAndroid Build Coastguard Worker self.run(debug, True) 139*cda5da8dSAndroid Build Coastguard Worker 140*cda5da8dSAndroid Build Coastguard Worker ################################ 141*cda5da8dSAndroid Build Coastguard Worker 142*cda5da8dSAndroid Build Coastguard Worker def _handleClassSetUp(self, test, result): 143*cda5da8dSAndroid Build Coastguard Worker previousClass = getattr(result, '_previousTestClass', None) 144*cda5da8dSAndroid Build Coastguard Worker currentClass = test.__class__ 145*cda5da8dSAndroid Build Coastguard Worker if currentClass == previousClass: 146*cda5da8dSAndroid Build Coastguard Worker return 147*cda5da8dSAndroid Build Coastguard Worker if result._moduleSetUpFailed: 148*cda5da8dSAndroid Build Coastguard Worker return 149*cda5da8dSAndroid Build Coastguard Worker if getattr(currentClass, "__unittest_skip__", False): 150*cda5da8dSAndroid Build Coastguard Worker return 151*cda5da8dSAndroid Build Coastguard Worker 152*cda5da8dSAndroid Build Coastguard Worker failed = False 153*cda5da8dSAndroid Build Coastguard Worker try: 154*cda5da8dSAndroid Build Coastguard Worker currentClass._classSetupFailed = False 155*cda5da8dSAndroid Build Coastguard Worker except TypeError: 156*cda5da8dSAndroid Build Coastguard Worker # test may actually be a function 157*cda5da8dSAndroid Build Coastguard Worker # so its class will be a builtin-type 158*cda5da8dSAndroid Build Coastguard Worker pass 159*cda5da8dSAndroid Build Coastguard Worker 160*cda5da8dSAndroid Build Coastguard Worker setUpClass = getattr(currentClass, 'setUpClass', None) 161*cda5da8dSAndroid Build Coastguard Worker doClassCleanups = getattr(currentClass, 'doClassCleanups', None) 162*cda5da8dSAndroid Build Coastguard Worker if setUpClass is not None: 163*cda5da8dSAndroid Build Coastguard Worker _call_if_exists(result, '_setupStdout') 164*cda5da8dSAndroid Build Coastguard Worker try: 165*cda5da8dSAndroid Build Coastguard Worker try: 166*cda5da8dSAndroid Build Coastguard Worker setUpClass() 167*cda5da8dSAndroid Build Coastguard Worker except Exception as e: 168*cda5da8dSAndroid Build Coastguard Worker if isinstance(result, _DebugResult): 169*cda5da8dSAndroid Build Coastguard Worker raise 170*cda5da8dSAndroid Build Coastguard Worker failed = True 171*cda5da8dSAndroid Build Coastguard Worker try: 172*cda5da8dSAndroid Build Coastguard Worker currentClass._classSetupFailed = True 173*cda5da8dSAndroid Build Coastguard Worker except TypeError: 174*cda5da8dSAndroid Build Coastguard Worker pass 175*cda5da8dSAndroid Build Coastguard Worker className = util.strclass(currentClass) 176*cda5da8dSAndroid Build Coastguard Worker self._createClassOrModuleLevelException(result, e, 177*cda5da8dSAndroid Build Coastguard Worker 'setUpClass', 178*cda5da8dSAndroid Build Coastguard Worker className) 179*cda5da8dSAndroid Build Coastguard Worker if failed and doClassCleanups is not None: 180*cda5da8dSAndroid Build Coastguard Worker doClassCleanups() 181*cda5da8dSAndroid Build Coastguard Worker for exc_info in currentClass.tearDown_exceptions: 182*cda5da8dSAndroid Build Coastguard Worker self._createClassOrModuleLevelException( 183*cda5da8dSAndroid Build Coastguard Worker result, exc_info[1], 'setUpClass', className, 184*cda5da8dSAndroid Build Coastguard Worker info=exc_info) 185*cda5da8dSAndroid Build Coastguard Worker finally: 186*cda5da8dSAndroid Build Coastguard Worker _call_if_exists(result, '_restoreStdout') 187*cda5da8dSAndroid Build Coastguard Worker 188*cda5da8dSAndroid Build Coastguard Worker def _get_previous_module(self, result): 189*cda5da8dSAndroid Build Coastguard Worker previousModule = None 190*cda5da8dSAndroid Build Coastguard Worker previousClass = getattr(result, '_previousTestClass', None) 191*cda5da8dSAndroid Build Coastguard Worker if previousClass is not None: 192*cda5da8dSAndroid Build Coastguard Worker previousModule = previousClass.__module__ 193*cda5da8dSAndroid Build Coastguard Worker return previousModule 194*cda5da8dSAndroid Build Coastguard Worker 195*cda5da8dSAndroid Build Coastguard Worker 196*cda5da8dSAndroid Build Coastguard Worker def _handleModuleFixture(self, test, result): 197*cda5da8dSAndroid Build Coastguard Worker previousModule = self._get_previous_module(result) 198*cda5da8dSAndroid Build Coastguard Worker currentModule = test.__class__.__module__ 199*cda5da8dSAndroid Build Coastguard Worker if currentModule == previousModule: 200*cda5da8dSAndroid Build Coastguard Worker return 201*cda5da8dSAndroid Build Coastguard Worker 202*cda5da8dSAndroid Build Coastguard Worker self._handleModuleTearDown(result) 203*cda5da8dSAndroid Build Coastguard Worker 204*cda5da8dSAndroid Build Coastguard Worker 205*cda5da8dSAndroid Build Coastguard Worker result._moduleSetUpFailed = False 206*cda5da8dSAndroid Build Coastguard Worker try: 207*cda5da8dSAndroid Build Coastguard Worker module = sys.modules[currentModule] 208*cda5da8dSAndroid Build Coastguard Worker except KeyError: 209*cda5da8dSAndroid Build Coastguard Worker return 210*cda5da8dSAndroid Build Coastguard Worker setUpModule = getattr(module, 'setUpModule', None) 211*cda5da8dSAndroid Build Coastguard Worker if setUpModule is not None: 212*cda5da8dSAndroid Build Coastguard Worker _call_if_exists(result, '_setupStdout') 213*cda5da8dSAndroid Build Coastguard Worker try: 214*cda5da8dSAndroid Build Coastguard Worker try: 215*cda5da8dSAndroid Build Coastguard Worker setUpModule() 216*cda5da8dSAndroid Build Coastguard Worker except Exception as e: 217*cda5da8dSAndroid Build Coastguard Worker if isinstance(result, _DebugResult): 218*cda5da8dSAndroid Build Coastguard Worker raise 219*cda5da8dSAndroid Build Coastguard Worker result._moduleSetUpFailed = True 220*cda5da8dSAndroid Build Coastguard Worker self._createClassOrModuleLevelException(result, e, 221*cda5da8dSAndroid Build Coastguard Worker 'setUpModule', 222*cda5da8dSAndroid Build Coastguard Worker currentModule) 223*cda5da8dSAndroid Build Coastguard Worker if result._moduleSetUpFailed: 224*cda5da8dSAndroid Build Coastguard Worker try: 225*cda5da8dSAndroid Build Coastguard Worker case.doModuleCleanups() 226*cda5da8dSAndroid Build Coastguard Worker except Exception as e: 227*cda5da8dSAndroid Build Coastguard Worker self._createClassOrModuleLevelException(result, e, 228*cda5da8dSAndroid Build Coastguard Worker 'setUpModule', 229*cda5da8dSAndroid Build Coastguard Worker currentModule) 230*cda5da8dSAndroid Build Coastguard Worker finally: 231*cda5da8dSAndroid Build Coastguard Worker _call_if_exists(result, '_restoreStdout') 232*cda5da8dSAndroid Build Coastguard Worker 233*cda5da8dSAndroid Build Coastguard Worker def _createClassOrModuleLevelException(self, result, exc, method_name, 234*cda5da8dSAndroid Build Coastguard Worker parent, info=None): 235*cda5da8dSAndroid Build Coastguard Worker errorName = f'{method_name} ({parent})' 236*cda5da8dSAndroid Build Coastguard Worker self._addClassOrModuleLevelException(result, exc, errorName, info) 237*cda5da8dSAndroid Build Coastguard Worker 238*cda5da8dSAndroid Build Coastguard Worker def _addClassOrModuleLevelException(self, result, exception, errorName, 239*cda5da8dSAndroid Build Coastguard Worker info=None): 240*cda5da8dSAndroid Build Coastguard Worker error = _ErrorHolder(errorName) 241*cda5da8dSAndroid Build Coastguard Worker addSkip = getattr(result, 'addSkip', None) 242*cda5da8dSAndroid Build Coastguard Worker if addSkip is not None and isinstance(exception, case.SkipTest): 243*cda5da8dSAndroid Build Coastguard Worker addSkip(error, str(exception)) 244*cda5da8dSAndroid Build Coastguard Worker else: 245*cda5da8dSAndroid Build Coastguard Worker if not info: 246*cda5da8dSAndroid Build Coastguard Worker result.addError(error, sys.exc_info()) 247*cda5da8dSAndroid Build Coastguard Worker else: 248*cda5da8dSAndroid Build Coastguard Worker result.addError(error, info) 249*cda5da8dSAndroid Build Coastguard Worker 250*cda5da8dSAndroid Build Coastguard Worker def _handleModuleTearDown(self, result): 251*cda5da8dSAndroid Build Coastguard Worker previousModule = self._get_previous_module(result) 252*cda5da8dSAndroid Build Coastguard Worker if previousModule is None: 253*cda5da8dSAndroid Build Coastguard Worker return 254*cda5da8dSAndroid Build Coastguard Worker if result._moduleSetUpFailed: 255*cda5da8dSAndroid Build Coastguard Worker return 256*cda5da8dSAndroid Build Coastguard Worker 257*cda5da8dSAndroid Build Coastguard Worker try: 258*cda5da8dSAndroid Build Coastguard Worker module = sys.modules[previousModule] 259*cda5da8dSAndroid Build Coastguard Worker except KeyError: 260*cda5da8dSAndroid Build Coastguard Worker return 261*cda5da8dSAndroid Build Coastguard Worker 262*cda5da8dSAndroid Build Coastguard Worker _call_if_exists(result, '_setupStdout') 263*cda5da8dSAndroid Build Coastguard Worker try: 264*cda5da8dSAndroid Build Coastguard Worker tearDownModule = getattr(module, 'tearDownModule', None) 265*cda5da8dSAndroid Build Coastguard Worker if tearDownModule is not None: 266*cda5da8dSAndroid Build Coastguard Worker try: 267*cda5da8dSAndroid Build Coastguard Worker tearDownModule() 268*cda5da8dSAndroid Build Coastguard Worker except Exception as e: 269*cda5da8dSAndroid Build Coastguard Worker if isinstance(result, _DebugResult): 270*cda5da8dSAndroid Build Coastguard Worker raise 271*cda5da8dSAndroid Build Coastguard Worker self._createClassOrModuleLevelException(result, e, 272*cda5da8dSAndroid Build Coastguard Worker 'tearDownModule', 273*cda5da8dSAndroid Build Coastguard Worker previousModule) 274*cda5da8dSAndroid Build Coastguard Worker try: 275*cda5da8dSAndroid Build Coastguard Worker case.doModuleCleanups() 276*cda5da8dSAndroid Build Coastguard Worker except Exception as e: 277*cda5da8dSAndroid Build Coastguard Worker if isinstance(result, _DebugResult): 278*cda5da8dSAndroid Build Coastguard Worker raise 279*cda5da8dSAndroid Build Coastguard Worker self._createClassOrModuleLevelException(result, e, 280*cda5da8dSAndroid Build Coastguard Worker 'tearDownModule', 281*cda5da8dSAndroid Build Coastguard Worker previousModule) 282*cda5da8dSAndroid Build Coastguard Worker finally: 283*cda5da8dSAndroid Build Coastguard Worker _call_if_exists(result, '_restoreStdout') 284*cda5da8dSAndroid Build Coastguard Worker 285*cda5da8dSAndroid Build Coastguard Worker def _tearDownPreviousClass(self, test, result): 286*cda5da8dSAndroid Build Coastguard Worker previousClass = getattr(result, '_previousTestClass', None) 287*cda5da8dSAndroid Build Coastguard Worker currentClass = test.__class__ 288*cda5da8dSAndroid Build Coastguard Worker if currentClass == previousClass or previousClass is None: 289*cda5da8dSAndroid Build Coastguard Worker return 290*cda5da8dSAndroid Build Coastguard Worker if getattr(previousClass, '_classSetupFailed', False): 291*cda5da8dSAndroid Build Coastguard Worker return 292*cda5da8dSAndroid Build Coastguard Worker if getattr(result, '_moduleSetUpFailed', False): 293*cda5da8dSAndroid Build Coastguard Worker return 294*cda5da8dSAndroid Build Coastguard Worker if getattr(previousClass, "__unittest_skip__", False): 295*cda5da8dSAndroid Build Coastguard Worker return 296*cda5da8dSAndroid Build Coastguard Worker 297*cda5da8dSAndroid Build Coastguard Worker tearDownClass = getattr(previousClass, 'tearDownClass', None) 298*cda5da8dSAndroid Build Coastguard Worker doClassCleanups = getattr(previousClass, 'doClassCleanups', None) 299*cda5da8dSAndroid Build Coastguard Worker if tearDownClass is None and doClassCleanups is None: 300*cda5da8dSAndroid Build Coastguard Worker return 301*cda5da8dSAndroid Build Coastguard Worker 302*cda5da8dSAndroid Build Coastguard Worker _call_if_exists(result, '_setupStdout') 303*cda5da8dSAndroid Build Coastguard Worker try: 304*cda5da8dSAndroid Build Coastguard Worker if tearDownClass is not None: 305*cda5da8dSAndroid Build Coastguard Worker try: 306*cda5da8dSAndroid Build Coastguard Worker tearDownClass() 307*cda5da8dSAndroid Build Coastguard Worker except Exception as e: 308*cda5da8dSAndroid Build Coastguard Worker if isinstance(result, _DebugResult): 309*cda5da8dSAndroid Build Coastguard Worker raise 310*cda5da8dSAndroid Build Coastguard Worker className = util.strclass(previousClass) 311*cda5da8dSAndroid Build Coastguard Worker self._createClassOrModuleLevelException(result, e, 312*cda5da8dSAndroid Build Coastguard Worker 'tearDownClass', 313*cda5da8dSAndroid Build Coastguard Worker className) 314*cda5da8dSAndroid Build Coastguard Worker if doClassCleanups is not None: 315*cda5da8dSAndroid Build Coastguard Worker doClassCleanups() 316*cda5da8dSAndroid Build Coastguard Worker for exc_info in previousClass.tearDown_exceptions: 317*cda5da8dSAndroid Build Coastguard Worker if isinstance(result, _DebugResult): 318*cda5da8dSAndroid Build Coastguard Worker raise exc_info[1] 319*cda5da8dSAndroid Build Coastguard Worker className = util.strclass(previousClass) 320*cda5da8dSAndroid Build Coastguard Worker self._createClassOrModuleLevelException(result, exc_info[1], 321*cda5da8dSAndroid Build Coastguard Worker 'tearDownClass', 322*cda5da8dSAndroid Build Coastguard Worker className, 323*cda5da8dSAndroid Build Coastguard Worker info=exc_info) 324*cda5da8dSAndroid Build Coastguard Worker finally: 325*cda5da8dSAndroid Build Coastguard Worker _call_if_exists(result, '_restoreStdout') 326*cda5da8dSAndroid Build Coastguard Worker 327*cda5da8dSAndroid Build Coastguard Worker 328*cda5da8dSAndroid Build Coastguard Workerclass _ErrorHolder(object): 329*cda5da8dSAndroid Build Coastguard Worker """ 330*cda5da8dSAndroid Build Coastguard Worker Placeholder for a TestCase inside a result. As far as a TestResult 331*cda5da8dSAndroid Build Coastguard Worker is concerned, this looks exactly like a unit test. Used to insert 332*cda5da8dSAndroid Build Coastguard Worker arbitrary errors into a test suite run. 333*cda5da8dSAndroid Build Coastguard Worker """ 334*cda5da8dSAndroid Build Coastguard Worker # Inspired by the ErrorHolder from Twisted: 335*cda5da8dSAndroid Build Coastguard Worker # http://twistedmatrix.com/trac/browser/trunk/twisted/trial/runner.py 336*cda5da8dSAndroid Build Coastguard Worker 337*cda5da8dSAndroid Build Coastguard Worker # attribute used by TestResult._exc_info_to_string 338*cda5da8dSAndroid Build Coastguard Worker failureException = None 339*cda5da8dSAndroid Build Coastguard Worker 340*cda5da8dSAndroid Build Coastguard Worker def __init__(self, description): 341*cda5da8dSAndroid Build Coastguard Worker self.description = description 342*cda5da8dSAndroid Build Coastguard Worker 343*cda5da8dSAndroid Build Coastguard Worker def id(self): 344*cda5da8dSAndroid Build Coastguard Worker return self.description 345*cda5da8dSAndroid Build Coastguard Worker 346*cda5da8dSAndroid Build Coastguard Worker def shortDescription(self): 347*cda5da8dSAndroid Build Coastguard Worker return None 348*cda5da8dSAndroid Build Coastguard Worker 349*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 350*cda5da8dSAndroid Build Coastguard Worker return "<ErrorHolder description=%r>" % (self.description,) 351*cda5da8dSAndroid Build Coastguard Worker 352*cda5da8dSAndroid Build Coastguard Worker def __str__(self): 353*cda5da8dSAndroid Build Coastguard Worker return self.id() 354*cda5da8dSAndroid Build Coastguard Worker 355*cda5da8dSAndroid Build Coastguard Worker def run(self, result): 356*cda5da8dSAndroid Build Coastguard Worker # could call result.addError(...) - but this test-like object 357*cda5da8dSAndroid Build Coastguard Worker # shouldn't be run anyway 358*cda5da8dSAndroid Build Coastguard Worker pass 359*cda5da8dSAndroid Build Coastguard Worker 360*cda5da8dSAndroid Build Coastguard Worker def __call__(self, result): 361*cda5da8dSAndroid Build Coastguard Worker return self.run(result) 362*cda5da8dSAndroid Build Coastguard Worker 363*cda5da8dSAndroid Build Coastguard Worker def countTestCases(self): 364*cda5da8dSAndroid Build Coastguard Worker return 0 365*cda5da8dSAndroid Build Coastguard Worker 366*cda5da8dSAndroid Build Coastguard Workerdef _isnotsuite(test): 367*cda5da8dSAndroid Build Coastguard Worker "A crude way to tell apart testcases and suites with duck-typing" 368*cda5da8dSAndroid Build Coastguard Worker try: 369*cda5da8dSAndroid Build Coastguard Worker iter(test) 370*cda5da8dSAndroid Build Coastguard Worker except TypeError: 371*cda5da8dSAndroid Build Coastguard Worker return True 372*cda5da8dSAndroid Build Coastguard Worker return False 373*cda5da8dSAndroid Build Coastguard Worker 374*cda5da8dSAndroid Build Coastguard Worker 375*cda5da8dSAndroid Build Coastguard Workerclass _DebugResult(object): 376*cda5da8dSAndroid Build Coastguard Worker "Used by the TestSuite to hold previous class when running in debug." 377*cda5da8dSAndroid Build Coastguard Worker _previousTestClass = None 378*cda5da8dSAndroid Build Coastguard Worker _moduleSetUpFailed = False 379*cda5da8dSAndroid Build Coastguard Worker shouldStop = False 380