Index: test/dotest.py =================================================================== --- test/dotest.py +++ test/dotest.py @@ -1685,6 +1685,17 @@ if parsable: self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test))) + def addCleanupError(self, test, err): + global sdir_has_content + global parsable + sdir_has_content = True + super(LLDBTestResult, self).addCleanupError(test, err) + method = getattr(test, "markCleanupError", None) + if method: + method() + if parsable: + self.stream.write("CLEANUP ERROR: LLDB (%s) :: %s\n" % (self._config_string(test), str(test))) + def addFailure(self, test, err): global sdir_has_content global failuresPerCategory Index: test/lldbtest.py =================================================================== --- test/lldbtest.py +++ test/lldbtest.py @@ -1195,8 +1195,7 @@ if doCleanup and not lldb.skip_build_and_cleanup: # First, let's do the platform-specific cleanup. module = builder_module() - if not module.cleanup(): - raise Exception("Don't know how to do cleanup") + module.cleanup() # Subclass might have specific cleanup function defined. if getattr(cls, "classCleanup", None): @@ -1385,6 +1384,7 @@ # initially. If the test errored/failed, the session info # (self.session) is then dumped into a session specific file for # diagnosis. + self.__cleanup_errored__ = False self.__errored__ = False self.__failed__ = False self.__expected__ = False @@ -1616,9 +1616,6 @@ self.disableLogChannelsForCurrentTest() - # Decide whether to dump the session info. - self.dumpSessionInfo() - # ========================================================= # Various callbacks to allow introspection of test progress # ========================================================= @@ -1631,6 +1628,14 @@ # Once by the Python unittest framework, and a second time by us. print >> sbuf, "ERROR" + def markCleanupError(self): + """Callback invoked when an error occurs while a test is cleaning up.""" + self.__cleanup_errored__ = True + with recording(self, False) as sbuf: + # False because there's no need to write "CLEANUP_ERROR" to the stderr twice. + # Once by the Python unittest framework, and a second time by us. + print >> sbuf, "CLEANUP_ERROR" + def markFailure(self): """Callback invoked when a failure (test assertion failure) occurred.""" self.__failed__ = True @@ -1729,6 +1734,9 @@ if self.__errored__: pairs = lldb.test_result.errors prefix = 'Error' + if self.__cleanup_errored__: + pairs = lldb.test_result.cleanup_errors + prefix = 'CleanupError' elif self.__failed__: pairs = lldb.test_result.failures prefix = 'Failure' Index: test/unittest2/case.py =================================================================== --- test/unittest2/case.py +++ test/unittest2/case.py @@ -383,9 +383,11 @@ try: self.tearDown() except Exception: - result.addError(self, sys.exc_info()) + result.addCleanupError(self, sys.exc_info()) success = False + self.dumpSessionInfo() + cleanUpSuccess = self.doCleanups() success = success and cleanUpSuccess if success: Index: test/unittest2/result.py =================================================================== --- test/unittest2/result.py +++ test/unittest2/result.py @@ -42,6 +42,7 @@ self.failures = [] self.passes = [] self.errors = [] + self.cleanup_errors = [] self.testsRun = 0 self.skipped = [] self.expectedFailures = [] @@ -109,6 +110,13 @@ self.errors.append((test, self._exc_info_to_string(err, test))) self._mirrorOutput = True + def addCleanupError(self, test, err): + """Called when an error has occurred during cleanup. 'err' is a tuple of + values as returned by sys.exc_info(). + """ + self.cleanup_errors.append((test, self._exc_info_to_string(err, test))) + self._mirrorOutput = True + @failfast def addFailure(self, test, err): """Called when an error has occurred. 'err' is a tuple of values as