17db96d56Sopenharmony_ciimport os.path
27db96d56Sopenharmony_cifrom os.path import abspath
37db96d56Sopenharmony_ciimport re
47db96d56Sopenharmony_ciimport sys
57db96d56Sopenharmony_ciimport types
67db96d56Sopenharmony_ciimport pickle
77db96d56Sopenharmony_cifrom test import support
87db96d56Sopenharmony_cifrom test.support import import_helper
97db96d56Sopenharmony_ciimport test.test_importlib.util
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ciimport unittest
127db96d56Sopenharmony_ciimport unittest.mock
137db96d56Sopenharmony_ciimport unittest.test
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ciclass TestableTestProgram(unittest.TestProgram):
177db96d56Sopenharmony_ci    module = None
187db96d56Sopenharmony_ci    exit = True
197db96d56Sopenharmony_ci    defaultTest = failfast = catchbreak = buffer = None
207db96d56Sopenharmony_ci    verbosity = 1
217db96d56Sopenharmony_ci    progName = ''
227db96d56Sopenharmony_ci    testRunner = testLoader = None
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_ci    def __init__(self):
257db96d56Sopenharmony_ci        pass
267db96d56Sopenharmony_ci
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ciclass TestDiscovery(unittest.TestCase):
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci    # Heavily mocked tests so I can avoid hitting the filesystem
317db96d56Sopenharmony_ci    def test_get_name_from_path(self):
327db96d56Sopenharmony_ci        loader = unittest.TestLoader()
337db96d56Sopenharmony_ci        loader._top_level_dir = '/foo'
347db96d56Sopenharmony_ci        name = loader._get_name_from_path('/foo/bar/baz.py')
357db96d56Sopenharmony_ci        self.assertEqual(name, 'bar.baz')
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_ci        if not __debug__:
387db96d56Sopenharmony_ci            # asserts are off
397db96d56Sopenharmony_ci            return
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci        with self.assertRaises(AssertionError):
427db96d56Sopenharmony_ci            loader._get_name_from_path('/bar/baz.py')
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ci    def test_find_tests(self):
457db96d56Sopenharmony_ci        loader = unittest.TestLoader()
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ci        original_listdir = os.listdir
487db96d56Sopenharmony_ci        def restore_listdir():
497db96d56Sopenharmony_ci            os.listdir = original_listdir
507db96d56Sopenharmony_ci        original_isfile = os.path.isfile
517db96d56Sopenharmony_ci        def restore_isfile():
527db96d56Sopenharmony_ci            os.path.isfile = original_isfile
537db96d56Sopenharmony_ci        original_isdir = os.path.isdir
547db96d56Sopenharmony_ci        def restore_isdir():
557db96d56Sopenharmony_ci            os.path.isdir = original_isdir
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci        path_lists = [['test2.py', 'test1.py', 'not_a_test.py', 'test_dir',
587db96d56Sopenharmony_ci                       'test.foo', 'test-not-a-module.py', 'another_dir'],
597db96d56Sopenharmony_ci                      ['test4.py', 'test3.py', ]]
607db96d56Sopenharmony_ci        os.listdir = lambda path: path_lists.pop(0)
617db96d56Sopenharmony_ci        self.addCleanup(restore_listdir)
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci        def isdir(path):
647db96d56Sopenharmony_ci            return path.endswith('dir')
657db96d56Sopenharmony_ci        os.path.isdir = isdir
667db96d56Sopenharmony_ci        self.addCleanup(restore_isdir)
677db96d56Sopenharmony_ci
687db96d56Sopenharmony_ci        def isfile(path):
697db96d56Sopenharmony_ci            # another_dir is not a package and so shouldn't be recursed into
707db96d56Sopenharmony_ci            return not path.endswith('dir') and not 'another_dir' in path
717db96d56Sopenharmony_ci        os.path.isfile = isfile
727db96d56Sopenharmony_ci        self.addCleanup(restore_isfile)
737db96d56Sopenharmony_ci
747db96d56Sopenharmony_ci        loader._get_module_from_name = lambda path: path + ' module'
757db96d56Sopenharmony_ci        orig_load_tests = loader.loadTestsFromModule
767db96d56Sopenharmony_ci        def loadTestsFromModule(module, pattern=None):
777db96d56Sopenharmony_ci            # This is where load_tests is called.
787db96d56Sopenharmony_ci            base = orig_load_tests(module, pattern=pattern)
797db96d56Sopenharmony_ci            return base + [module + ' tests']
807db96d56Sopenharmony_ci        loader.loadTestsFromModule = loadTestsFromModule
817db96d56Sopenharmony_ci        loader.suiteClass = lambda thing: thing
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ci        top_level = os.path.abspath('/foo')
847db96d56Sopenharmony_ci        loader._top_level_dir = top_level
857db96d56Sopenharmony_ci        suite = list(loader._find_tests(top_level, 'test*.py'))
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ci        # The test suites found should be sorted alphabetically for reliable
887db96d56Sopenharmony_ci        # execution order.
897db96d56Sopenharmony_ci        expected = [[name + ' module tests'] for name in
907db96d56Sopenharmony_ci                    ('test1', 'test2', 'test_dir')]
917db96d56Sopenharmony_ci        expected.extend([[('test_dir.%s' % name) + ' module tests'] for name in
927db96d56Sopenharmony_ci                    ('test3', 'test4')])
937db96d56Sopenharmony_ci        self.assertEqual(suite, expected)
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci    def test_find_tests_socket(self):
967db96d56Sopenharmony_ci        # A socket is neither a directory nor a regular file.
977db96d56Sopenharmony_ci        # https://bugs.python.org/issue25320
987db96d56Sopenharmony_ci        loader = unittest.TestLoader()
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_ci        original_listdir = os.listdir
1017db96d56Sopenharmony_ci        def restore_listdir():
1027db96d56Sopenharmony_ci            os.listdir = original_listdir
1037db96d56Sopenharmony_ci        original_isfile = os.path.isfile
1047db96d56Sopenharmony_ci        def restore_isfile():
1057db96d56Sopenharmony_ci            os.path.isfile = original_isfile
1067db96d56Sopenharmony_ci        original_isdir = os.path.isdir
1077db96d56Sopenharmony_ci        def restore_isdir():
1087db96d56Sopenharmony_ci            os.path.isdir = original_isdir
1097db96d56Sopenharmony_ci
1107db96d56Sopenharmony_ci        path_lists = [['socket']]
1117db96d56Sopenharmony_ci        os.listdir = lambda path: path_lists.pop(0)
1127db96d56Sopenharmony_ci        self.addCleanup(restore_listdir)
1137db96d56Sopenharmony_ci
1147db96d56Sopenharmony_ci        os.path.isdir = lambda path: False
1157db96d56Sopenharmony_ci        self.addCleanup(restore_isdir)
1167db96d56Sopenharmony_ci
1177db96d56Sopenharmony_ci        os.path.isfile = lambda path: False
1187db96d56Sopenharmony_ci        self.addCleanup(restore_isfile)
1197db96d56Sopenharmony_ci
1207db96d56Sopenharmony_ci        loader._get_module_from_name = lambda path: path + ' module'
1217db96d56Sopenharmony_ci        orig_load_tests = loader.loadTestsFromModule
1227db96d56Sopenharmony_ci        def loadTestsFromModule(module, pattern=None):
1237db96d56Sopenharmony_ci            # This is where load_tests is called.
1247db96d56Sopenharmony_ci            base = orig_load_tests(module, pattern=pattern)
1257db96d56Sopenharmony_ci            return base + [module + ' tests']
1267db96d56Sopenharmony_ci        loader.loadTestsFromModule = loadTestsFromModule
1277db96d56Sopenharmony_ci        loader.suiteClass = lambda thing: thing
1287db96d56Sopenharmony_ci
1297db96d56Sopenharmony_ci        top_level = os.path.abspath('/foo')
1307db96d56Sopenharmony_ci        loader._top_level_dir = top_level
1317db96d56Sopenharmony_ci        suite = list(loader._find_tests(top_level, 'test*.py'))
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_ci        self.assertEqual(suite, [])
1347db96d56Sopenharmony_ci
1357db96d56Sopenharmony_ci    def test_find_tests_with_package(self):
1367db96d56Sopenharmony_ci        loader = unittest.TestLoader()
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci        original_listdir = os.listdir
1397db96d56Sopenharmony_ci        def restore_listdir():
1407db96d56Sopenharmony_ci            os.listdir = original_listdir
1417db96d56Sopenharmony_ci        original_isfile = os.path.isfile
1427db96d56Sopenharmony_ci        def restore_isfile():
1437db96d56Sopenharmony_ci            os.path.isfile = original_isfile
1447db96d56Sopenharmony_ci        original_isdir = os.path.isdir
1457db96d56Sopenharmony_ci        def restore_isdir():
1467db96d56Sopenharmony_ci            os.path.isdir = original_isdir
1477db96d56Sopenharmony_ci
1487db96d56Sopenharmony_ci        directories = ['a_directory', 'test_directory', 'test_directory2']
1497db96d56Sopenharmony_ci        path_lists = [directories, [], [], []]
1507db96d56Sopenharmony_ci        os.listdir = lambda path: path_lists.pop(0)
1517db96d56Sopenharmony_ci        self.addCleanup(restore_listdir)
1527db96d56Sopenharmony_ci
1537db96d56Sopenharmony_ci        os.path.isdir = lambda path: True
1547db96d56Sopenharmony_ci        self.addCleanup(restore_isdir)
1557db96d56Sopenharmony_ci
1567db96d56Sopenharmony_ci        os.path.isfile = lambda path: os.path.basename(path) not in directories
1577db96d56Sopenharmony_ci        self.addCleanup(restore_isfile)
1587db96d56Sopenharmony_ci
1597db96d56Sopenharmony_ci        class Module(object):
1607db96d56Sopenharmony_ci            paths = []
1617db96d56Sopenharmony_ci            load_tests_args = []
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci            def __init__(self, path):
1647db96d56Sopenharmony_ci                self.path = path
1657db96d56Sopenharmony_ci                self.paths.append(path)
1667db96d56Sopenharmony_ci                if os.path.basename(path) == 'test_directory':
1677db96d56Sopenharmony_ci                    def load_tests(loader, tests, pattern):
1687db96d56Sopenharmony_ci                        self.load_tests_args.append((loader, tests, pattern))
1697db96d56Sopenharmony_ci                        return [self.path + ' load_tests']
1707db96d56Sopenharmony_ci                    self.load_tests = load_tests
1717db96d56Sopenharmony_ci
1727db96d56Sopenharmony_ci            def __eq__(self, other):
1737db96d56Sopenharmony_ci                return self.path == other.path
1747db96d56Sopenharmony_ci
1757db96d56Sopenharmony_ci        loader._get_module_from_name = lambda name: Module(name)
1767db96d56Sopenharmony_ci        orig_load_tests = loader.loadTestsFromModule
1777db96d56Sopenharmony_ci        def loadTestsFromModule(module, pattern=None):
1787db96d56Sopenharmony_ci            # This is where load_tests is called.
1797db96d56Sopenharmony_ci            base = orig_load_tests(module, pattern=pattern)
1807db96d56Sopenharmony_ci            return base + [module.path + ' module tests']
1817db96d56Sopenharmony_ci        loader.loadTestsFromModule = loadTestsFromModule
1827db96d56Sopenharmony_ci        loader.suiteClass = lambda thing: thing
1837db96d56Sopenharmony_ci
1847db96d56Sopenharmony_ci        loader._top_level_dir = '/foo'
1857db96d56Sopenharmony_ci        # this time no '.py' on the pattern so that it can match
1867db96d56Sopenharmony_ci        # a test package
1877db96d56Sopenharmony_ci        suite = list(loader._find_tests('/foo', 'test*'))
1887db96d56Sopenharmony_ci
1897db96d56Sopenharmony_ci        # We should have loaded tests from the a_directory and test_directory2
1907db96d56Sopenharmony_ci        # directly and via load_tests for the test_directory package, which
1917db96d56Sopenharmony_ci        # still calls the baseline module loader.
1927db96d56Sopenharmony_ci        self.assertEqual(suite,
1937db96d56Sopenharmony_ci                         [['a_directory module tests'],
1947db96d56Sopenharmony_ci                          ['test_directory load_tests',
1957db96d56Sopenharmony_ci                           'test_directory module tests'],
1967db96d56Sopenharmony_ci                          ['test_directory2 module tests']])
1977db96d56Sopenharmony_ci
1987db96d56Sopenharmony_ci
1997db96d56Sopenharmony_ci        # The test module paths should be sorted for reliable execution order
2007db96d56Sopenharmony_ci        self.assertEqual(Module.paths,
2017db96d56Sopenharmony_ci                         ['a_directory', 'test_directory', 'test_directory2'])
2027db96d56Sopenharmony_ci
2037db96d56Sopenharmony_ci        # load_tests should have been called once with loader, tests and pattern
2047db96d56Sopenharmony_ci        # (but there are no tests in our stub module itself, so that is [] at
2057db96d56Sopenharmony_ci        # the time of call).
2067db96d56Sopenharmony_ci        self.assertEqual(Module.load_tests_args,
2077db96d56Sopenharmony_ci                         [(loader, [], 'test*')])
2087db96d56Sopenharmony_ci
2097db96d56Sopenharmony_ci    def test_find_tests_default_calls_package_load_tests(self):
2107db96d56Sopenharmony_ci        loader = unittest.TestLoader()
2117db96d56Sopenharmony_ci
2127db96d56Sopenharmony_ci        original_listdir = os.listdir
2137db96d56Sopenharmony_ci        def restore_listdir():
2147db96d56Sopenharmony_ci            os.listdir = original_listdir
2157db96d56Sopenharmony_ci        original_isfile = os.path.isfile
2167db96d56Sopenharmony_ci        def restore_isfile():
2177db96d56Sopenharmony_ci            os.path.isfile = original_isfile
2187db96d56Sopenharmony_ci        original_isdir = os.path.isdir
2197db96d56Sopenharmony_ci        def restore_isdir():
2207db96d56Sopenharmony_ci            os.path.isdir = original_isdir
2217db96d56Sopenharmony_ci
2227db96d56Sopenharmony_ci        directories = ['a_directory', 'test_directory', 'test_directory2']
2237db96d56Sopenharmony_ci        path_lists = [directories, [], [], []]
2247db96d56Sopenharmony_ci        os.listdir = lambda path: path_lists.pop(0)
2257db96d56Sopenharmony_ci        self.addCleanup(restore_listdir)
2267db96d56Sopenharmony_ci
2277db96d56Sopenharmony_ci        os.path.isdir = lambda path: True
2287db96d56Sopenharmony_ci        self.addCleanup(restore_isdir)
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci        os.path.isfile = lambda path: os.path.basename(path) not in directories
2317db96d56Sopenharmony_ci        self.addCleanup(restore_isfile)
2327db96d56Sopenharmony_ci
2337db96d56Sopenharmony_ci        class Module(object):
2347db96d56Sopenharmony_ci            paths = []
2357db96d56Sopenharmony_ci            load_tests_args = []
2367db96d56Sopenharmony_ci
2377db96d56Sopenharmony_ci            def __init__(self, path):
2387db96d56Sopenharmony_ci                self.path = path
2397db96d56Sopenharmony_ci                self.paths.append(path)
2407db96d56Sopenharmony_ci                if os.path.basename(path) == 'test_directory':
2417db96d56Sopenharmony_ci                    def load_tests(loader, tests, pattern):
2427db96d56Sopenharmony_ci                        self.load_tests_args.append((loader, tests, pattern))
2437db96d56Sopenharmony_ci                        return [self.path + ' load_tests']
2447db96d56Sopenharmony_ci                    self.load_tests = load_tests
2457db96d56Sopenharmony_ci
2467db96d56Sopenharmony_ci            def __eq__(self, other):
2477db96d56Sopenharmony_ci                return self.path == other.path
2487db96d56Sopenharmony_ci
2497db96d56Sopenharmony_ci        loader._get_module_from_name = lambda name: Module(name)
2507db96d56Sopenharmony_ci        orig_load_tests = loader.loadTestsFromModule
2517db96d56Sopenharmony_ci        def loadTestsFromModule(module, pattern=None):
2527db96d56Sopenharmony_ci            # This is where load_tests is called.
2537db96d56Sopenharmony_ci            base = orig_load_tests(module, pattern=pattern)
2547db96d56Sopenharmony_ci            return base + [module.path + ' module tests']
2557db96d56Sopenharmony_ci        loader.loadTestsFromModule = loadTestsFromModule
2567db96d56Sopenharmony_ci        loader.suiteClass = lambda thing: thing
2577db96d56Sopenharmony_ci
2587db96d56Sopenharmony_ci        loader._top_level_dir = '/foo'
2597db96d56Sopenharmony_ci        # this time no '.py' on the pattern so that it can match
2607db96d56Sopenharmony_ci        # a test package
2617db96d56Sopenharmony_ci        suite = list(loader._find_tests('/foo', 'test*.py'))
2627db96d56Sopenharmony_ci
2637db96d56Sopenharmony_ci        # We should have loaded tests from the a_directory and test_directory2
2647db96d56Sopenharmony_ci        # directly and via load_tests for the test_directory package, which
2657db96d56Sopenharmony_ci        # still calls the baseline module loader.
2667db96d56Sopenharmony_ci        self.assertEqual(suite,
2677db96d56Sopenharmony_ci                         [['a_directory module tests'],
2687db96d56Sopenharmony_ci                          ['test_directory load_tests',
2697db96d56Sopenharmony_ci                           'test_directory module tests'],
2707db96d56Sopenharmony_ci                          ['test_directory2 module tests']])
2717db96d56Sopenharmony_ci        # The test module paths should be sorted for reliable execution order
2727db96d56Sopenharmony_ci        self.assertEqual(Module.paths,
2737db96d56Sopenharmony_ci                         ['a_directory', 'test_directory', 'test_directory2'])
2747db96d56Sopenharmony_ci
2757db96d56Sopenharmony_ci
2767db96d56Sopenharmony_ci        # load_tests should have been called once with loader, tests and pattern
2777db96d56Sopenharmony_ci        self.assertEqual(Module.load_tests_args,
2787db96d56Sopenharmony_ci                         [(loader, [], 'test*.py')])
2797db96d56Sopenharmony_ci
2807db96d56Sopenharmony_ci    def test_find_tests_customize_via_package_pattern(self):
2817db96d56Sopenharmony_ci        # This test uses the example 'do-nothing' load_tests from
2827db96d56Sopenharmony_ci        # https://docs.python.org/3/library/unittest.html#load-tests-protocol
2837db96d56Sopenharmony_ci        # to make sure that that actually works.
2847db96d56Sopenharmony_ci        # Housekeeping
2857db96d56Sopenharmony_ci        original_listdir = os.listdir
2867db96d56Sopenharmony_ci        def restore_listdir():
2877db96d56Sopenharmony_ci            os.listdir = original_listdir
2887db96d56Sopenharmony_ci        self.addCleanup(restore_listdir)
2897db96d56Sopenharmony_ci        original_isfile = os.path.isfile
2907db96d56Sopenharmony_ci        def restore_isfile():
2917db96d56Sopenharmony_ci            os.path.isfile = original_isfile
2927db96d56Sopenharmony_ci        self.addCleanup(restore_isfile)
2937db96d56Sopenharmony_ci        original_isdir = os.path.isdir
2947db96d56Sopenharmony_ci        def restore_isdir():
2957db96d56Sopenharmony_ci            os.path.isdir = original_isdir
2967db96d56Sopenharmony_ci        self.addCleanup(restore_isdir)
2977db96d56Sopenharmony_ci        self.addCleanup(sys.path.remove, abspath('/foo'))
2987db96d56Sopenharmony_ci
2997db96d56Sopenharmony_ci        # Test data: we expect the following:
3007db96d56Sopenharmony_ci        # a listdir to find our package, and isfile and isdir checks on it.
3017db96d56Sopenharmony_ci        # a module-from-name call to turn that into a module
3027db96d56Sopenharmony_ci        # followed by load_tests.
3037db96d56Sopenharmony_ci        # then our load_tests will call discover() which is messy
3047db96d56Sopenharmony_ci        # but that finally chains into find_tests again for the child dir -
3057db96d56Sopenharmony_ci        # which is why we don't have an infinite loop.
3067db96d56Sopenharmony_ci        # We expect to see:
3077db96d56Sopenharmony_ci        # the module load tests for both package and plain module called,
3087db96d56Sopenharmony_ci        # and the plain module result nested by the package module load_tests
3097db96d56Sopenharmony_ci        # indicating that it was processed and could have been mutated.
3107db96d56Sopenharmony_ci        vfs = {abspath('/foo'): ['my_package'],
3117db96d56Sopenharmony_ci               abspath('/foo/my_package'): ['__init__.py', 'test_module.py']}
3127db96d56Sopenharmony_ci        def list_dir(path):
3137db96d56Sopenharmony_ci            return list(vfs[path])
3147db96d56Sopenharmony_ci        os.listdir = list_dir
3157db96d56Sopenharmony_ci        os.path.isdir = lambda path: not path.endswith('.py')
3167db96d56Sopenharmony_ci        os.path.isfile = lambda path: path.endswith('.py')
3177db96d56Sopenharmony_ci
3187db96d56Sopenharmony_ci        class Module(object):
3197db96d56Sopenharmony_ci            paths = []
3207db96d56Sopenharmony_ci            load_tests_args = []
3217db96d56Sopenharmony_ci
3227db96d56Sopenharmony_ci            def __init__(self, path):
3237db96d56Sopenharmony_ci                self.path = path
3247db96d56Sopenharmony_ci                self.paths.append(path)
3257db96d56Sopenharmony_ci                if path.endswith('test_module'):
3267db96d56Sopenharmony_ci                    def load_tests(loader, tests, pattern):
3277db96d56Sopenharmony_ci                        self.load_tests_args.append((loader, tests, pattern))
3287db96d56Sopenharmony_ci                        return [self.path + ' load_tests']
3297db96d56Sopenharmony_ci                else:
3307db96d56Sopenharmony_ci                    def load_tests(loader, tests, pattern):
3317db96d56Sopenharmony_ci                        self.load_tests_args.append((loader, tests, pattern))
3327db96d56Sopenharmony_ci                        # top level directory cached on loader instance
3337db96d56Sopenharmony_ci                        __file__ = '/foo/my_package/__init__.py'
3347db96d56Sopenharmony_ci                        this_dir = os.path.dirname(__file__)
3357db96d56Sopenharmony_ci                        pkg_tests = loader.discover(
3367db96d56Sopenharmony_ci                            start_dir=this_dir, pattern=pattern)
3377db96d56Sopenharmony_ci                        return [self.path + ' load_tests', tests
3387db96d56Sopenharmony_ci                            ] + pkg_tests
3397db96d56Sopenharmony_ci                self.load_tests = load_tests
3407db96d56Sopenharmony_ci
3417db96d56Sopenharmony_ci            def __eq__(self, other):
3427db96d56Sopenharmony_ci                return self.path == other.path
3437db96d56Sopenharmony_ci
3447db96d56Sopenharmony_ci        loader = unittest.TestLoader()
3457db96d56Sopenharmony_ci        loader._get_module_from_name = lambda name: Module(name)
3467db96d56Sopenharmony_ci        loader.suiteClass = lambda thing: thing
3477db96d56Sopenharmony_ci
3487db96d56Sopenharmony_ci        loader._top_level_dir = abspath('/foo')
3497db96d56Sopenharmony_ci        # this time no '.py' on the pattern so that it can match
3507db96d56Sopenharmony_ci        # a test package
3517db96d56Sopenharmony_ci        suite = list(loader._find_tests(abspath('/foo'), 'test*.py'))
3527db96d56Sopenharmony_ci
3537db96d56Sopenharmony_ci        # We should have loaded tests from both my_package and
3547db96d56Sopenharmony_ci        # my_package.test_module, and also run the load_tests hook in both.
3557db96d56Sopenharmony_ci        # (normally this would be nested TestSuites.)
3567db96d56Sopenharmony_ci        self.assertEqual(suite,
3577db96d56Sopenharmony_ci                         [['my_package load_tests', [],
3587db96d56Sopenharmony_ci                          ['my_package.test_module load_tests']]])
3597db96d56Sopenharmony_ci        # Parents before children.
3607db96d56Sopenharmony_ci        self.assertEqual(Module.paths,
3617db96d56Sopenharmony_ci                         ['my_package', 'my_package.test_module'])
3627db96d56Sopenharmony_ci
3637db96d56Sopenharmony_ci        # load_tests should have been called twice with loader, tests and pattern
3647db96d56Sopenharmony_ci        self.assertEqual(Module.load_tests_args,
3657db96d56Sopenharmony_ci                         [(loader, [], 'test*.py'),
3667db96d56Sopenharmony_ci                          (loader, [], 'test*.py')])
3677db96d56Sopenharmony_ci
3687db96d56Sopenharmony_ci    def test_discover(self):
3697db96d56Sopenharmony_ci        loader = unittest.TestLoader()
3707db96d56Sopenharmony_ci
3717db96d56Sopenharmony_ci        original_isfile = os.path.isfile
3727db96d56Sopenharmony_ci        original_isdir = os.path.isdir
3737db96d56Sopenharmony_ci        def restore_isfile():
3747db96d56Sopenharmony_ci            os.path.isfile = original_isfile
3757db96d56Sopenharmony_ci
3767db96d56Sopenharmony_ci        os.path.isfile = lambda path: False
3777db96d56Sopenharmony_ci        self.addCleanup(restore_isfile)
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_ci        orig_sys_path = sys.path[:]
3807db96d56Sopenharmony_ci        def restore_path():
3817db96d56Sopenharmony_ci            sys.path[:] = orig_sys_path
3827db96d56Sopenharmony_ci        self.addCleanup(restore_path)
3837db96d56Sopenharmony_ci
3847db96d56Sopenharmony_ci        full_path = os.path.abspath(os.path.normpath('/foo'))
3857db96d56Sopenharmony_ci        with self.assertRaises(ImportError):
3867db96d56Sopenharmony_ci            loader.discover('/foo/bar', top_level_dir='/foo')
3877db96d56Sopenharmony_ci
3887db96d56Sopenharmony_ci        self.assertEqual(loader._top_level_dir, full_path)
3897db96d56Sopenharmony_ci        self.assertIn(full_path, sys.path)
3907db96d56Sopenharmony_ci
3917db96d56Sopenharmony_ci        os.path.isfile = lambda path: True
3927db96d56Sopenharmony_ci        os.path.isdir = lambda path: True
3937db96d56Sopenharmony_ci
3947db96d56Sopenharmony_ci        def restore_isdir():
3957db96d56Sopenharmony_ci            os.path.isdir = original_isdir
3967db96d56Sopenharmony_ci        self.addCleanup(restore_isdir)
3977db96d56Sopenharmony_ci
3987db96d56Sopenharmony_ci        _find_tests_args = []
3997db96d56Sopenharmony_ci        def _find_tests(start_dir, pattern):
4007db96d56Sopenharmony_ci            _find_tests_args.append((start_dir, pattern))
4017db96d56Sopenharmony_ci            return ['tests']
4027db96d56Sopenharmony_ci        loader._find_tests = _find_tests
4037db96d56Sopenharmony_ci        loader.suiteClass = str
4047db96d56Sopenharmony_ci
4057db96d56Sopenharmony_ci        suite = loader.discover('/foo/bar/baz', 'pattern', '/foo/bar')
4067db96d56Sopenharmony_ci
4077db96d56Sopenharmony_ci        top_level_dir = os.path.abspath('/foo/bar')
4087db96d56Sopenharmony_ci        start_dir = os.path.abspath('/foo/bar/baz')
4097db96d56Sopenharmony_ci        self.assertEqual(suite, "['tests']")
4107db96d56Sopenharmony_ci        self.assertEqual(loader._top_level_dir, top_level_dir)
4117db96d56Sopenharmony_ci        self.assertEqual(_find_tests_args, [(start_dir, 'pattern')])
4127db96d56Sopenharmony_ci        self.assertIn(top_level_dir, sys.path)
4137db96d56Sopenharmony_ci
4147db96d56Sopenharmony_ci    def test_discover_start_dir_is_package_calls_package_load_tests(self):
4157db96d56Sopenharmony_ci        # This test verifies that the package load_tests in a package is indeed
4167db96d56Sopenharmony_ci        # invoked when the start_dir is a package (and not the top level).
4177db96d56Sopenharmony_ci        # http://bugs.python.org/issue22457
4187db96d56Sopenharmony_ci
4197db96d56Sopenharmony_ci        # Test data: we expect the following:
4207db96d56Sopenharmony_ci        # an isfile to verify the package, then importing and scanning
4217db96d56Sopenharmony_ci        # as per _find_tests' normal behaviour.
4227db96d56Sopenharmony_ci        # We expect to see our load_tests hook called once.
4237db96d56Sopenharmony_ci        vfs = {abspath('/toplevel'): ['startdir'],
4247db96d56Sopenharmony_ci               abspath('/toplevel/startdir'): ['__init__.py']}
4257db96d56Sopenharmony_ci        def list_dir(path):
4267db96d56Sopenharmony_ci            return list(vfs[path])
4277db96d56Sopenharmony_ci        self.addCleanup(setattr, os, 'listdir', os.listdir)
4287db96d56Sopenharmony_ci        os.listdir = list_dir
4297db96d56Sopenharmony_ci        self.addCleanup(setattr, os.path, 'isfile', os.path.isfile)
4307db96d56Sopenharmony_ci        os.path.isfile = lambda path: path.endswith('.py')
4317db96d56Sopenharmony_ci        self.addCleanup(setattr, os.path, 'isdir', os.path.isdir)
4327db96d56Sopenharmony_ci        os.path.isdir = lambda path: not path.endswith('.py')
4337db96d56Sopenharmony_ci        self.addCleanup(sys.path.remove, abspath('/toplevel'))
4347db96d56Sopenharmony_ci
4357db96d56Sopenharmony_ci        class Module(object):
4367db96d56Sopenharmony_ci            paths = []
4377db96d56Sopenharmony_ci            load_tests_args = []
4387db96d56Sopenharmony_ci
4397db96d56Sopenharmony_ci            def __init__(self, path):
4407db96d56Sopenharmony_ci                self.path = path
4417db96d56Sopenharmony_ci
4427db96d56Sopenharmony_ci            def load_tests(self, loader, tests, pattern):
4437db96d56Sopenharmony_ci                return ['load_tests called ' + self.path]
4447db96d56Sopenharmony_ci
4457db96d56Sopenharmony_ci            def __eq__(self, other):
4467db96d56Sopenharmony_ci                return self.path == other.path
4477db96d56Sopenharmony_ci
4487db96d56Sopenharmony_ci        loader = unittest.TestLoader()
4497db96d56Sopenharmony_ci        loader._get_module_from_name = lambda name: Module(name)
4507db96d56Sopenharmony_ci        loader.suiteClass = lambda thing: thing
4517db96d56Sopenharmony_ci
4527db96d56Sopenharmony_ci        suite = loader.discover('/toplevel/startdir', top_level_dir='/toplevel')
4537db96d56Sopenharmony_ci
4547db96d56Sopenharmony_ci        # We should have loaded tests from the package __init__.
4557db96d56Sopenharmony_ci        # (normally this would be nested TestSuites.)
4567db96d56Sopenharmony_ci        self.assertEqual(suite,
4577db96d56Sopenharmony_ci                         [['load_tests called startdir']])
4587db96d56Sopenharmony_ci
4597db96d56Sopenharmony_ci    def setup_import_issue_tests(self, fakefile):
4607db96d56Sopenharmony_ci        listdir = os.listdir
4617db96d56Sopenharmony_ci        os.listdir = lambda _: [fakefile]
4627db96d56Sopenharmony_ci        isfile = os.path.isfile
4637db96d56Sopenharmony_ci        os.path.isfile = lambda _: True
4647db96d56Sopenharmony_ci        orig_sys_path = sys.path[:]
4657db96d56Sopenharmony_ci        def restore():
4667db96d56Sopenharmony_ci            os.path.isfile = isfile
4677db96d56Sopenharmony_ci            os.listdir = listdir
4687db96d56Sopenharmony_ci            sys.path[:] = orig_sys_path
4697db96d56Sopenharmony_ci        self.addCleanup(restore)
4707db96d56Sopenharmony_ci
4717db96d56Sopenharmony_ci    def setup_import_issue_package_tests(self, vfs):
4727db96d56Sopenharmony_ci        self.addCleanup(setattr, os, 'listdir', os.listdir)
4737db96d56Sopenharmony_ci        self.addCleanup(setattr, os.path, 'isfile', os.path.isfile)
4747db96d56Sopenharmony_ci        self.addCleanup(setattr, os.path, 'isdir', os.path.isdir)
4757db96d56Sopenharmony_ci        self.addCleanup(sys.path.__setitem__, slice(None), list(sys.path))
4767db96d56Sopenharmony_ci        def list_dir(path):
4777db96d56Sopenharmony_ci            return list(vfs[path])
4787db96d56Sopenharmony_ci        os.listdir = list_dir
4797db96d56Sopenharmony_ci        os.path.isdir = lambda path: not path.endswith('.py')
4807db96d56Sopenharmony_ci        os.path.isfile = lambda path: path.endswith('.py')
4817db96d56Sopenharmony_ci
4827db96d56Sopenharmony_ci    def test_discover_with_modules_that_fail_to_import(self):
4837db96d56Sopenharmony_ci        loader = unittest.TestLoader()
4847db96d56Sopenharmony_ci
4857db96d56Sopenharmony_ci        self.setup_import_issue_tests('test_this_does_not_exist.py')
4867db96d56Sopenharmony_ci
4877db96d56Sopenharmony_ci        suite = loader.discover('.')
4887db96d56Sopenharmony_ci        self.assertIn(os.getcwd(), sys.path)
4897db96d56Sopenharmony_ci        self.assertEqual(suite.countTestCases(), 1)
4907db96d56Sopenharmony_ci        # Errors loading the suite are also captured for introspection.
4917db96d56Sopenharmony_ci        self.assertNotEqual([], loader.errors)
4927db96d56Sopenharmony_ci        self.assertEqual(1, len(loader.errors))
4937db96d56Sopenharmony_ci        error = loader.errors[0]
4947db96d56Sopenharmony_ci        self.assertTrue(
4957db96d56Sopenharmony_ci            'Failed to import test module: test_this_does_not_exist' in error,
4967db96d56Sopenharmony_ci            'missing error string in %r' % error)
4977db96d56Sopenharmony_ci        test = list(list(suite)[0])[0] # extract test from suite
4987db96d56Sopenharmony_ci
4997db96d56Sopenharmony_ci        with self.assertRaises(ImportError):
5007db96d56Sopenharmony_ci            test.test_this_does_not_exist()
5017db96d56Sopenharmony_ci
5027db96d56Sopenharmony_ci    def test_discover_with_init_modules_that_fail_to_import(self):
5037db96d56Sopenharmony_ci        vfs = {abspath('/foo'): ['my_package'],
5047db96d56Sopenharmony_ci               abspath('/foo/my_package'): ['__init__.py', 'test_module.py']}
5057db96d56Sopenharmony_ci        self.setup_import_issue_package_tests(vfs)
5067db96d56Sopenharmony_ci        import_calls = []
5077db96d56Sopenharmony_ci        def _get_module_from_name(name):
5087db96d56Sopenharmony_ci            import_calls.append(name)
5097db96d56Sopenharmony_ci            raise ImportError("Cannot import Name")
5107db96d56Sopenharmony_ci        loader = unittest.TestLoader()
5117db96d56Sopenharmony_ci        loader._get_module_from_name = _get_module_from_name
5127db96d56Sopenharmony_ci        suite = loader.discover(abspath('/foo'))
5137db96d56Sopenharmony_ci
5147db96d56Sopenharmony_ci        self.assertIn(abspath('/foo'), sys.path)
5157db96d56Sopenharmony_ci        self.assertEqual(suite.countTestCases(), 1)
5167db96d56Sopenharmony_ci        # Errors loading the suite are also captured for introspection.
5177db96d56Sopenharmony_ci        self.assertNotEqual([], loader.errors)
5187db96d56Sopenharmony_ci        self.assertEqual(1, len(loader.errors))
5197db96d56Sopenharmony_ci        error = loader.errors[0]
5207db96d56Sopenharmony_ci        self.assertTrue(
5217db96d56Sopenharmony_ci            'Failed to import test module: my_package' in error,
5227db96d56Sopenharmony_ci            'missing error string in %r' % error)
5237db96d56Sopenharmony_ci        test = list(list(suite)[0])[0] # extract test from suite
5247db96d56Sopenharmony_ci        with self.assertRaises(ImportError):
5257db96d56Sopenharmony_ci            test.my_package()
5267db96d56Sopenharmony_ci        self.assertEqual(import_calls, ['my_package'])
5277db96d56Sopenharmony_ci
5287db96d56Sopenharmony_ci        # Check picklability
5297db96d56Sopenharmony_ci        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
5307db96d56Sopenharmony_ci            pickle.loads(pickle.dumps(test, proto))
5317db96d56Sopenharmony_ci
5327db96d56Sopenharmony_ci    def test_discover_with_module_that_raises_SkipTest_on_import(self):
5337db96d56Sopenharmony_ci        if not unittest.BaseTestSuite._cleanup:
5347db96d56Sopenharmony_ci            raise unittest.SkipTest("Suite cleanup is disabled")
5357db96d56Sopenharmony_ci
5367db96d56Sopenharmony_ci        loader = unittest.TestLoader()
5377db96d56Sopenharmony_ci
5387db96d56Sopenharmony_ci        def _get_module_from_name(name):
5397db96d56Sopenharmony_ci            raise unittest.SkipTest('skipperoo')
5407db96d56Sopenharmony_ci        loader._get_module_from_name = _get_module_from_name
5417db96d56Sopenharmony_ci
5427db96d56Sopenharmony_ci        self.setup_import_issue_tests('test_skip_dummy.py')
5437db96d56Sopenharmony_ci
5447db96d56Sopenharmony_ci        suite = loader.discover('.')
5457db96d56Sopenharmony_ci        self.assertEqual(suite.countTestCases(), 1)
5467db96d56Sopenharmony_ci
5477db96d56Sopenharmony_ci        result = unittest.TestResult()
5487db96d56Sopenharmony_ci        suite.run(result)
5497db96d56Sopenharmony_ci        self.assertEqual(len(result.skipped), 1)
5507db96d56Sopenharmony_ci
5517db96d56Sopenharmony_ci        # Check picklability
5527db96d56Sopenharmony_ci        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
5537db96d56Sopenharmony_ci            pickle.loads(pickle.dumps(suite, proto))
5547db96d56Sopenharmony_ci
5557db96d56Sopenharmony_ci    def test_discover_with_init_module_that_raises_SkipTest_on_import(self):
5567db96d56Sopenharmony_ci        if not unittest.BaseTestSuite._cleanup:
5577db96d56Sopenharmony_ci            raise unittest.SkipTest("Suite cleanup is disabled")
5587db96d56Sopenharmony_ci
5597db96d56Sopenharmony_ci        vfs = {abspath('/foo'): ['my_package'],
5607db96d56Sopenharmony_ci               abspath('/foo/my_package'): ['__init__.py', 'test_module.py']}
5617db96d56Sopenharmony_ci        self.setup_import_issue_package_tests(vfs)
5627db96d56Sopenharmony_ci        import_calls = []
5637db96d56Sopenharmony_ci        def _get_module_from_name(name):
5647db96d56Sopenharmony_ci            import_calls.append(name)
5657db96d56Sopenharmony_ci            raise unittest.SkipTest('skipperoo')
5667db96d56Sopenharmony_ci        loader = unittest.TestLoader()
5677db96d56Sopenharmony_ci        loader._get_module_from_name = _get_module_from_name
5687db96d56Sopenharmony_ci        suite = loader.discover(abspath('/foo'))
5697db96d56Sopenharmony_ci
5707db96d56Sopenharmony_ci        self.assertIn(abspath('/foo'), sys.path)
5717db96d56Sopenharmony_ci        self.assertEqual(suite.countTestCases(), 1)
5727db96d56Sopenharmony_ci        result = unittest.TestResult()
5737db96d56Sopenharmony_ci        suite.run(result)
5747db96d56Sopenharmony_ci        self.assertEqual(len(result.skipped), 1)
5757db96d56Sopenharmony_ci        self.assertEqual(result.testsRun, 1)
5767db96d56Sopenharmony_ci        self.assertEqual(import_calls, ['my_package'])
5777db96d56Sopenharmony_ci
5787db96d56Sopenharmony_ci        # Check picklability
5797db96d56Sopenharmony_ci        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
5807db96d56Sopenharmony_ci            pickle.loads(pickle.dumps(suite, proto))
5817db96d56Sopenharmony_ci
5827db96d56Sopenharmony_ci    def test_command_line_handling_parseArgs(self):
5837db96d56Sopenharmony_ci        program = TestableTestProgram()
5847db96d56Sopenharmony_ci
5857db96d56Sopenharmony_ci        args = []
5867db96d56Sopenharmony_ci        program._do_discovery = args.append
5877db96d56Sopenharmony_ci        program.parseArgs(['something', 'discover'])
5887db96d56Sopenharmony_ci        self.assertEqual(args, [[]])
5897db96d56Sopenharmony_ci
5907db96d56Sopenharmony_ci        args[:] = []
5917db96d56Sopenharmony_ci        program.parseArgs(['something', 'discover', 'foo', 'bar'])
5927db96d56Sopenharmony_ci        self.assertEqual(args, [['foo', 'bar']])
5937db96d56Sopenharmony_ci
5947db96d56Sopenharmony_ci    def test_command_line_handling_discover_by_default(self):
5957db96d56Sopenharmony_ci        program = TestableTestProgram()
5967db96d56Sopenharmony_ci
5977db96d56Sopenharmony_ci        args = []
5987db96d56Sopenharmony_ci        program._do_discovery = args.append
5997db96d56Sopenharmony_ci        program.parseArgs(['something'])
6007db96d56Sopenharmony_ci        self.assertEqual(args, [[]])
6017db96d56Sopenharmony_ci        self.assertEqual(program.verbosity, 1)
6027db96d56Sopenharmony_ci        self.assertIs(program.buffer, False)
6037db96d56Sopenharmony_ci        self.assertIs(program.catchbreak, False)
6047db96d56Sopenharmony_ci        self.assertIs(program.failfast, False)
6057db96d56Sopenharmony_ci
6067db96d56Sopenharmony_ci    def test_command_line_handling_discover_by_default_with_options(self):
6077db96d56Sopenharmony_ci        program = TestableTestProgram()
6087db96d56Sopenharmony_ci
6097db96d56Sopenharmony_ci        args = []
6107db96d56Sopenharmony_ci        program._do_discovery = args.append
6117db96d56Sopenharmony_ci        program.parseArgs(['something', '-v', '-b', '-v', '-c', '-f'])
6127db96d56Sopenharmony_ci        self.assertEqual(args, [[]])
6137db96d56Sopenharmony_ci        self.assertEqual(program.verbosity, 2)
6147db96d56Sopenharmony_ci        self.assertIs(program.buffer, True)
6157db96d56Sopenharmony_ci        self.assertIs(program.catchbreak, True)
6167db96d56Sopenharmony_ci        self.assertIs(program.failfast, True)
6177db96d56Sopenharmony_ci
6187db96d56Sopenharmony_ci
6197db96d56Sopenharmony_ci    def test_command_line_handling_do_discovery_too_many_arguments(self):
6207db96d56Sopenharmony_ci        program = TestableTestProgram()
6217db96d56Sopenharmony_ci        program.testLoader = None
6227db96d56Sopenharmony_ci
6237db96d56Sopenharmony_ci        with support.captured_stderr() as stderr, \
6247db96d56Sopenharmony_ci             self.assertRaises(SystemExit) as cm:
6257db96d56Sopenharmony_ci            # too many args
6267db96d56Sopenharmony_ci            program._do_discovery(['one', 'two', 'three', 'four'])
6277db96d56Sopenharmony_ci        self.assertEqual(cm.exception.args, (2,))
6287db96d56Sopenharmony_ci        self.assertIn('usage:', stderr.getvalue())
6297db96d56Sopenharmony_ci
6307db96d56Sopenharmony_ci
6317db96d56Sopenharmony_ci    def test_command_line_handling_do_discovery_uses_default_loader(self):
6327db96d56Sopenharmony_ci        program = object.__new__(unittest.TestProgram)
6337db96d56Sopenharmony_ci        program._initArgParsers()
6347db96d56Sopenharmony_ci
6357db96d56Sopenharmony_ci        class Loader(object):
6367db96d56Sopenharmony_ci            args = []
6377db96d56Sopenharmony_ci            def discover(self, start_dir, pattern, top_level_dir):
6387db96d56Sopenharmony_ci                self.args.append((start_dir, pattern, top_level_dir))
6397db96d56Sopenharmony_ci                return 'tests'
6407db96d56Sopenharmony_ci
6417db96d56Sopenharmony_ci        program.testLoader = Loader()
6427db96d56Sopenharmony_ci        program._do_discovery(['-v'])
6437db96d56Sopenharmony_ci        self.assertEqual(Loader.args, [('.', 'test*.py', None)])
6447db96d56Sopenharmony_ci
6457db96d56Sopenharmony_ci    def test_command_line_handling_do_discovery_calls_loader(self):
6467db96d56Sopenharmony_ci        program = TestableTestProgram()
6477db96d56Sopenharmony_ci
6487db96d56Sopenharmony_ci        class Loader(object):
6497db96d56Sopenharmony_ci            args = []
6507db96d56Sopenharmony_ci            def discover(self, start_dir, pattern, top_level_dir):
6517db96d56Sopenharmony_ci                self.args.append((start_dir, pattern, top_level_dir))
6527db96d56Sopenharmony_ci                return 'tests'
6537db96d56Sopenharmony_ci
6547db96d56Sopenharmony_ci        program._do_discovery(['-v'], Loader=Loader)
6557db96d56Sopenharmony_ci        self.assertEqual(program.verbosity, 2)
6567db96d56Sopenharmony_ci        self.assertEqual(program.test, 'tests')
6577db96d56Sopenharmony_ci        self.assertEqual(Loader.args, [('.', 'test*.py', None)])
6587db96d56Sopenharmony_ci
6597db96d56Sopenharmony_ci        Loader.args = []
6607db96d56Sopenharmony_ci        program = TestableTestProgram()
6617db96d56Sopenharmony_ci        program._do_discovery(['--verbose'], Loader=Loader)
6627db96d56Sopenharmony_ci        self.assertEqual(program.test, 'tests')
6637db96d56Sopenharmony_ci        self.assertEqual(Loader.args, [('.', 'test*.py', None)])
6647db96d56Sopenharmony_ci
6657db96d56Sopenharmony_ci        Loader.args = []
6667db96d56Sopenharmony_ci        program = TestableTestProgram()
6677db96d56Sopenharmony_ci        program._do_discovery([], Loader=Loader)
6687db96d56Sopenharmony_ci        self.assertEqual(program.test, 'tests')
6697db96d56Sopenharmony_ci        self.assertEqual(Loader.args, [('.', 'test*.py', None)])
6707db96d56Sopenharmony_ci
6717db96d56Sopenharmony_ci        Loader.args = []
6727db96d56Sopenharmony_ci        program = TestableTestProgram()
6737db96d56Sopenharmony_ci        program._do_discovery(['fish'], Loader=Loader)
6747db96d56Sopenharmony_ci        self.assertEqual(program.test, 'tests')
6757db96d56Sopenharmony_ci        self.assertEqual(Loader.args, [('fish', 'test*.py', None)])
6767db96d56Sopenharmony_ci
6777db96d56Sopenharmony_ci        Loader.args = []
6787db96d56Sopenharmony_ci        program = TestableTestProgram()
6797db96d56Sopenharmony_ci        program._do_discovery(['fish', 'eggs'], Loader=Loader)
6807db96d56Sopenharmony_ci        self.assertEqual(program.test, 'tests')
6817db96d56Sopenharmony_ci        self.assertEqual(Loader.args, [('fish', 'eggs', None)])
6827db96d56Sopenharmony_ci
6837db96d56Sopenharmony_ci        Loader.args = []
6847db96d56Sopenharmony_ci        program = TestableTestProgram()
6857db96d56Sopenharmony_ci        program._do_discovery(['fish', 'eggs', 'ham'], Loader=Loader)
6867db96d56Sopenharmony_ci        self.assertEqual(program.test, 'tests')
6877db96d56Sopenharmony_ci        self.assertEqual(Loader.args, [('fish', 'eggs', 'ham')])
6887db96d56Sopenharmony_ci
6897db96d56Sopenharmony_ci        Loader.args = []
6907db96d56Sopenharmony_ci        program = TestableTestProgram()
6917db96d56Sopenharmony_ci        program._do_discovery(['-s', 'fish'], Loader=Loader)
6927db96d56Sopenharmony_ci        self.assertEqual(program.test, 'tests')
6937db96d56Sopenharmony_ci        self.assertEqual(Loader.args, [('fish', 'test*.py', None)])
6947db96d56Sopenharmony_ci
6957db96d56Sopenharmony_ci        Loader.args = []
6967db96d56Sopenharmony_ci        program = TestableTestProgram()
6977db96d56Sopenharmony_ci        program._do_discovery(['-t', 'fish'], Loader=Loader)
6987db96d56Sopenharmony_ci        self.assertEqual(program.test, 'tests')
6997db96d56Sopenharmony_ci        self.assertEqual(Loader.args, [('.', 'test*.py', 'fish')])
7007db96d56Sopenharmony_ci
7017db96d56Sopenharmony_ci        Loader.args = []
7027db96d56Sopenharmony_ci        program = TestableTestProgram()
7037db96d56Sopenharmony_ci        program._do_discovery(['-p', 'fish'], Loader=Loader)
7047db96d56Sopenharmony_ci        self.assertEqual(program.test, 'tests')
7057db96d56Sopenharmony_ci        self.assertEqual(Loader.args, [('.', 'fish', None)])
7067db96d56Sopenharmony_ci        self.assertFalse(program.failfast)
7077db96d56Sopenharmony_ci        self.assertFalse(program.catchbreak)
7087db96d56Sopenharmony_ci
7097db96d56Sopenharmony_ci        Loader.args = []
7107db96d56Sopenharmony_ci        program = TestableTestProgram()
7117db96d56Sopenharmony_ci        program._do_discovery(['-p', 'eggs', '-s', 'fish', '-v', '-f', '-c'],
7127db96d56Sopenharmony_ci                              Loader=Loader)
7137db96d56Sopenharmony_ci        self.assertEqual(program.test, 'tests')
7147db96d56Sopenharmony_ci        self.assertEqual(Loader.args, [('fish', 'eggs', None)])
7157db96d56Sopenharmony_ci        self.assertEqual(program.verbosity, 2)
7167db96d56Sopenharmony_ci        self.assertTrue(program.failfast)
7177db96d56Sopenharmony_ci        self.assertTrue(program.catchbreak)
7187db96d56Sopenharmony_ci
7197db96d56Sopenharmony_ci    def setup_module_clash(self):
7207db96d56Sopenharmony_ci        class Module(object):
7217db96d56Sopenharmony_ci            __file__ = 'bar/foo.py'
7227db96d56Sopenharmony_ci        sys.modules['foo'] = Module
7237db96d56Sopenharmony_ci        full_path = os.path.abspath('foo')
7247db96d56Sopenharmony_ci        original_listdir = os.listdir
7257db96d56Sopenharmony_ci        original_isfile = os.path.isfile
7267db96d56Sopenharmony_ci        original_isdir = os.path.isdir
7277db96d56Sopenharmony_ci        original_realpath = os.path.realpath
7287db96d56Sopenharmony_ci
7297db96d56Sopenharmony_ci        def cleanup():
7307db96d56Sopenharmony_ci            os.listdir = original_listdir
7317db96d56Sopenharmony_ci            os.path.isfile = original_isfile
7327db96d56Sopenharmony_ci            os.path.isdir = original_isdir
7337db96d56Sopenharmony_ci            os.path.realpath = original_realpath
7347db96d56Sopenharmony_ci            del sys.modules['foo']
7357db96d56Sopenharmony_ci            if full_path in sys.path:
7367db96d56Sopenharmony_ci                sys.path.remove(full_path)
7377db96d56Sopenharmony_ci        self.addCleanup(cleanup)
7387db96d56Sopenharmony_ci
7397db96d56Sopenharmony_ci        def listdir(_):
7407db96d56Sopenharmony_ci            return ['foo.py']
7417db96d56Sopenharmony_ci        def isfile(_):
7427db96d56Sopenharmony_ci            return True
7437db96d56Sopenharmony_ci        def isdir(_):
7447db96d56Sopenharmony_ci            return True
7457db96d56Sopenharmony_ci        os.listdir = listdir
7467db96d56Sopenharmony_ci        os.path.isfile = isfile
7477db96d56Sopenharmony_ci        os.path.isdir = isdir
7487db96d56Sopenharmony_ci        if os.name == 'nt':
7497db96d56Sopenharmony_ci            # ntpath.realpath may inject path prefixes when failing to
7507db96d56Sopenharmony_ci            # resolve real files, so we substitute abspath() here instead.
7517db96d56Sopenharmony_ci            os.path.realpath = os.path.abspath
7527db96d56Sopenharmony_ci        return full_path
7537db96d56Sopenharmony_ci
7547db96d56Sopenharmony_ci    def test_detect_module_clash(self):
7557db96d56Sopenharmony_ci        full_path = self.setup_module_clash()
7567db96d56Sopenharmony_ci        loader = unittest.TestLoader()
7577db96d56Sopenharmony_ci
7587db96d56Sopenharmony_ci        mod_dir = os.path.abspath('bar')
7597db96d56Sopenharmony_ci        expected_dir = os.path.abspath('foo')
7607db96d56Sopenharmony_ci        msg = re.escape(r"'foo' module incorrectly imported from %r. Expected %r. "
7617db96d56Sopenharmony_ci                "Is this module globally installed?" % (mod_dir, expected_dir))
7627db96d56Sopenharmony_ci        self.assertRaisesRegex(
7637db96d56Sopenharmony_ci            ImportError, '^%s$' % msg, loader.discover,
7647db96d56Sopenharmony_ci            start_dir='foo', pattern='foo.py'
7657db96d56Sopenharmony_ci        )
7667db96d56Sopenharmony_ci        self.assertEqual(sys.path[0], full_path)
7677db96d56Sopenharmony_ci
7687db96d56Sopenharmony_ci    def test_module_symlink_ok(self):
7697db96d56Sopenharmony_ci        full_path = self.setup_module_clash()
7707db96d56Sopenharmony_ci
7717db96d56Sopenharmony_ci        original_realpath = os.path.realpath
7727db96d56Sopenharmony_ci
7737db96d56Sopenharmony_ci        mod_dir = os.path.abspath('bar')
7747db96d56Sopenharmony_ci        expected_dir = os.path.abspath('foo')
7757db96d56Sopenharmony_ci
7767db96d56Sopenharmony_ci        def cleanup():
7777db96d56Sopenharmony_ci            os.path.realpath = original_realpath
7787db96d56Sopenharmony_ci        self.addCleanup(cleanup)
7797db96d56Sopenharmony_ci
7807db96d56Sopenharmony_ci        def realpath(path):
7817db96d56Sopenharmony_ci            if path == os.path.join(mod_dir, 'foo.py'):
7827db96d56Sopenharmony_ci                return os.path.join(expected_dir, 'foo.py')
7837db96d56Sopenharmony_ci            return path
7847db96d56Sopenharmony_ci        os.path.realpath = realpath
7857db96d56Sopenharmony_ci        loader = unittest.TestLoader()
7867db96d56Sopenharmony_ci        loader.discover(start_dir='foo', pattern='foo.py')
7877db96d56Sopenharmony_ci
7887db96d56Sopenharmony_ci    def test_discovery_from_dotted_path(self):
7897db96d56Sopenharmony_ci        loader = unittest.TestLoader()
7907db96d56Sopenharmony_ci
7917db96d56Sopenharmony_ci        tests = [self]
7927db96d56Sopenharmony_ci        expectedPath = os.path.abspath(os.path.dirname(unittest.test.__file__))
7937db96d56Sopenharmony_ci
7947db96d56Sopenharmony_ci        self.wasRun = False
7957db96d56Sopenharmony_ci        def _find_tests(start_dir, pattern):
7967db96d56Sopenharmony_ci            self.wasRun = True
7977db96d56Sopenharmony_ci            self.assertEqual(start_dir, expectedPath)
7987db96d56Sopenharmony_ci            return tests
7997db96d56Sopenharmony_ci        loader._find_tests = _find_tests
8007db96d56Sopenharmony_ci        suite = loader.discover('unittest.test')
8017db96d56Sopenharmony_ci        self.assertTrue(self.wasRun)
8027db96d56Sopenharmony_ci        self.assertEqual(suite._tests, tests)
8037db96d56Sopenharmony_ci
8047db96d56Sopenharmony_ci
8057db96d56Sopenharmony_ci    def test_discovery_from_dotted_path_builtin_modules(self):
8067db96d56Sopenharmony_ci
8077db96d56Sopenharmony_ci        loader = unittest.TestLoader()
8087db96d56Sopenharmony_ci
8097db96d56Sopenharmony_ci        listdir = os.listdir
8107db96d56Sopenharmony_ci        os.listdir = lambda _: ['test_this_does_not_exist.py']
8117db96d56Sopenharmony_ci        isfile = os.path.isfile
8127db96d56Sopenharmony_ci        isdir = os.path.isdir
8137db96d56Sopenharmony_ci        os.path.isdir = lambda _: False
8147db96d56Sopenharmony_ci        orig_sys_path = sys.path[:]
8157db96d56Sopenharmony_ci        def restore():
8167db96d56Sopenharmony_ci            os.path.isfile = isfile
8177db96d56Sopenharmony_ci            os.path.isdir = isdir
8187db96d56Sopenharmony_ci            os.listdir = listdir
8197db96d56Sopenharmony_ci            sys.path[:] = orig_sys_path
8207db96d56Sopenharmony_ci        self.addCleanup(restore)
8217db96d56Sopenharmony_ci
8227db96d56Sopenharmony_ci        with self.assertRaises(TypeError) as cm:
8237db96d56Sopenharmony_ci            loader.discover('sys')
8247db96d56Sopenharmony_ci        self.assertEqual(str(cm.exception),
8257db96d56Sopenharmony_ci                         'Can not use builtin modules '
8267db96d56Sopenharmony_ci                         'as dotted module names')
8277db96d56Sopenharmony_ci
8287db96d56Sopenharmony_ci    def test_discovery_failed_discovery(self):
8297db96d56Sopenharmony_ci        loader = unittest.TestLoader()
8307db96d56Sopenharmony_ci        package = types.ModuleType('package')
8317db96d56Sopenharmony_ci
8327db96d56Sopenharmony_ci        def _import(packagename, *args, **kwargs):
8337db96d56Sopenharmony_ci            sys.modules[packagename] = package
8347db96d56Sopenharmony_ci            return package
8357db96d56Sopenharmony_ci
8367db96d56Sopenharmony_ci        with unittest.mock.patch('builtins.__import__', _import):
8377db96d56Sopenharmony_ci            # Since loader.discover() can modify sys.path, restore it when done.
8387db96d56Sopenharmony_ci            with import_helper.DirsOnSysPath():
8397db96d56Sopenharmony_ci                # Make sure to remove 'package' from sys.modules when done.
8407db96d56Sopenharmony_ci                with test.test_importlib.util.uncache('package'):
8417db96d56Sopenharmony_ci                    with self.assertRaises(TypeError) as cm:
8427db96d56Sopenharmony_ci                        loader.discover('package')
8437db96d56Sopenharmony_ci                    self.assertEqual(str(cm.exception),
8447db96d56Sopenharmony_ci                                     'don\'t know how to discover from {!r}'
8457db96d56Sopenharmony_ci                                     .format(package))
8467db96d56Sopenharmony_ci
8477db96d56Sopenharmony_ci
8487db96d56Sopenharmony_ciif __name__ == '__main__':
8497db96d56Sopenharmony_ci    unittest.main()
850