175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen"""TestSuite"""
275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport sys
475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport unittest
575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenfrom unittest2 import case, util
675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen__unittest = True
875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
1075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass BaseTestSuite(unittest.TestSuite):
1175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """A simple test suite that doesn't provide class or module shared fixtures.
1275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
1375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __init__(self, tests=()):
1475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._tests = []
1575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addTests(tests)
1675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
1775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __repr__(self):
1875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return "<%s tests=%s>" % (util.strclass(self.__class__), list(self))
1975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
2075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __eq__(self, other):
2175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not isinstance(other, self.__class__):
2275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return NotImplemented
2375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return list(self) == list(other)
2475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
2575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __ne__(self, other):
2675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return not self == other
2775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
2875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # Can't guarantee hash invariant, so flag as unhashable
2975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    __hash__ = None
3075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
3175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __iter__(self):
3275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return iter(self._tests)
3375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
3475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def countTestCases(self):
3575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        cases = 0
3675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        for test in self:
3775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            cases += test.countTestCases()
3875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return cases
3975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
4075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def addTest(self, test):
4175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # sanity checks
4275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not hasattr(test, '__call__'):
4375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise TypeError("%r is not callable" % (repr(test),))
4475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if isinstance(test, type) and issubclass(test,
4575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                 (case.TestCase, TestSuite)):
4675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise TypeError("TestCases and TestSuites must be instantiated "
4775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                            "before passing them to addTest()")
4875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._tests.append(test)
4975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
5075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def addTests(self, tests):
5175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if isinstance(tests, basestring):
5275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise TypeError("tests must be an iterable of tests, not a string")
5375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        for test in tests:
5475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.addTest(test)
5575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
5675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def run(self, result):
5775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        for test in self:
5875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if result.shouldStop:
5975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                break
6075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            test(result)
6175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return result
6275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
6375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __call__(self, *args, **kwds):
6475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return self.run(*args, **kwds)
6575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
6675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def debug(self):
6775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Run the tests without collecting errors in a TestResult"""
6875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        for test in self:
6975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            test.debug()
7075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
7175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
7275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass TestSuite(BaseTestSuite):
7375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """A test suite is a composite test consisting of a number of TestCases.
7475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
7575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    For use, create an instance of TestSuite, then add test case instances.
7675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    When all tests have been added, the suite can be passed to a test
7775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    runner, such as TextTestRunner. It will run the individual test cases
7875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    in the order in which they were added, aggregating the results. When
7975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    subclassing, do not forget to call the base class constructor.
8075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
8175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
8275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
8375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def run(self, result):
8475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._wrapped_run(result)
8575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._tearDownPreviousClass(None, result)
8675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._handleModuleTearDown(result)
8775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return result
8875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
8975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def debug(self):
9075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Run the tests without collecting errors in a TestResult"""
9175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        debug = _DebugResult()
9275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._wrapped_run(debug, True)
9375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._tearDownPreviousClass(None, debug)
9475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._handleModuleTearDown(debug)
9575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
9675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    ################################
9775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # private methods
9875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _wrapped_run(self, result, debug=False):
9975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        for test in self:
10075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if result.shouldStop:
10175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                break
10275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
10375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if _isnotsuite(test):
10475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self._tearDownPreviousClass(test, result)
10575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self._handleModuleFixture(test, result)
10675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self._handleClassSetUp(test, result)
10775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                result._previousTestClass = test.__class__
10875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
10975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                if (getattr(test.__class__, '_classSetupFailed', False) or
11075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    getattr(result, '_moduleSetUpFailed', False)):
11175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    continue
11275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
11375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if hasattr(test, '_wrapped_run'):
11475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                test._wrapped_run(result, debug)
11575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            elif not debug:
11675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                test(result)
11775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            else:
11875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                test.debug()
11975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
12075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _handleClassSetUp(self, test, result):
12175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        previousClass = getattr(result, '_previousTestClass', None)
12275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        currentClass = test.__class__
12375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if currentClass == previousClass:
12475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
12575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if result._moduleSetUpFailed:
12675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
12775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if getattr(currentClass, "__unittest_skip__", False):
12875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
12975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
13075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
13175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            currentClass._classSetupFailed = False
13275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except TypeError:
13375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            # test may actually be a function
13475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            # so its class will be a builtin-type
13575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            pass
13675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
13775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        setUpClass = getattr(currentClass, 'setUpClass', None)
13875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if setUpClass is not None:
13975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            try:
14075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                setUpClass()
14175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            except Exception, e:
14275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                if isinstance(result, _DebugResult):
14375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    raise
14475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                currentClass._classSetupFailed = True
14575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                className = util.strclass(currentClass)
14675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                errorName = 'setUpClass (%s)' % className
14775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self._addClassOrModuleLevelException(result, e, errorName)
14875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
14975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _get_previous_module(self, result):
15075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        previousModule = None
15175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        previousClass = getattr(result, '_previousTestClass', None)
15275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if previousClass is not None:
15375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            previousModule = previousClass.__module__
15475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return previousModule
15575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
15675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
15775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _handleModuleFixture(self, test, result):
15875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        previousModule = self._get_previous_module(result)
15975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        currentModule = test.__class__.__module__
16075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if currentModule == previousModule:
16175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
16275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
16375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._handleModuleTearDown(result)
16475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
16575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
16675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        result._moduleSetUpFailed = False
16775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
16875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            module = sys.modules[currentModule]
16975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except KeyError:
17075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
17175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        setUpModule = getattr(module, 'setUpModule', None)
17275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if setUpModule is not None:
17375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            try:
17475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                setUpModule()
17575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            except Exception, e:
17675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                if isinstance(result, _DebugResult):
17775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    raise
17875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                result._moduleSetUpFailed = True
17975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                errorName = 'setUpModule (%s)' % currentModule
18075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self._addClassOrModuleLevelException(result, e, errorName)
18175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
18275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _addClassOrModuleLevelException(self, result, exception, errorName):
18375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        error = _ErrorHolder(errorName)
18475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        addSkip = getattr(result, 'addSkip', None)
18575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if addSkip is not None and isinstance(exception, case.SkipTest):
18675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            addSkip(error, str(exception))
18775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        else:
18875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            result.addError(error, sys.exc_info())
18975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
19075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _handleModuleTearDown(self, result):
19175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        previousModule = self._get_previous_module(result)
19275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if previousModule is None:
19375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
19475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if result._moduleSetUpFailed:
19575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
19675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
19775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
19875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            module = sys.modules[previousModule]
19975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except KeyError:
20075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
20175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
20275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        tearDownModule = getattr(module, 'tearDownModule', None)
20375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if tearDownModule is not None:
20475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            try:
20575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                tearDownModule()
20675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            except Exception, e:
20775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                if isinstance(result, _DebugResult):
20875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    raise
20975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                errorName = 'tearDownModule (%s)' % previousModule
21075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self._addClassOrModuleLevelException(result, e, errorName)
21175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
21275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _tearDownPreviousClass(self, test, result):
21375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        previousClass = getattr(result, '_previousTestClass', None)
21475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        currentClass = test.__class__
21575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if currentClass == previousClass:
21675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
21775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if getattr(previousClass, '_classSetupFailed', False):
21875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
21975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if getattr(result, '_moduleSetUpFailed', False):
22075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
22175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if getattr(previousClass, "__unittest_skip__", False):
22275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
22375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
22475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        tearDownClass = getattr(previousClass, 'tearDownClass', None)
22575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if tearDownClass is not None:
22675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            try:
22775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                tearDownClass()
22875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            except Exception, e:
22975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                if isinstance(result, _DebugResult):
23075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    raise
23175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                className = util.strclass(previousClass)
23275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                errorName = 'tearDownClass (%s)' % className
23375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self._addClassOrModuleLevelException(result, e, errorName)
23475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
23575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
23675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass _ErrorHolder(object):
23775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
23875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    Placeholder for a TestCase inside a result. As far as a TestResult
23975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    is concerned, this looks exactly like a unit test. Used to insert
24075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    arbitrary errors into a test suite run.
24175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
24275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # Inspired by the ErrorHolder from Twisted:
24375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # http://twistedmatrix.com/trac/browser/trunk/twisted/trial/runner.py
24475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
24575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # attribute used by TestResult._exc_info_to_string
24675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    failureException = None
24775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
24875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __init__(self, description):
24975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.description = description
25075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
25175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def id(self):
25275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return self.description
25375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
25475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def shortDescription(self):
25575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return None
25675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
25775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __repr__(self):
25875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return "<ErrorHolder description=%r>" % (self.description,)
25975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
26075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __str__(self):
26175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return self.id()
26275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
26375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def run(self, result):
26475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # could call result.addError(...) - but this test-like object
26575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # shouldn't be run anyway
26675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        pass
26775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
26875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __call__(self, result):
26975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return self.run(result)
27075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
27175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def countTestCases(self):
27275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return 0
27375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
27475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chendef _isnotsuite(test):
27575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    "A crude way to tell apart testcases and suites with duck-typing"
27675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    try:
27775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        iter(test)
27875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    except TypeError:
27975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return True
28075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    return False
28175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
28275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
28375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass _DebugResult(object):
28475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    "Used by the TestSuite to hold previous class when running in debug."
28575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    _previousTestClass = None
28675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    _moduleSetUpFailed = False
28775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    shouldStop = False
288