OLD | NEW |
---|---|
1 # Copyright (c) 2012 Google Inc. All rights reserved. | 1 # Copyright (c) 2012 Google Inc. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """ | 5 """ |
6 TestGyp.py: a testing framework for GYP integration tests. | 6 TestGyp.py: a testing framework for GYP integration tests. |
7 """ | 7 """ |
8 | 8 |
9 from __future__ import print_function | |
10 | |
9 import collections | 11 import collections |
10 from contextlib import contextmanager | 12 from contextlib import contextmanager |
11 import itertools | 13 import itertools |
12 import os | 14 import os |
13 import re | 15 import re |
14 import shutil | 16 import shutil |
15 import subprocess | 17 import subprocess |
16 import sys | 18 import sys |
17 import tempfile | 19 import tempfile |
18 | 20 |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
275 | 277 |
276 def report_not_up_to_date(self): | 278 def report_not_up_to_date(self): |
277 """ | 279 """ |
278 Reports that a build is not up-to-date. | 280 Reports that a build is not up-to-date. |
279 | 281 |
280 This provides common reporting for formats that have complicated | 282 This provides common reporting for formats that have complicated |
281 conditions for checking whether a build is up-to-date. Formats | 283 conditions for checking whether a build is up-to-date. Formats |
282 that expect exact output from the command (make) can | 284 that expect exact output from the command (make) can |
283 just set stdout= when they call the run_build() method. | 285 just set stdout= when they call the run_build() method. |
284 """ | 286 """ |
285 print "Build is not up-to-date:" | 287 print("Build is not up-to-date:") |
286 print self.banner('STDOUT ') | 288 print(self.banner('STDOUT ')) |
287 print self.stdout() | 289 print(self.stdout()) |
288 stderr = self.stderr() | 290 stderr = self.stderr() |
289 if stderr: | 291 if stderr: |
290 print self.banner('STDERR ') | 292 print(self.banner('STDERR ')) |
291 print stderr | 293 print(stderr) |
292 | 294 |
293 def run_gyp(self, gyp_file, *args, **kw): | 295 def run_gyp(self, gyp_file, *args, **kw): |
294 """ | 296 """ |
295 Runs gyp against the specified gyp_file with the specified args. | 297 Runs gyp against the specified gyp_file with the specified args. |
296 """ | 298 """ |
297 | 299 |
298 # When running gyp, and comparing its output we use a comparitor | 300 # When running gyp, and comparing its output we use a comparitor |
299 # that ignores the line numbers that gyp logs in its debug output. | 301 # that ignores the line numbers that gyp logs in its debug output. |
300 if kw.pop('ignore_line_numbers', False): | 302 if kw.pop('ignore_line_numbers', False): |
301 kw.setdefault('match', match_modulo_line_numbers) | 303 kw.setdefault('match', match_modulo_line_numbers) |
(...skipping 17 matching lines...) Expand all Loading... | |
319 | 321 |
320 def run(self, *args, **kw): | 322 def run(self, *args, **kw): |
321 """ | 323 """ |
322 Executes a program by calling the superclass .run() method. | 324 Executes a program by calling the superclass .run() method. |
323 | 325 |
324 This exists to provide a common place to filter out keyword | 326 This exists to provide a common place to filter out keyword |
325 arguments implemented in this layer, without having to update | 327 arguments implemented in this layer, without having to update |
326 the tool-specific subclasses or clutter the tests themselves | 328 the tool-specific subclasses or clutter the tests themselves |
327 with platform-specific code. | 329 with platform-specific code. |
328 """ | 330 """ |
329 if kw.has_key('SYMROOT'): | 331 if 'SYMROOT' in kw: |
330 del kw['SYMROOT'] | 332 del kw['SYMROOT'] |
331 super(TestGypBase, self).run(*args, **kw) | 333 super(TestGypBase, self).run(*args, **kw) |
332 | 334 |
333 def set_configuration(self, configuration): | 335 def set_configuration(self, configuration): |
334 """ | 336 """ |
335 Sets the configuration, to be used for invoking the build | 337 Sets the configuration, to be used for invoking the build |
336 tool and testing potential built output. | 338 tool and testing potential built output. |
337 """ | 339 """ |
338 self.configuration = configuration | 340 self.configuration = configuration |
339 | 341 |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
549 """ | 551 """ |
550 arguments = kw.get('arguments', [])[:] | 552 arguments = kw.get('arguments', [])[:] |
551 if self.configuration: | 553 if self.configuration: |
552 arguments.append('BUILDTYPE=' + self.configuration) | 554 arguments.append('BUILDTYPE=' + self.configuration) |
553 if target not in (None, self.DEFAULT): | 555 if target not in (None, self.DEFAULT): |
554 arguments.append(target) | 556 arguments.append(target) |
555 # Sub-directory builds provide per-gyp Makefiles (i.e. | 557 # Sub-directory builds provide per-gyp Makefiles (i.e. |
556 # Makefile.gyp_filename), so use that if there is no Makefile. | 558 # Makefile.gyp_filename), so use that if there is no Makefile. |
557 chdir = kw.get('chdir', '') | 559 chdir = kw.get('chdir', '') |
558 if not os.path.exists(os.path.join(chdir, 'Makefile')): | 560 if not os.path.exists(os.path.join(chdir, 'Makefile')): |
559 print "NO Makefile in " + os.path.join(chdir, 'Makefile') | 561 print("NO Makefile in " + os.path.join(chdir, 'Makefile')) |
560 arguments.insert(0, '-f') | 562 arguments.insert(0, '-f') |
561 arguments.insert(1, os.path.splitext(gyp_file)[0] + '.Makefile') | 563 arguments.insert(1, os.path.splitext(gyp_file)[0] + '.Makefile') |
562 kw['arguments'] = arguments | 564 kw['arguments'] = arguments |
563 return self.run(program=self.build_tool, **kw) | 565 return self.run(program=self.build_tool, **kw) |
564 def up_to_date(self, gyp_file, target=None, **kw): | 566 def up_to_date(self, gyp_file, target=None, **kw): |
565 """ | 567 """ |
566 Verifies that a build of the specified Make target is up to date. | 568 Verifies that a build of the specified Make target is up to date. |
567 """ | 569 """ |
568 if target in (None, self.DEFAULT): | 570 if target in (None, self.DEFAULT): |
569 message_target = 'all' | 571 message_target = 'all' |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
656 import TestWin | 658 import TestWin |
657 registry = TestWin.Registry() | 659 registry = TestWin.Registry() |
658 | 660 |
659 msvs_to_msbuild = { | 661 msvs_to_msbuild = { |
660 '2013': r'12.0', | 662 '2013': r'12.0', |
661 '2012': r'4.0', # Really v4.0.30319 which comes with .NET 4.5. | 663 '2012': r'4.0', # Really v4.0.30319 which comes with .NET 4.5. |
662 '2010': r'4.0'} | 664 '2010': r'4.0'} |
663 | 665 |
664 msbuild_basekey = r'HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions' | 666 msbuild_basekey = r'HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions' |
665 if not registry.KeyExists(msbuild_basekey): | 667 if not registry.KeyExists(msbuild_basekey): |
666 print 'Error: could not find MSBuild base registry entry' | 668 print('Error: could not find MSBuild base registry entry') |
667 return None | 669 return None |
668 | 670 |
669 msbuild_version = None | 671 msbuild_version = None |
670 if msvs_version in msvs_to_msbuild: | 672 if msvs_version in msvs_to_msbuild: |
671 msbuild_test_version = msvs_to_msbuild[msvs_version] | 673 msbuild_test_version = msvs_to_msbuild[msvs_version] |
672 if registry.KeyExists(msbuild_basekey + '\\' + msbuild_test_version): | 674 if registry.KeyExists(msbuild_basekey + '\\' + msbuild_test_version): |
673 msbuild_version = msbuild_test_version | 675 msbuild_version = msbuild_test_version |
674 else: | 676 else: |
675 print ('Warning: Environment variable GYP_MSVS_VERSION specifies "%s" ' | 677 print ('Warning: Environment variable GYP_MSVS_VERSION specifies "%s" ' |
676 'but corresponding MSBuild "%s" was not found.' % | 678 'but corresponding MSBuild "%s" was not found.' % |
677 (msvs_version, msbuild_version)) | 679 (msvs_version, msbuild_version)) |
678 if not msbuild_version: | 680 if not msbuild_version: |
679 for msvs_version in sorted(msvs_to_msbuild, reverse=True): | 681 for msvs_version in sorted(msvs_to_msbuild, reverse=True): |
680 msbuild_test_version = msvs_to_msbuild[msvs_version] | 682 msbuild_test_version = msvs_to_msbuild[msvs_version] |
681 if registry.KeyExists(msbuild_basekey + '\\' + msbuild_test_version): | 683 if registry.KeyExists(msbuild_basekey + '\\' + msbuild_test_version): |
682 msbuild_version = msbuild_test_version | 684 msbuild_version = msbuild_test_version |
683 break | 685 break |
684 if not msbuild_version: | 686 if not msbuild_version: |
685 print 'Error: could not find MSBuild registry entry' | 687 print('Error: could not find MSBuild registry entry') |
686 return None | 688 return None |
687 | 689 |
688 msbuild_path = registry.GetValue(msbuild_basekey + '\\' + msbuild_version, | 690 msbuild_path = registry.GetValue(msbuild_basekey + '\\' + msbuild_version, |
689 'MSBuildToolsPath') | 691 'MSBuildToolsPath') |
690 if not msbuild_path: | 692 if not msbuild_path: |
691 print 'Error: could not get MSBuild registry entry value' | 693 print('Error: could not get MSBuild registry entry value') |
692 return None | 694 return None |
693 | 695 |
694 return os.path.join(msbuild_path, 'MSBuild.exe') | 696 return os.path.join(msbuild_path, 'MSBuild.exe') |
695 | 697 |
696 | 698 |
697 def FindVisualStudioInstallation(): | 699 def FindVisualStudioInstallation(): |
698 """Returns appropriate values for .build_tool and .uses_msbuild fields | 700 """Returns appropriate values for .build_tool and .uses_msbuild fields |
699 of TestGypBase for Visual Studio. | 701 of TestGypBase for Visual Studio. |
700 | 702 |
701 We use the value specified by GYP_MSVS_VERSION. If not specified, we | 703 We use the value specified by GYP_MSVS_VERSION. If not specified, we |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
734 # Neither GYP_MSVS_VERSION nor the path help us out. Iterate through | 736 # Neither GYP_MSVS_VERSION nor the path help us out. Iterate through |
735 # the choices looking for a match. | 737 # the choices looking for a match. |
736 for version in sorted(possible_paths, reverse=True): | 738 for version in sorted(possible_paths, reverse=True): |
737 path = possible_paths[version] | 739 path = possible_paths[version] |
738 for r in possible_roots: | 740 for r in possible_roots: |
739 build_tool = os.path.join(r, path) | 741 build_tool = os.path.join(r, path) |
740 if os.path.exists(build_tool): | 742 if os.path.exists(build_tool): |
741 uses_msbuild = msvs_version >= '2010' | 743 uses_msbuild = msvs_version >= '2010' |
742 msbuild_path = FindMSBuildInstallation(msvs_version) | 744 msbuild_path = FindMSBuildInstallation(msvs_version) |
743 return build_tool, uses_msbuild, msbuild_path | 745 return build_tool, uses_msbuild, msbuild_path |
744 print 'Error: could not find devenv' | 746 print('Error: could not find devenv') |
745 sys.exit(1) | 747 sys.exit(1) |
746 | 748 |
747 class TestGypOnMSToolchain(TestGypBase): | 749 class TestGypOnMSToolchain(TestGypBase): |
748 """ | 750 """ |
749 Common subclass for testing generators that target the Microsoft Visual | 751 Common subclass for testing generators that target the Microsoft Visual |
750 Studio toolchain (cl, link, dumpbin, etc.) | 752 Studio toolchain (cl, link, dumpbin, etc.) |
751 """ | 753 """ |
752 @staticmethod | 754 @staticmethod |
753 def _ComputeVsvarsPath(devenv_path): | 755 def _ComputeVsvarsPath(devenv_path): |
754 devenv_dir = os.path.split(devenv_path)[0] | 756 devenv_dir = os.path.split(devenv_path)[0] |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
879 arguments.extend(['/Project', target]) | 881 arguments.extend(['/Project', target]) |
880 if self.configuration: | 882 if self.configuration: |
881 arguments.extend(['/ProjectConfig', self.configuration]) | 883 arguments.extend(['/ProjectConfig', self.configuration]) |
882 kw['arguments'] = arguments | 884 kw['arguments'] = arguments |
883 return self.run(program=self.build_tool, **kw) | 885 return self.run(program=self.build_tool, **kw) |
884 def up_to_date(self, gyp_file, target=None, **kw): | 886 def up_to_date(self, gyp_file, target=None, **kw): |
885 """ | 887 """ |
886 Verifies that a build of the specified Visual Studio target is up to date. | 888 Verifies that a build of the specified Visual Studio target is up to date. |
887 | 889 |
888 Beware that VS2010 will behave strangely if you build under | 890 Beware that VS2010 will behave strangely if you build under |
889 C:\USERS\yourname\AppData\Local. It will cause needless work. The ouptut | 891 C:/USERS/yourname/AppData/Local. It will cause needless work. The ouptut |
Nico
2016/07/29 22:22:06
out of interest, is this needed? with \ it's more
AWhetter
2016/11/05 23:59:50
I've worked around it by making the docstring a ra
| |
890 will be "1 succeeded and 0 up to date". MSBuild tracing reveals that: | 892 will be "1 succeeded and 0 up to date". MSBuild tracing reveals that: |
891 "Project 'C:\Users\...\AppData\Local\...vcxproj' not up to date because | 893 "Project 'C:/Users/.../AppData/Local/...vcxproj' not up to date because |
892 'C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 10.0\VC\BIN\1033\CLUI.DLL' | 894 'C:/PROGRAM FILES (X86)/MICROSOFT VISUAL STUDIO 10.0/VC/BIN/1033/CLUI.DLL' |
893 was modified at 02/21/2011 17:03:30, which is newer than '' which was | 895 was modified at 02/21/2011 17:03:30, which is newer than '' which was |
894 modified at 01/01/0001 00:00:00. | 896 modified at 01/01/0001 00:00:00. |
895 | 897 |
896 The workaround is to specify a workdir when instantiating the test, e.g. | 898 The workaround is to specify a workdir when instantiating the test, e.g. |
897 test = TestGyp.TestGyp(workdir='workarea') | 899 test = TestGyp.TestGyp(workdir='workarea') |
898 """ | 900 """ |
899 result = self.build(gyp_file, target, **kw) | 901 result = self.build(gyp_file, target, **kw) |
900 if not result: | 902 if not result: |
901 stdout = self.stdout() | 903 stdout = self.stdout() |
902 | 904 |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1180 ] | 1182 ] |
1181 | 1183 |
1182 def TestGyp(*args, **kw): | 1184 def TestGyp(*args, **kw): |
1183 """ | 1185 """ |
1184 Returns an appropriate TestGyp* instance for a specified GYP format. | 1186 Returns an appropriate TestGyp* instance for a specified GYP format. |
1185 """ | 1187 """ |
1186 format = kw.pop('format', os.environ.get('TESTGYP_FORMAT')) | 1188 format = kw.pop('format', os.environ.get('TESTGYP_FORMAT')) |
1187 for format_class in format_class_list: | 1189 for format_class in format_class_list: |
1188 if format == format_class.format: | 1190 if format == format_class.format: |
1189 return format_class(*args, **kw) | 1191 return format_class(*args, **kw) |
1190 raise Exception, "unknown format %r" % format | 1192 raise Exception("unknown format %r" % format) |
OLD | NEW |