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