2013-01-13 13:16:46 +01:00
|
|
|
"""
|
|
|
|
locations.py tests
|
|
|
|
|
|
|
|
"""
|
2017-05-16 12:16:30 +02:00
|
|
|
import getpass
|
2013-01-13 13:16:46 +01:00
|
|
|
import os
|
|
|
|
import shutil
|
2017-05-16 12:16:30 +02:00
|
|
|
import sys
|
2013-01-13 13:16:46 +01:00
|
|
|
import tempfile
|
2013-08-18 11:59:44 +02:00
|
|
|
|
2018-10-09 08:23:03 +02:00
|
|
|
import pytest
|
2013-01-13 13:16:46 +01:00
|
|
|
from mock import Mock
|
2017-06-13 14:17:00 +02:00
|
|
|
|
2017-08-31 17:48:18 +02:00
|
|
|
from pip._internal.locations import distutils_scheme
|
2013-10-31 13:49:23 +01:00
|
|
|
|
2013-06-15 05:17:45 +02:00
|
|
|
if sys.platform == 'win32':
|
2014-01-28 15:17:51 +01:00
|
|
|
pwd = Mock()
|
2013-06-15 05:17:45 +02:00
|
|
|
else:
|
2014-01-28 15:17:51 +01:00
|
|
|
import pwd
|
2013-06-15 05:17:45 +02:00
|
|
|
|
|
|
|
|
2013-01-13 13:16:46 +01:00
|
|
|
class TestLocations:
|
|
|
|
def setup(self):
|
|
|
|
self.tempdir = tempfile.mkdtemp()
|
|
|
|
self.st_uid = 9999
|
|
|
|
self.username = "example"
|
|
|
|
self.patch()
|
|
|
|
|
2014-04-22 22:09:13 +02:00
|
|
|
def teardown(self):
|
2013-01-13 13:16:46 +01:00
|
|
|
self.revert_patch()
|
|
|
|
shutil.rmtree(self.tempdir, ignore_errors=True)
|
|
|
|
|
|
|
|
def patch(self):
|
|
|
|
""" first store and then patch python methods pythons """
|
|
|
|
self.tempfile_gettempdir = tempfile.gettempdir
|
|
|
|
self.old_os_fstat = os.fstat
|
2013-01-26 08:09:46 +01:00
|
|
|
if sys.platform != 'win32':
|
2013-06-15 05:17:45 +02:00
|
|
|
# os.geteuid and pwd.getpwuid are not implemented on windows
|
|
|
|
self.old_os_geteuid = os.geteuid
|
|
|
|
self.old_pwd_getpwuid = pwd.getpwuid
|
2013-01-13 13:16:46 +01:00
|
|
|
self.old_getpass_getuser = getpass.getuser
|
|
|
|
|
|
|
|
# now patch
|
2014-01-28 15:17:51 +01:00
|
|
|
tempfile.gettempdir = lambda: self.tempdir
|
|
|
|
getpass.getuser = lambda: self.username
|
|
|
|
os.geteuid = lambda: self.st_uid
|
|
|
|
os.fstat = lambda fd: self.get_mock_fstat(fd)
|
2013-01-13 13:16:46 +01:00
|
|
|
|
2013-06-15 05:17:45 +02:00
|
|
|
if sys.platform != 'win32':
|
|
|
|
pwd.getpwuid = lambda uid: self.get_mock_getpwuid(uid)
|
|
|
|
|
2013-01-13 13:16:46 +01:00
|
|
|
def revert_patch(self):
|
|
|
|
""" revert the patches to python methods """
|
|
|
|
tempfile.gettempdir = self.tempfile_gettempdir
|
2013-01-13 13:20:38 +01:00
|
|
|
getpass.getuser = self.old_getpass_getuser
|
2013-01-26 08:09:46 +01:00
|
|
|
if sys.platform != 'win32':
|
2013-06-15 05:17:45 +02:00
|
|
|
# os.geteuid and pwd.getpwuid are not implemented on windows
|
|
|
|
os.geteuid = self.old_os_geteuid
|
|
|
|
pwd.getpwuid = self.old_pwd_getpwuid
|
2013-01-13 13:16:46 +01:00
|
|
|
os.fstat = self.old_os_fstat
|
|
|
|
|
|
|
|
def get_mock_fstat(self, fd):
|
|
|
|
""" returns a basic mock fstat call result.
|
|
|
|
Currently only the st_uid attribute has been set.
|
|
|
|
"""
|
|
|
|
result = Mock()
|
|
|
|
result.st_uid = self.st_uid
|
|
|
|
return result
|
|
|
|
|
2013-06-15 05:17:45 +02:00
|
|
|
def get_mock_getpwuid(self, uid):
|
|
|
|
""" returns a basic mock pwd.getpwuid call result.
|
|
|
|
Currently only the pw_name attribute has been set.
|
|
|
|
"""
|
|
|
|
result = Mock()
|
|
|
|
result.pw_name = self.username
|
|
|
|
return result
|
|
|
|
|
2013-10-31 13:49:23 +01:00
|
|
|
|
2019-09-06 10:29:34 +02:00
|
|
|
class TestDistutilsScheme:
|
2013-10-31 13:49:23 +01:00
|
|
|
|
2015-12-04 23:34:20 +01:00
|
|
|
def test_root_modifies_appropriately(self, monkeypatch):
|
|
|
|
# This deals with nt/posix path differences
|
|
|
|
# root is c:\somewhere\else or /somewhere/else
|
|
|
|
root = os.path.normcase(os.path.abspath(
|
|
|
|
os.path.join(os.path.sep, 'somewhere', 'else')))
|
2013-10-31 13:49:23 +01:00
|
|
|
norm_scheme = distutils_scheme("example")
|
2015-12-04 23:34:20 +01:00
|
|
|
root_scheme = distutils_scheme("example", root=root)
|
2013-10-31 13:49:23 +01:00
|
|
|
|
|
|
|
for key, value in norm_scheme.items():
|
2015-12-04 23:34:20 +01:00
|
|
|
drive, path = os.path.splitdrive(os.path.abspath(value))
|
|
|
|
expected = os.path.join(root, path[1:])
|
2014-03-13 21:04:43 +01:00
|
|
|
assert os.path.abspath(root_scheme[key]) == expected
|
2013-11-05 08:40:26 +01:00
|
|
|
|
2018-10-09 08:23:03 +02:00
|
|
|
@pytest.mark.incompatible_with_venv
|
2013-11-05 08:40:26 +01:00
|
|
|
def test_distutils_config_file_read(self, tmpdir, monkeypatch):
|
2015-12-04 23:34:20 +01:00
|
|
|
# This deals with nt/posix path differences
|
|
|
|
install_scripts = os.path.normcase(os.path.abspath(
|
|
|
|
os.path.join(os.path.sep, 'somewhere', 'else')))
|
2019-08-17 03:34:17 +02:00
|
|
|
f = tmpdir / "config" / "setup.cfg"
|
|
|
|
f.parent.mkdir()
|
2019-07-02 07:00:32 +02:00
|
|
|
f.write_text("[install]\ninstall-scripts=" + install_scripts)
|
2014-01-28 15:17:51 +01:00
|
|
|
from distutils.dist import Distribution
|
2020-09-23 15:08:01 +02:00
|
|
|
|
2014-01-28 15:17:51 +01:00
|
|
|
# patch the function that returns what config files are present
|
|
|
|
monkeypatch.setattr(
|
|
|
|
Distribution,
|
|
|
|
'find_config_files',
|
|
|
|
lambda self: [f],
|
|
|
|
)
|
|
|
|
scheme = distutils_scheme('example')
|
2015-12-04 23:34:20 +01:00
|
|
|
assert scheme['scripts'] == install_scripts
|
2014-03-13 20:19:26 +01:00
|
|
|
|
2018-10-09 08:23:03 +02:00
|
|
|
@pytest.mark.incompatible_with_venv
|
2015-08-19 06:09:21 +02:00
|
|
|
# when we request install-lib, we should install everything (.py &
|
|
|
|
# .so) into that path; i.e. ensure platlib & purelib are set to
|
|
|
|
# this path
|
2014-03-13 20:19:26 +01:00
|
|
|
def test_install_lib_takes_precedence(self, tmpdir, monkeypatch):
|
2015-12-04 23:34:20 +01:00
|
|
|
# This deals with nt/posix path differences
|
|
|
|
install_lib = os.path.normcase(os.path.abspath(
|
|
|
|
os.path.join(os.path.sep, 'somewhere', 'else')))
|
2019-08-17 03:34:17 +02:00
|
|
|
f = tmpdir / "config" / "setup.cfg"
|
|
|
|
f.parent.mkdir()
|
2019-07-02 07:00:32 +02:00
|
|
|
f.write_text("[install]\ninstall-lib=" + install_lib)
|
2014-03-13 20:19:26 +01:00
|
|
|
from distutils.dist import Distribution
|
2020-09-23 15:08:01 +02:00
|
|
|
|
2014-03-13 20:19:26 +01:00
|
|
|
# patch the function that returns what config files are present
|
|
|
|
monkeypatch.setattr(
|
|
|
|
Distribution,
|
|
|
|
'find_config_files',
|
|
|
|
lambda self: [f],
|
|
|
|
)
|
|
|
|
scheme = distutils_scheme('example')
|
2015-12-04 23:34:20 +01:00
|
|
|
assert scheme['platlib'] == install_lib + os.path.sep
|
|
|
|
assert scheme['purelib'] == install_lib + os.path.sep
|
2020-07-07 11:34:23 +02:00
|
|
|
|
|
|
|
def test_prefix_modifies_appropriately(self):
|
|
|
|
prefix = os.path.abspath(os.path.join('somewhere', 'else'))
|
|
|
|
|
|
|
|
normal_scheme = distutils_scheme("example")
|
|
|
|
prefix_scheme = distutils_scheme("example", prefix=prefix)
|
|
|
|
|
|
|
|
def _calculate_expected(value):
|
|
|
|
path = os.path.join(prefix, os.path.relpath(value, sys.prefix))
|
|
|
|
return os.path.normpath(path)
|
|
|
|
|
|
|
|
expected = {
|
|
|
|
k: _calculate_expected(v)
|
|
|
|
for k, v in normal_scheme.items()
|
|
|
|
}
|
|
|
|
assert prefix_scheme == expected
|