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): |