17db96d56Sopenharmony_ci"""Tests for distutils.command.install."""
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ciimport os
47db96d56Sopenharmony_ciimport sys
57db96d56Sopenharmony_ciimport unittest
67db96d56Sopenharmony_ciimport site
77db96d56Sopenharmony_ci
87db96d56Sopenharmony_cifrom test.support import captured_stdout, run_unittest, requires_subprocess
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_cifrom distutils import sysconfig
117db96d56Sopenharmony_cifrom distutils.command.install import install, HAS_USER_SITE
127db96d56Sopenharmony_cifrom distutils.command import install as install_module
137db96d56Sopenharmony_cifrom distutils.command.build_ext import build_ext
147db96d56Sopenharmony_cifrom distutils.command.install import INSTALL_SCHEMES
157db96d56Sopenharmony_cifrom distutils.core import Distribution
167db96d56Sopenharmony_cifrom distutils.errors import DistutilsOptionError
177db96d56Sopenharmony_cifrom distutils.extension import Extension
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_cifrom distutils.tests import support
207db96d56Sopenharmony_cifrom test import support as test_support
217db96d56Sopenharmony_ci
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_cidef _make_ext_name(modname):
247db96d56Sopenharmony_ci    return modname + sysconfig.get_config_var('EXT_SUFFIX')
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ci
277db96d56Sopenharmony_ciclass InstallTestCase(support.TempdirManager,
287db96d56Sopenharmony_ci                      support.EnvironGuard,
297db96d56Sopenharmony_ci                      support.LoggingSilencer,
307db96d56Sopenharmony_ci                      unittest.TestCase):
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci    def setUp(self):
337db96d56Sopenharmony_ci        super().setUp()
347db96d56Sopenharmony_ci        self._backup_config_vars = dict(sysconfig._config_vars)
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ci    def tearDown(self):
377db96d56Sopenharmony_ci        super().tearDown()
387db96d56Sopenharmony_ci        sysconfig._config_vars.clear()
397db96d56Sopenharmony_ci        sysconfig._config_vars.update(self._backup_config_vars)
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci    def test_home_installation_scheme(self):
427db96d56Sopenharmony_ci        # This ensure two things:
437db96d56Sopenharmony_ci        # - that --home generates the desired set of directory names
447db96d56Sopenharmony_ci        # - test --home is supported on all platforms
457db96d56Sopenharmony_ci        builddir = self.mkdtemp()
467db96d56Sopenharmony_ci        destination = os.path.join(builddir, "installation")
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_ci        dist = Distribution({"name": "foopkg"})
497db96d56Sopenharmony_ci        # script_name need not exist, it just need to be initialized
507db96d56Sopenharmony_ci        dist.script_name = os.path.join(builddir, "setup.py")
517db96d56Sopenharmony_ci        dist.command_obj["build"] = support.DummyCommand(
527db96d56Sopenharmony_ci            build_base=builddir,
537db96d56Sopenharmony_ci            build_lib=os.path.join(builddir, "lib"),
547db96d56Sopenharmony_ci            )
557db96d56Sopenharmony_ci
567db96d56Sopenharmony_ci        cmd = install(dist)
577db96d56Sopenharmony_ci        cmd.home = destination
587db96d56Sopenharmony_ci        cmd.ensure_finalized()
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ci        self.assertEqual(cmd.install_base, destination)
617db96d56Sopenharmony_ci        self.assertEqual(cmd.install_platbase, destination)
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci        def check_path(got, expected):
647db96d56Sopenharmony_ci            got = os.path.normpath(got)
657db96d56Sopenharmony_ci            expected = os.path.normpath(expected)
667db96d56Sopenharmony_ci            self.assertEqual(got, expected)
677db96d56Sopenharmony_ci
687db96d56Sopenharmony_ci        libdir = os.path.join(destination, "lib", "python")
697db96d56Sopenharmony_ci        check_path(cmd.install_lib, libdir)
707db96d56Sopenharmony_ci        platlibdir = os.path.join(destination, sys.platlibdir, "python")
717db96d56Sopenharmony_ci        check_path(cmd.install_platlib, platlibdir)
727db96d56Sopenharmony_ci        check_path(cmd.install_purelib, libdir)
737db96d56Sopenharmony_ci        check_path(cmd.install_headers,
747db96d56Sopenharmony_ci                   os.path.join(destination, "include", "python", "foopkg"))
757db96d56Sopenharmony_ci        check_path(cmd.install_scripts, os.path.join(destination, "bin"))
767db96d56Sopenharmony_ci        check_path(cmd.install_data, destination)
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ci    @unittest.skipUnless(HAS_USER_SITE, 'need user site')
797db96d56Sopenharmony_ci    def test_user_site(self):
807db96d56Sopenharmony_ci        # test install with --user
817db96d56Sopenharmony_ci        # preparing the environment for the test
827db96d56Sopenharmony_ci        self.old_user_base = site.USER_BASE
837db96d56Sopenharmony_ci        self.old_user_site = site.USER_SITE
847db96d56Sopenharmony_ci        self.tmpdir = self.mkdtemp()
857db96d56Sopenharmony_ci        self.user_base = os.path.join(self.tmpdir, 'B')
867db96d56Sopenharmony_ci        self.user_site = os.path.join(self.tmpdir, 'S')
877db96d56Sopenharmony_ci        site.USER_BASE = self.user_base
887db96d56Sopenharmony_ci        site.USER_SITE = self.user_site
897db96d56Sopenharmony_ci        install_module.USER_BASE = self.user_base
907db96d56Sopenharmony_ci        install_module.USER_SITE = self.user_site
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ci        def _expanduser(path):
937db96d56Sopenharmony_ci            return self.tmpdir
947db96d56Sopenharmony_ci        self.old_expand = os.path.expanduser
957db96d56Sopenharmony_ci        os.path.expanduser = _expanduser
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_ci        def cleanup():
987db96d56Sopenharmony_ci            site.USER_BASE = self.old_user_base
997db96d56Sopenharmony_ci            site.USER_SITE = self.old_user_site
1007db96d56Sopenharmony_ci            install_module.USER_BASE = self.old_user_base
1017db96d56Sopenharmony_ci            install_module.USER_SITE = self.old_user_site
1027db96d56Sopenharmony_ci            os.path.expanduser = self.old_expand
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ci        self.addCleanup(cleanup)
1057db96d56Sopenharmony_ci
1067db96d56Sopenharmony_ci        if HAS_USER_SITE:
1077db96d56Sopenharmony_ci            for key in ('nt_user', 'unix_user'):
1087db96d56Sopenharmony_ci                self.assertIn(key, INSTALL_SCHEMES)
1097db96d56Sopenharmony_ci
1107db96d56Sopenharmony_ci        dist = Distribution({'name': 'xx'})
1117db96d56Sopenharmony_ci        cmd = install(dist)
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_ci        # making sure the user option is there
1147db96d56Sopenharmony_ci        options = [name for name, short, lable in
1157db96d56Sopenharmony_ci                   cmd.user_options]
1167db96d56Sopenharmony_ci        self.assertIn('user', options)
1177db96d56Sopenharmony_ci
1187db96d56Sopenharmony_ci        # setting a value
1197db96d56Sopenharmony_ci        cmd.user = 1
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_ci        # user base and site shouldn't be created yet
1227db96d56Sopenharmony_ci        self.assertFalse(os.path.exists(self.user_base))
1237db96d56Sopenharmony_ci        self.assertFalse(os.path.exists(self.user_site))
1247db96d56Sopenharmony_ci
1257db96d56Sopenharmony_ci        # let's run finalize
1267db96d56Sopenharmony_ci        cmd.ensure_finalized()
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_ci        # now they should
1297db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(self.user_base))
1307db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(self.user_site))
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_ci        self.assertIn('userbase', cmd.config_vars)
1337db96d56Sopenharmony_ci        self.assertIn('usersite', cmd.config_vars)
1347db96d56Sopenharmony_ci
1357db96d56Sopenharmony_ci    def test_handle_extra_path(self):
1367db96d56Sopenharmony_ci        dist = Distribution({'name': 'xx', 'extra_path': 'path,dirs'})
1377db96d56Sopenharmony_ci        cmd = install(dist)
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_ci        # two elements
1407db96d56Sopenharmony_ci        cmd.handle_extra_path()
1417db96d56Sopenharmony_ci        self.assertEqual(cmd.extra_path, ['path', 'dirs'])
1427db96d56Sopenharmony_ci        self.assertEqual(cmd.extra_dirs, 'dirs')
1437db96d56Sopenharmony_ci        self.assertEqual(cmd.path_file, 'path')
1447db96d56Sopenharmony_ci
1457db96d56Sopenharmony_ci        # one element
1467db96d56Sopenharmony_ci        cmd.extra_path = ['path']
1477db96d56Sopenharmony_ci        cmd.handle_extra_path()
1487db96d56Sopenharmony_ci        self.assertEqual(cmd.extra_path, ['path'])
1497db96d56Sopenharmony_ci        self.assertEqual(cmd.extra_dirs, 'path')
1507db96d56Sopenharmony_ci        self.assertEqual(cmd.path_file, 'path')
1517db96d56Sopenharmony_ci
1527db96d56Sopenharmony_ci        # none
1537db96d56Sopenharmony_ci        dist.extra_path = cmd.extra_path = None
1547db96d56Sopenharmony_ci        cmd.handle_extra_path()
1557db96d56Sopenharmony_ci        self.assertEqual(cmd.extra_path, None)
1567db96d56Sopenharmony_ci        self.assertEqual(cmd.extra_dirs, '')
1577db96d56Sopenharmony_ci        self.assertEqual(cmd.path_file, None)
1587db96d56Sopenharmony_ci
1597db96d56Sopenharmony_ci        # three elements (no way !)
1607db96d56Sopenharmony_ci        cmd.extra_path = 'path,dirs,again'
1617db96d56Sopenharmony_ci        self.assertRaises(DistutilsOptionError, cmd.handle_extra_path)
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci    def test_finalize_options(self):
1647db96d56Sopenharmony_ci        dist = Distribution({'name': 'xx'})
1657db96d56Sopenharmony_ci        cmd = install(dist)
1667db96d56Sopenharmony_ci
1677db96d56Sopenharmony_ci        # must supply either prefix/exec-prefix/home or
1687db96d56Sopenharmony_ci        # install-base/install-platbase -- not both
1697db96d56Sopenharmony_ci        cmd.prefix = 'prefix'
1707db96d56Sopenharmony_ci        cmd.install_base = 'base'
1717db96d56Sopenharmony_ci        self.assertRaises(DistutilsOptionError, cmd.finalize_options)
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_ci        # must supply either home or prefix/exec-prefix -- not both
1747db96d56Sopenharmony_ci        cmd.install_base = None
1757db96d56Sopenharmony_ci        cmd.home = 'home'
1767db96d56Sopenharmony_ci        self.assertRaises(DistutilsOptionError, cmd.finalize_options)
1777db96d56Sopenharmony_ci
1787db96d56Sopenharmony_ci        # can't combine user with prefix/exec_prefix/home or
1797db96d56Sopenharmony_ci        # install_(plat)base
1807db96d56Sopenharmony_ci        cmd.prefix = None
1817db96d56Sopenharmony_ci        cmd.user = 'user'
1827db96d56Sopenharmony_ci        self.assertRaises(DistutilsOptionError, cmd.finalize_options)
1837db96d56Sopenharmony_ci
1847db96d56Sopenharmony_ci    def test_record(self):
1857db96d56Sopenharmony_ci        install_dir = self.mkdtemp()
1867db96d56Sopenharmony_ci        project_dir, dist = self.create_dist(py_modules=['hello'],
1877db96d56Sopenharmony_ci                                             scripts=['sayhi'])
1887db96d56Sopenharmony_ci        os.chdir(project_dir)
1897db96d56Sopenharmony_ci        self.write_file('hello.py', "def main(): print('o hai')")
1907db96d56Sopenharmony_ci        self.write_file('sayhi', 'from hello import main; main()')
1917db96d56Sopenharmony_ci
1927db96d56Sopenharmony_ci        cmd = install(dist)
1937db96d56Sopenharmony_ci        dist.command_obj['install'] = cmd
1947db96d56Sopenharmony_ci        cmd.root = install_dir
1957db96d56Sopenharmony_ci        cmd.record = os.path.join(project_dir, 'filelist')
1967db96d56Sopenharmony_ci        cmd.ensure_finalized()
1977db96d56Sopenharmony_ci        cmd.run()
1987db96d56Sopenharmony_ci
1997db96d56Sopenharmony_ci        f = open(cmd.record)
2007db96d56Sopenharmony_ci        try:
2017db96d56Sopenharmony_ci            content = f.read()
2027db96d56Sopenharmony_ci        finally:
2037db96d56Sopenharmony_ci            f.close()
2047db96d56Sopenharmony_ci
2057db96d56Sopenharmony_ci        found = [os.path.basename(line) for line in content.splitlines()]
2067db96d56Sopenharmony_ci        expected = ['hello.py', 'hello.%s.pyc' % sys.implementation.cache_tag,
2077db96d56Sopenharmony_ci                    'sayhi',
2087db96d56Sopenharmony_ci                    'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]]
2097db96d56Sopenharmony_ci        self.assertEqual(found, expected)
2107db96d56Sopenharmony_ci
2117db96d56Sopenharmony_ci    @requires_subprocess()
2127db96d56Sopenharmony_ci    def test_record_extensions(self):
2137db96d56Sopenharmony_ci        cmd = test_support.missing_compiler_executable()
2147db96d56Sopenharmony_ci        if cmd is not None:
2157db96d56Sopenharmony_ci            self.skipTest('The %r command is not found' % cmd)
2167db96d56Sopenharmony_ci        install_dir = self.mkdtemp()
2177db96d56Sopenharmony_ci        project_dir, dist = self.create_dist(ext_modules=[
2187db96d56Sopenharmony_ci            Extension('xx', ['xxmodule.c'])])
2197db96d56Sopenharmony_ci        os.chdir(project_dir)
2207db96d56Sopenharmony_ci        support.copy_xxmodule_c(project_dir)
2217db96d56Sopenharmony_ci
2227db96d56Sopenharmony_ci        buildextcmd = build_ext(dist)
2237db96d56Sopenharmony_ci        support.fixup_build_ext(buildextcmd)
2247db96d56Sopenharmony_ci        buildextcmd.ensure_finalized()
2257db96d56Sopenharmony_ci
2267db96d56Sopenharmony_ci        cmd = install(dist)
2277db96d56Sopenharmony_ci        dist.command_obj['install'] = cmd
2287db96d56Sopenharmony_ci        dist.command_obj['build_ext'] = buildextcmd
2297db96d56Sopenharmony_ci        cmd.root = install_dir
2307db96d56Sopenharmony_ci        cmd.record = os.path.join(project_dir, 'filelist')
2317db96d56Sopenharmony_ci        cmd.ensure_finalized()
2327db96d56Sopenharmony_ci        cmd.run()
2337db96d56Sopenharmony_ci
2347db96d56Sopenharmony_ci        f = open(cmd.record)
2357db96d56Sopenharmony_ci        try:
2367db96d56Sopenharmony_ci            content = f.read()
2377db96d56Sopenharmony_ci        finally:
2387db96d56Sopenharmony_ci            f.close()
2397db96d56Sopenharmony_ci
2407db96d56Sopenharmony_ci        found = [os.path.basename(line) for line in content.splitlines()]
2417db96d56Sopenharmony_ci        expected = [_make_ext_name('xx'),
2427db96d56Sopenharmony_ci                    'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]]
2437db96d56Sopenharmony_ci        self.assertEqual(found, expected)
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ci    def test_debug_mode(self):
2467db96d56Sopenharmony_ci        # this covers the code called when DEBUG is set
2477db96d56Sopenharmony_ci        old_logs_len = len(self.logs)
2487db96d56Sopenharmony_ci        install_module.DEBUG = True
2497db96d56Sopenharmony_ci        try:
2507db96d56Sopenharmony_ci            with captured_stdout():
2517db96d56Sopenharmony_ci                self.test_record()
2527db96d56Sopenharmony_ci        finally:
2537db96d56Sopenharmony_ci            install_module.DEBUG = False
2547db96d56Sopenharmony_ci        self.assertGreater(len(self.logs), old_logs_len)
2557db96d56Sopenharmony_ci
2567db96d56Sopenharmony_ci
2577db96d56Sopenharmony_cidef test_suite():
2587db96d56Sopenharmony_ci    return unittest.TestLoader().loadTestsFromTestCase(InstallTestCase)
2597db96d56Sopenharmony_ci
2607db96d56Sopenharmony_ciif __name__ == "__main__":
2617db96d56Sopenharmony_ci    run_unittest(test_suite())
262