Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 78 additions & 67 deletions Doc/library/test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -838,18 +838,6 @@ The :mod:`test.support` module defines the following functions:
.. versionadded:: 3.9


.. function:: wait_threads_exit(timeout=60.0)

Context manager to wait until all threads created in the ``with`` statement
exit.


.. function:: start_threads(threads, unlock=None)

Context manager to start *threads*. It attempts to join the threads upon
exit.


.. function:: calcobjsize(fmt)

Return :func:`struct.calcsize` for ``nP{fmt}0n`` or, if ``gettotalrefcount``
Expand Down Expand Up @@ -988,11 +976,6 @@ The :mod:`test.support` module defines the following functions:
the trace function.


.. decorator:: reap_threads(func)

Decorator to ensure the threads are cleaned up even if the test fails.


.. decorator:: bigmemtest(size, memuse, dry_run=True)

Decorator for bigmem tests.
Expand Down Expand Up @@ -1110,23 +1093,6 @@ The :mod:`test.support` module defines the following functions:
preserve internal cache.


.. function:: threading_setup()

Return current thread count and copy of dangling threads.


.. function:: threading_cleanup(*original_values)

Cleanup up threads not specified in *original_values*. Designed to emit
a warning if a test leaves running threads in the background.


.. function:: join_thread(thread, timeout=30.0)

Join a *thread* within *timeout*. Raise an :exc:`AssertionError` if thread
is still alive after *timeout* seconds.


.. function:: reap_children()

Use this at the end of ``test_main`` whenever sub-processes are started.
Expand All @@ -1140,39 +1106,6 @@ The :mod:`test.support` module defines the following functions:
is raised.


.. function:: catch_threading_exception()

Context manager catching :class:`threading.Thread` exception using
:func:`threading.excepthook`.

Attributes set when an exception is catched:

* ``exc_type``
* ``exc_value``
* ``exc_traceback``
* ``thread``

See :func:`threading.excepthook` documentation.

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)

.. versionadded:: 3.8


.. function:: catch_unraisable_exception()

Context manager catching unraisable exception using
Expand Down Expand Up @@ -1628,3 +1561,81 @@ The module defines the following class:
.. method:: BytecodeTestCase.assertNotInBytecode(x, opname, argval=_UNSPECIFIED)

Throws :exc:`AssertionError` if *opname* is found.


:mod:`test.support.threading_helper` --- Utilities for threading tests
======================================================================

.. module:: test.support.threading_helper
:synopsis: Support for threading tests.

The :mod:`test.support.threading_helper` module provides support for threading tests.

.. versionadded:: 3.10


.. function:: join_thread(thread, timeout=None)

Join a *thread* within *timeout*. Raise an :exc:`AssertionError` if thread
is still alive after *timeout* seconds.


.. decorator:: reap_threads(func)

Decorator to ensure the threads are cleaned up even if the test fails.


.. function:: start_threads(threads, unlock=None)

Context manager to start *threads*. It attempts to join the threads upon
exit.


.. function:: threading_cleanup(*original_values)

Cleanup up threads not specified in *original_values*. Designed to emit
a warning if a test leaves running threads in the background.


.. function:: threading_setup()

Return current thread count and copy of dangling threads.


.. function:: wait_threads_exit(timeout=None)

Context manager to wait until all threads created in the ``with`` statement
exit.


.. function:: catch_threading_exception()

Context manager catching :class:`threading.Thread` exception using
:func:`threading.excepthook`.

Attributes set when an exception is catched:

* ``exc_type``
* ``exc_value``
* ``exc_traceback``
* ``thread``

See :func:`threading.excepthook` documentation.

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)

.. versionadded:: 3.8
3 changes: 2 additions & 1 deletion Lib/distutils/tests/support.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import sysconfig
from copy import deepcopy
import test.support
from test.support import filesystem_helper

from distutils import log
from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL
Expand Down Expand Up @@ -64,7 +65,7 @@ def tearDown(self):
super().tearDown()
while self.tempdirs:
tmpdir = self.tempdirs.pop()
test.support.rmtree(tmpdir)
filesystem_helper.rmtree(tmpdir)

