diff options
author | Hai Shi <shihai1992@gmail.com> | 2020-05-27 22:10:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-27 22:10:27 (GMT) |
commit | e80697d687b610bd7fb9104af905dec8f0bc55a7 (patch) | |
tree | c848b98eaec2d959237fda725cf47b059f34b12a /Lib/test | |
parent | 7d80b35af1ee03834ae4af83e920dee89c2bc273 (diff) | |
download | cpython-e80697d687b610bd7fb9104af905dec8f0bc55a7.zip cpython-e80697d687b610bd7fb9104af905dec8f0bc55a7.tar.gz cpython-e80697d687b610bd7fb9104af905dec8f0bc55a7.tar.bz2 |
bpo-40275: Adding threading_helper submodule in test.support (GH-20263)
Diffstat (limited to 'Lib/test')
45 files changed, 405 insertions, 361 deletions
diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 155a827..bbba2b4 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -27,6 +27,7 @@ import test.support import test.support.script_helper from test import support from test.support import socket_helper +from test.support import threading_helper # Skip tests if _multiprocessing wasn't built. @@ -81,7 +82,7 @@ def close_queue(queue): def join_process(process): # Since multiprocessing.Process has the same API than threading.Thread # (join() and is_alive(), the support function can be reused - support.join_thread(process) + threading_helper.join_thread(process) if os.name == "posix": @@ -4234,7 +4235,7 @@ class _TestFinalize(BaseTestCase): gc.set_threshold(5, 5, 5) threads = [threading.Thread(target=run_finalizers), threading.Thread(target=make_finalizers)] - with test.support.start_threads(threads): + with threading_helper.start_threads(threads): time.sleep(4.0) # Wait a bit to trigger race condition finish = True if exc is not None: diff --git a/Lib/test/fork_wait.py b/Lib/test/fork_wait.py index 249b5e9..4d3dbd8 100644 --- a/Lib/test/fork_wait.py +++ b/Lib/test/fork_wait.py @@ -12,6 +12,7 @@ active threads survive in the child after a fork(); this is an error. import os, sys, time, unittest import threading from test import support +from test.support import threading_helper LONGSLEEP = 2 @@ -21,7 +22,7 @@ NUM_THREADS = 4 class ForkWait(unittest.TestCase): def setUp(self): - self._threading_key = support.threading_setup() + self._threading_key = threading_helper.threading_setup() self.alive = {} self.stop = 0 self.threads = [] @@ -33,7 +34,7 @@ class ForkWait(unittest.TestCase): thread.join() thread = None self.threads.clear() - support.threading_cleanup(*self._threading_key) + threading_helper.threading_cleanup(*self._threading_key) def f(self, id): while not self.stop: diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py index b397525..d69bcc9 100644 --- a/Lib/test/lock_tests.py +++ b/Lib/test/lock_tests.py @@ -11,6 +11,7 @@ import unittest import weakref from test import support +from test.support import threading_helper requires_fork = unittest.skipUnless(hasattr(os, 'fork'), @@ -37,7 +38,7 @@ class Bunch(object): self.started = [] self.finished = [] self._can_exit = not wait_before_exit - self.wait_thread = support.wait_threads_exit() + self.wait_thread = threading_helper.wait_threads_exit() self.wait_thread.__enter__() def task(): @@ -73,10 +74,10 @@ class Bunch(object): class BaseTestCase(unittest.TestCase): def setUp(self): - self._threads = support.threading_setup() + self._threads = threading_helper.threading_setup() def tearDown(self): - support.threading_cleanup(*self._threads) + threading_helper.threading_cleanup(*self._threads) support.reap_children() def assertTimeout(self, actual, expected): @@ -239,7 +240,7 @@ class LockTests(BaseLockTests): lock.acquire() phase.append(None) - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): start_new_thread(f, ()) while len(phase) == 0: _wait() diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 6ef4c89..ca566a2 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -29,8 +29,9 @@ except ImportError: from test import support from test.support import ( TestFailed, TESTFN, run_with_locale, no_tracing, - _2G, _4G, bigmemtest, reap_threads, forget, + _2G, _4G, bigmemtest, forget, ) +from test.support import threading_helper from pickle import bytes_types @@ -1350,7 +1351,7 @@ class AbstractUnpickleTests(unittest.TestCase): for p in badpickles: self.check_unpickling_error(self.truncated_errors, p) - @reap_threads + @threading_helper.reap_threads def test_unpickle_module_race(self): # https://bugs.python.org/issue34572 locker_module = dedent(""" diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 8dee5b9..e894545 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -19,8 +19,6 @@ import struct import subprocess import sys import sysconfig -import _thread -import threading import time import types import unittest @@ -62,8 +60,6 @@ __all__ = [ "open_urlresource", # processes 'temp_umask', "reap_children", - # threads - "threading_setup", "threading_cleanup", "reap_threads", "start_threads", # miscellaneous "check_warnings", "check_no_resource_warning", "check_no_warnings", "EnvironmentVarGuard", @@ -1991,120 +1987,14 @@ def modules_cleanup(oldmodules): # Implicitly imported *real* modules should be left alone (see issue 10556). sys.modules.update(oldmodules) -#======================================================================= -# Threading support to prevent reporting refleaks when running regrtest.py -R - # Flag used by saved_test_environment of test.libregrtest.save_env, # to check if a test modified the environment. The flag should be set to False # before running a new test. # -# For example, threading_cleanup() sets the flag is the function fails +# For example, threading_helper.threading_cleanup() sets the flag is the function fails # to cleanup threads. environment_altered = False -# NOTE: we use thread._count() rather than threading.enumerate() (or the -# moral equivalent thereof) because a threading.Thread object is still alive -# until its __bootstrap() method has returned, even after it has been -# unregistered from the threading module. -# thread._count(), on the other hand, only gets decremented *after* the -# __bootstrap() method has returned, which gives us reliable reference counts -# at the end of a test run. - -def threading_setup(): - return _thread._count(), threading._dangling.copy() - -def threading_cleanup(*original_values): - global environment_altered - - _MAX_COUNT = 100 - - for count in range(_MAX_COUNT): - values = _thread._count(), threading._dangling - if values == original_values: - break - - if not count: - # Display a warning at the first iteration - environment_altered = True - dangling_threads = values[1] - print_warning(f"threading_cleanup() failed to cleanup " - f"{values[0] - original_values[0]} threads " - f"(count: {values[0]}, " - f"dangling: {len(dangling_threads)})") - for thread in dangling_threads: - print_warning(f"Dangling thread: {thread!r}") - - # Don't hold references to threads - dangling_threads = None - values = None - - time.sleep(0.01) - gc_collect() - - -def reap_threads(func): - """Use this function when threads are being used. This will - ensure that the threads are cleaned up even when the test fails. - """ - @functools.wraps(func) - def decorator(*args): - key = threading_setup() - try: - return func(*args) - finally: - threading_cleanup(*key) - return decorator - - -@contextlib.contextmanager -def wait_threads_exit(timeout=None): - """ - bpo-31234: Context manager to wait until all threads created in the with - statement exit. - - Use _thread.count() to check if threads exited. Indirectly, wait until - threads exit the internal t_bootstrap() C function of the _thread module. - - threading_setup() and threading_cleanup() are designed to emit a warning - if a test leaves running threads in the background. This context manager - is designed to cleanup threads started by the _thread.start_new_thread() - which doesn't allow to wait for thread exit, whereas thread.Thread has a - join() method. - """ - if timeout is None: - timeout = SHORT_TIMEOUT - old_count = _thread._count() - try: - yield - finally: - start_time = time.monotonic() - deadline = start_time + timeout - while True: - count = _thread._count() - if count <= old_count: - break - if time.monotonic() > deadline: - dt = time.monotonic() - start_time - msg = (f"wait_threads() failed to cleanup {count - old_count} " - f"threads after {dt:.1f} seconds " - f"(count: {count}, old count: {old_count})") - raise AssertionError(msg) - time.sleep(0.010) - gc_collect() - - -def join_thread(thread, timeout=None): - """Join a thread. Raise an AssertionError if the thread is still alive - after timeout seconds. - """ - if timeout is None: - timeout = SHORT_TIMEOUT - thread.join(timeout) - if thread.is_alive(): - msg = f"failed to join the thread in {timeout:.1f} seconds" - raise AssertionError(msg) - - def reap_children(): """Use this function at the end of test_main() whenever sub-processes are started. This will help ensure that no extra children (zombies) @@ -2134,43 +2024,6 @@ def reap_children(): @contextlib.contextmanager -def start_threads(threads, unlock=None): - import faulthandler - 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.monotonic() - for timeout in range(1, 16): - endtime += 60 - for t in started: - t.join(max(endtime - time.monotonic(), 0.01)) - started = [t for t in started if t.is_alive()] - 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.is_alive()] - 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. @@ -3023,63 +2876,6 @@ class catch_unraisable_exception: del self.unraisable -class catch_threading_exception: - """ - Context manager catching threading.Thread exception using - threading.excepthook. - - Attributes set when an exception is catched: - - * exc_type - * exc_value - * exc_traceback - * thread - - See threading.excepthook() documentation for these attributes. - - These attributes are deleted at the context manager exit. - - Usage: - - with support.catch_threading_exception() as cm: - # code spawning a thread which raises an exception - ... - - # check the thread exception, use cm attributes: - # exc_type, exc_value, exc_traceback, thread - ... - - # exc_type, exc_value, exc_traceback, thread attributes of cm no longer - # exists at this point - # (to avoid reference cycles) - """ - - def __init__(self): - self.exc_type = None - self.exc_value = None - self.exc_traceback = None - self.thread = None - self._old_hook = None - - def _hook(self, args): - self.exc_type = args.exc_type - self.exc_value = args.exc_value - self.exc_traceback = args.exc_traceback - self.thread = args.thread - - def __enter__(self): - self._old_hook = threading.excepthook - threading.excepthook = self._hook - return self - - def __exit__(self, *exc_info): - threading.excepthook = self._old_hook - del self.exc_type - del self.exc_value - del self.exc_traceback - del self.thread - - def wait_process(pid, *, exitcode, timeout=None): """ Wait until process pid completes and check that the process exit code is diff --git a/Lib/test/support/threading_helper.py b/Lib/test/support/threading_helper.py new file mode 100644 index 0000000..96f7b3f --- /dev/null +++ b/Lib/test/support/threading_helper.py @@ -0,0 +1,208 @@ +import contextlib +import functools +import _thread +import threading +import time + +from test import support + + +#======================================================================= +# Threading support to prevent reporting refleaks when running regrtest.py -R + +# NOTE: we use thread._count() rather than threading.enumerate() (or the +# moral equivalent thereof) because a threading.Thread object is still alive +# until its __bootstrap() method has returned, even after it has been +# unregistered from the threading module. +# thread._count(), on the other hand, only gets decremented *after* the +# __bootstrap() method has returned, which gives us reliable reference counts +# at the end of a test run. + + +def threading_setup(): + return _thread._count(), threading._dangling.copy() + + +def threading_cleanup(*original_values): + _MAX_COUNT = 100 + + for count in range(_MAX_COUNT): + values = _thread._count(), threading._dangling + if values == original_values: + break + + if not count: + # Display a warning at the first iteration + support.environment_altered = True + dangling_threads = values[1] + support.print_warning(f"threading_cleanup() failed to cleanup " + f"{values[0] - original_values[0]} threads " + f"(count: {values[0]}, " + f"dangling: {len(dangling_threads)})") + for thread in dangling_threads: + support.print_warning(f"Dangling thread: {thread!r}") + + # Don't hold references to threads + dangling_threads = None + values = None + + time.sleep(0.01) + gc_collect() + + +def reap_threads(func): + """Use this function when threads are being used. This will + ensure that the threads are cleaned up even when the test fails. + """ + @functools.wraps(func) + def decorator(*args): + key = threading_setup() + try: + return func(*args) + finally: + threading_cleanup(*key) + return decorator + + +@contextlib.contextmanager +def wait_threads_exit(timeout=None): + """ + bpo-31234: Context manager to wait until all threads created in the with + statement exit. + + Use _thread.count() to check if threads exited. Indirectly, wait until + threads exit the internal t_bootstrap() C function of the _thread module. + + threading_setup() and threading_cleanup() are designed to emit a warning + if a test leaves running threads in the background. This context manager + is designed to cleanup threads started by the _thread.start_new_thread() + which doesn't allow to wait for thread exit, whereas thread.Thread has a + join() method. + """ + if timeout is None: + timeout = support.SHORT_TIMEOUT + old_count = _thread._count() + try: + yield + finally: + start_time = time.monotonic() + deadline = start_time + timeout + while True: + count = _thread._count() + if count <= old_count: + break + if time.monotonic() > deadline: + dt = time.monotonic() - start_time + msg = (f"wait_threads() failed to cleanup {count - old_count} " + f"threads after {dt:.1f} seconds " + f"(count: {count}, old count: {old_count})") + raise AssertionError(msg) + time.sleep(0.010) + gc_collect() + + +def join_thread(thread, timeout=None): + """Join a thread. Raise an AssertionError if the thread is still alive + after timeout seconds. + """ + if timeout is None: + timeout = support.SHORT_TIMEOUT + thread.join(timeout) + if thread.is_alive(): + msg = f"failed to join the thread in {timeout:.1f} seconds" + raise AssertionError(msg) + + +@contextlib.contextmanager +def start_threads(threads, unlock=None): + import faulthandler + 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.monotonic() + for timeout in range(1, 16): + endtime += 60 + for t in started: + t.join(max(endtime - time.monotonic(), 0.01)) + started = [t for t in started if t.is_alive()] + 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.is_alive()] + if started: + faulthandler.dump_traceback(sys.stdout) + raise AssertionError('Unable to join %d threads' % len(started)) + + +class catch_threading_exception: + """ + Context manager catching threading.Thread exception using + threading.excepthook. + + Attributes set when an exception is catched: + + * exc_type + * exc_value + * exc_traceback + * thread + + See threading.excepthook() documentation for these attributes. + + These attributes are deleted at the context manager exit. + + Usage: + + with threading_helper.catch_threading_exception() as cm: + # code spawning a thread which raises an exception + ... + + # check the thread exception, use cm attributes: + # exc_type, exc_value, exc_traceback, thread + ... + + # exc_type, exc_value, exc_traceback, thread attributes of cm no longer + # exists at this point + # (to avoid reference cycles) + """ + + def __init__(self): + self.exc_type = None + self.exc_value = None + self.exc_traceback = None + self.thread = None + self._old_hook = None + + def _hook(self, args): + self.exc_type = args.exc_type + self.exc_value = args.exc_value + self.exc_traceback = args.exc_traceback + self.thread = args.thread + + def __enter__(self): + self._old_hook = threading.excepthook + threading.excepthook = self._hook + return self + + def __exit__(self, *exc_info): + threading.excepthook = self._old_hook + del self.exc_type + del self.exc_value + del self.exc_traceback + del self.thread diff --git a/Lib/test/test_asynchat.py b/Lib/test/test_asynchat.py index 004d368..b32eddd 100644 --- a/Lib/test/test_asynchat.py +++ b/Lib/test/test_asynchat.py @@ -2,6 +2,7 @@ from test import support from test.support import socket_helper +from test.support import threading_helper import asynchat import asyncore @@ -103,10 +104,10 @@ class TestAsynchat(unittest.TestCase): usepoll = False def setUp(self): - self._threads = support.threading_setup() + self._threads = threading_helper.threading_setup() def tearDown(self): - support.threading_cleanup(*self._threads) + threading_helper.threading_cleanup(*self._threads) def line_terminator_check(self, term, server_chunk): event = threading.Event() @@ -122,7 +123,7 @@ class TestAsynchat(unittest.TestCase): c.push(b"I'm not dead yet!" + term) c.push(SERVER_QUIT) asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s) + threading_helper.join_thread(s) self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"]) @@ -153,7 +154,7 @@ class TestAsynchat(unittest.TestCase): c.push(data) c.push(SERVER_QUIT) asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s) + threading_helper.join_thread(s) self.assertEqual(c.contents, [data[:termlen]]) @@ -173,7 +174,7 @@ class TestAsynchat(unittest.TestCase): c.push(data) c.push(SERVER_QUIT) asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s) + threading_helper.join_thread(s) self.assertEqual(c.contents, []) self.assertEqual(c.buffer, data) @@ -185,7 +186,7 @@ class TestAsynchat(unittest.TestCase): p = asynchat.simple_producer(data+SERVER_QUIT, buffer_size=8) c.push_with_producer(p) asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s) + threading_helper.join_thread(s) self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"]) @@ -195,7 +196,7 @@ class TestAsynchat(unittest.TestCase): data = b"hello world\nI'm not dead yet!\n" c.push_with_producer(data+SERVER_QUIT) asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s) + threading_helper.join_thread(s) self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"]) @@ -206,7 +207,7 @@ class TestAsynchat(unittest.TestCase): c.push(b"hello world\n\nI'm not dead yet!\n") c.push(SERVER_QUIT) asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s) + threading_helper.join_thread(s) self.assertEqual(c.contents, [b"hello world", b"", b"I'm not dead yet!"]) @@ -225,7 +226,7 @@ class TestAsynchat(unittest.TestCase): # where the server echoes all of its data before we can check that it # got any down below. s.start_resend_event.set() - support.join_thread(s) + threading_helper.join_thread(s) self.assertEqual(c.contents, []) # the server might have been able to send a byte or two back, but this @@ -246,7 +247,7 @@ class TestAsynchat(unittest.TestCase): self.assertRaises(TypeError, c.push, 'unicode') c.push(SERVER_QUIT) asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s) + threading_helper.join_thread(s) self.assertEqual(c.contents, [b'bytes', b'bytes', b'bytes']) diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 0fb3618..e7324d2 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -33,6 +33,7 @@ from asyncio import selector_events from test.test_asyncio import utils as test_utils from test import support from test.support import socket_helper +from test.support import threading_helper from test.support import ALWAYS_EQ, LARGEST, SMALLEST @@ -706,7 +707,7 @@ class EventLoopTestsMixin: proto.transport.close() lsock.close() - support.join_thread(thread) + threading_helper.join_thread(thread) self.assertFalse(thread.is_alive()) self.assertEqual(proto.state, 'CLOSED') self.assertEqual(proto.nbytes, len(message)) diff --git a/Lib/test/test_asyncio/utils.py b/Lib/test/test_asyncio/utils.py index 804db91..34da739 100644 --- a/Lib/test/test_asyncio/utils.py +++ b/Lib/test/test_asyncio/utils.py @@ -34,6 +34,7 @@ from asyncio import futures from asyncio import tasks from asyncio.log import logger from test import support +from test.support import threading_helper def data_file(filename): @@ -546,7 +547,7 @@ class TestCase(unittest.TestCase): def setUp(self): self._get_running_loop = events._get_running_loop events._get_running_loop = lambda: None - self._thread_cleanup = support.threading_setup() + self._thread_cleanup = threading_helper.threading_setup() def tearDown(self): self.unpatch_get_running_loop() @@ -558,7 +559,7 @@ class TestCase(unittest.TestCase): self.assertEqual(sys.exc_info(), (None, None, None)) self.doCleanups() - support.threading_cleanup(*self._thread_cleanup) + threading_helper.threading_cleanup(*self._thread_cleanup) support.reap_children() diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py index 3c3abe4..2cee6fb 100644 --- a/Lib/test/test_asyncore.py +++ b/Lib/test/test_asyncore.py @@ -11,6 +11,7 @@ import threading from test import support from test.support import socket_helper +from test.support import threading_helper from io import BytesIO if support.PGO: @@ -323,7 +324,7 @@ class DispatcherWithSendTests(unittest.TestCase): def tearDown(self): asyncore.close_all() - @support.reap_threads + @threading_helper.reap_threads def test_send(self): evt = threading.Event() sock = socket.socket() @@ -360,7 +361,7 @@ class DispatcherWithSendTests(unittest.TestCase): self.assertEqual(cap.getvalue(), data*2) finally: - support.join_thread(t) + threading_helper.join_thread(t) @unittest.skipUnless(hasattr(asyncore, 'file_wrapper'), @@ -766,7 +767,7 @@ class BaseTestAPI: self.assertTrue(s.socket.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)) - @support.reap_threads + @threading_helper.reap_threads def test_quick_connect(self): # see: http://bugs.python.org/issue10340 if self.family not in (socket.AF_INET, getattr(socket, "AF_INET6", object())): @@ -788,7 +789,7 @@ class BaseTestAPI: except OSError: pass finally: - support.join_thread(t) + threading_helper.join_thread(t) class TestAPI_UseIPv4Sockets(BaseTestAPI): family = socket.AF_INET diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py index 78b95d8..91ccff2 100644 --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -12,6 +12,7 @@ import random import shutil import subprocess import threading +from test.support import threading_helper from test.support import unlink import _compression import sys @@ -502,7 +503,7 @@ class BZ2FileTest(BaseTest): for i in range(5): f.write(data) threads = [threading.Thread(target=comp) for i in range(nthreads)] - with support.start_threads(threads): + with threading_helper.start_threads(threads): pass def testMixedIterationAndReads(self): diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 5c7526a..44693b8 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -17,6 +17,7 @@ import importlib.machinery import importlib.util from test import support from test.support import MISSING_C_DOCSTRINGS +from test.support import threading_helper from test.support.script_helper import assert_python_failure, assert_python_ok try: import _posixsubprocess @@ -575,7 +576,7 @@ class TestPendingCalls(unittest.TestCase): threads = [threading.Thread(target=self.pendingcalls_thread, args=(context,)) for i in range(context.nThreads)] - with support.start_threads(threads): + with threading_helper.start_threads(threads): self.pendingcalls_wait(context.l, n, context) def pendingcalls_thread(self, context): @@ -634,7 +635,7 @@ class SubinterpreterTest(unittest.TestCase): class TestThreadState(unittest.TestCase): - @support.reap_threads + @threading_helper.reap_threads def test_thread_state(self): # some extra thread-state tests driven via _testcapi def target(): diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index 40597ff..3b74949 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -1,4 +1,5 @@ from test import support +from test.support import threading_helper # Skip tests if _multiprocessing wasn't built. support.import_module('_multiprocessing') @@ -100,11 +101,11 @@ def make_dummy_object(_): class BaseTestCase(unittest.TestCase): def setUp(self): - self._thread_key = support.threading_setup() + self._thread_key = threading_helper.threading_setup() def tearDown(self): support.reap_children() - support.threading_cleanup(*self._thread_key) + threading_helper.threading_cleanup(*self._thread_key) class ExecutorMixin: @@ -1496,11 +1497,11 @@ _threads_key = None def setUpModule(): global _threads_key - _threads_key = support.threading_setup() + _threads_key = threading_helper.threading_setup() def tearDownModule(): - support.threading_cleanup(*_threads_key) + threading_helper.threading_cleanup(*_threads_key) multiprocessing.util._cleanup_tests() diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 59eabb0..1d28e26 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -37,7 +37,8 @@ from email import iterators from email import base64mime from email import quoprimime -from test.support import unlink, start_threads +from test.support import threading_helper +from test.support import unlink from test.test_email import openfile, TestEmailBase # These imports are documented to work, but we are testing them using a @@ -3241,7 +3242,7 @@ Foo append(make_msgid(domain='testdomain-string')) threads = [MsgidsThread() for i in range(5)] - with start_threads(threads): + with threading_helper.start_threads(threads): pass all_ids = sum([t.msgids for t in threads], []) self.assertEqual(len(set(all_ids)), len(all_ids)) diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 1df0313..e7bad62 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -10,6 +10,7 @@ from io import StringIO from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL from test import support from test.support import ALWAYS_EQ +from test.support import threading_helper from datetime import timedelta @@ -2333,7 +2334,7 @@ class TestFlag(unittest.TestCase): self.assertEqual(Color.ALL.value, 7) self.assertEqual(str(Color.BLUE), 'blue') - @support.reap_threads + @threading_helper.reap_threads def test_unique_composite(self): # override __eq__ to be identity only class TestFlag(Flag): @@ -2363,7 +2364,7 @@ class TestFlag(unittest.TestCase): threading.Thread(target=cycle_enum) for _ in range(8) ] - with support.start_threads(threads): + with threading_helper.start_threads(threads): pass # check that only 248 members were created self.assertFalse( @@ -2751,7 +2752,7 @@ class TestIntFlag(unittest.TestCase): self.assertEqual(Color.ALL.value, 7) self.assertEqual(str(Color.BLUE), 'blue') - @support.reap_threads + @threading_helper.reap_threads def test_unique_composite(self): # override __eq__ to be identity only class TestFlag(IntFlag): @@ -2781,7 +2782,7 @@ class TestIntFlag(unittest.TestCase): threading.Thread(target=cycle_enum) for _ in range(8) ] - with support.start_threads(threads): + with threading_helper.start_threads(threads): pass # check that only 248 members were created self.assertFalse( diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py index e424076..cb43573 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -19,6 +19,7 @@ except ImportError: from unittest import TestCase, skipUnless from test import support +from test.support import threading_helper from test.support import socket_helper from test.support.socket_helper import HOST, HOSTv6 @@ -1117,11 +1118,11 @@ def test_main(): TestTLS_FTPClassMixin, TestTLS_FTPClass, MiscTestCase] - thread_info = support.threading_setup() + thread_info = threading_helper.threading_setup() try: support.run_unittest(*tests) finally: - support.threading_cleanup(*thread_info) + threading_helper.threading_cleanup(*thread_info) if __name__ == '__main__': diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index e122fe0..72b7765 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -19,6 +19,7 @@ import gc from weakref import proxy import contextlib +from test.support import threading_helper from test.support.script_helper import assert_python_ok import functools @@ -1798,7 +1799,7 @@ class TestLRU: # create n threads in order to fill cache threads = [threading.Thread(target=full, args=[k]) for k in range(n)] - with support.start_threads(threads): + with threading_helper.start_threads(threads): start.set() hits, misses, maxsize, currsize = f.cache_info() @@ -1816,7 +1817,7 @@ class TestLRU: threads += [threading.Thread(target=full, args=[k]) for k in range(n)] start.clear() - with support.start_threads(threads): + with threading_helper.start_threads(threads): start.set() finally: sys.setswitchinterval(orig_si) @@ -1838,7 +1839,7 @@ class TestLRU: self.assertEqual(f(i), 3 * i) stop.wait(10) threads = [threading.Thread(target=test) for k in range(n)] - with support.start_threads(threads): + with threading_helper.start_threads(threads): for i in range(m): start.wait(10) stop.reset() @@ -1858,7 +1859,7 @@ class TestLRU: self.assertEqual(f(x), 3 * x, i) threads = [threading.Thread(target=test, args=(i, v)) for i, v in enumerate([1, 2, 2, 3, 2])] - with support.start_threads(threads): + with threading_helper.start_threads(threads): pass def test_need_for_rlock(self): @@ -2792,7 +2793,7 @@ class TestCachedProperty(unittest.TestCase): threading.Thread(target=lambda: item.cost) for k in range(num_threads) ] - with support.start_threads(threads): + with threading_helper.start_threads(threads): go.set() finally: sys.setswitchinterval(orig_si) diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index acb6391..c829708 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -1,10 +1,10 @@ import unittest import unittest.mock from test.support import (verbose, refcount_test, run_unittest, - cpython_only, start_threads, - temp_dir, TESTFN, unlink, + cpython_only, temp_dir, TESTFN, unlink, import_module) from test.support.script_helper import assert_python_ok, make_script +from test.support import threading_helper import gc import sys @@ -415,7 +415,7 @@ class GCTests(unittest.TestCase): for i in range(N_THREADS): t = threading.Thread(target=run_thread) threads.append(t) - with start_threads(threads, lambda: exit.append(1)): + with threading_helper.start_threads(threads, lambda: exit.append(1)): time.sleep(1.0) finally: sys.setswitchinterval(old_switchinterval) diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 6088307..2f79244 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -19,6 +19,7 @@ import unittest import warnings from test import support from test.support import _4G, bigmemtest, import_fresh_module +from test.support import threading_helper from http.client import HTTPException # Were we compiled --with-pydebug or with #define Py_DEBUG? @@ -870,7 +871,7 @@ class HashLibTestCase(unittest.TestCase): '1cfceca95989f51f658e3f3ffe7f1cd43726c9e088c13ee10b46f57cef135b94' ) - @support.reap_threads + @threading_helper.reap_threads def test_threaded_hashing(self): # Updating the same hash object from several threads at once # using data chunk sizes containing the same byte sequences. diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index c442f55..71a0511 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -30,6 +30,7 @@ from io import BytesIO import unittest from test import support +from test.support import threading_helper class NoLogRequestHandler: @@ -64,7 +65,7 @@ class TestServerThread(threading.Thread): class BaseTestCase(unittest.TestCase): def setUp(self): - self._threads = support.threading_setup() + self._threads = threading_helper.threading_setup() os.environ = support.EnvironmentVarGuard() self.server_started = threading.Event() self.thread = TestServerThread(self, self.request_handler) @@ -75,7 +76,7 @@ class BaseTestCase(unittest.TestCase): self.thread.stop() self.thread = None os.environ.__exit__() - support.threading_cleanup(*self._threads) + threading_helper.threading_cleanup(*self._threads) def request(self, uri, method='GET', body=None, headers={}): self.connection = http.client.HTTPConnection(self.HOST, self.PORT) diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index d1e3550..0fcc1fb 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -10,9 +10,10 @@ import calendar import threading import socket -from test.support import (reap_threads, verbose, +from test.support import (verbose, run_with_tz, run_with_locale, cpython_only) from test.support import hashlib_helper +from test.support import threading_helper import unittest from unittest import mock from datetime import datetime, timezone, timedelta @@ -252,7 +253,7 @@ class NewIMAPTestsMixin(): # cleanup the server self.server.shutdown() self.server.server_close() - support.join_thread(self.thread) + threading_helper.join_thread(self.thread) # Explicitly clear the attribute to prevent dangling thread self.thread = None @@ -641,13 +642,13 @@ class ThreadedNetworkedTests(unittest.TestCase): finally: client.logout() - @reap_threads + @threading_helper.reap_threads def test_connect(self): with self.reaped_server(SimpleIMAPHandler) as server: client = self.imap_class(*server.server_address) client.shutdown() - @reap_threads + @threading_helper.reap_threads def test_bracket_flags(self): # This violates RFC 3501, which disallows ']' characters in tag names, @@ -696,7 +697,7 @@ class ThreadedNetworkedTests(unittest.TestCase): typ, [data] = client.response('PERMANENTFLAGS') self.assertIn(b'[test]', data) - @reap_threads + @threading_helper.reap_threads def test_issue5949(self): class EOFHandler(socketserver.StreamRequestHandler): @@ -708,7 +709,7 @@ class ThreadedNetworkedTests(unittest.TestCase): self.assertRaises(imaplib.IMAP4.abort, self.imap_class, *server.server_address) - @reap_threads + @threading_helper.reap_threads def test_line_termination(self): class BadNewlineHandler(SimpleIMAPHandler): @@ -732,7 +733,7 @@ class ThreadedNetworkedTests(unittest.TestCase): self.server.response = yield self._send_tagged(tag, 'OK', 'FAKEAUTH successful') - @reap_threads + @threading_helper.reap_threads def test_enable_raises_error_if_not_AUTH(self): with self.reaped_pair(self.UTF8Server) as (server, client): self.assertFalse(client.utf8_enabled) @@ -741,14 +742,14 @@ class ThreadedNetworkedTests(unittest.TestCase): # XXX Also need a test that enable after SELECT raises an error. - @reap_threads + @threading_helper.reap_threads def test_enable_raises_error_if_no_capability(self): class NoEnableServer(self.UTF8Server): capabilities = 'AUTH' with self.reaped_pair(NoEnableServer) as (server, client): self.assertRaises(imaplib.IMAP4.error, client.enable, 'foo') - @reap_threads + @threading_helper.reap_threads def test_enable_UTF8_raises_error_if_not_supported(self): class NonUTF8Server(SimpleIMAPHandler): pass @@ -759,7 +760,7 @@ class ThreadedNetworkedTests(unittest.TestCase): client.enable('UTF8=ACCEPT') pass - @reap_threads + @threading_helper.reap_threads def test_enable_UTF8_True_append(self): class UTF8AppendServer(self.UTF8Server): @@ -789,7 +790,7 @@ class ThreadedNetworkedTests(unittest.TestCase): # XXX also need a test that makes sure that the Literal and Untagged_status # regexes uses unicode in UTF8 mode instead of the default ASCII. - @reap_threads + @threading_helper.reap_threads def test_search_disallows_charset_in_utf8_mode(self): with self.reaped_pair(self.UTF8Server) as (server, client): typ, _ = client.authenticate('MYAUTH', lambda x: b'fake') @@ -799,7 +800,7 @@ class ThreadedNetworkedTests(unittest.TestCase): self.assertTrue(client.utf8_enabled) self.assertRaises(imaplib.IMAP4.error, client.search, 'foo', 'bar') - @reap_threads + @threading_helper.reap_threads def test_bad_auth_name(self): class MyServer(SimpleIMAPHandler): @@ -812,7 +813,7 @@ class ThreadedNetworkedTests(unittest.TestCase): with self.assertRaises(imaplib.IMAP4.error): client.authenticate('METHOD', lambda: 1) - @reap_threads + @threading_helper.reap_threads def test_invalid_authentication(self): class MyServer(SimpleIMAPHandler): @@ -826,7 +827,7 @@ class ThreadedNetworkedTests(unittest.TestCase): with self.assertRaises(imaplib.IMAP4.error): code, data = client.authenticate('MYAUTH', lambda x: b'fake') - @reap_threads + @threading_helper.reap_threads def test_valid_authentication(self): class MyServer(SimpleIMAPHandler): @@ -848,7 +849,7 @@ class ThreadedNetworkedTests(unittest.TestCase): self.assertEqual(server.response, b'ZmFrZQ==\r\n') # b64 encoded 'fake' - @reap_threads + @threading_helper.reap_threads @hashlib_helper.requires_hashdigest('md5') def test_login_cram_md5(self): @@ -877,7 +878,7 @@ class ThreadedNetworkedTests(unittest.TestCase): self.assertEqual(ret, "OK") - @reap_threads + @threading_helper.reap_threads def test_aborted_authentication(self): class MyServer(SimpleIMAPHandler): @@ -906,14 +907,14 @@ class ThreadedNetworkedTests(unittest.TestCase): self.assertRaises(imaplib.IMAP4.error, self.imap_class, *server.server_address) - @reap_threads + @threading_helper.reap_threads def test_simple_with_statement(self): # simplest call with self.reaped_server(SimpleIMAPHandler) as server: with self.imap_class(*server.server_address): pass - @reap_threads + @threading_helper.reap_threads def test_with_statement(self): with self.reaped_server(SimpleIMAPHandler) as server: with self.imap_class(*server.server_address) as imap: @@ -921,7 +922,7 @@ class ThreadedNetworkedTests(unittest.TestCase): self.assertEqual(server.logged, 'user') self.assertIsNone(server.logged) - @reap_threads + @threading_helper.reap_threads def test_with_statement_logout(self): # what happens if already logout in the block? with self.reaped_server(SimpleIMAPHandler) as server: @@ -938,7 +939,7 @@ class ThreadedNetworkedTestsSSL(ThreadedNetworkedTests): server_class = SecureTCPServer imap_class = IMAP4_SSL - @reap_threads + @threading_helper.reap_threads def test_ssl_verified(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ssl_context.load_verify_locations(CAFILE) diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index d50befc..060d145 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -25,6 +25,7 @@ from test.support import ( unlink, unload, cpython_only, TESTFN_UNENCODABLE, temp_dir, DirsOnSysPath) from test.support import script_helper +from test.support import threading_helper from test.test_importlib.util import uncache from types import ModuleType @@ -459,7 +460,7 @@ class ImportTests(unittest.TestCase): event = threading.Event() threads = [threading.Thread(target=run) for x in range(2)] try: - with test.support.start_threads(threads, event.set): + with threading_helper.start_threads(threads, event.set): time.sleep(0) finally: sys.modules.pop('package', None) diff --git a/Lib/test/test_importlib/test_locks.py b/Lib/test/test_importlib/test_locks.py index 21794d9..0e94ce9 100644 --- a/Lib/test/test_importlib/test_locks.py +++ b/Lib/test/test_importlib/test_locks.py @@ -7,6 +7,7 @@ import threading import weakref from test import support +from test.support import threading_helper from test import lock_tests @@ -138,7 +139,7 @@ class LifetimeTests: ) = test_util.test_both(LifetimeTests, init=init) -@support.reap_threads +@threading_helper.reap_threads def test_main(): support.run_unittest(Frozen_ModuleLockAsRLockTests, Source_ModuleLockAsRLockTests, diff --git a/Lib/test/test_importlib/test_threaded_import.py b/Lib/test/test_importlib/test_threaded_import.py index d1f64c7..06da18e 100644 --- a/Lib/test/test_importlib/test_threaded_import.py +++ b/Lib/test/test_importlib/test_threaded_import.py @@ -15,8 +15,9 @@ import threading import unittest from unittest import mock from test.support import ( - verbose, run_unittest, TESTFN, reap_threads, - forget, unlink, rmtree, start_threads) + verbose, run_unittest, TESTFN, + forget, unlink, rmtree) +from test.support import threading_helper def task(N, done, done_tasks, errors): try: @@ -124,9 +125,9 @@ class ThreadedImportTests(unittest.TestCase): done_tasks = [] done.clear() t0 = time.monotonic() - with start_threads(threading.Thread(target=task, - args=(N, done, done_tasks, errors,)) - for i in range(N)): + with threading_helper.start_threads( + threading.Thread(target=task, args=(N, done, done_tasks, errors,)) + for i in range(N)): pass completed = done.wait(10 * 60) dt = time.monotonic() - t0 @@ -245,7 +246,7 @@ class ThreadedImportTests(unittest.TestCase): del sys.modules[TESTFN] -@reap_threads +@threading_helper.reap_threads def test_main(): old_switchinterval = None try: diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index fe07b56..7b8511b 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -40,6 +40,7 @@ from itertools import cycle, count from test import support from test.support.script_helper import ( assert_python_ok, assert_python_failure, run_python_until_end) +from test.support import threading_helper from test.support import FakePath import codecs @@ -1472,7 +1473,7 @@ class BufferedReaderTest(unittest.TestCase, CommonBufferedTests): errors.append(e) raise threads = [threading.Thread(target=f) for x in range(20)] - with support.start_threads(threads): + with threading_helper.start_threads(threads): time.sleep(0.02) # yield self.assertFalse(errors, "the following exceptions were caught: %r" % errors) @@ -1836,7 +1837,7 @@ class BufferedWriterTest(unittest.TestCase, CommonBufferedTests): errors.append(e) raise threads = [threading.Thread(target=f) for x in range(20)] - with support.start_threads(threads): + with threading_helper.start_threads(threads): time.sleep(0.02) # yield self.assertFalse(errors, "the following exceptions were caught: %r" % errors) @@ -3270,7 +3271,7 @@ class TextIOWrapperTest(unittest.TestCase): f.write(text) threads = [threading.Thread(target=run, args=(x,)) for x in range(20)] - with support.start_threads(threads, event.set): + with threading_helper.start_threads(threads, event.set): time.sleep(0.02) with self.open(support.TESTFN) as f: content = f.read() diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 9a11445..275ce2e 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -43,6 +43,7 @@ import tempfile from test.support.script_helper import assert_python_ok, assert_python_failure from test import support from test.support import socket_helper +from test.support import threading_helper from test.support.logging_helper import TestHandler import textwrap import threading @@ -79,7 +80,7 @@ class BaseTest(unittest.TestCase): def setUp(self): """Setup the default logging stream to an internal StringIO instance, so that we can examine log output as we want.""" - self._threading_key = support.threading_setup() + self._threading_key = threading_helper.threading_setup() logger_dict = logging.getLogger().manager.loggerDict logging._acquireLock() @@ -150,7 +151,7 @@ class BaseTest(unittest.TestCase): logging._releaseLock() self.doCleanups() - support.threading_cleanup(*self._threading_key) + threading_helper.threading_cleanup(*self._threading_key) def assert_log_lines(self, expected_values, stream=None, pat=None): """Match the collected log lines against the regular expression @@ -865,7 +866,7 @@ class TestSMTPServer(smtpd.SMTPServer): Wait for the server thread to terminate. """ self.close() - support.join_thread(self._thread) + threading_helper.join_thread(self._thread) self._thread = None asyncore.close_all(map=self._map, ignore_all=True) @@ -915,7 +916,7 @@ class ControlMixin(object): """ self.shutdown() if self._thread is not None: - support.join_thread(self._thread) + threading_helper.join_thread(self._thread) self._thread = None self.server_close() self.ready.clear() @@ -3212,7 +3213,7 @@ class ConfigDictTest(BaseTest): finally: t.ready.wait(2.0) logging.config.stopListening() - support.join_thread(t) + threading_helper.join_thread(t) def test_listen_config_10_ok(self): with support.captured_stdout() as output: diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 0db7d30..7d4376a 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -31,6 +31,7 @@ import uuid import warnings from test import support from test.support import socket_helper +from test.support import threading_helper from platform import win32_is_iot try: @@ -3163,12 +3164,12 @@ class TestSendfile(unittest.TestCase): @classmethod def setUpClass(cls): - cls.key = support.threading_setup() + cls.key = threading_helper.threading_setup() create_file(support.TESTFN, cls.DATA) @classmethod def tearDownClass(cls): - support.threading_cleanup(*cls.key) + threading_helper.threading_cleanup(*cls.key) support.unlink(support.TESTFN) def setUp(self): diff --git a/Lib/test/test_poll.py b/Lib/test/test_poll.py index ef966bf..a14c69a 100644 --- a/Lib/test/test_poll.py +++ b/Lib/test/test_poll.py @@ -7,7 +7,8 @@ import select import threading import time import unittest -from test.support import TESTFN, run_unittest, reap_threads, cpython_only +from test.support import TESTFN, run_unittest, cpython_only +from test.support import threading_helper try: select.poll @@ -175,7 +176,7 @@ class PollTests(unittest.TestCase): self.assertRaises(OverflowError, pollster.poll, INT_MAX + 1) self.assertRaises(OverflowError, pollster.poll, UINT_MAX + 1) - @reap_threads + @threading_helper.reap_threads def test_threaded_poll(self): r, w = os.pipe() self.addCleanup(os.close, r) @@ -204,7 +205,7 @@ class PollTests(unittest.TestCase): t.join() @unittest.skipUnless(threading, 'Threading required for this test.') - @reap_threads + @threading_helper.reap_threads def test_poll_blocks_with_negative_ms(self): for timeout_ms in [None, -1000, -1, -1.0, -0.1, -1e-100]: # Create two file descriptors. This will be used to unlock diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index b670afc..2ac345d 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -15,6 +15,7 @@ from unittest import TestCase, skipUnless from test import support as test_support from test.support import hashlib_helper from test.support import socket_helper +from test.support import threading_helper HOST = socket_helper.HOST PORT = 0 @@ -536,11 +537,11 @@ class TestTimeouts(TestCase): def test_main(): tests = [TestPOP3Class, TestTimeouts, TestPOP3_SSLClass, TestPOP3_TLSClass] - thread_info = test_support.threading_setup() + thread_info = threading_helper.threading_setup() try: test_support.run_unittest(*tests) finally: - test_support.threading_cleanup(*thread_info) + threading_helper.threading_cleanup(*thread_info) if __name__ == '__main__': diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index ffabb7f..f0d7ffd 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -24,9 +24,10 @@ import textwrap from io import StringIO from collections import namedtuple from test.support.script_helper import assert_python_ok +from test.support import threading_helper from test.support import ( TESTFN, rmtree, - reap_children, reap_threads, captured_output, captured_stdout, + reap_children, captured_output, captured_stdout, captured_stderr, unlink, requires_docstrings ) from test import pydoc_mod @@ -1575,7 +1576,7 @@ class TestInternalUtilities(unittest.TestCase): self.assertIsNone(self._get_revised_path(trailing_argv0dir)) -@reap_threads +@threading_helper.reap_threads def test_main(): try: test.support.run_unittest(PydocDocTest, diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index d88e28a..7b23699 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -7,6 +7,7 @@ import time import unittest import weakref from test import support +from test.support import threading_helper py_queue = support.import_fresh_module('queue', blocked=['_queue']) c_queue = support.import_fresh_module('queue', fresh=['_queue']) @@ -63,7 +64,7 @@ class BlockingTestMixin: block_func) return self.result finally: - support.join_thread(thread) # make sure the thread terminates + threading_helper.join_thread(thread) # make sure the thread terminates # Call this instead if block_func is supposed to raise an exception. def do_exceptional_blocking_test(self,block_func, block_args, trigger_func, @@ -79,7 +80,7 @@ class BlockingTestMixin: self.fail("expected exception of kind %r" % expected_exception_class) finally: - support.join_thread(thread) # make sure the thread terminates + threading_helper.join_thread(thread) # make sure the thread terminates if not thread.startedEvent.is_set(): self.fail("trigger thread ended but event never set") @@ -484,7 +485,7 @@ class BaseSimpleQueueTest: args=(q, results, sentinel)) for i in range(n_consumers)] - with support.start_threads(feeders + consumers): + with threading_helper.start_threads(feeders + consumers): pass self.assertFalse(exceptions) diff --git a/Lib/test/test_robotparser.py b/Lib/test/test_robotparser.py index a3112b8..b0bed43 100644 --- a/Lib/test/test_robotparser.py +++ b/Lib/test/test_robotparser.py @@ -5,6 +5,7 @@ import unittest import urllib.robotparser from test import support from test.support import socket_helper +from test.support import threading_helper from http.server import BaseHTTPRequestHandler, HTTPServer @@ -330,7 +331,7 @@ class PasswordProtectedSiteTestCase(unittest.TestCase): self.t.join() self.server.server_close() - @support.reap_threads + @threading_helper.reap_threads def testPasswordProtectedSite(self): addr = self.server.server_address url = 'http://' + socket_helper.HOST + ':' + str(addr[1]) diff --git a/Lib/test/test_sched.py b/Lib/test/test_sched.py index 26cb4be..491d7b3 100644 --- a/Lib/test/test_sched.py +++ b/Lib/test/test_sched.py @@ -4,6 +4,7 @@ import threading import time import unittest from test import support +from test.support import threading_helper TIMEOUT = support.SHORT_TIMEOUT @@ -82,7 +83,7 @@ class TestCase(unittest.TestCase): self.assertEqual(q.get(timeout=TIMEOUT), 5) self.assertTrue(q.empty()) timer.advance(1000) - support.join_thread(t) + threading_helper.join_thread(t) self.assertTrue(q.empty()) self.assertEqual(timer.time(), 5) @@ -137,7 +138,7 @@ class TestCase(unittest.TestCase): self.assertEqual(q.get(timeout=TIMEOUT), 4) self.assertTrue(q.empty()) timer.advance(1000) - support.join_thread(t) + threading_helper.join_thread(t) self.assertTrue(q.empty()) self.assertEqual(timer.time(), 4) diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 5762999..7816ed3 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -22,7 +22,7 @@ import unittest from test import support, mock_socket from test.support import hashlib_helper from test.support import socket_helper -from test.support import threading_setup, threading_cleanup, join_thread +from test.support import threading_helper from unittest.mock import Mock HOST = socket_helper.HOST @@ -217,7 +217,7 @@ class DebuggingServerTests(unittest.TestCase): maxDiff = None def setUp(self): - self.thread_key = threading_setup() + self.thread_key = threading_helper.threading_setup() self.real_getfqdn = socket.getfqdn socket.getfqdn = mock_socket.getfqdn # temporarily replace sys.stdout to capture DebuggingServer output @@ -249,7 +249,7 @@ class DebuggingServerTests(unittest.TestCase): self.client_evt.set() # wait for the server thread to terminate self.serv_evt.wait() - join_thread(self.thread) + threading_helper.join_thread(self.thread) # restore sys.stdout sys.stdout = self.old_stdout # restore DEBUGSTREAM @@ -257,7 +257,7 @@ class DebuggingServerTests(unittest.TestCase): smtpd.DEBUGSTREAM = self.old_DEBUGSTREAM del self.thread self.doCleanups() - threading_cleanup(*self.thread_key) + threading_helper.threading_cleanup(*self.thread_key) def get_output_without_xpeer(self): test_output = self.output.getvalue() @@ -704,7 +704,7 @@ class TooLongLineTests(unittest.TestCase): respdata = b'250 OK' + (b'.' * smtplib._MAXLINE * 2) + b'\n' def setUp(self): - self.thread_key = threading_setup() + self.thread_key = threading_helper.threading_setup() self.old_stdout = sys.stdout self.output = io.StringIO() sys.stdout = self.output @@ -722,10 +722,10 @@ class TooLongLineTests(unittest.TestCase): def tearDown(self): self.evt.wait() sys.stdout = self.old_stdout - join_thread(self.thread) + threading_helper.join_thread(self.thread) del self.thread self.doCleanups() - threading_cleanup(*self.thread_key) + threading_helper.threading_cleanup(*self.thread_key) def testLineTooLong(self): self.assertRaises(smtplib.SMTPResponseException, smtplib.SMTP, @@ -955,7 +955,7 @@ class SimSMTPServer(smtpd.SMTPServer): class SMTPSimTests(unittest.TestCase): def setUp(self): - self.thread_key = threading_setup() + self.thread_key = threading_helper.threading_setup() self.real_getfqdn = socket.getfqdn socket.getfqdn = mock_socket.getfqdn self.serv_evt = threading.Event() @@ -978,10 +978,10 @@ class SMTPSimTests(unittest.TestCase): self.client_evt.set() # wait for the server thread to terminate self.serv_evt.wait() - join_thread(self.thread) + threading_helper.join_thread(self.thread) del self.thread self.doCleanups() - threading_cleanup(*self.thread_key) + threading_helper.threading_cleanup(*self.thread_key) def testBasic(self): # smoke test @@ -1268,7 +1268,7 @@ class SMTPUTF8SimTests(unittest.TestCase): maxDiff = None def setUp(self): - self.thread_key = threading_setup() + self.thread_key = threading_helper.threading_setup() self.real_getfqdn = socket.getfqdn socket.getfqdn = mock_socket.getfqdn self.serv_evt = threading.Event() @@ -1293,10 +1293,10 @@ class SMTPUTF8SimTests(unittest.TestCase): self.client_evt.set() # wait for the server thread to terminate self.serv_evt.wait() - join_thread(self.thread) + threading_helper.join_thread(self.thread) del self.thread self.doCleanups() - threading_cleanup(*self.thread_key) + threading_helper.threading_cleanup(*self.thread_key) def test_test_server_supports_extensions(self): smtp = smtplib.SMTP( @@ -1397,7 +1397,7 @@ class SimSMTPAUTHInitialResponseServer(SimSMTPServer): class SMTPAUTHInitialResponseSimTests(unittest.TestCase): def setUp(self): - self.thread_key = threading_setup() + self.thread_key = threading_helper.threading_setup() self.real_getfqdn = socket.getfqdn socket.getfqdn = mock_socket.getfqdn self.serv_evt = threading.Event() @@ -1421,10 +1421,10 @@ class SMTPAUTHInitialResponseSimTests(unittest.TestCase): self.client_evt.set() # wait for the server thread to terminate self.serv_evt.wait() - join_thread(self.thread) + threading_helper.join_thread(self.thread) del self.thread self.doCleanups() - threading_cleanup(*self.thread_key) + threading_helper.threading_cleanup(*self.thread_key) def testAUTH_PLAIN_initial_response_login(self): self.serv.add_feature('AUTH PLAIN') diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index dc13307..cff07b4 100755 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1,6 +1,7 @@ import unittest from test import support from test.support import socket_helper +from test.support import threading_helper import errno import io @@ -336,7 +337,7 @@ class ThreadableTest: self.server_ready.set() def _setUp(self): - self.wait_threads = support.wait_threads_exit() + self.wait_threads = threading_helper.wait_threads_exit() self.wait_threads.__enter__() self.server_ready = threading.Event() @@ -6665,9 +6666,9 @@ def test_main(): ]) tests.append(TestMSWindowsTCPFlags) - thread_info = support.threading_setup() + thread_info = threading_helper.threading_setup() support.run_unittest(*tests) - support.threading_cleanup(*thread_info) + threading_helper.threading_cleanup(*thread_info) if __name__ == "__main__": diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index c663cc9..5db8cec 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -14,8 +14,9 @@ import unittest import socketserver import test.support -from test.support import reap_children, reap_threads, verbose +from test.support import reap_children, verbose from test.support import socket_helper +from test.support import threading_helper test.support.requires("network") @@ -120,7 +121,7 @@ class SocketServerTest(unittest.TestCase): self.assertEqual(server.server_address, server.socket.getsockname()) return server - @reap_threads + @threading_helper.reap_threads def run_server(self, svrcls, hdlrbase, testfunc): server = self.make_server(self.pickaddr(svrcls.address_family), svrcls, hdlrbase) @@ -249,7 +250,7 @@ class SocketServerTest(unittest.TestCase): socketserver.DatagramRequestHandler, self.dgram_examine) - @reap_threads + @threading_helper.reap_threads def test_shutdown(self): # Issue #2302: shutdown() should always succeed in making an # other thread leave serve_forever(). diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 5d496c6..ecb6049 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -5,6 +5,7 @@ import unittest import unittest.mock from test import support from test.support import socket_helper +from test.support import threading_helper import socket import select import time @@ -4429,7 +4430,7 @@ class TestPostHandshakeAuth(unittest.TestCase): # Ignore expected SSLError in ConnectionHandler of ThreadedEchoServer # (it is only raised sometimes on Windows) - with support.catch_threading_exception() as cm: + with threading_helper.catch_threading_exception() as cm: server = ThreadedEchoServer(context=server_context, chatty=False) with server: with client_context.wrap_socket(socket.socket(), @@ -4750,11 +4751,11 @@ def test_main(verbose=False): if support.is_resource_enabled('network'): tests.append(NetworkedTests) - thread_info = support.threading_setup() + thread_info = threading_helper.threading_setup() try: support.run_unittest(*tests) finally: - support.threading_cleanup(*thread_info) + threading_helper.threading_cleanup(*thread_info) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 33b3459..2f93eaa 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1,5 +1,3 @@ -from test import support -from test.support.script_helper import assert_python_ok, assert_python_failure import builtins import codecs import gc @@ -11,6 +9,9 @@ import subprocess import sys import sysconfig import test.support +from test import support +from test.support.script_helper import assert_python_ok, assert_python_failure +from test.support import threading_helper import textwrap import unittest import warnings @@ -365,7 +366,7 @@ class SysModuleTest(unittest.TestCase): ) # sys._current_frames() is a CPython-only gimmick. - @test.support.reap_threads + @threading_helper.reap_threads def test_current_frames(self): import threading import traceback diff --git a/Lib/test/test_thread.py b/Lib/test/test_thread.py index 77e46f2..62b57fa 100644 --- a/Lib/test/test_thread.py +++ b/Lib/test/test_thread.py @@ -2,6 +2,7 @@ import os import unittest import random from test import support +from test.support import threading_helper import _thread as thread import time import weakref @@ -32,8 +33,8 @@ class BasicThreadTest(unittest.TestCase): self.running = 0 self.next_ident = 0 - key = support.threading_setup() - self.addCleanup(support.threading_cleanup, *key) + key = threading_helper.threading_setup() + self.addCleanup(threading_helper.threading_cleanup, *key) class ThreadRunningTests(BasicThreadTest): @@ -58,7 +59,7 @@ class ThreadRunningTests(BasicThreadTest): self.done_mutex.release() def test_starting_threads(self): - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): # Basic test for thread creation. for i in range(NUMTASKS): self.newtask() @@ -94,7 +95,7 @@ class ThreadRunningTests(BasicThreadTest): verbose_print("trying stack_size = (%d)" % tss) self.next_ident = 0 self.created = 0 - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): for i in range(NUMTASKS): self.newtask() @@ -116,7 +117,7 @@ class ThreadRunningTests(BasicThreadTest): mut.acquire() mut.release() - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): thread.start_new_thread(task, ()) while not started: time.sleep(POLL_SLEEP) @@ -140,7 +141,7 @@ class ThreadRunningTests(BasicThreadTest): started = thread.allocate_lock() with support.catch_unraisable_exception() as cm: - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): started.acquire() thread.start_new_thread(task, ()) started.acquire() @@ -180,7 +181,7 @@ class Barrier: class BarrierTest(BasicThreadTest): def test_barrier(self): - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): self.bar = Barrier(NUMTASKS) self.running = NUMTASKS for i in range(NUMTASKS): @@ -223,7 +224,7 @@ class TestForkInThread(unittest.TestCase): self.read_fd, self.write_fd = os.pipe() @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork') - @support.reap_threads + @threading_helper.reap_threads def test_forkinthread(self): pid = None @@ -243,7 +244,7 @@ class TestForkInThread(unittest.TestCase): finally: os._exit(0) - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): thread.start_new_thread(fork_thread, (self.read_fd, self.write_fd)) self.assertEqual(os.read(self.read_fd, 2), b"OK") os.close(self.write_fd) diff --git a/Lib/test/test_threadedtempfile.py b/Lib/test/test_threadedtempfile.py index e1d7a10..fe63c9e 100644 --- a/Lib/test/test_threadedtempfile.py +++ b/Lib/test/test_threadedtempfile.py @@ -15,7 +15,7 @@ provoking a 2.0 failure under Linux. import tempfile -from test.support import start_threads +from test.support import threading_helper import unittest import io import threading @@ -50,7 +50,7 @@ class TempFileGreedy(threading.Thread): class ThreadedTempFileTest(unittest.TestCase): def test_main(self): threads = [TempFileGreedy() for i in range(NUM_THREADS)] - with start_threads(threads, startEvent.set): + with threading_helper.start_threads(threads, startEvent.set): pass ok = sum(t.ok_count for t in threads) errors = [str(t.name) + str(t.errors.getvalue()) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 81e5f70..ad82e30 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -3,6 +3,7 @@ Tests for the threading module. """ import test.support +from test.support import threading_helper from test.support import verbose, import_module, cpython_only from test.support.script_helper import assert_python_ok, assert_python_failure @@ -75,10 +76,10 @@ class TestThread(threading.Thread): class BaseTestCase(unittest.TestCase): def setUp(self): - self._threads = test.support.threading_setup() + self._threads = threading_helper.threading_setup() def tearDown(self): - test.support.threading_cleanup(*self._threads) + threading_helper.threading_cleanup(*self._threads) test.support.reap_children() @@ -130,7 +131,7 @@ class ThreadTests(BaseTestCase): done.set() done = threading.Event() ident = [] - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): tid = _thread.start_new_thread(f, ()) done.wait() self.assertEqual(ident[0], tid) @@ -171,7 +172,7 @@ class ThreadTests(BaseTestCase): mutex = threading.Lock() mutex.acquire() - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): tid = _thread.start_new_thread(f, (mutex,)) # Wait for the thread to finish. mutex.acquire() diff --git a/Lib/test/test_threading_local.py b/Lib/test/test_threading_local.py index 2fd14ae..9862094 100644 --- a/Lib/test/test_threading_local.py +++ b/Lib/test/test_threading_local.py @@ -2,6 +2,7 @@ import sys import unittest from doctest import DocTestSuite from test import support +from test.support import threading_helper import weakref import gc @@ -65,8 +66,8 @@ class BaseLocalTest: # Simply check that the variable is correctly set self.assertEqual(local.x, i) - with support.start_threads(threading.Thread(target=f, args=(i,)) - for i in range(10)): + with threading_helper.start_threads(threading.Thread(target=f, args=(i,)) + for i in range(10)): pass def test_derived_cycle_dealloc(self): diff --git a/Lib/test/test_threadsignals.py b/Lib/test/test_threadsignals.py index eeacd36..15e8078 100644 --- a/Lib/test/test_threadsignals.py +++ b/Lib/test/test_threadsignals.py @@ -5,6 +5,7 @@ import signal import os import sys from test import support +from test.support import threading_helper import _thread as thread import time @@ -39,7 +40,7 @@ def send_signals(): class ThreadSignals(unittest.TestCase): def test_signals(self): - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): # Test signal handling semantics of threads. # We spawn a thread, have the thread send two signals, and # wait for it to finish. Check that we got both signals @@ -129,7 +130,7 @@ class ThreadSignals(unittest.TestCase): def other_thread(): rlock.acquire() - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): thread.start_new_thread(other_thread, ()) # Wait until we can't acquire it without blocking... while rlock.acquire(blocking=False): @@ -165,7 +166,7 @@ class ThreadSignals(unittest.TestCase): time.sleep(0.5) lock.release() - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): thread.start_new_thread(other_thread, ()) # Wait until we can't acquire it without blocking... while lock.acquire(blocking=False): @@ -212,7 +213,7 @@ class ThreadSignals(unittest.TestCase): os.kill(process_pid, signal.SIGUSR1) done.release() - with support.wait_threads_exit(): + with threading_helper.wait_threads_exit(): # Send the signals from the non-main thread, since the main thread # is the only one that can process signals. thread.start_new_thread(send_signals, ()) diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py index ed426b0..e568cc4 100644 --- a/Lib/test/test_urllib2_localnet.py +++ b/Lib/test/test_urllib2_localnet.py @@ -10,6 +10,7 @@ import hashlib from test import support from test.support import hashlib_helper +from test.support import threading_helper try: import ssl @@ -666,11 +667,11 @@ def setUpModule(): # Store the threading_setup in a key and ensure that it is cleaned up # in the tearDown global threads_key - threads_key = support.threading_setup() + threads_key = threading_helper.threading_setup() def tearDownModule(): if threads_key: - support.threading_cleanup(*threads_key) + threading_helper.threading_cleanup(*threads_key) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index f68af52..79f702d 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -16,6 +16,7 @@ import io import contextlib from test import support from test.support import socket_helper +from test.support import threading_helper from test.support import ALWAYS_EQ, LARGEST, SMALLEST try: @@ -1464,7 +1465,7 @@ class UseBuiltinTypesTestCase(unittest.TestCase): self.assertTrue(server.use_builtin_types) -@support.reap_threads +@threading_helper.reap_threads def test_main(): support.run_unittest(XMLRPCTestCase, HelperTestCase, DateTimeTestCase, BinaryTestCase, FaultTestCase, UseBuiltinTypesTestCase, |