(root)/
Python-3.12.0/
Lib/
test/
test_support.py
       1  import errno
       2  import importlib
       3  import io
       4  import os
       5  import shutil
       6  import socket
       7  import stat
       8  import subprocess
       9  import sys
      10  import tempfile
      11  import textwrap
      12  import unittest
      13  import warnings
      14  
      15  from test import support
      16  from test.support import import_helper
      17  from test.support import os_helper
      18  from test.support import script_helper
      19  from test.support import socket_helper
      20  from test.support import warnings_helper
      21  
      22  TESTFN = os_helper.TESTFN
      23  
      24  
      25  class ESC[4;38;5;81mTestSupport(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      26      @classmethod
      27      def setUpClass(cls):
      28          orig_filter_len = len(warnings.filters)
      29          cls._warnings_helper_token = support.ignore_deprecations_from(
      30              "test.support.warnings_helper", like=".*used in test_support.*"
      31          )
      32          cls._test_support_token = support.ignore_deprecations_from(
      33              __name__, like=".*You should NOT be seeing this.*"
      34          )
      35          assert len(warnings.filters) == orig_filter_len + 2
      36  
      37      @classmethod
      38      def tearDownClass(cls):
      39          orig_filter_len = len(warnings.filters)
      40          support.clear_ignored_deprecations(
      41              cls._warnings_helper_token,
      42              cls._test_support_token,
      43          )
      44          assert len(warnings.filters) == orig_filter_len - 2
      45  
      46      def test_ignored_deprecations_are_silent(self):
      47          """Test support.ignore_deprecations_from() silences warnings"""
      48          with warnings.catch_warnings(record=True) as warning_objs:
      49              warnings_helper._warn_about_deprecation()
      50              warnings.warn("You should NOT be seeing this.", DeprecationWarning)
      51              messages = [str(w.message) for w in warning_objs]
      52          self.assertEqual(len(messages), 0, messages)
      53  
      54      def test_import_module(self):
      55          import_helper.import_module("ftplib")
      56          self.assertRaises(unittest.SkipTest,
      57                            import_helper.import_module, "foo")
      58  
      59      def test_import_fresh_module(self):
      60          import_helper.import_fresh_module("ftplib")
      61  
      62      def test_get_attribute(self):
      63          self.assertEqual(support.get_attribute(self, "test_get_attribute"),
      64                          self.test_get_attribute)
      65          self.assertRaises(unittest.SkipTest, support.get_attribute, self, "foo")
      66  
      67      @unittest.skip("failing buildbots")
      68      def test_get_original_stdout(self):
      69          self.assertEqual(support.get_original_stdout(), sys.stdout)
      70  
      71      def test_unload(self):
      72          import sched
      73          self.assertIn("sched", sys.modules)
      74          import_helper.unload("sched")
      75          self.assertNotIn("sched", sys.modules)
      76  
      77      def test_unlink(self):
      78          with open(TESTFN, "w", encoding="utf-8") as f:
      79              pass
      80          os_helper.unlink(TESTFN)
      81          self.assertFalse(os.path.exists(TESTFN))
      82          os_helper.unlink(TESTFN)
      83  
      84      def test_rmtree(self):
      85          dirpath = os_helper.TESTFN + 'd'
      86          subdirpath = os.path.join(dirpath, 'subdir')
      87          os.mkdir(dirpath)
      88          os.mkdir(subdirpath)
      89          os_helper.rmtree(dirpath)
      90          self.assertFalse(os.path.exists(dirpath))
      91          with support.swap_attr(support, 'verbose', 0):
      92              os_helper.rmtree(dirpath)
      93  
      94          os.mkdir(dirpath)
      95          os.mkdir(subdirpath)
      96          os.chmod(dirpath, stat.S_IRUSR|stat.S_IXUSR)
      97          with support.swap_attr(support, 'verbose', 0):
      98              os_helper.rmtree(dirpath)
      99          self.assertFalse(os.path.exists(dirpath))
     100  
     101          os.mkdir(dirpath)
     102          os.mkdir(subdirpath)
     103          os.chmod(dirpath, 0)
     104          with support.swap_attr(support, 'verbose', 0):
     105              os_helper.rmtree(dirpath)
     106          self.assertFalse(os.path.exists(dirpath))
     107  
     108      def test_forget(self):
     109          mod_filename = TESTFN + '.py'
     110          with open(mod_filename, 'w', encoding="utf-8") as f:
     111              print('foo = 1', file=f)
     112          sys.path.insert(0, os.curdir)
     113          importlib.invalidate_caches()
     114          try:
     115              mod = __import__(TESTFN)
     116              self.assertIn(TESTFN, sys.modules)
     117  
     118              import_helper.forget(TESTFN)
     119              self.assertNotIn(TESTFN, sys.modules)
     120          finally:
     121              del sys.path[0]
     122              os_helper.unlink(mod_filename)
     123              os_helper.rmtree('__pycache__')
     124  
     125      @support.requires_working_socket()
     126      def test_HOST(self):
     127          s = socket.create_server((socket_helper.HOST, 0))
     128          s.close()
     129  
     130      @support.requires_working_socket()
     131      def test_find_unused_port(self):
     132          port = socket_helper.find_unused_port()
     133          s = socket.create_server((socket_helper.HOST, port))
     134          s.close()
     135  
     136      @support.requires_working_socket()
     137      def test_bind_port(self):
     138          s = socket.socket()
     139          socket_helper.bind_port(s)
     140          s.listen()
     141          s.close()
     142  
     143      # Tests for temp_dir()
     144  
     145      def test_temp_dir(self):
     146          """Test that temp_dir() creates and destroys its directory."""
     147          parent_dir = tempfile.mkdtemp()
     148          parent_dir = os.path.realpath(parent_dir)
     149  
     150          try:
     151              path = os.path.join(parent_dir, 'temp')
     152              self.assertFalse(os.path.isdir(path))
     153              with os_helper.temp_dir(path) as temp_path:
     154                  self.assertEqual(temp_path, path)
     155                  self.assertTrue(os.path.isdir(path))
     156              self.assertFalse(os.path.isdir(path))
     157          finally:
     158              os_helper.rmtree(parent_dir)
     159  
     160      def test_temp_dir__path_none(self):
     161          """Test passing no path."""
     162          with os_helper.temp_dir() as temp_path:
     163              self.assertTrue(os.path.isdir(temp_path))
     164          self.assertFalse(os.path.isdir(temp_path))
     165  
     166      def test_temp_dir__existing_dir__quiet_default(self):
     167          """Test passing a directory that already exists."""
     168          def call_temp_dir(path):
     169              with os_helper.temp_dir(path) as temp_path:
     170                  raise Exception("should not get here")
     171  
     172          path = tempfile.mkdtemp()
     173          path = os.path.realpath(path)
     174          try:
     175              self.assertTrue(os.path.isdir(path))
     176              self.assertRaises(FileExistsError, call_temp_dir, path)
     177              # Make sure temp_dir did not delete the original directory.
     178              self.assertTrue(os.path.isdir(path))
     179          finally:
     180              shutil.rmtree(path)
     181  
     182      def test_temp_dir__existing_dir__quiet_true(self):
     183          """Test passing a directory that already exists with quiet=True."""
     184          path = tempfile.mkdtemp()
     185          path = os.path.realpath(path)
     186  
     187          try:
     188              with warnings_helper.check_warnings() as recorder:
     189                  with os_helper.temp_dir(path, quiet=True) as temp_path:
     190                      self.assertEqual(path, temp_path)
     191                  warnings = [str(w.message) for w in recorder.warnings]
     192              # Make sure temp_dir did not delete the original directory.
     193              self.assertTrue(os.path.isdir(path))
     194          finally:
     195              shutil.rmtree(path)
     196  
     197          self.assertEqual(len(warnings), 1, warnings)
     198          warn = warnings[0]
     199          self.assertTrue(warn.startswith(f'tests may fail, unable to create '
     200                                          f'temporary directory {path!r}: '),
     201                          warn)
     202  
     203      @support.requires_fork()
     204      def test_temp_dir__forked_child(self):
     205          """Test that a forked child process does not remove the directory."""
     206          # See bpo-30028 for details.
     207          # Run the test as an external script, because it uses fork.
     208          script_helper.assert_python_ok("-c", textwrap.dedent("""
     209              import os
     210              from test import support
     211              from test.support import os_helper
     212              with os_helper.temp_cwd() as temp_path:
     213                  pid = os.fork()
     214                  if pid != 0:
     215                      # parent process
     216  
     217                      # wait for the child to terminate
     218                      support.wait_process(pid, exitcode=0)
     219  
     220                      # Make sure that temp_path is still present. When the child
     221                      # process leaves the 'temp_cwd'-context, the __exit__()-
     222                      # method of the context must not remove the temporary
     223                      # directory.
     224                      if not os.path.isdir(temp_path):
     225                          raise AssertionError("Child removed temp_path.")
     226          """))
     227  
     228      # Tests for change_cwd()
     229  
     230      def test_change_cwd(self):
     231          original_cwd = os.getcwd()
     232  
     233          with os_helper.temp_dir() as temp_path:
     234              with os_helper.change_cwd(temp_path) as new_cwd:
     235                  self.assertEqual(new_cwd, temp_path)
     236                  self.assertEqual(os.getcwd(), new_cwd)
     237  
     238          self.assertEqual(os.getcwd(), original_cwd)
     239  
     240      def test_change_cwd__non_existent_dir(self):
     241          """Test passing a non-existent directory."""
     242          original_cwd = os.getcwd()
     243  
     244          def call_change_cwd(path):
     245              with os_helper.change_cwd(path) as new_cwd:
     246                  raise Exception("should not get here")
     247  
     248          with os_helper.temp_dir() as parent_dir:
     249              non_existent_dir = os.path.join(parent_dir, 'does_not_exist')
     250              self.assertRaises(FileNotFoundError, call_change_cwd,
     251                                non_existent_dir)
     252  
     253          self.assertEqual(os.getcwd(), original_cwd)
     254  
     255      def test_change_cwd__non_existent_dir__quiet_true(self):
     256          """Test passing a non-existent directory with quiet=True."""
     257          original_cwd = os.getcwd()
     258  
     259          with os_helper.temp_dir() as parent_dir:
     260              bad_dir = os.path.join(parent_dir, 'does_not_exist')
     261              with warnings_helper.check_warnings() as recorder:
     262                  with os_helper.change_cwd(bad_dir, quiet=True) as new_cwd:
     263                      self.assertEqual(new_cwd, original_cwd)
     264                      self.assertEqual(os.getcwd(), new_cwd)
     265                  warnings = [str(w.message) for w in recorder.warnings]
     266  
     267          self.assertEqual(len(warnings), 1, warnings)
     268          warn = warnings[0]
     269          self.assertTrue(warn.startswith(f'tests may fail, unable to change '
     270                                          f'the current working directory '
     271                                          f'to {bad_dir!r}: '),
     272                          warn)
     273  
     274      # Tests for change_cwd()
     275  
     276      def test_change_cwd__chdir_warning(self):
     277          """Check the warning message when os.chdir() fails."""
     278          path = TESTFN + '_does_not_exist'
     279          with warnings_helper.check_warnings() as recorder:
     280              with os_helper.change_cwd(path=path, quiet=True):
     281                  pass
     282              messages = [str(w.message) for w in recorder.warnings]
     283  
     284          self.assertEqual(len(messages), 1, messages)
     285          msg = messages[0]
     286          self.assertTrue(msg.startswith(f'tests may fail, unable to change '
     287                                         f'the current working directory '
     288                                         f'to {path!r}: '),
     289                          msg)
     290  
     291      # Tests for temp_cwd()
     292  
     293      def test_temp_cwd(self):
     294          here = os.getcwd()
     295          with os_helper.temp_cwd(name=TESTFN):
     296              self.assertEqual(os.path.basename(os.getcwd()), TESTFN)
     297          self.assertFalse(os.path.exists(TESTFN))
     298          self.assertEqual(os.getcwd(), here)
     299  
     300  
     301      def test_temp_cwd__name_none(self):
     302          """Test passing None to temp_cwd()."""
     303          original_cwd = os.getcwd()
     304          with os_helper.temp_cwd(name=None) as new_cwd:
     305              self.assertNotEqual(new_cwd, original_cwd)
     306              self.assertTrue(os.path.isdir(new_cwd))
     307              self.assertEqual(os.getcwd(), new_cwd)
     308          self.assertEqual(os.getcwd(), original_cwd)
     309  
     310      def test_sortdict(self):
     311          self.assertEqual(support.sortdict({3:3, 2:2, 1:1}), "{1: 1, 2: 2, 3: 3}")
     312  
     313      def test_make_bad_fd(self):
     314          fd = os_helper.make_bad_fd()
     315          with self.assertRaises(OSError) as cm:
     316              os.write(fd, b"foo")
     317          self.assertEqual(cm.exception.errno, errno.EBADF)
     318  
     319      def test_check_syntax_error(self):
     320          support.check_syntax_error(self, "def class", lineno=1, offset=5)
     321          with self.assertRaises(AssertionError):
     322              support.check_syntax_error(self, "x=1")
     323  
     324      def test_CleanImport(self):
     325          import importlib
     326          with import_helper.CleanImport("pprint"):
     327              importlib.import_module("pprint")
     328  
     329      def test_DirsOnSysPath(self):
     330          with import_helper.DirsOnSysPath('foo', 'bar'):
     331              self.assertIn("foo", sys.path)
     332              self.assertIn("bar", sys.path)
     333          self.assertNotIn("foo", sys.path)
     334          self.assertNotIn("bar", sys.path)
     335  
     336      def test_captured_stdout(self):
     337          with support.captured_stdout() as stdout:
     338              print("hello")
     339          self.assertEqual(stdout.getvalue(), "hello\n")
     340  
     341      def test_captured_stderr(self):
     342          with support.captured_stderr() as stderr:
     343              print("hello", file=sys.stderr)
     344          self.assertEqual(stderr.getvalue(), "hello\n")
     345  
     346      def test_captured_stdin(self):
     347          with support.captured_stdin() as stdin:
     348              stdin.write('hello\n')
     349              stdin.seek(0)
     350              # call test code that consumes from sys.stdin
     351              captured = input()
     352          self.assertEqual(captured, "hello")
     353  
     354      def test_gc_collect(self):
     355          support.gc_collect()
     356  
     357      def test_python_is_optimized(self):
     358          self.assertIsInstance(support.python_is_optimized(), bool)
     359  
     360      def test_swap_attr(self):
     361          class ESC[4;38;5;81mObj:
     362              pass
     363          obj = Obj()
     364          obj.x = 1
     365          with support.swap_attr(obj, "x", 5) as x:
     366              self.assertEqual(obj.x, 5)
     367              self.assertEqual(x, 1)
     368          self.assertEqual(obj.x, 1)
     369          with support.swap_attr(obj, "y", 5) as y:
     370              self.assertEqual(obj.y, 5)
     371              self.assertIsNone(y)
     372          self.assertFalse(hasattr(obj, 'y'))
     373          with support.swap_attr(obj, "y", 5):
     374              del obj.y
     375          self.assertFalse(hasattr(obj, 'y'))
     376  
     377      def test_swap_item(self):
     378          D = {"x":1}
     379          with support.swap_item(D, "x", 5) as x:
     380              self.assertEqual(D["x"], 5)
     381              self.assertEqual(x, 1)
     382          self.assertEqual(D["x"], 1)
     383          with support.swap_item(D, "y", 5) as y:
     384              self.assertEqual(D["y"], 5)
     385              self.assertIsNone(y)
     386          self.assertNotIn("y", D)
     387          with support.swap_item(D, "y", 5):
     388              del D["y"]
     389          self.assertNotIn("y", D)
     390  
     391      class ESC[4;38;5;81mRefClass:
     392          attribute1 = None
     393          attribute2 = None
     394          _hidden_attribute1 = None
     395          __magic_1__ = None
     396  
     397      class ESC[4;38;5;81mOtherClass:
     398          attribute2 = None
     399          attribute3 = None
     400          __magic_1__ = None
     401          __magic_2__ = None
     402  
     403      def test_detect_api_mismatch(self):
     404          missing_items = support.detect_api_mismatch(self.RefClass,
     405                                                      self.OtherClass)
     406          self.assertEqual({'attribute1'}, missing_items)
     407  
     408          missing_items = support.detect_api_mismatch(self.OtherClass,
     409                                                      self.RefClass)
     410          self.assertEqual({'attribute3', '__magic_2__'}, missing_items)
     411  
     412      def test_detect_api_mismatch__ignore(self):
     413          ignore = ['attribute1', 'attribute3', '__magic_2__', 'not_in_either']
     414  
     415          missing_items = support.detect_api_mismatch(
     416                  self.RefClass, self.OtherClass, ignore=ignore)
     417          self.assertEqual(set(), missing_items)
     418  
     419          missing_items = support.detect_api_mismatch(
     420                  self.OtherClass, self.RefClass, ignore=ignore)
     421          self.assertEqual(set(), missing_items)
     422  
     423      def test_check__all__(self):
     424          extra = {'tempdir'}
     425          not_exported = {'template'}
     426          support.check__all__(self,
     427                               tempfile,
     428                               extra=extra,
     429                               not_exported=not_exported)
     430  
     431          extra = {
     432              'TextTestResult',
     433              'findTestCases',
     434              'getTestCaseNames',
     435              'installHandler',
     436              'makeSuite',
     437          }
     438          not_exported = {'load_tests', "TestProgram", "BaseTestSuite"}
     439          support.check__all__(self,
     440                               unittest,
     441                               ("unittest.result", "unittest.case",
     442                                "unittest.suite", "unittest.loader",
     443                                "unittest.main", "unittest.runner",
     444                                "unittest.signals", "unittest.async_case"),
     445                               extra=extra,
     446                               not_exported=not_exported)
     447  
     448          self.assertRaises(AssertionError, support.check__all__, self, unittest)
     449  
     450      @unittest.skipUnless(hasattr(os, 'waitpid') and hasattr(os, 'WNOHANG'),
     451                           'need os.waitpid() and os.WNOHANG')
     452      @support.requires_fork()
     453      def test_reap_children(self):
     454          # Make sure that there is no other pending child process
     455          support.reap_children()
     456  
     457          # Create a child process
     458          pid = os.fork()
     459          if pid == 0:
     460              # child process: do nothing, just exit
     461              os._exit(0)
     462  
     463          was_altered = support.environment_altered
     464          try:
     465              support.environment_altered = False
     466              stderr = io.StringIO()
     467  
     468              for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
     469                  with support.swap_attr(support.print_warning, 'orig_stderr', stderr):
     470                      support.reap_children()
     471  
     472                  # Use environment_altered to check if reap_children() found
     473                  # the child process
     474                  if support.environment_altered:
     475                      break
     476  
     477              msg = "Warning -- reap_children() reaped child process %s" % pid
     478              self.assertIn(msg, stderr.getvalue())
     479              self.assertTrue(support.environment_altered)
     480          finally:
     481              support.environment_altered = was_altered
     482  
     483          # Just in case, check again that there is no other
     484          # pending child process
     485          support.reap_children()
     486  
     487      @support.requires_subprocess()
     488      def check_options(self, args, func, expected=None):
     489          code = f'from test.support import {func}; print(repr({func}()))'
     490          cmd = [sys.executable, *args, '-c', code]
     491          env = {key: value for key, value in os.environ.items()
     492                 if not key.startswith('PYTHON')}
     493          proc = subprocess.run(cmd,
     494                                stdout=subprocess.PIPE,
     495                                stderr=subprocess.DEVNULL,
     496                                universal_newlines=True,
     497                                env=env)
     498          if expected is None:
     499              expected = args
     500          self.assertEqual(proc.stdout.rstrip(), repr(expected))
     501          self.assertEqual(proc.returncode, 0)
     502  
     503      @support.requires_resource('cpu')
     504      def test_args_from_interpreter_flags(self):
     505          # Test test.support.args_from_interpreter_flags()
     506          for opts in (
     507              # no option
     508              [],
     509              # single option
     510              ['-B'],
     511              ['-s'],
     512              ['-S'],
     513              ['-E'],
     514              ['-v'],
     515              ['-b'],
     516              ['-P'],
     517              ['-q'],
     518              ['-I'],
     519              # same option multiple times
     520              ['-bb'],
     521              ['-vvv'],
     522              # -W options
     523              ['-Wignore'],
     524              # -X options
     525              ['-X', 'dev'],
     526              ['-Wignore', '-X', 'dev'],
     527              ['-X', 'faulthandler'],
     528              ['-X', 'importtime'],
     529              ['-X', 'showrefcount'],
     530              ['-X', 'tracemalloc'],
     531              ['-X', 'tracemalloc=3'],
     532          ):
     533              with self.subTest(opts=opts):
     534                  self.check_options(opts, 'args_from_interpreter_flags')
     535  
     536          self.check_options(['-I', '-E', '-s', '-P'],
     537                             'args_from_interpreter_flags',
     538                             ['-I'])
     539  
     540      def test_optim_args_from_interpreter_flags(self):
     541          # Test test.support.optim_args_from_interpreter_flags()
     542          for opts in (
     543              # no option
     544              [],
     545              ['-O'],
     546              ['-OO'],
     547              ['-OOOO'],
     548          ):
     549              with self.subTest(opts=opts):
     550                  self.check_options(opts, 'optim_args_from_interpreter_flags')
     551  
     552      def test_match_test(self):
     553          class ESC[4;38;5;81mTest:
     554              def __init__(self, test_id):
     555                  self.test_id = test_id
     556  
     557              def id(self):
     558                  return self.test_id
     559  
     560          test_access = Test('test.test_os.FileTests.test_access')
     561          test_chdir = Test('test.test_os.Win32ErrorTests.test_chdir')
     562  
     563          # Test acceptance
     564          with support.swap_attr(support, '_match_test_func', None):
     565              # match all
     566              support.set_match_tests([])
     567              self.assertTrue(support.match_test(test_access))
     568              self.assertTrue(support.match_test(test_chdir))
     569  
     570              # match all using None
     571              support.set_match_tests(None, None)
     572              self.assertTrue(support.match_test(test_access))
     573              self.assertTrue(support.match_test(test_chdir))
     574  
     575              # match the full test identifier
     576              support.set_match_tests([test_access.id()], None)
     577              self.assertTrue(support.match_test(test_access))
     578              self.assertFalse(support.match_test(test_chdir))
     579  
     580              # match the module name
     581              support.set_match_tests(['test_os'], None)
     582              self.assertTrue(support.match_test(test_access))
     583              self.assertTrue(support.match_test(test_chdir))
     584  
     585              # Test '*' pattern
     586              support.set_match_tests(['test_*'], None)
     587              self.assertTrue(support.match_test(test_access))
     588              self.assertTrue(support.match_test(test_chdir))
     589  
     590              # Test case sensitivity
     591              support.set_match_tests(['filetests'], None)
     592              self.assertFalse(support.match_test(test_access))
     593              support.set_match_tests(['FileTests'], None)
     594              self.assertTrue(support.match_test(test_access))
     595  
     596              # Test pattern containing '.' and a '*' metacharacter
     597              support.set_match_tests(['*test_os.*.test_*'], None)
     598              self.assertTrue(support.match_test(test_access))
     599              self.assertTrue(support.match_test(test_chdir))
     600  
     601              # Multiple patterns
     602              support.set_match_tests([test_access.id(), test_chdir.id()], None)
     603              self.assertTrue(support.match_test(test_access))
     604              self.assertTrue(support.match_test(test_chdir))
     605  
     606              support.set_match_tests(['test_access', 'DONTMATCH'], None)
     607              self.assertTrue(support.match_test(test_access))
     608              self.assertFalse(support.match_test(test_chdir))
     609  
     610          # Test rejection
     611          with support.swap_attr(support, '_match_test_func', None):
     612              # match all
     613              support.set_match_tests(ignore_patterns=[])
     614              self.assertTrue(support.match_test(test_access))
     615              self.assertTrue(support.match_test(test_chdir))
     616  
     617              # match all using None
     618              support.set_match_tests(None, None)
     619              self.assertTrue(support.match_test(test_access))
     620              self.assertTrue(support.match_test(test_chdir))
     621  
     622              # match the full test identifier
     623              support.set_match_tests(None, [test_access.id()])
     624              self.assertFalse(support.match_test(test_access))
     625              self.assertTrue(support.match_test(test_chdir))
     626  
     627              # match the module name
     628              support.set_match_tests(None, ['test_os'])
     629              self.assertFalse(support.match_test(test_access))
     630              self.assertFalse(support.match_test(test_chdir))
     631  
     632              # Test '*' pattern
     633              support.set_match_tests(None, ['test_*'])
     634              self.assertFalse(support.match_test(test_access))
     635              self.assertFalse(support.match_test(test_chdir))
     636  
     637              # Test case sensitivity
     638              support.set_match_tests(None, ['filetests'])
     639              self.assertTrue(support.match_test(test_access))
     640              support.set_match_tests(None, ['FileTests'])
     641              self.assertFalse(support.match_test(test_access))
     642  
     643              # Test pattern containing '.' and a '*' metacharacter
     644              support.set_match_tests(None, ['*test_os.*.test_*'])
     645              self.assertFalse(support.match_test(test_access))
     646              self.assertFalse(support.match_test(test_chdir))
     647  
     648              # Multiple patterns
     649              support.set_match_tests(None, [test_access.id(), test_chdir.id()])
     650              self.assertFalse(support.match_test(test_access))
     651              self.assertFalse(support.match_test(test_chdir))
     652  
     653              support.set_match_tests(None, ['test_access', 'DONTMATCH'])
     654              self.assertFalse(support.match_test(test_access))
     655              self.assertTrue(support.match_test(test_chdir))
     656  
     657      @unittest.skipIf(support.is_emscripten, "Unstable in Emscripten")
     658      @unittest.skipIf(support.is_wasi, "Unavailable on WASI")
     659      def test_fd_count(self):
     660          # We cannot test the absolute value of fd_count(): on old Linux
     661          # kernel or glibc versions, os.urandom() keeps a FD open on
     662          # /dev/urandom device and Python has 4 FD opens instead of 3.
     663          # Test is unstable on Emscripten. The platform starts and stops
     664          # background threads that use pipes and epoll fds.
     665          start = os_helper.fd_count()
     666          fd = os.open(__file__, os.O_RDONLY)
     667          try:
     668              more = os_helper.fd_count()
     669          finally:
     670              os.close(fd)
     671          self.assertEqual(more - start, 1)
     672  
     673      def check_print_warning(self, msg, expected):
     674          stderr = io.StringIO()
     675          with support.swap_attr(support.print_warning, 'orig_stderr', stderr):
     676              support.print_warning(msg)
     677          self.assertEqual(stderr.getvalue(), expected)
     678  
     679      def test_print_warning(self):
     680          self.check_print_warning("msg",
     681                                   "Warning -- msg\n")
     682          self.check_print_warning("a\nb",
     683                                   'Warning -- a\nWarning -- b\n')
     684  
     685      def test_has_strftime_extensions(self):
     686          if support.is_emscripten or sys.platform == "win32":
     687              self.assertFalse(support.has_strftime_extensions)
     688          else:
     689              self.assertTrue(support.has_strftime_extensions)
     690  
     691      def test_get_recursion_depth(self):
     692          # test support.get_recursion_depth()
     693          code = textwrap.dedent("""
     694              from test import support
     695              import sys
     696  
     697              def check(cond):
     698                  if not cond:
     699                      raise AssertionError("test failed")
     700  
     701              # depth 1
     702              check(support.get_recursion_depth() == 1)
     703  
     704              # depth 2
     705              def test_func():
     706                  check(support.get_recursion_depth() == 2)
     707              test_func()
     708  
     709              def test_recursive(depth, limit):
     710                  if depth >= limit:
     711                      # cannot call get_recursion_depth() at this depth,
     712                      # it can raise RecursionError
     713                      return
     714                  get_depth = support.get_recursion_depth()
     715                  print(f"test_recursive: {depth}/{limit}: "
     716                        f"get_recursion_depth() says {get_depth}")
     717                  check(get_depth == depth)
     718                  test_recursive(depth + 1, limit)
     719  
     720              # depth up to 25
     721              with support.infinite_recursion(max_depth=25):
     722                  limit = sys.getrecursionlimit()
     723                  print(f"test with sys.getrecursionlimit()={limit}")
     724                  test_recursive(2, limit)
     725  
     726              # depth up to 500
     727              with support.infinite_recursion(max_depth=500):
     728                  limit = sys.getrecursionlimit()
     729                  print(f"test with sys.getrecursionlimit()={limit}")
     730                  test_recursive(2, limit)
     731          """)
     732          script_helper.assert_python_ok("-c", code)
     733  
     734      def test_recursion(self):
     735          # Test infinite_recursion() and get_recursion_available() functions.
     736          def recursive_function(depth):
     737              if depth:
     738                  recursive_function(depth - 1)
     739  
     740          for max_depth in (5, 25, 250):
     741              with support.infinite_recursion(max_depth):
     742                  available = support.get_recursion_available()
     743  
     744                  # Recursion up to 'available' additional frames should be OK.
     745                  recursive_function(available)
     746  
     747                  # Recursion up to 'available+1' additional frames must raise
     748                  # RecursionError. Avoid self.assertRaises(RecursionError) which
     749                  # can consume more than 3 frames and so raises RecursionError.
     750                  try:
     751                      recursive_function(available + 1)
     752                  except RecursionError:
     753                      pass
     754                  else:
     755                      self.fail("RecursionError was not raised")
     756  
     757          # Test the bare minimumum: max_depth=3
     758          with support.infinite_recursion(3):
     759              try:
     760                  recursive_function(3)
     761              except RecursionError:
     762                  pass
     763              else:
     764                  self.fail("RecursionError was not raised")
     765  
     766          #self.assertEqual(available, 2)
     767  
     768      # XXX -follows a list of untested API
     769      # make_legacy_pyc
     770      # is_resource_enabled
     771      # requires
     772      # fcmp
     773      # umaks
     774      # findfile
     775      # check_warnings
     776      # EnvironmentVarGuard
     777      # transient_internet
     778      # run_with_locale
     779      # set_memlimit
     780      # bigmemtest
     781      # precisionbigmemtest
     782      # bigaddrspacetest
     783      # requires_resource
     784      # run_doctest
     785      # threading_cleanup
     786      # reap_threads
     787      # can_symlink
     788      # skip_unless_symlink
     789      # SuppressCrashReport
     790  
     791  
     792  if __name__ == '__main__':
     793      unittest.main()