def mkdtemp(self):
"""Create a temporary directory that will be cleaned up.
Expand Down
9 changes: 5 additions & 4 deletions Lib/distutils/tests/test_archive_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
ARCHIVE_FORMATS)
from distutils.spawn import find_executable, spawn
from distutils.tests import support
from test.support import check_warnings, run_unittest, patch, change_cwd
from test.support import check_warnings, run_unittest, patch
from test.support import filesystem_helper

try:
import grp
Expand Down Expand Up @@ -109,7 +110,7 @@ def _make_tarball(self, tmpdir, target_name, suffix, **kwargs):
base_name = os.path.join(tmpdir2, target_name)

# working with relative paths to avoid tar warnings
with change_cwd(tmpdir):
with filesystem_helper.change_cwd(tmpdir):
make_tarball(splitdrive(base_name)[1], 'dist', **kwargs)

# check if the compressed tarball was created
Expand Down Expand Up @@ -238,7 +239,7 @@ def test_make_zipfile(self):
# creating something to tar
tmpdir = self._create_files()
base_name = os.path.join(self.mkdtemp(), 'archive')
with change_cwd(tmpdir):
with filesystem_helper.change_cwd(tmpdir):
make_zipfile(base_name, 'dist')

# check if the compressed tarball was created
Expand All @@ -263,7 +264,7 @@ def fake_zipfile(*a, **kw):
# create something to tar and compress
tmpdir = self._create_files()
base_name = os.path.join(self.mkdtemp(), 'archive')
with change_cwd(tmpdir):
with filesystem_helper.change_cwd(tmpdir):
make_zipfile(base_name, 'dist')

tarball = base_name + '.zip'
Expand Down
3 changes: 2 additions & 1 deletion Lib/distutils/tests/test_build_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import unittest
from test import support
from test.support import filesystem_helper
from test.support.script_helper import assert_python_ok

# http://bugs.python.org/issue4373
Expand All @@ -38,7 +39,7 @@ def setUp(self):
# bpo-30132: On Windows, a .pdb file may be created in the current
# working directory. Create a temporary working directory to cleanup
# everything at the end of the test.
change_cwd = support.change_cwd(self.tmp_dir)
change_cwd = filesystem_helper.change_cwd(self.tmp_dir)
change_cwd.__enter__()
self.addCleanup(change_cwd.__exit__, None, None, None)

Expand Down
9 changes: 5 additions & 4 deletions Lib/distutils/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import shutil
import sys
import test.support
from test.support import filesystem_helper
from test.support import captured_stdout, run_unittest
import unittest
from distutils.tests import support
Expand Down Expand Up @@ -62,13 +63,13 @@ def tearDown(self):
super(CoreTestCase, self).tearDown()

def cleanup_testfn(self):
path = test.support.TESTFN
path = filesystem_helper.TESTFN
if os.path.isfile(path):
os.remove(path)
elif os.path.isdir(path):
shutil.rmtree(path)

def write_setup(self, text, path=test.support.TESTFN):
def write_setup(self, text, path=filesystem_helper.TESTFN):
f = open(path, "w")
try:
f.write(text)
Expand Down Expand Up @@ -105,8 +106,8 @@ def test_run_setup_uses_current_dir(self):
cwd = os.getcwd()

# Create a directory and write the setup.py file there:
os.mkdir(test.support.TESTFN)
setup_py = os.path.join(test.support.TESTFN, "setup.py")
os.mkdir(filesystem_helper.TESTFN)
setup_py = os.path.join(filesystem_helper.TESTFN, "setup.py")
distutils.core.run_setup(
self.write_setup(setup_prints_cwd, path=setup_py))

Expand Down
23 changes: 12 additions & 11 deletions Lib/distutils/tests/test_dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
from distutils.cmd import Command

from test.support import (
TESTFN, captured_stdout, captured_stderr, run_unittest
captured_stdout, captured_stderr, run_unittest
)
from test.support import filesystem_helper
from distutils.tests import support
from distutils import log

Expand Down Expand Up @@ -85,11 +86,11 @@ def test_command_packages_cmdline(self):

def test_venv_install_options(self):
sys.argv.append("install")
self.addCleanup(os.unlink, TESTFN)
self.addCleanup(os.unlink, filesystem_helper.TESTFN)

fakepath = '/somedir'

with open(TESTFN, "w") as f:
with open(filesystem_helper.TESTFN, "w") as f:
print(("[install]\n"
"install-base = {0}\n"
"install-platbase = {0}\n"
Expand All @@ -107,9 +108,9 @@ def test_venv_install_options(self):

# Base case: Not in a Virtual Environment
with mock.patch.multiple(sys, prefix='/a', base_prefix='/a') as values:
d = self.create_distribution([TESTFN])
d = self.create_distribution([filesystem_helper.TESTFN])

option_tuple = (TESTFN, fakepath)
option_tuple = (filesystem_helper.TESTFN, fakepath)

result_dict = {
'install_base': option_tuple,
Expand All @@ -136,35 +137,35 @@ def test_venv_install_options(self):

# Test case: In a Virtual Environment
with mock.patch.multiple(sys, prefix='/a', base_prefix='/b') as values:
d = self.create_distribution([TESTFN])
d = self.create_distribution([filesystem_helper.TESTFN])

for key in result_dict.keys():
self.assertNotIn(key, d.command_options.get('install', {}))

def test_command_packages_configfile(self):
sys.argv.append("build")
self.addCleanup(os.unlink, TESTFN)
f = open(TESTFN, "w")
self.addCleanup(os.unlink, filesystem_helper.TESTFN)
f = open(filesystem_helper.TESTFN, "w")
try:
print("[global]", file=f)
print("command_packages = foo.bar, splat", file=f)
finally:
f.close()

d = self.create_distribution([TESTFN])
d = self.create_distribution([filesystem_helper.TESTFN])
self.assertEqual(d.get_command_packages(),
["distutils.command", "foo.bar", "splat"])

# ensure command line overrides config:
sys.argv[1:] = ["--command-packages", "spork", "build"]
d = self.create_distribution([TESTFN])
d = self.create_distribution([filesystem_helper.TESTFN])
self.assertEqual(d.get_command_packages(),
["distutils.command", "spork"])

# Setting --command-packages to '' should cause the default to
# be used even if a config file specified something else:
sys.argv[1:] = ["--command-packages", "", "build"]
d = self.create_distribution([TESTFN])
d = self.create_distribution([filesystem_helper.TESTFN])
self.assertEqual(d.get_command_packages(), ["distutils.command"])

def test_empty_options(self):
Expand Down
6 changes: 4 additions & 2 deletions Lib/distutils/tests/test_file_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from distutils import log
from distutils.tests import support
from distutils.errors import DistutilsFileError
from test.support import run_unittest, unlink
from test.support import run_unittest
from test.support import filesystem_helper


class FileUtilTestCase(support.TempdirManager, unittest.TestCase):

Expand Down Expand Up @@ -87,7 +89,7 @@ def test_copy_file_hard_link(self):
except OSError as e:
self.skipTest('os.link: %s' % e)
else:
unlink(self.target)
filesystem_helper.unlink(self.target)
st = os.stat(self.source)
copy_file(self.source, self.target, link='hard')
st2 = os.stat(self.source)
Expand Down
Loading