Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(672)

Unified Diff: trunk/test/lib/TestGyp.py

Issue 160351: Test infrastructure for end-to-end tests of GYP generators, and... (Closed) Base URL: http://gyp.googlecode.com/svn/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « trunk/test/lib/TestCommon.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: trunk/test/lib/TestGyp.py
===================================================================
--- trunk/test/lib/TestGyp.py (revision 0)
+++ trunk/test/lib/TestGyp.py (revision 0)
@@ -0,0 +1,347 @@
+#!/usr/bin/python
+
+"""
+TestGyp.py: a testing framework for GYP integration tests.
+"""
+
+import os
+import shutil
+import stat
+import sys
+
+import TestCommon
+from TestCommon import __all__
+
+__all__.extend([
+ 'TestGyp',
+])
+
+
+class TestGypBase(TestCommon.TestCommon):
+ """
+ Class for controlling end-to-end tests of gyp generators.
+
+ Instantiating this class will create a temporary directory and
+ arrange for its destruction (via the TestCmd superclass) and
+ copy all of the non-gyptest files in the directory hierarchy of the
+ executing script.
+
+ The default behavior is to test the 'gyp' or 'gyp.bat' file in the
+ current directory. An alternative may be specified explicitly on
+ instantiation, or by setting the TESTGYP_GYP environment variable.
+
+ This class should be subclassed for each supported gyp generator
+ (format). Various abstract methods below define calling signatures
+ used by the test scripts to invoke builds on the generated build
+ configuration and to run executables generated by those builds.
+ """
+
+ build_tool = None
+
+ def __init__(self, gyp=None, *args, **kw):
+ self.origin_cwd = os.path.abspath(os.path.dirname(sys.argv[0]))
+
+ if not gyp:
+ gyp = os.environ.get('TESTGYP_GYP')
+ if not gyp:
+ if sys.platform == 'win32':
+ gyp = 'gyp.bat'
+ else:
+ gyp = 'gyp'
+ self.gyp = os.path.abspath(gyp)
+
+ self.initialize_build_tool()
+
+ if not kw.has_key('match'):
+ kw['match'] = TestCommon.match_exact
+
+ if not kw.has_key('workdir'):
+ # Default behavior: the null string causes TestCmd to create
+ # a temporary directory for us.
+ kw['workdir'] = ''
+
+ super(TestGypBase, self).__init__(*args, **kw)
+
+ self.copy_test_configuration(self.origin_cwd, self.workdir)
+
+ def copy_test_configuration(self, source_dir, dest_dir):
+ """
+ Copies the test configuration from the specified source_dir
+ (the directory in which the test script lives) to the
+ specified dest_dir (a temporary working directory).
+
+ This ignores all files and directories that begin with
+ the string 'gyptest', and all '.svn' subdirectories.
+ """
+ for root, dirs, files in os.walk(source_dir):
+ if '.svn' in dirs:
+ dirs.remove('.svn')
+ dirs = [ d for d in dirs if not d.startswith('gyptest') ]
+ files = [ f for f in files if not f.startswith('gyptest') ]
+ for dirname in dirs:
+ source = os.path.join(root, dirname)
+ destination = source.replace(source_dir, dest_dir)
+ os.mkdir(destination)
+ if sys.platform != 'win32':
+ shutil.copystat(source, destination)
+ for filename in files:
+ source = os.path.join(root, filename)
+ destination = source.replace(source_dir, dest_dir)
+ shutil.copy2(source, destination)
+
+ def initialize_build_tool(self):
+ """
+ Initializes the .build_tool attribute to the absolute path of
+ an actual executable on the user's $PATH.
+ """
+ if self.build_tool and not os.path.isabs(self.build_tool):
+ build_tool = self.where_is(self.build_tool)
+ if build_tool:
+ self.build_tool = build_tool
+
+ def run_gyp(self, gyp_file, *args, **kw):
+ """
+ Runs gyp against the specified gyp_file with the specified args.
+ """
+ # TODO: --depth=. works around Chromium-specific tree climbing.
+ args = ('--depth=.', '--format='+self.format) + args
+ return self.run(program=self.gyp, arguments=args, **kw)
+
+ #
+ # Abstract methods to be defined by format-specific subclasses.
+ #
+
+ def build_all(self, gyp_file):
+ """
+ Runs an "all" build of the configuration generated from the
+ specified gyp_file.
+ """
+ raise NotImplementeError
+
+ def build_default(self, gyp_file):
+ """
+ Runs the default build of the configuration generated from the
+ specified gyp_file.
+ """
+ raise NotImplementeError
+
+ def build_target(self, gyp_file, target):
+ """
+ Runs a build of the specified target against the configuration
+ generated from the specified gyp_file.
+ """
+ raise NotImplementeError
+
+ def run_built_executable(self, name, *args, **kw):
+ """
+ Runs an executable program built from a gyp-generated configuration.
+
+ The specified name should be independent of any particular generator.
+ Subclasses should find the output executable in the appropriate
+ output build directory, tack on any necessary executable suffix, etc.
+ """
+ raise NotImplementeError
+
+
+class TestGypMake(TestGypBase):
+ """
+ Subclass for testing the GYP Make generator.
+ """
+ format = 'make'
+ build_tool = 'make'
+ def build_all(self, gyp_file):
+ """
+ Builds the Make 'all' target to build all targets for the Makefiles
+ generated from the specified gyp_file.
+ """
+ self.run_build(gyp_file, 'all')
+ def build_default(self, gyp_file):
+ """
+ Runs Make with no additional command-line arguments to get the
+ default build for the Makefiles generated from the specified gyp_file.
+ """
+ self.run_build(gyp_file)
+ def build_target(self, gyp_file, target):
+ """
+ Runs a Make build with the specified target on the command line
+ to build just that target using the Makefile generated from the
+ specified gyp_file.
+ """
+ self.run_build(gyp_file, target)
+ def run_build(self, gyp_file, *args):
+ """
+ Runs a Make build using the Makefiles generated from the specified
+ gyp_file.
+ """
+ return self.run(program=self.build_tool, arguments=args)
+ def run_built_executable(self, name, *args, **kw):
+ """
+ Runs an executable built by Make.
+ """
+ # TODO: generalize to different configurations.
+ program = self.workpath('out/Debug/' + name)
+ return self.run(program=program, *args, **kw)
+
+
+class TestGypMSVS(TestGypBase):
+ """
+ Subclass for testing the GYP Visual Studio generator.
+ """
+ format = 'msvs'
+ build_tool = 'devenv'
+ def build_all(self, gyp_file):
+ """
+ Runs devenv.exe with no target-specific options to get the "all"
+ build for the Visual Studio configuration generated from the
+ specified gyp_file.
+
+ (NOTE: This is the same as the default, our generated Visual Studio
+ configuration doesn't create an explicit "all" target.)
+ """
+ return self.run_build(gyp_file)
+ def build_default(self, gyp_file):
+ """
+ Runs devenv.exe with no target-specific options to get the default
+ build for the Visual Studio configuration generated from the
+ specified gyp_file.
+ """
+ return self.run_build(gyp_file)
+ def build_target(self, gyp_file, target):
+ """
+ Uses the devenv.exe /Project option to build the specified target with
+ the Visual Studio configuration generated from the specified gyp_file.
+ """
+ return self.run_build(gyp_file, '/Project', target)
+ def initialize_build_tool(self):
+ """
+ Initializes the Visual Studio .build_tool parameter, searching %PATH%
+ and %PATHEXT% for a devenv.{exe,bat,...} executable, and falling
+ back to a hard-coded default (on the current drive) if necessary.
+ """
+ build_tool = self.where_is(self.build_tool)
+ if build_tool:
+ self.build_tool = build_tool
+ return
+ # We didn't find 'devenv' on the path. Just hard-code a default,
+ # and revisit this if it becomes important.
+ self.build_tool = os.path.join('\\Program Files',
+ 'Microsoft Visual Studio 8',
+ 'Common7',
+ 'IDE',
+ 'devenv.exe')
+ def run_build(self, gyp_file, *args):
+ """
+ Runs a Visual Studio build using the configuration generated
+ from the specified gyp_file.
+ """
+ # TODO: generalize to different configurations.
+ args = (gyp_file.replace('.gyp', '.sln'), '/Build', 'Default') + args
+ return self.run(program=self.build_tool, arguments=args)
+ def run_built_executable(self, name, *args, **kw):
+ """
+ Runs an executable built by Visual Studio.
+ """
+ # TODO: generalize to different configurations.
+ program = self.workpath('Default/%s.exe' % name)
+ return self.run(program=program, *args, **kw)
+
+
+class TestGypSCons(TestGypBase):
+ """
+ Subclass for testing the GYP SCons generator.
+ """
+ format = 'scons'
+ build_tool = 'scons'
+ def build_all(self, gyp_file):
+ """
+ Builds the scons 'all' target to build all targets for the
+ SCons configuration generated from the specified gyp_file.
+ """
+ self.run_build(gyp_file, 'all')
+ def build_default(self, gyp_file):
+ """
+ Runs scons with no additional command-line arguments to get the
+ default build for the SCons configuration generated from the
+ specified gyp_file.
+ """
+ self.run_build(gyp_file)
+ def build_target(self, gyp_file, target):
+ """
+ Runs a scons build with the specified target on the command line to
+ build just that target using the SCons configuration generated from
+ the specified gyp_file.
+ """
+ self.run_build(gyp_file, target)
+ def run_build(self, gyp_file, *args):
+ """
+ Runs a scons build using the SCons configuration generated from the
+ specified gyp_file.
+ """
+ return self.run(program=self.build_tool, arguments=args)
+ def run_built_executable(self, name, *args, **kw):
+ """
+ Runs an executable built by scons.
+ """
+ # TODO: generalize to different configurations.
+ program = self.workpath('Default/' + name)
+ return self.run(program=program, *args, **kw)
+
+
+class TestGypXcode(TestGypBase):
+ """
+ Subclass for testing the GYP Xcode generator.
+ """
+ format = 'xcode'
+ build_tool = 'xcodebuild'
+ def build_all(self, gyp_file):
+ """
+ Uses the xcodebuild -alltargets option to build all targets for the
+ .xcodeproj generated from the specified gyp_file.
+ """
+ return self.run_build(gyp_file, '-alltargets')
+ def build_default(self, gyp_file):
+ """
+ Runs xcodebuild with no target-specific options to get the default
+ build for the .xcodeproj generated from the specified gyp_file.
+ """
+ return self.run_build(gyp_file)
+ def build_target(self, gyp_file, target):
+ """
+ Uses the xcodebuild -target option to build the specified target
+ with the .xcodeproj generated from the specified gyp_file.
+ """
+ return self.run_build(gyp_file, '-target', target)
+ def run_build(self, gyp_file, *args):
+ """
+ Runs an xcodebuild using the .xcodeproj generated from the specified
+ gyp_file.
+ """
+ args = ('-project', gyp_file.replace('.gyp', '.xcodeproj')) + args
+ return self.run(program=self.build_tool, arguments=args)
+ def run_built_executable(self, name, *args, **kw):
+ """
+ Runs an executable built by xcodebuild.
+ """
+ # TODO: generalize to different configurations.
+ program = self.workpath('build/Default/' + name)
+ return self.run(program=program, *args, **kw)
+
+
+format_class_list = [
+ TestGypMake,
+ TestGypMSVS,
+ TestGypSCons,
+ TestGypXcode,
+]
+
+def TestGyp(*args, **kw):
+ """
+ Returns an appropriate TestGyp* instance for a specified GYP format.
+ """
+ format = kw.get('format')
+ if not format:
+ format = os.environ.get('TESTGYP_FORMAT')
+ for format_class in format_class_list:
+ if format == format_class.format:
+ return format_class(*args, **kw)
+ raise Exception, "unknown format %r" % format
Property changes on: trunk/test/lib/TestGyp.py
___________________________________________________________________
Name: svn:eol-style
+ LF
« no previous file with comments | « trunk/test/lib/TestCommon.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698