| Index: testing_support/thread_watcher.py
|
| diff --git a/testing_support/thread_watcher.py b/testing_support/thread_watcher.py
|
| index ca5180bad59f101c4da41700586ec3b6663d86b5..85246f302cc51d5d642a83f72d9e2a15a14e2f98 100644
|
| --- a/testing_support/thread_watcher.py
|
| +++ b/testing_support/thread_watcher.py
|
| @@ -3,6 +3,7 @@
|
| # found in the LICENSE file.
|
|
|
|
|
| +import logging
|
| import sys
|
| import threading
|
| import traceback
|
| @@ -14,6 +15,12 @@ class ThreadWatcherMixIn(object):
|
| self._pre_test_threads = [t.ident for t in threading.enumerate()]
|
|
|
| def tearDown(self):
|
| + # If test failed before this check, don't raise another exception
|
| + # overwriting the original one, and making it harder to debug.
|
| + # Besides, that exception might be the reason cleanup didn't happen.
|
| + if self._test_definitely_failed():
|
| + return
|
| +
|
| post_test_threads = threading.enumerate()
|
| new_threads = [t for t in post_test_threads
|
| if t.ident not in self._pre_test_threads]
|
| @@ -31,8 +38,25 @@ class ThreadWatcherMixIn(object):
|
| details = ''.join(details)
|
|
|
| self.fail('Found %d running thread(s) after the test.\n%s' % (
|
| - len(new_threads), details))
|
| + len(new_threads), details))
|
| +
|
| + def _test_definitely_failed(self):
|
| + """Returns True only if test has definitely failed already.
|
|
|
| + This is necessary to determine whether we should fail the test when finding
|
| + stray threads. If the test has failed in some other way, we should avoid
|
| + throwing an exception because it will mask the original error.
|
| + """
|
| + # When run using unittest runner,
|
| + # self._resultForDoCleanups is set to internal unittest object.
|
| + if hasattr(self, '_resultForDoCleanups') and self._resultForDoCleanups:
|
| + return not self._resultForDoCleanups.wasSuccessful()
|
| + # expect_tests runner does so differently (see
|
| + # https://codereview.chromium.org/2121343004).
|
| + if hasattr(self, '_test_failed_with_exception'):
|
| + return self._test_failed_with_exception
|
| + # Default case - be conservative.
|
| + return False
|
|
|
|
|
| class TestCase(unittest.TestCase, ThreadWatcherMixIn):
|
|
|