blob: 472c6ebec00cb2888e4b4ef0ccd6399b3cf67d53 [file] [log] [blame]
Victor Stinner234cbef2015-09-30 01:13:53 +02001import atexit
2import faulthandler
3import os
4import signal
5import sys
6import unittest
7from test import support
8try:
9 import gc
10except ImportError:
11 gc = None
12
Victor Stinnerb136b1a2021-04-16 14:33:10 +020013from test.libregrtest.utils import (setup_unraisable_hook,
14 setup_threading_excepthook)
Victor Stinner95f61c82019-06-13 01:09:04 +020015
Victor Stinner234cbef2015-09-30 01:13:53 +020016
Miss Islington (bot)93d36a52021-07-16 06:55:26 -070017UNICODE_GUARD_ENV = "PYTHONREGRTEST_UNICODE_GUARD"
18
19
Victor Stinnera2045022015-09-30 02:17:28 +020020def setup_tests(ns):
Victor Stinnerccef8232017-10-13 12:59:12 -070021 try:
22 stderr_fd = sys.__stderr__.fileno()
23 except (ValueError, AttributeError):
24 # Catch ValueError to catch io.UnsupportedOperation on TextIOBase
25 # and ValueError on a closed stream.
26 #
27 # Catch AttributeError for stderr being None.
28 stderr_fd = None
29 else:
30 # Display the Python traceback on fatal errors (e.g. segfault)
31 faulthandler.enable(all_threads=True, file=stderr_fd)
Victor Stinner234cbef2015-09-30 01:13:53 +020032
Victor Stinnerccef8232017-10-13 12:59:12 -070033 # Display the Python traceback on SIGALRM or SIGUSR1 signal
34 signals = []
35 if hasattr(signal, 'SIGALRM'):
36 signals.append(signal.SIGALRM)
37 if hasattr(signal, 'SIGUSR1'):
38 signals.append(signal.SIGUSR1)
39 for signum in signals:
40 faulthandler.register(signum, chain=True, file=stderr_fd)
Victor Stinner234cbef2015-09-30 01:13:53 +020041
42 replace_stdout()
43 support.record_original_stdout(sys.stdout)
44
Victor Stinner9759dd32016-03-30 02:32:52 +020045 if ns.testdir:
46 # Prepend test directory to sys.path, so runtest() will be able
47 # to locate tests
48 sys.path.insert(0, os.path.abspath(ns.testdir))
49
Victor Stinner234cbef2015-09-30 01:13:53 +020050 # Some times __path__ and __file__ are not absolute (e.g. while running from
51 # Lib/) and, if we change the CWD to run the tests in a temporary dir, some
52 # imports might fail. This affects only the modules imported before os.chdir().
53 # These modules are searched first in sys.path[0] (so '' -- the CWD) and if
54 # they are found in the CWD their __file__ and __path__ will be relative (this
55 # happens before the chdir). All the modules imported after the chdir, are
56 # not found in the CWD, and since the other paths in sys.path[1:] are absolute
57 # (site.py absolutize them), the __file__ and __path__ will be absolute too.
58 # Therefore it is necessary to absolutize manually the __file__ and __path__ of
59 # the packages to prevent later imports to fail when the CWD is different.
60 for module in sys.modules.values():
61 if hasattr(module, '__path__'):
Victor Stinner82f04e22016-03-15 23:08:44 +010062 for index, path in enumerate(module.__path__):
63 module.__path__[index] = os.path.abspath(path)
Ned Deilye52ac042018-03-28 01:57:13 -040064 if getattr(module, '__file__', None):
Victor Stinner234cbef2015-09-30 01:13:53 +020065 module.__file__ = os.path.abspath(module.__file__)
66
Victor Stinner234cbef2015-09-30 01:13:53 +020067 if ns.huntrleaks:
68 unittest.BaseTestSuite._cleanup = False
Pablo Galindoaf5fa132021-02-28 22:41:09 +000069 sys._deactivate_opcache()
Victor Stinner234cbef2015-09-30 01:13:53 +020070
Victor Stinner234cbef2015-09-30 01:13:53 +020071 if ns.memlimit is not None:
72 support.set_memlimit(ns.memlimit)
73
74 if ns.threshold is not None:
75 gc.set_threshold(ns.threshold)
76
Victor Stinnerf6e58ae2020-06-10 18:49:23 +020077 support.suppress_msvcrt_asserts(ns.verbose and ns.verbose >= 2)
Victor Stinner234cbef2015-09-30 01:13:53 +020078
Victor Stinnera2045022015-09-30 02:17:28 +020079 support.use_resources = ns.use_resources
80
Steve Dowerb82e17e2019-05-23 08:45:22 -070081 if hasattr(sys, 'addaudithook'):
82 # Add an auditing hook for all tests to ensure PySys_Audit is tested
83 def _test_audit_hook(name, args):
84 pass
85 sys.addaudithook(_test_audit_hook)
86
Victor Stinner95f61c82019-06-13 01:09:04 +020087 setup_unraisable_hook()
Victor Stinnerb136b1a2021-04-16 14:33:10 +020088 setup_threading_excepthook()
Victor Stinner95f61c82019-06-13 01:09:04 +020089
Victor Stinner24c62582019-10-30 12:41:43 +010090 if ns.timeout is not None:
91 # For a slow buildbot worker, increase SHORT_TIMEOUT and LONG_TIMEOUT
92 support.SHORT_TIMEOUT = max(support.SHORT_TIMEOUT, ns.timeout / 40)
93 support.LONG_TIMEOUT = max(support.LONG_TIMEOUT, ns.timeout / 4)
94
95 # If --timeout is short: reduce timeouts
96 support.LOOPBACK_TIMEOUT = min(support.LOOPBACK_TIMEOUT, ns.timeout)
97 support.INTERNET_TIMEOUT = min(support.INTERNET_TIMEOUT, ns.timeout)
98 support.SHORT_TIMEOUT = min(support.SHORT_TIMEOUT, ns.timeout)
99 support.LONG_TIMEOUT = min(support.LONG_TIMEOUT, ns.timeout)
100
Victor Stinner30793e82021-03-23 01:11:31 +0100101 if ns.xmlpath:
102 from test.support.testresult import RegressionTestResult
103 RegressionTestResult.USE_XML = True
104
Miss Islington (bot)93d36a52021-07-16 06:55:26 -0700105 # Ensure there's a non-ASCII character in env vars at all times to force
106 # tests consider this case. See BPO-44647 for details.
107 os.environ.setdefault(
108 UNICODE_GUARD_ENV,
109 "\N{SMILING FACE WITH SUNGLASSES}",
110 )
111
Victor Stinner234cbef2015-09-30 01:13:53 +0200112
113def replace_stdout():
114 """Set stdout encoder error handler to backslashreplace (as stderr error
115 handler) to avoid UnicodeEncodeError when printing a traceback"""
116 stdout = sys.stdout
Victor Stinnerccef8232017-10-13 12:59:12 -0700117 try:
118 fd = stdout.fileno()
119 except ValueError:
120 # On IDLE, sys.stdout has no file descriptor and is not a TextIOWrapper
121 # object. Leaving sys.stdout unchanged.
122 #
123 # Catch ValueError to catch io.UnsupportedOperation on TextIOBase
124 # and ValueError on a closed stream.
125 return
126
127 sys.stdout = open(fd, 'w',
Victor Stinner234cbef2015-09-30 01:13:53 +0200128 encoding=stdout.encoding,
129 errors="backslashreplace",
130 closefd=False,
131 newline='\n')
132
133 def restore_stdout():
134 sys.stdout.close()
135 sys.stdout = stdout
136 atexit.register(restore_stdout)