aboutsummaryrefslogtreecommitdiffstats
path: root/setuptools/tests/test_msvc9compiler.py
diff options
context:
space:
mode:
Diffstat (limited to 'setuptools/tests/test_msvc9compiler.py')
-rw-r--r--setuptools/tests/test_msvc9compiler.py135
1 files changed, 135 insertions, 0 deletions
diff --git a/setuptools/tests/test_msvc9compiler.py b/setuptools/tests/test_msvc9compiler.py
new file mode 100644
index 00000000..272e99e8
--- /dev/null
+++ b/setuptools/tests/test_msvc9compiler.py
@@ -0,0 +1,135 @@
+"""msvc9compiler monkey patch test
+
+This test ensures that importing setuptools is sufficient to replace
+the standard find_vcvarsall function with our patched version that
+finds the Visual C++ for Python package.
+"""
+
+import os
+import shutil
+import sys
+import tempfile
+import unittest
+
+try:
+ from winreg import HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE
+except ImportError:
+ from _winreg import HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE
+
+import distutils.msvc9compiler
+from distutils.errors import DistutilsPlatformError
+
+# importing only setuptools should apply the patch
+import setuptools
+
+class MockReg:
+ """Mock for distutils.msvc9compiler.Reg. We patch it
+ with an instance of this class that mocks out the
+ functions that access the registry.
+ """
+
+ def __init__(self, hkey_local_machine={}, hkey_current_user={}):
+ self.hklm = hkey_local_machine
+ self.hkcu = hkey_current_user
+
+ def __enter__(self):
+ self.original_read_keys = distutils.msvc9compiler.Reg.read_keys
+ self.original_read_values = distutils.msvc9compiler.Reg.read_values
+
+ hives = {
+ HKEY_CURRENT_USER: self.hkcu,
+ HKEY_LOCAL_MACHINE: self.hklm,
+ }
+
+ 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())]
+
+ 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()))
+
+ distutils.msvc9compiler.Reg.read_keys = classmethod(read_keys)
+ distutils.msvc9compiler.Reg.read_values = classmethod(read_values)
+
+ return self
+
+ def __exit__(self, exc_type, exc_value, exc_tb):
+ distutils.msvc9compiler.Reg.read_keys = self.original_read_keys
+ distutils.msvc9compiler.Reg.read_values = self.original_read_values
+
+class TestMSVC9Compiler(unittest.TestCase):
+
+ def test_find_vcvarsall_patch(self):
+ self.assertEqual(
+ "setuptools.extension",
+ distutils.msvc9compiler.find_vcvarsall.__module__,
+ "find_vcvarsall was not patched"
+ )
+
+ find_vcvarsall = distutils.msvc9compiler.find_vcvarsall
+ query_vcvarsall = distutils.msvc9compiler.query_vcvarsall
+
+ # No registry entries or environment variable means we should
+ # not find anything
+ old_value = os.environ.pop("VS90COMNTOOLS", None)
+ try:
+ with MockReg():
+ self.assertIsNone(find_vcvarsall(9.0))
+
+ try:
+ query_vcvarsall(9.0)
+ self.fail('Expected DistutilsPlatformError from query_vcvarsall()')
+ except DistutilsPlatformError:
+ exc_message = str(sys.exc_info()[1])
+ self.assertIn('aka.ms/vcpython27', exc_message)
+ finally:
+ if old_value:
+ os.environ["VS90COMNTOOLS"] = old_value
+
+ key_32 = r'software\microsoft\devdiv\vcforpython\9.0\installdir'
+ key_64 = r'software\wow6432node\microsoft\devdiv\vcforpython\9.0\installdir'
+
+ # Make two mock files so we can tell whether HCKU entries are
+ # preferred to HKLM entries.
+ mock_installdir_1 = tempfile.mkdtemp()
+ mock_vcvarsall_bat_1 = os.path.join(mock_installdir_1, 'vcvarsall.bat')
+ open(mock_vcvarsall_bat_1, 'w').close()
+ mock_installdir_2 = tempfile.mkdtemp()
+ mock_vcvarsall_bat_2 = os.path.join(mock_installdir_2, 'vcvarsall.bat')
+ open(mock_vcvarsall_bat_2, 'w').close()
+ try:
+ # Ensure we get the current user's setting first
+ with MockReg(
+ hkey_current_user={ key_32: mock_installdir_1 },
+ hkey_local_machine={
+ key_32: mock_installdir_2,
+ key_64: mock_installdir_2,
+ }
+ ):
+ self.assertEqual(mock_vcvarsall_bat_1, find_vcvarsall(9.0))
+
+ # Ensure we get the local machine value if it's there
+ with MockReg(hkey_local_machine={ key_32: mock_installdir_2 }):
+ self.assertEqual(mock_vcvarsall_bat_2, find_vcvarsall(9.0))
+
+ # Ensure we prefer the 64-bit local machine key
+ # (*not* the Wow6432Node key)
+ with MockReg(
+ hkey_local_machine={
+ # This *should* only exist on 32-bit machines
+ key_32: mock_installdir_1,
+ # This *should* only exist on 64-bit machines
+ key_64: mock_installdir_2,
+ }
+ ):
+ self.assertEqual(mock_vcvarsall_bat_1, find_vcvarsall(9.0))
+ finally:
+ shutil.rmtree(mock_installdir_1)
+ shutil.rmtree(mock_installdir_2)
+
+ \ No newline at end of file