diff options
author | zhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925> | 2009-11-24 20:19:45 +0000 |
---|---|---|
committer | zhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925> | 2009-11-24 20:19:45 +0000 |
commit | 2e075a7f60da95cd02a3935fda49d222a435d56a (patch) | |
tree | 38f5aae68b5e0a48991fdcbd7729647c9213fdfa /run_tests.py | |
parent | b6fe6899bef6dd90572fc0e7f12912d9ad87a19e (diff) | |
download | googletest-2e075a7f60da95cd02a3935fda49d222a435d56a.tar.gz googletest-2e075a7f60da95cd02a3935fda49d222a435d56a.tar.bz2 googletest-2e075a7f60da95cd02a3935fda49d222a435d56a.zip |
Refactors run_tests.py s.t. it can be shared by gmock (by Vlad Losev); Fixes a warning in gtest-tuple_test.cc on Cygwin (by Vlad Losev).
Diffstat (limited to 'run_tests.py')
-rwxr-xr-x | run_tests.py | 405 |
1 files changed, 8 insertions, 397 deletions
diff --git a/run_tests.py b/run_tests.py index 9d85b805..e1084056 100755 --- a/run_tests.py +++ b/run_tests.py @@ -28,415 +28,26 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""Runs specified tests for Google Test. +"""Runs the specified tests for Google Test. -SYNOPSIS - run_tests.py [OPTION]... [BUILD_DIR]... [TEST]... - -DESCRIPTION - Runs the specified tests (either binary or Python), and prints a - summary of the results. BUILD_DIRS will be used to search for the - binaries. If no TESTs are specified, all binary tests found in - BUILD_DIRs and all Python tests found in the directory test/ (in the - gtest root) are run. - - TEST is a name of either a binary or a Python test. A binary test is - an executable file named *_test or *_unittest (with the .exe - extension on Windows) A Python test is a script named *_test.py or - *_unittest.py. - -OPTIONS - -c CONFIGURATIONS - Specify build directories via build configurations. - CONFIGURATIONS is either a comma-separated list of build - configurations or 'all'. Each configuration is equivalent to - adding 'scons/build/<configuration>/gtest/scons' to BUILD_DIRs. - Specifying -c=all is equivalent to providing all directories - listed in KNOWN BUILD DIRECTORIES section below. - - -a - Equivalent to -c=all - - -b - Equivalent to -c=all with the exception that the script will not - fail if some of the KNOWN BUILD DIRECTORIES do not exists; the - script will simply not run the tests there. 'b' stands for - 'built directories'. - -RETURN VALUE - Returns 0 if all tests are successful; otherwise returns 1. - -EXAMPLES - run_tests.py - Runs all tests for the default build configuration. - - run_tests.py -a - Runs all tests with binaries in KNOWN BUILD DIRECTORIES. - - run_tests.py -b - Runs all tests in KNOWN BUILD DIRECTORIES that have been - built. - - run_tests.py foo/ - Runs all tests in the foo/ directory and all Python tests in - the directory test. The Python tests are instructed to look - for binaries in foo/. - - run_tests.py bar_test.exe test/baz_test.exe foo/ bar/ - Runs foo/bar_test.exe, bar/bar_test.exe, foo/baz_test.exe, and - bar/baz_test.exe. - - run_tests.py foo bar test/foo_test.py - Runs test/foo_test.py twice instructing it to look for its - test binaries in the directories foo and bar, - correspondingly. - -KNOWN BUILD DIRECTORIES - run_tests.py knows about directories where the SCons build script - deposits its products. These are the directories where run_tests.py - will be looking for its binaries. Currently, gtest's SConstruct file - defines them as follows (the default build directory is the first one - listed in each group): - On Windows: - <gtest root>/scons/build/win-dbg8/gtest/scons/ - <gtest root>/scons/build/win-opt8/gtest/scons/ - <gtest root>/scons/build/win-dbg/gtest/scons/ - <gtest root>/scons/build/win-opt/gtest/scons/ - On Mac: - <gtest root>/scons/build/mac-dbg/gtest/scons/ - <gtest root>/scons/build/mac-opt/gtest/scons/ - On other platforms: - <gtest root>/scons/build/dbg/gtest/scons/ - <gtest root>/scons/build/opt/gtest/scons/ - -AUTHOR - Written by Zhanyong Wan (wan@google.com) - and Vlad Losev(vladl@google.com). - -REQUIREMENTS - This script requires Python 2.3 or higher. +This script requires Python 2.3 or higher. To learn the usage, run it +with -h. """ -import optparse import os -import re -import sets import sys -try: - # subrocess module is a preferable way to invoke subprocesses but it may - # not be available on MacOS X 10.4. - import subprocess -except ImportError: - subprocess = None - -IS_WINDOWS = os.name == 'nt' -IS_MAC = os.name == 'posix' and os.uname()[0] == 'Darwin' -IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] - -# Definition of CONFIGS must match that of the build directory names in the -# SConstruct script. The first list item is the default build configuration. -if IS_WINDOWS: - CONFIGS = ('win-dbg8', 'win-opt8', 'win-dbg', 'win-opt') -elif IS_MAC: - CONFIGS = ('mac-dbg', 'mac-opt') -else: - CONFIGS = ('dbg', 'opt') - -if IS_WINDOWS or IS_CYGWIN: - PYTHON_TEST_REGEX = re.compile(r'_(unit)?test\.py$', re.IGNORECASE) - BINARY_TEST_REGEX = re.compile(r'_(unit)?test(\.exe)?$', re.IGNORECASE) - BINARY_TEST_SEARCH_REGEX = re.compile(r'_(unit)?test\.exe$', re.IGNORECASE) -else: - PYTHON_TEST_REGEX = re.compile(r'_(unit)?test\.py$') - BINARY_TEST_REGEX = re.compile(r'_(unit)?test$') - BINARY_TEST_SEARCH_REGEX = BINARY_TEST_REGEX - - -def _GetGtestBuildDir(os, script_dir, config): - """Calculates path to the Google Test SCons build directory.""" - - return os.path.normpath(os.path.join(script_dir, - 'scons/build', - config, - 'gtest/scons')) - - -# All paths in this script are either absolute or relative to the current -# working directory, unless otherwise specified. -class TestRunner(object): - """Provides facilities for running Python and binary tests for Google Test.""" - - def __init__(self, - build_dir_var_name='GTEST_BUILD_DIR', - injected_os=os, - injected_subprocess=subprocess, - injected_script_dir=os.path.dirname(__file__), - injected_build_dir_finder=_GetGtestBuildDir): - self.os = injected_os - self.subprocess = injected_subprocess - self.build_dir_finder = injected_build_dir_finder - self.build_dir_var_name = build_dir_var_name - # If a program using this file is invoked via a relative path, the - # script directory will be relative to the path of the main program - # file. It may be '.' when this script is invoked directly or '..' when - # it is imported for testing. To simplify testing we inject the script - # directory into TestRunner. - self.script_dir = injected_script_dir - - def _GetBuildDirForConfig(self, config): - """Returns the build directory for a given configuration.""" - - return self.build_dir_finder(self.os, self.script_dir, config) - - def _Run(self, args): - """Runs the executable with given args (args[0] is the executable name). - - Args: - args: Command line arguments for the process. - - Returns: - Process's exit code if it exits normally, or -signal if the process is - killed by a signal. - """ - - if self.subprocess: - return self.subprocess.Popen(args).wait() - else: - return self.os.spawnv(self.os.P_WAIT, args[0], args) - - def _RunBinaryTest(self, test): - """Runs the binary test given its path. - - Args: - test: Path to the test binary. - - Returns: - Process's exit code if it exits normally, or -signal if the process is - killed by a signal. - """ - - return self._Run([test]) - - def _RunPythonTest(self, test, build_dir): - """Runs the Python test script with the specified build directory. +SCRIPT_DIR = os.path.dirname(__file__) or '.' - Args: - test: Path to the test's Python script. - build_dir: Path to the directory where the test binary is to be found. - - Returns: - Process's exit code if it exits normally, or -signal if the process is - killed by a signal. - """ - - old_build_dir = self.os.environ.get(self.build_dir_var_name) - - try: - self.os.environ[self.build_dir_var_name] = build_dir - - # If this script is run on a Windows machine that has no association - # between the .py extension and a python interpreter, simply passing - # the script name into subprocess.Popen/os.spawn will not work. - print 'Running %s . . .' % (test,) - return self._Run([sys.executable, test]) - - finally: - if old_build_dir is None: - del self.os.environ[self.build_dir_var_name] - else: - self.os.environ[self.build_dir_var_name] = old_build_dir - - def _FindFilesByRegex(self, directory, regex): - """Returns files in a directory whose names match a regular expression. - - Args: - directory: Path to the directory to search for files. - regex: Regular expression to filter file names. - - Returns: - The list of the paths to the files in the directory. - """ - - return [self.os.path.join(directory, file_name) - for file_name in self.os.listdir(directory) - if re.search(regex, file_name)] - - # TODO(vladl@google.com): Implement parsing of scons/SConscript to run all - # tests defined there when no tests are specified. - # TODO(vladl@google.com): Update the docstring after the code is changed to - # try to test all builds defined in scons/SConscript. - def GetTestsToRun(self, - args, - named_configurations, - built_configurations, - available_configurations=CONFIGS): - """Determines what tests should be run. - - Args: - args: The list of non-option arguments from the command line. - named_configurations: The list of configurations specified via -c or -a. - built_configurations: True if -b has been specified. - available_configurations: a list of configurations available on the - current platform, injectable for testing. - - Returns: - A tuple with 2 elements: the list of Python tests to run and the list of - binary tests to run. - """ - - if named_configurations == 'all': - named_configurations = ','.join(available_configurations) - - normalized_args = [self.os.path.normpath(arg) for arg in args] - - # A final list of build directories which will be searched for the test - # binaries. First, add directories specified directly on the command - # line. - build_dirs = filter(self.os.path.isdir, normalized_args) - - # Adds build directories specified via their build configurations using - # the -c or -a options. - if named_configurations: - build_dirs += [self._GetBuildDirForConfig(config) - for config in named_configurations.split(',')] - - # Adds KNOWN BUILD DIRECTORIES if -b is specified. - if built_configurations: - build_dirs += [self._GetBuildDirForConfig(config) - for config in available_configurations - if self.os.path.isdir(self._GetBuildDirForConfig(config))] - - # If no directories were specified either via -a, -b, -c, or directly, use - # the default configuration. - elif not build_dirs: - build_dirs = [self._GetBuildDirForConfig(available_configurations[0])] - - # Makes sure there are no duplications. - build_dirs = sets.Set(build_dirs) - - errors_found = False - listed_python_tests = [] # All Python tests listed on the command line. - listed_binary_tests = [] # All binary tests listed on the command line. - - test_dir = self.os.path.normpath(self.os.path.join(self.script_dir, 'test')) - - # Sifts through non-directory arguments fishing for any Python or binary - # tests and detecting errors. - for argument in sets.Set(normalized_args) - build_dirs: - if re.search(PYTHON_TEST_REGEX, argument): - python_path = self.os.path.join(test_dir, - self.os.path.basename(argument)) - if self.os.path.isfile(python_path): - listed_python_tests.append(python_path) - else: - sys.stderr.write('Unable to find Python test %s' % argument) - errors_found = True - elif re.search(BINARY_TEST_REGEX, argument): - # This script also accepts binary test names prefixed with test/ for - # the convenience of typing them (can use path completions in the - # shell). Strips test/ prefix from the binary test names. - listed_binary_tests.append(self.os.path.basename(argument)) - else: - sys.stderr.write('%s is neither test nor build directory' % argument) - errors_found = True - - if errors_found: - return None - - user_has_listed_tests = listed_python_tests or listed_binary_tests - - if user_has_listed_tests: - selected_python_tests = listed_python_tests - else: - selected_python_tests = self._FindFilesByRegex(test_dir, - PYTHON_TEST_REGEX) - - # TODO(vladl@google.com): skip unbuilt Python tests when -b is specified. - python_test_pairs = [] - for directory in build_dirs: - for test in selected_python_tests: - python_test_pairs.append((directory, test)) - - binary_test_pairs = [] - for directory in build_dirs: - if user_has_listed_tests: - binary_test_pairs.extend( - [(directory, self.os.path.join(directory, test)) - for test in listed_binary_tests]) - else: - tests = self._FindFilesByRegex(directory, BINARY_TEST_SEARCH_REGEX) - binary_test_pairs.extend([(directory, test) for test in tests]) - - return (python_test_pairs, binary_test_pairs) - - def RunTests(self, python_tests, binary_tests): - """Runs Python and binary tests and reports results to the standard output. - - Args: - python_tests: List of Python tests to run in the form of tuples - (build directory, Python test script). - binary_tests: List of binary tests to run in the form of tuples - (build directory, binary file). - - Returns: - The exit code the program should pass into sys.exit(). - """ - - if python_tests or binary_tests: - results = [] - for directory, test in python_tests: - results.append((directory, - test, - self._RunPythonTest(test, directory) == 0)) - for directory, test in binary_tests: - results.append((directory, - self.os.path.basename(test), - self._RunBinaryTest(test) == 0)) - - failed = [(directory, test) - for (directory, test, success) in results - if not success] - print - print '%d tests run.' % len(results) - if failed: - print 'The following %d tests failed:' % len(failed) - for (directory, test) in failed: - print '%s in %s' % (test, directory) - return 1 - else: - print 'All tests passed!' - else: # No tests defined - print 'Nothing to test - no tests specified!' - - return 0 +sys.path.append(os.path.join(SCRIPT_DIR, 'test')) +import run_tests_util def _Main(): """Runs all tests for Google Test.""" - parser = optparse.OptionParser() - parser.add_option('-c', - action='store', - dest='configurations', - default=None, - help='Test in the specified build directories') - parser.add_option('-a', - action='store_const', - dest='configurations', - default=None, - const='all', - help='Test in all default build directories') - parser.add_option('-b', - action='store_const', - dest='built_configurations', - default=False, - const=True, - help=('Test in all default build directories, do not fail' - 'if some of them do not exist')) - (options, args) = parser.parse_args() - - test_runner = TestRunner() + options, args = run_tests_util.ParseArgs('gtest') + test_runner = run_tests_util.TestRunner(script_dir=SCRIPT_DIR) tests = test_runner.GetTestsToRun(args, options.configurations, options.built_configurations) |