setup.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import atexit
  2. import faulthandler
  3. import os
  4. import signal
  5. import sys
  6. import unittest
  7. from test import support
  8. from test.support.os_helper import TESTFN_UNDECODABLE, FS_NONASCII
  9. try:
  10. import gc
  11. except ImportError:
  12. gc = None
  13. from test.libregrtest.utils import (setup_unraisable_hook,
  14. setup_threading_excepthook)
  15. UNICODE_GUARD_ENV = "PYTHONREGRTEST_UNICODE_GUARD"
  16. def setup_tests(ns):
  17. try:
  18. stderr_fd = sys.__stderr__.fileno()
  19. except (ValueError, AttributeError):
  20. # Catch ValueError to catch io.UnsupportedOperation on TextIOBase
  21. # and ValueError on a closed stream.
  22. #
  23. # Catch AttributeError for stderr being None.
  24. stderr_fd = None
  25. else:
  26. # Display the Python traceback on fatal errors (e.g. segfault)
  27. faulthandler.enable(all_threads=True, file=stderr_fd)
  28. # Display the Python traceback on SIGALRM or SIGUSR1 signal
  29. signals = []
  30. if hasattr(signal, 'SIGALRM'):
  31. signals.append(signal.SIGALRM)
  32. if hasattr(signal, 'SIGUSR1'):
  33. signals.append(signal.SIGUSR1)
  34. for signum in signals:
  35. faulthandler.register(signum, chain=True, file=stderr_fd)
  36. _adjust_resource_limits()
  37. replace_stdout()
  38. support.record_original_stdout(sys.stdout)
  39. if ns.testdir:
  40. # Prepend test directory to sys.path, so runtest() will be able
  41. # to locate tests
  42. sys.path.insert(0, os.path.abspath(ns.testdir))
  43. # Some times __path__ and __file__ are not absolute (e.g. while running from
  44. # Lib/) and, if we change the CWD to run the tests in a temporary dir, some
  45. # imports might fail. This affects only the modules imported before os.chdir().
  46. # These modules are searched first in sys.path[0] (so '' -- the CWD) and if
  47. # they are found in the CWD their __file__ and __path__ will be relative (this
  48. # happens before the chdir). All the modules imported after the chdir, are
  49. # not found in the CWD, and since the other paths in sys.path[1:] are absolute
  50. # (site.py absolutize them), the __file__ and __path__ will be absolute too.
  51. # Therefore it is necessary to absolutize manually the __file__ and __path__ of
  52. # the packages to prevent later imports to fail when the CWD is different.
  53. for module in sys.modules.values():
  54. if hasattr(module, '__path__'):
  55. for index, path in enumerate(module.__path__):
  56. module.__path__[index] = os.path.abspath(path)
  57. if getattr(module, '__file__', None):
  58. module.__file__ = os.path.abspath(module.__file__)
  59. if ns.huntrleaks:
  60. unittest.BaseTestSuite._cleanup = False
  61. if ns.memlimit is not None:
  62. support.set_memlimit(ns.memlimit)
  63. if ns.threshold is not None:
  64. gc.set_threshold(ns.threshold)
  65. support.suppress_msvcrt_asserts(ns.verbose and ns.verbose >= 2)
  66. support.use_resources = ns.use_resources
  67. if hasattr(sys, 'addaudithook'):
  68. # Add an auditing hook for all tests to ensure PySys_Audit is tested
  69. def _test_audit_hook(name, args):
  70. pass
  71. sys.addaudithook(_test_audit_hook)
  72. setup_unraisable_hook()
  73. setup_threading_excepthook()
  74. if ns.timeout is not None:
  75. # For a slow buildbot worker, increase SHORT_TIMEOUT and LONG_TIMEOUT
  76. support.SHORT_TIMEOUT = max(support.SHORT_TIMEOUT, ns.timeout / 40)
  77. support.LONG_TIMEOUT = max(support.LONG_TIMEOUT, ns.timeout / 4)
  78. # If --timeout is short: reduce timeouts
  79. support.LOOPBACK_TIMEOUT = min(support.LOOPBACK_TIMEOUT, ns.timeout)
  80. support.INTERNET_TIMEOUT = min(support.INTERNET_TIMEOUT, ns.timeout)
  81. support.SHORT_TIMEOUT = min(support.SHORT_TIMEOUT, ns.timeout)
  82. support.LONG_TIMEOUT = min(support.LONG_TIMEOUT, ns.timeout)
  83. if ns.xmlpath:
  84. from test.support.testresult import RegressionTestResult
  85. RegressionTestResult.USE_XML = True
  86. # Ensure there's a non-ASCII character in env vars at all times to force
  87. # tests consider this case. See BPO-44647 for details.
  88. if TESTFN_UNDECODABLE and os.supports_bytes_environ:
  89. os.environb.setdefault(UNICODE_GUARD_ENV.encode(), TESTFN_UNDECODABLE)
  90. elif FS_NONASCII:
  91. os.environ.setdefault(UNICODE_GUARD_ENV, FS_NONASCII)
  92. def replace_stdout():
  93. """Set stdout encoder error handler to backslashreplace (as stderr error
  94. handler) to avoid UnicodeEncodeError when printing a traceback"""
  95. stdout = sys.stdout
  96. try:
  97. fd = stdout.fileno()
  98. except ValueError:
  99. # On IDLE, sys.stdout has no file descriptor and is not a TextIOWrapper
  100. # object. Leaving sys.stdout unchanged.
  101. #
  102. # Catch ValueError to catch io.UnsupportedOperation on TextIOBase
  103. # and ValueError on a closed stream.
  104. return
  105. sys.stdout = open(fd, 'w',
  106. encoding=stdout.encoding,
  107. errors="backslashreplace",
  108. closefd=False,
  109. newline='\n')
  110. def restore_stdout():
  111. sys.stdout.close()
  112. sys.stdout = stdout
  113. atexit.register(restore_stdout)
  114. def _adjust_resource_limits():
  115. """Adjust the system resource limits (ulimit) if needed."""
  116. try:
  117. import resource
  118. from resource import RLIMIT_NOFILE, RLIM_INFINITY
  119. except ImportError:
  120. return
  121. fd_limit, max_fds = resource.getrlimit(RLIMIT_NOFILE)
  122. # On macOS the default fd limit is sometimes too low (256) for our
  123. # test suite to succeed. Raise it to something more reasonable.
  124. # 1024 is a common Linux default.
  125. desired_fds = 1024
  126. if fd_limit < desired_fds and fd_limit < max_fds:
  127. new_fd_limit = min(desired_fds, max_fds)
  128. try:
  129. resource.setrlimit(RLIMIT_NOFILE, (new_fd_limit, max_fds))
  130. print(f"Raised RLIMIT_NOFILE: {fd_limit} -> {new_fd_limit}")
  131. except (ValueError, OSError) as err:
  132. print(f"Unable to raise RLIMIT_NOFILE from {fd_limit} to "
  133. f"{new_fd_limit}: {err}.")