diff options
Diffstat (limited to 'src/engine/SCons/Tool/msvsTests.py')
| -rw-r--r-- | src/engine/SCons/Tool/msvsTests.py | 192 | 
1 files changed, 159 insertions, 33 deletions
diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py index 8c09487..e0b5ced 100644 --- a/src/engine/SCons/Tool/msvsTests.py +++ b/src/engine/SCons/Tool/msvsTests.py @@ -1,5 +1,5 @@  # -# Copyright (c) 2001 - 2017 The SCons Foundation +# Copyright (c) 2001 - 2019 The SCons Foundation  #  # Permission is hereby granted, free of charge, to any person obtaining  # a copy of this software and associated documentation files (the @@ -22,7 +22,7 @@  #  from __future__ import print_function -__revision__ = "src/engine/SCons/Tool/msvsTests.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog" +__revision__ = "src/engine/SCons/Tool/msvsTests.py e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan"  import os  import sys @@ -34,6 +34,7 @@ import TestUnit  from SCons.Tool.msvs import *  from SCons.Tool.MSCommon.vs import SupportedVSList +import SCons.Node.FS  import SCons.Util  import SCons.Warnings @@ -352,6 +353,36 @@ regdata_80 = r'''  "VCXDCMakeTool"="*.xdc"  '''.split('\n') +regdata_140 = r''' +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\14.0\Setup\VS] +"MSMDir"="C:\\Program Files (x86)\\Common Files\\Merge Modules\\" +"ProductDir"="C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\" +"VS7EnvironmentLocation"="C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\devenv.exe" +"EnvironmentPath"="C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\devenv.exe" +"EnvironmentDirectory"="C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\" +"VS7CommonDir"="C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\" +"VS7CommonBinDir"="" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\14.0\Setup\VS\BuildNumber] +"1033"="14.0" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\14.0\Setup\VS\Community] +"ProductDir"="C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\14.0\Setup\VS\JSLS_MSI] +"Version"="14.0.25527" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\14.0\Setup\VS\JSPS_MSI] +"Version"="14.0.25527" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\14.0\Setup\VS\Pro] +"ProductDir"="C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\14.0\Setup\VS\professional] +"IsInstallInProgress"="0" +"CurrentOperation"="install" +"SetupFeedUri"="http://go.microsoft.com/fwlink/?LinkID=659004&clcid=0x409" +"SetupFeedLocalCache"="C:\\ProgramData\\Microsoft\\VisualStudioSecondaryInstaller\\14.0\\LastUsedFeed\\{68432bbb-c9a5-4a7b-bab3-ae5a49b28303}\\Feed.xml" +"InstallResult"="0" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\14.0\Setup\VS\SecondaryInstaller] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\14.0\Setup\VS\SecondaryInstaller\AppInsightsTools] +"Version"="7.0.20620.1" +'''.split('\n') +  regdata_cv = r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion]  "ProgramFilesDir"="C:\Program Files"  "CommonFilesDir"="C:\Program Files\Common Files" @@ -363,6 +394,7 @@ regdata_none = []  class DummyEnv(object):      def __init__(self, dict=None): +        self.fs = SCons.Node.FS.FS()          if dict:              self.dict = dict          else: @@ -385,6 +417,16 @@ class DummyEnv(object):      def has_key(self,name):          return name in self.dict +    def get(self, name, value=None): +        if self.has_key(name): +            return self.dict[name] +        else: +            return value + +    def Dir(self, name): +        return self.fs.Dir(name) + +  class RegKey(object):      """key class for storing an 'open' registry key"""      def __init__(self,key): @@ -482,8 +524,8 @@ class DummyRegistry(object):      def parse(self, data):          parents = [None, None]          parents[0] = self.root -        keymatch = re.compile('^\[(.*)\]$') -        valmatch = re.compile('^(?:"(.*)"|[@])="(.*)"$') +        keymatch = re.compile(r'^\[(.*)\]$') +        valmatch = re.compile(r'^(?:"(.*)"|[@])="(.*)"$')          for line in data:              m1 = keymatch.match(line)              if m1: @@ -540,6 +582,10 @@ def DummyQueryValue(key, value):  def DummyExists(path):      return 1 +def DummyVsWhere(msvc_version): +    # not testing versions with vswhere, so return none +    return None +  class msvsTestCase(unittest.TestCase):      """This test case is run several times with different defaults.      See its subclasses below.""" @@ -550,6 +596,11 @@ class msvsTestCase(unittest.TestCase):          from SCons.Tool.MSCommon.vs import reset_installed_visual_studios          reset_installed_visual_studios() +        self.test = TestCmd.TestCmd(workdir='') +        # FS doesn't like the cwd to be something other than its root. +        os.chdir(self.test.workpath("")) +        self.fs = SCons.Node.FS.FS() +      def test_get_default_version(self):          """Test retrieval of the default visual studio version""" @@ -603,13 +654,19 @@ class msvsTestCase(unittest.TestCase):          version_num, suite = msvs_parse_version(self.highest_version)          if version_num >= 10.0:              function_test = _GenerateV10DSP +            suffix = '.vcxproj'          elif version_num >= 7.0:              function_test = _GenerateV7DSP +            suffix = '.dsp'          else:              function_test = _GenerateV6DSP +            suffix = '.dsp' + +        # Avoid any race conditions between the test cases when we test +        # actually writing the files. +        dspfile = 'test%s%s' % (hash(self), suffix)          str_function_test = str(function_test.__init__) -        dspfile = 'test.dsp'          source = 'test.cpp'          # Create the cmdargs test list @@ -619,50 +676,95 @@ class msvsTestCase(unittest.TestCase):                          'debug=False target_arch=32',                          'debug=True target_arch=x64',                           'debug=False target_arch=x64'] -         -        # Tuple list :   (parameter,        dictionary of expected result per variant) -        tests_cmdargs = [(None,            dict.fromkeys(list_variant, '')),  -                         ('',              dict.fromkeys(list_variant, '')),  -                         (list_cmdargs[0], dict.fromkeys(list_variant, list_cmdargs[0])), -                         (list_cmdargs,    dict(list(zip(list_variant, list_cmdargs))))] -         +        list_cppdefines = [['_A', '_B', 'C'], ['_B', '_C_'], ['D'], []] +        list_cpppaths = [[r'C:\test1'], [r'C:\test1;C:\test2'], +                         [self.fs.Dir('subdir')], []] + +        def TestParamsFromList(test_variant, test_list): +            """ +            Generates test data based on the parameters passed in. + +            Returns tuple list: +                1. Parameter. +                2. Dictionary of expected result per variant. +            """ +            def normalizeParam(param): +                """ +                Converts the raw data based into the AddConfig function of +                msvs.py to the expected result. + +                Expects the following behavior: +                    1. A value of None will be converted to an empty list. +                    2. A File or Directory object will be converted to an +                       absolute path (because those objects can't be pickled). +                    3. Otherwise, the parameter will be used. +                """ +                if param is None: +                    return [] +                elif isinstance(param, list): +                    return [normalizeParam(p) for p in param] +                elif hasattr(param, 'abspath'): +                    return param.abspath +                else: +                    return param + +            return [ +                (None, dict.fromkeys(test_variant, '')), +                ('', dict.fromkeys(test_variant, '')), +                (test_list[0], dict.fromkeys(test_variant, normalizeParam(test_list[0]))), +                (test_list, dict(list(zip(test_variant, [normalizeParam(x) for x in test_list])))) +            ] + +        tests_cmdargs = TestParamsFromList(list_variant, list_cmdargs) +        tests_cppdefines = TestParamsFromList(list_variant, list_cppdefines) +        tests_cpppaths = TestParamsFromList(list_variant, list_cpppaths) +          # Run the test for each test case          for param_cmdargs, expected_cmdargs in tests_cmdargs: -            debug('Testing %s. with :\n  variant = %s \n  cmdargs = "%s"' % \ -                  (str_function_test, list_variant, param_cmdargs)) -            param_configs = [] -            expected_configs = {} -            for platform in ['Win32', 'x64']: -                for variant in ['Debug', 'Release']: -                    variant_platform = '%s|%s' % (variant, platform) -                    runfile = '%s\\%s\\test.exe' % (platform, variant) -                    buildtarget = '%s\\%s\\test.exe' % (platform, variant) -                    outdir = '%s\\%s' % (platform, variant) +            for param_cppdefines, expected_cppdefines in tests_cppdefines: +                for param_cpppaths, expected_cpppaths in tests_cpppaths: +                    debug('Testing %s. with :\n  variant = %s \n  cmdargs = "%s" \n  cppdefines = "%s" \n  cpppaths = "%s"' % \ +                          (str_function_test, list_variant, param_cmdargs, param_cppdefines, param_cpppaths)) +                    param_configs = [] +                    expected_configs = {} +                    for platform in ['Win32', 'x64']: +                        for variant in ['Debug', 'Release']: +                            variant_platform = '%s|%s' % (variant, platform) +                            runfile = '%s\\%s\\test.exe' % (platform, variant) +                            buildtarget = '%s\\%s\\test.exe' % (platform, variant) +                            outdir = '%s\\%s' % (platform, variant) -                    # Create parameter list for this variant_platform -                    param_configs.append([variant_platform, runfile, buildtarget, outdir]) -             -                    # Create expected dictionary result for this variant_platform -                    expected_configs[variant_platform] = \ -                    {'variant': variant, 'platform': platform,  -                     'runfile': runfile, -                     'buildtarget': buildtarget,  -                     'outdir': outdir, -                     'cmdargs': expected_cmdargs[variant_platform]} +                            # Create parameter list for this variant_platform +                            param_configs.append([variant_platform, runfile, buildtarget, outdir]) +                            # Create expected dictionary result for this variant_platform +                            expected_configs[variant_platform] = { +                                'variant': variant, +                                'platform': platform,  +                                'runfile': runfile, +                                'buildtarget': buildtarget,  +                                'outdir': outdir, +                                'cmdargs': expected_cmdargs[variant_platform], +                                'cppdefines': expected_cppdefines[variant_platform], +                                'cpppaths': expected_cpppaths[variant_platform], +                            } +              # Create parameter environment with final parameter dictionary              param_dict = dict(list(zip(('variant', 'runfile', 'buildtarget', 'outdir'),                                    [list(l) for l in zip(*param_configs)])))              param_dict['cmdargs'] = param_cmdargs +            param_dict['cppdefines'] = param_cppdefines +            param_dict['cpppaths'] = param_cpppaths              # Hack to be able to run the test with a 'DummyEnv'              class _DummyEnv(DummyEnv): -                def subst(self, string) :  +                def subst(self, string, *args, **kwargs):                      return string              env = _DummyEnv(param_dict)              env['MSVSSCONSCRIPT'] = ''              env['MSVS_VERSION'] = self.highest_version +            env['MSVSBUILDTARGET'] = 'target'              # Call function to test              genDSP = function_test(dspfile, source, env) @@ -672,6 +774,16 @@ class msvsTestCase(unittest.TestCase):              for key in list(genDSP.configs.keys()):                  self.assertDictEqual(genDSP.configs[key].__dict__, expected_configs[key]) +            genDSP.Build() + +            # Delete the resulting file so we don't leave anything behind. +            for file in [dspfile, dspfile + '.filters']: +                path = os.path.realpath(file) +                try: +                    os.remove(path) +                except OSError: +                    pass +  class msvs6aTestCase(msvsTestCase):      """Test MSVS 6 Registry"""      registry = DummyRegistry(regdata_6a + regdata_cv) @@ -783,6 +895,18 @@ class msvs80TestCase(msvsTestCase):      }      default_install_loc = install_locs['8.0'] +class msvs140TestCase(msvsTestCase): +    """Test MSVS 140 Registry""" +    registry = DummyRegistry(regdata_140 + regdata_cv) +    default_version = '14.0' +    highest_version = '14.0' +    number_of_versions = 2 +    install_locs = { +        '14.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 14.0', +                  'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 14.0\\VC'}, +    } +    default_install_loc = install_locs['14.0'] +  class msvsEmptyTestCase(msvsTestCase):      """Test Empty Registry"""      registry = DummyRegistry(regdata_none) @@ -809,6 +933,7 @@ if __name__ == "__main__":      SCons.Util.RegEnumKey      = DummyEnumKey      SCons.Util.RegEnumValue    = DummyEnumValue      SCons.Util.RegQueryValueEx = DummyQueryValue +    SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere      os.path.exists = DummyExists # make sure all files exist :-)      os.path.isfile = DummyExists # make sure all files are files :-) @@ -824,6 +949,7 @@ if __name__ == "__main__":          msvs71TestCase,          msvs8ExpTestCase,          msvs80TestCase, +        msvs140TestCase,          msvsEmptyTestCase,      ]  | 
