summaryrefslogtreecommitdiffstats
path: root/Lib/test/support
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2015-04-01 10:06:18 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2015-04-01 10:06:18 (GMT)
commitc05e260ecb822431cf5bdcd02b7cb0f4cfc88f6b (patch)
treefb71efc4179189df04b94d4f0e7d628b2cee62b0 /Lib/test/support
parenta7726624239367a72f5117700e675d5915a40714 (diff)
parent263dcd20a374d540c8f0bc07332f1657adf6da83 (diff)
downloadcpython-c05e260ecb822431cf5bdcd02b7cb0f4cfc88f6b.zip
cpython-c05e260ecb822431cf5bdcd02b7cb0f4cfc88f6b.tar.gz
cpython-c05e260ecb822431cf5bdcd02b7cb0f4cfc88f6b.tar.bz2
Issue #23799: Added test.support.start_threads() for running and cleaning up
multiple threads.
Diffstat (limited to 'Lib/test/support')
-rw-r--r--Lib/test/support/__init__.py39
1 files changed, 38 insertions, 1 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 1919082..82321af 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -6,6 +6,7 @@ if __name__ != 'test.support':
import collections.abc
import contextlib
import errno
+import faulthandler
import fnmatch
import functools
import gc
@@ -96,7 +97,7 @@ __all__ = [
# logging
"TestHandler",
# threads
- "threading_setup", "threading_cleanup",
+ "threading_setup", "threading_cleanup", "reap_threads", "start_threads",
# miscellaneous
"check_warnings", "EnvironmentVarGuard", "run_with_locale", "swap_item",
"swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict",
@@ -1942,6 +1943,42 @@ def reap_children():
break
@contextlib.contextmanager
+def start_threads(threads, unlock=None):
+ threads = list(threads)
+ started = []
+ try:
+ try:
+ for t in threads:
+ t.start()
+ started.append(t)
+ except:
+ if verbose:
+ print("Can't start %d threads, only %d threads started" %
+ (len(threads), len(started)))
+ raise
+ yield
+ finally:
+ try:
+ if unlock:
+ unlock()
+ endtime = starttime = time.time()
+ for timeout in range(1, 16):
+ endtime += 60
+ for t in started:
+ t.join(max(endtime - time.time(), 0.01))
+ started = [t for t in started if t.isAlive()]
+ if not started:
+ break
+ if verbose:
+ print('Unable to join %d threads during a period of '
+ '%d minutes' % (len(started), timeout))
+ finally:
+ started = [t for t in started if t.isAlive()]
+ if started:
+ faulthandler.dump_traceback(sys.stdout)
+ raise AssertionError('Unable to join %d threads' % len(started))
+
+@contextlib.contextmanager
def swap_attr(obj, attr, new_val):
"""Temporary swap out an attribute with a new object.