| 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
|
|
|
|
|