377
377
if isinstance(test, TestCase):
378
378
test.addCleanup(self._check_leaked_threads, test)
380
def stopTest(self, test):
381
super(ExtendedTestResult, self).stopTest(test)
382
# Manually break cycles, means touching various private things but hey
383
getDetails = getattr(test, "getDetails", None)
384
if getDetails is not None:
386
type_equality_funcs = getattr(test, "_type_equality_funcs", None)
387
if type_equality_funcs is not None:
388
type_equality_funcs.clear()
389
self._traceback_from_test = None
380
391
def startTests(self):
381
392
self.report_tests_starting()
382
393
self._active_threads = threading.enumerate()
384
def stopTest(self, test):
385
self._traceback_from_test = None
387
395
def _check_leaked_threads(self, test):
388
396
"""See if any threads have leaked since last call
963
971
super(TestCase, self).setUp()
964
972
for feature in getattr(self, '_test_needs_features', []):
965
973
self.requireFeature(feature)
966
self._log_contents = None
967
self.addDetail("log", content.Content(content.ContentType("text",
968
"plain", {"charset": "utf8"}),
969
lambda:[self._get_log(keep_log_file=True)]))
970
974
self._cleanEnvironment()
971
975
self._silenceUI()
972
976
self._startLogFile()
1325
1329
orig_log_exception_quietly()
1326
captured.append(sys.exc_info())
1330
captured.append(sys.exc_info()[1])
1327
1331
trace.log_exception_quietly = capture
1328
1332
func(*args, **kwargs)
1330
1334
trace.log_exception_quietly = orig_log_exception_quietly
1331
1335
self.assertLength(1, captured)
1332
err = captured[0][1]
1333
1337
self.assertIsInstance(err, exception_class)
1631
1635
The file is removed as the test is torn down.
1633
self._log_file = StringIO()
1637
pseudo_log_file = StringIO()
1638
def _get_log_contents_for_weird_testtools_api():
1639
return [pseudo_log_file.getvalue().decode(
1640
"utf-8", "replace").encode("utf-8")]
1641
self.addDetail("log", content.Content(content.ContentType("text",
1642
"plain", {"charset": "utf8"}),
1643
_get_log_contents_for_weird_testtools_api))
1644
self._log_file = pseudo_log_file
1634
1645
self._log_memento = trace.push_log_file(self._log_file)
1635
1646
self.addCleanup(self._finishLogFile)
1643
1654
# flush the log file, to get all content
1644
1655
trace._trace_file.flush()
1645
1656
trace.pop_log_file(self._log_memento)
1646
# Cache the log result and delete the file on disk
1647
self._get_log(False)
1649
1658
def thisFailsStrictLockCheck(self):
1650
1659
"""It is known that this test would fail with -Dstrict_locks.
1699
1708
def _restoreHooks(self):
1700
1709
for klass, (name, hooks) in self._preserved_hooks.items():
1701
1710
setattr(klass, name, hooks)
1702
hooks._lazy_hooks = self._preserved_lazy_hooks
1711
self._preserved_hooks.clear()
1712
bzrlib.hooks._lazy_hooks = self._preserved_lazy_hooks
1713
self._preserved_lazy_hooks.clear()
1704
1715
def knownFailure(self, reason):
1705
1716
"""This test has failed for some known reason."""
1797
1808
def log(self, *args):
1798
1809
trace.mutter(*args)
1800
def _get_log(self, keep_log_file=False):
1801
"""Internal helper to get the log from bzrlib.trace for this test.
1803
Please use self.getDetails, or self.get_log to access this in test case
1806
:param keep_log_file: When True, if the log is still a file on disk
1807
leave it as a file on disk. When False, if the log is still a file
1808
on disk, the log file is deleted and the log preserved as
1810
:return: A string containing the log.
1812
if self._log_contents is not None:
1814
self._log_contents.decode('utf8')
1815
except UnicodeDecodeError:
1816
unicodestr = self._log_contents.decode('utf8', 'replace')
1817
self._log_contents = unicodestr.encode('utf8')
1818
return self._log_contents
1819
if self._log_file is not None:
1820
log_contents = self._log_file.getvalue()
1822
log_contents.decode('utf8')
1823
except UnicodeDecodeError:
1824
unicodestr = log_contents.decode('utf8', 'replace')
1825
log_contents = unicodestr.encode('utf8')
1826
if not keep_log_file:
1827
self._log_file = None
1828
# Permit multiple calls to get_log until we clean it up in
1830
self._log_contents = log_contents
1833
return "No log file content."
1835
1811
def get_log(self):
1836
1812
"""Get a unicode string containing the log from bzrlib.trace.