Chromium Code Reviews| Index: testing_support/thread_watcher.py |
| diff --git a/testing_support/thread_watcher.py b/testing_support/thread_watcher.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..90a53e957acf4b269fdd023f0f3fd921367653d4 |
| --- /dev/null |
| +++ b/testing_support/thread_watcher.py |
| @@ -0,0 +1,46 @@ |
| +# Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| + |
| +import sys |
| +import threading |
| +import traceback |
| +import unittest |
| + |
| + |
| +class ThreadWatcherMixIn(object): |
| + def setUp(self): |
| + self._pre_test_threads = [t.ident for t in threading.enumerate()] |
| + |
| + def tearDown(self): |
| + post_test_threads = threading.enumerate() |
| + new_threads = [t for t in post_test_threads |
| + if t.ident not in self._pre_test_threads] |
| + if new_threads: |
| + details = [] |
| + for th in new_threads: |
| + details.append('\nThread %s stacktrace:\n' % th) |
| + try: |
| + details.extend(traceback.format_stack(sys._current_frames()[t.ident])) |
| + except Exception: |
| + if t.ident in sys._current_frames(): |
| + raise |
| + # This can happen due to threads starting or stopping concurrently. |
| + details.append(' Thread already stopped.\n') |
|
tandrii(chromium)
2016/06/14 20:26:57
s/already stopped/stopped while acquiring stacktra
Sergiy Byelozyorov
2016/06/14 20:28:24
Done.
|
| + details = ''.join(details) |
| + |
| + self.fail('Found %d running thread(s) after the test.\n%s' % ( |
| + len(new_threads), details)) |
| + |
| + |
| + |
| +class TestCase(unittest.TestCase, ThreadWatcherMixIn): |
| + """Base unittest class that fails on leaked threads after the test.""" |
| + def setUp(self): |
| + super(TestCase, self).setUp() |
| + ThreadWatcherMixIn.setUp(self) |
| + |
| + def tearDown(self): |
| + ThreadWatcherMixIn.tearDown(self) |
| + super(TestCase, self).tearDown() |