Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 1 | import atexit |
| 2 | import faulthandler |
| 3 | import os |
| 4 | import signal |
| 5 | import sys |
| 6 | import unittest |
| 7 | from test import support |
| 8 | try: |
| 9 | import gc |
| 10 | except ImportError: |
| 11 | gc = None |
| 12 | |
Victor Stinner | b136b1a | 2021-04-16 14:33:10 +0200 | [diff] [blame] | 13 | from test.libregrtest.utils import (setup_unraisable_hook, |
| 14 | setup_threading_excepthook) |
Victor Stinner | 95f61c8 | 2019-06-13 01:09:04 +0200 | [diff] [blame] | 15 | |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 16 | |
Miss Islington (bot) | 93d36a5 | 2021-07-16 06:55:26 -0700 | [diff] [blame] | 17 | UNICODE_GUARD_ENV = "PYTHONREGRTEST_UNICODE_GUARD" |
| 18 | |
| 19 | |
Victor Stinner | a204502 | 2015-09-30 02:17:28 +0200 | [diff] [blame] | 20 | def setup_tests(ns): |
Victor Stinner | ccef823 | 2017-10-13 12:59:12 -0700 | [diff] [blame] | 21 | 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 Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 32 | |
Victor Stinner | ccef823 | 2017-10-13 12:59:12 -0700 | [diff] [blame] | 33 | # 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 Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 41 | |
Miss Islington (bot) | 8f6aa48 | 2021-10-21 21:47:07 -0700 | [diff] [blame] | 42 | _adjust_resource_limits() |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 43 | replace_stdout() |
| 44 | support.record_original_stdout(sys.stdout) |
| 45 | |
Victor Stinner | 9759dd3 | 2016-03-30 02:32:52 +0200 | [diff] [blame] | 46 | if ns.testdir: |
| 47 | # Prepend test directory to sys.path, so runtest() will be able |
| 48 | # to locate tests |
| 49 | sys.path.insert(0, os.path.abspath(ns.testdir)) |
| 50 | |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 51 | # Some times __path__ and __file__ are not absolute (e.g. while running from |
| 52 | # Lib/) and, if we change the CWD to run the tests in a temporary dir, some |
| 53 | # imports might fail. This affects only the modules imported before os.chdir(). |
| 54 | # These modules are searched first in sys.path[0] (so '' -- the CWD) and if |
| 55 | # they are found in the CWD their __file__ and __path__ will be relative (this |
| 56 | # happens before the chdir). All the modules imported after the chdir, are |
| 57 | # not found in the CWD, and since the other paths in sys.path[1:] are absolute |
| 58 | # (site.py absolutize them), the __file__ and __path__ will be absolute too. |
| 59 | # Therefore it is necessary to absolutize manually the __file__ and __path__ of |
| 60 | # the packages to prevent later imports to fail when the CWD is different. |
| 61 | for module in sys.modules.values(): |
| 62 | if hasattr(module, '__path__'): |
Victor Stinner | 82f04e2 | 2016-03-15 23:08:44 +0100 | [diff] [blame] | 63 | for index, path in enumerate(module.__path__): |
| 64 | module.__path__[index] = os.path.abspath(path) |
Ned Deily | e52ac04 | 2018-03-28 01:57:13 -0400 | [diff] [blame] | 65 | if getattr(module, '__file__', None): |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 66 | module.__file__ = os.path.abspath(module.__file__) |
| 67 | |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 68 | if ns.huntrleaks: |
| 69 | unittest.BaseTestSuite._cleanup = False |
Pablo Galindo | af5fa13 | 2021-02-28 22:41:09 +0000 | [diff] [blame] | 70 | sys._deactivate_opcache() |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 71 | |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 72 | if ns.memlimit is not None: |
| 73 | support.set_memlimit(ns.memlimit) |
| 74 | |
| 75 | if ns.threshold is not None: |
| 76 | gc.set_threshold(ns.threshold) |
| 77 | |
Victor Stinner | f6e58ae | 2020-06-10 18:49:23 +0200 | [diff] [blame] | 78 | support.suppress_msvcrt_asserts(ns.verbose and ns.verbose >= 2) |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 79 | |
Victor Stinner | a204502 | 2015-09-30 02:17:28 +0200 | [diff] [blame] | 80 | support.use_resources = ns.use_resources |
| 81 | |
Steve Dower | b82e17e | 2019-05-23 08:45:22 -0700 | [diff] [blame] | 82 | if hasattr(sys, 'addaudithook'): |
| 83 | # Add an auditing hook for all tests to ensure PySys_Audit is tested |
| 84 | def _test_audit_hook(name, args): |
| 85 | pass |
| 86 | sys.addaudithook(_test_audit_hook) |
| 87 | |
Victor Stinner | 95f61c8 | 2019-06-13 01:09:04 +0200 | [diff] [blame] | 88 | setup_unraisable_hook() |
Victor Stinner | b136b1a | 2021-04-16 14:33:10 +0200 | [diff] [blame] | 89 | setup_threading_excepthook() |
Victor Stinner | 95f61c8 | 2019-06-13 01:09:04 +0200 | [diff] [blame] | 90 | |
Victor Stinner | 24c6258 | 2019-10-30 12:41:43 +0100 | [diff] [blame] | 91 | if ns.timeout is not None: |
| 92 | # For a slow buildbot worker, increase SHORT_TIMEOUT and LONG_TIMEOUT |
| 93 | support.SHORT_TIMEOUT = max(support.SHORT_TIMEOUT, ns.timeout / 40) |
| 94 | support.LONG_TIMEOUT = max(support.LONG_TIMEOUT, ns.timeout / 4) |
| 95 | |
| 96 | # If --timeout is short: reduce timeouts |
| 97 | support.LOOPBACK_TIMEOUT = min(support.LOOPBACK_TIMEOUT, ns.timeout) |
| 98 | support.INTERNET_TIMEOUT = min(support.INTERNET_TIMEOUT, ns.timeout) |
| 99 | support.SHORT_TIMEOUT = min(support.SHORT_TIMEOUT, ns.timeout) |
| 100 | support.LONG_TIMEOUT = min(support.LONG_TIMEOUT, ns.timeout) |
| 101 | |
Victor Stinner | 30793e8 | 2021-03-23 01:11:31 +0100 | [diff] [blame] | 102 | if ns.xmlpath: |
| 103 | from test.support.testresult import RegressionTestResult |
| 104 | RegressionTestResult.USE_XML = True |
| 105 | |
Miss Islington (bot) | 93d36a5 | 2021-07-16 06:55:26 -0700 | [diff] [blame] | 106 | # Ensure there's a non-ASCII character in env vars at all times to force |
| 107 | # tests consider this case. See BPO-44647 for details. |
| 108 | os.environ.setdefault( |
| 109 | UNICODE_GUARD_ENV, |
| 110 | "\N{SMILING FACE WITH SUNGLASSES}", |
| 111 | ) |
| 112 | |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 113 | |
| 114 | def replace_stdout(): |
| 115 | """Set stdout encoder error handler to backslashreplace (as stderr error |
| 116 | handler) to avoid UnicodeEncodeError when printing a traceback""" |
| 117 | stdout = sys.stdout |
Victor Stinner | ccef823 | 2017-10-13 12:59:12 -0700 | [diff] [blame] | 118 | try: |
| 119 | fd = stdout.fileno() |
| 120 | except ValueError: |
| 121 | # On IDLE, sys.stdout has no file descriptor and is not a TextIOWrapper |
| 122 | # object. Leaving sys.stdout unchanged. |
| 123 | # |
| 124 | # Catch ValueError to catch io.UnsupportedOperation on TextIOBase |
| 125 | # and ValueError on a closed stream. |
| 126 | return |
| 127 | |
| 128 | sys.stdout = open(fd, 'w', |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 129 | encoding=stdout.encoding, |
| 130 | errors="backslashreplace", |
| 131 | closefd=False, |
| 132 | newline='\n') |
| 133 | |
| 134 | def restore_stdout(): |
| 135 | sys.stdout.close() |
| 136 | sys.stdout = stdout |
| 137 | atexit.register(restore_stdout) |
Miss Islington (bot) | 8f6aa48 | 2021-10-21 21:47:07 -0700 | [diff] [blame] | 138 | |
| 139 | |
| 140 | def _adjust_resource_limits(): |
| 141 | """Adjust the system resource limits (ulimit) if needed.""" |
| 142 | try: |
| 143 | import resource |
| 144 | from resource import RLIMIT_NOFILE, RLIM_INFINITY |
| 145 | except ImportError: |
| 146 | return |
| 147 | fd_limit, max_fds = resource.getrlimit(RLIMIT_NOFILE) |
| 148 | # On macOS the default fd limit is sometimes too low (256) for our |
| 149 | # test suite to succeed. Raise it to something more reasonable. |
| 150 | # 1024 is a common Linux default. |
| 151 | desired_fds = 1024 |
| 152 | if fd_limit < desired_fds and fd_limit < max_fds: |
| 153 | new_fd_limit = min(desired_fds, max_fds) |
| 154 | try: |
| 155 | resource.setrlimit(RLIMIT_NOFILE, (new_fd_limit, max_fds)) |
| 156 | print(f"Raised RLIMIT_NOFILE: {fd_limit} -> {new_fd_limit}") |
| 157 | except (ValueError, OSError) as err: |
| 158 | print(f"Unable to raise RLIMIT_NOFILE from {fd_limit} to " |
| 159 | f"{new_fd_limit}: {err}.") |
| 160 | |