123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- """
- Tests for msvc support module.
- """
- import os
- import contextlib
- import distutils.errors
- import mock
- import pytest
- from . import contexts
- # importing only setuptools should apply the patch
- __import__('setuptools')
- pytest.importorskip("distutils.msvc9compiler")
- def mock_reg(hkcu=None, hklm=None):
- """
- Return a mock for distutils.msvc9compiler.Reg, patched
- to mock out the functions that access the registry.
- """
- _winreg = getattr(distutils.msvc9compiler, '_winreg', None)
- winreg = getattr(distutils.msvc9compiler, 'winreg', _winreg)
- hives = {
- winreg.HKEY_CURRENT_USER: hkcu or {},
- winreg.HKEY_LOCAL_MACHINE: hklm or {},
- }
- @classmethod
- def read_keys(cls, base, key):
- """Return list of registry keys."""
- hive = hives.get(base, {})
- return [
- k.rpartition('\\')[2]
- for k in hive if k.startswith(key.lower())
- ]
- @classmethod
- def read_values(cls, base, key):
- """Return dict of registry keys and values."""
- hive = hives.get(base, {})
- return dict(
- (k.rpartition('\\')[2], hive[k])
- for k in hive if k.startswith(key.lower())
- )
- return mock.patch.multiple(
- distutils.msvc9compiler.Reg,
- read_keys=read_keys, read_values=read_values)
- class TestModulePatch:
- """
- Ensure that importing setuptools is sufficient to replace
- the standard find_vcvarsall function with a version that
- recognizes the "Visual C++ for Python" package.
- """
- key_32 = r'software\microsoft\devdiv\vcforpython\9.0\installdir'
- key_64 = key_32.replace(r'\microsoft', r'\wow6432node\microsoft')
- def test_patched(self):
- "Test the module is actually patched"
- mod_name = distutils.msvc9compiler.find_vcvarsall.__module__
- assert mod_name == "setuptools.msvc", "find_vcvarsall unpatched"
- def test_no_registry_entries_means_nothing_found(self):
- """
- No registry entries or environment variable should lead to an error
- directing the user to download vcpython27.
- """
- find_vcvarsall = distutils.msvc9compiler.find_vcvarsall
- query_vcvarsall = distutils.msvc9compiler.query_vcvarsall
- with contexts.environment(VS90COMNTOOLS=None):
- with mock_reg():
- assert find_vcvarsall(9.0) is None
- try:
- query_vcvarsall(9.0)
- except Exception as exc:
- expected = distutils.errors.DistutilsPlatformError
- assert isinstance(exc, expected)
- assert 'aka.ms/vcpython27' in str(exc)
- @pytest.fixture
- def user_preferred_setting(self):
- """
- Set up environment with different install dirs for user vs. system
- and yield the user_install_dir for the expected result.
- """
- with self.mock_install_dir() as user_install_dir:
- with self.mock_install_dir() as system_install_dir:
- reg = mock_reg(
- hkcu={
- self.key_32: user_install_dir,
- },
- hklm={
- self.key_32: system_install_dir,
- self.key_64: system_install_dir,
- },
- )
- with reg:
- yield user_install_dir
- def test_prefer_current_user(self, user_preferred_setting):
- """
- Ensure user's settings are preferred.
- """
- result = distutils.msvc9compiler.find_vcvarsall(9.0)
- expected = os.path.join(user_preferred_setting, 'vcvarsall.bat')
- assert expected == result
- @pytest.fixture
- def local_machine_setting(self):
- """
- Set up environment with only the system environment configured.
- """
- with self.mock_install_dir() as system_install_dir:
- reg = mock_reg(
- hklm={
- self.key_32: system_install_dir,
- },
- )
- with reg:
- yield system_install_dir
- def test_local_machine_recognized(self, local_machine_setting):
- """
- Ensure machine setting is honored if user settings are not present.
- """
- result = distutils.msvc9compiler.find_vcvarsall(9.0)
- expected = os.path.join(local_machine_setting, 'vcvarsall.bat')
- assert expected == result
- @pytest.fixture
- def x64_preferred_setting(self):
- """
- Set up environment with 64-bit and 32-bit system settings configured
- and yield the canonical location.
- """
- with self.mock_install_dir() as x32_dir:
- with self.mock_install_dir() as x64_dir:
- reg = mock_reg(
- hklm={
- # This *should* only exist on 32-bit machines
- self.key_32: x32_dir,
- # This *should* only exist on 64-bit machines
- self.key_64: x64_dir,
- },
- )
- with reg:
- yield x32_dir
- def test_ensure_64_bit_preferred(self, x64_preferred_setting):
- """
- Ensure 64-bit system key is preferred.
- """
- result = distutils.msvc9compiler.find_vcvarsall(9.0)
- expected = os.path.join(x64_preferred_setting, 'vcvarsall.bat')
- assert expected == result
- @staticmethod
- @contextlib.contextmanager
- def mock_install_dir():
- """
- Make a mock install dir in a unique location so that tests can
- distinguish which dir was detected in a given scenario.
- """
- with contexts.tempdir() as result:
- vcvarsall = os.path.join(result, 'vcvarsall.bat')
- with open(vcvarsall, 'w'):
- pass
- yield result
|