Makes the Python tests more stable (by Vlad Losev); fixes a memory leak in GetThreadCount() on Mac (by Vlad Losev); improves fuse_gtest_files.py to support fusing Google Mock files (by Zhanyong Wan).

This commit is contained in:
zhanyong.wan 2009-04-09 02:57:38 +00:00
parent c12f63214e
commit 7fa242a44b
15 changed files with 254 additions and 197 deletions

View File

@ -29,7 +29,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""fuse_gtest_files.py v0.1.0 """fuse_gtest_files.py v0.2.0
Fuses Google Test source code into a .h file and a .cc file. Fuses Google Test source code into a .h file and a .cc file.
SYNOPSIS SYNOPSIS
@ -42,8 +42,8 @@ SYNOPSIS
two files contain everything you need to use Google Test. Hence two files contain everything you need to use Google Test. Hence
you can "install" Google Test by copying them to wherever you want. you can "install" Google Test by copying them to wherever you want.
GTEST_ROOT_DIR can be omitted and defaults to the parent directory GTEST_ROOT_DIR can be omitted and defaults to the parent
of the directory holding the fuse_gtest_files.py script. directory of the directory holding this script.
EXAMPLES EXAMPLES
./fuse_gtest_files.py fused_gtest ./fuse_gtest_files.py fused_gtest
@ -63,13 +63,17 @@ import re
import sets import sets
import sys import sys
# We assume that this file is in the scripts/ directory in the Google
# Test root directory.
DEFAULT_GTEST_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
# Regex for matching '#include <gtest/...>'. # Regex for matching '#include <gtest/...>'.
INCLUDE_GTEST_FILE_REGEX = re.compile(r'^\s*#\s*include\s*<(gtest/.+)>') INCLUDE_GTEST_FILE_REGEX = re.compile(r'^\s*#\s*include\s*<(gtest/.+)>')
# Regex for matching '#include "src/..."'. # Regex for matching '#include "src/..."'.
INCLUDE_SRC_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(src/.+)"') INCLUDE_SRC_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(src/.+)"')
# Where to find the source files. # Where to find the source seed files.
GTEST_H_SEED = 'include/gtest/gtest.h' GTEST_H_SEED = 'include/gtest/gtest.h'
GTEST_SPI_H_SEED = 'include/gtest/gtest-spi.h' GTEST_SPI_H_SEED = 'include/gtest/gtest-spi.h'
GTEST_ALL_CC_SEED = 'src/gtest-all.cc' GTEST_ALL_CC_SEED = 'src/gtest-all.cc'
@ -79,18 +83,18 @@ GTEST_H_OUTPUT = 'gtest/gtest.h'
GTEST_ALL_CC_OUTPUT = 'gtest/gtest-all.cc' GTEST_ALL_CC_OUTPUT = 'gtest/gtest-all.cc'
def GetGTestRootDir(): def VerifyFileExists(directory, relative_path):
"""Returns the absolute path to the Google Test root directory. """Verifies that the given file exists; aborts on failure.
We assume that this script is in a sub-directory of the Google Test root. relative_path is the file path relative to the given directory.
""" """
my_path = sys.argv[0] # Path to this script. if not os.path.isfile(os.path.join(directory, relative_path)):
my_dir = os.path.dirname(my_path) print 'ERROR: Cannot find %s in directory %s.' % (relative_path,
if not my_dir: directory)
my_dir = '.' print ('Please either specify a valid project root directory '
'or omit it on the command line.')
return os.path.abspath(os.path.join(my_dir, '..')) sys.exit(1)
def ValidateGTestRootDir(gtest_root): def ValidateGTestRootDir(gtest_root):
@ -99,21 +103,34 @@ def ValidateGTestRootDir(gtest_root):
The function aborts the program on failure. The function aborts the program on failure.
""" """
def VerifyFileExists(relative_path): VerifyFileExists(gtest_root, GTEST_H_SEED)
"""Verifies that the given file exists; aborts on failure. VerifyFileExists(gtest_root, GTEST_ALL_CC_SEED)
relative_path is the file path relative to the gtest root.
"""
if not os.path.isfile(os.path.join(gtest_root, relative_path)): def VerifyOutputFile(output_dir, relative_path):
print 'ERROR: Cannot find %s in directory %s.' % (relative_path, """Verifies that the given output file path is valid.
gtest_root)
print ('Please either specify a valid Google Test root directory ' relative_path is relative to the output_dir directory.
'or omit it on the command line.') """
# Makes sure the output file either doesn't exist or can be overwritten.
output_file = os.path.join(output_dir, relative_path)
if os.path.exists(output_file):
# TODO(wan@google.com): The following user-interaction doesn't
# work with automated processes. We should provide a way for the
# Makefile to force overwriting the files.
print ('%s already exists in directory %s - overwrite it? (y/N) ' %
(relative_path, output_dir))
answer = sys.stdin.readline().strip()
if answer not in ['y', 'Y']:
print 'ABORTED.'
sys.exit(1) sys.exit(1)
VerifyFileExists(GTEST_H_SEED) # Makes sure the directory holding the output file exists; creates
VerifyFileExists(GTEST_ALL_CC_SEED) # it and all its ancestors if necessary.
parent_directory = os.path.dirname(output_file)
if not os.path.isdir(parent_directory):
os.makedirs(parent_directory)
def ValidateOutputDir(output_dir): def ValidateOutputDir(output_dir):
@ -122,30 +139,8 @@ def ValidateOutputDir(output_dir):
The function aborts the program on failure. The function aborts the program on failure.
""" """
def VerifyOutputFile(relative_path): VerifyOutputFile(output_dir, GTEST_H_OUTPUT)
"""Verifies that the given output file path is valid. VerifyOutputFile(output_dir, GTEST_ALL_CC_OUTPUT)
relative_path is relative to the output_dir directory.
"""
# Makes sure the output file either doesn't exist or can be overwritten.
output_file = os.path.join(output_dir, relative_path)
if os.path.exists(output_file):
print ('%s already exists in directory %s - overwrite it? (y/N) ' %
(relative_path, output_dir))
answer = sys.stdin.readline().strip()
if answer not in ['y', 'Y']:
print 'ABORTED.'
sys.exit(1)
# Makes sure the directory holding the output file exists; creates
# it and all its ancestors if necessary.
parent_directory = os.path.dirname(output_file)
if not os.path.isdir(parent_directory):
os.makedirs(parent_directory)
VerifyOutputFile(GTEST_H_OUTPUT)
VerifyOutputFile(GTEST_ALL_CC_OUTPUT)
def FuseGTestH(gtest_root, output_dir): def FuseGTestH(gtest_root, output_dir):
@ -177,10 +172,9 @@ def FuseGTestH(gtest_root, output_dir):
output_file.close() output_file.close()
def FuseGTestAllCc(gtest_root, output_dir): def FuseGTestAllCcToFile(gtest_root, output_file):
"""Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir.""" """Scans folder gtest_root to generate gtest/gtest-all.cc in output_file."""
output_file = file(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w')
processed_files = sets.Set() processed_files = sets.Set()
def ProcessFile(gtest_source_file): def ProcessFile(gtest_source_file):
@ -219,10 +213,19 @@ def FuseGTestAllCc(gtest_root, output_dir):
output_file.write(line) output_file.write(line)
ProcessFile(GTEST_ALL_CC_SEED) ProcessFile(GTEST_ALL_CC_SEED)
def FuseGTestAllCc(gtest_root, output_dir):
"""Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir."""
output_file = file(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w')
FuseGTestAllCcToFile(gtest_root, output_file)
output_file.close() output_file.close()
def FuseGTest(gtest_root, output_dir): def FuseGTest(gtest_root, output_dir):
"""Fuses gtest.h and gtest-all.cc."""
ValidateGTestRootDir(gtest_root) ValidateGTestRootDir(gtest_root)
ValidateOutputDir(output_dir) ValidateOutputDir(output_dir)
@ -234,7 +237,7 @@ def main():
argc = len(sys.argv) argc = len(sys.argv)
if argc == 2: if argc == 2:
# fuse_gtest_files.py OUTPUT_DIR # fuse_gtest_files.py OUTPUT_DIR
FuseGTest(GetGTestRootDir(), sys.argv[1]) FuseGTest(DEFAULT_GTEST_ROOT_DIR, sys.argv[1])
elif argc == 3: elif argc == 3:
# fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR # fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR
FuseGTest(sys.argv[1], sys.argv[2]) FuseGTest(sys.argv[1], sys.argv[2])

View File

@ -45,6 +45,7 @@
#if GTEST_OS_MAC #if GTEST_OS_MAC
#include <mach/mach_init.h> #include <mach/mach_init.h>
#include <mach/task.h> #include <mach/task.h>
#include <mach/vm_map.h>
#endif // GTEST_OS_MAC #endif // GTEST_OS_MAC
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
@ -74,22 +75,37 @@ const int kStdErrFileno = 2;
const int kStdErrFileno = STDERR_FILENO; const int kStdErrFileno = STDERR_FILENO;
#endif // _MSC_VER #endif // _MSC_VER
#if GTEST_OS_MAC
// Returns the number of threads running in the process, or 0 to indicate that // Returns the number of threads running in the process, or 0 to indicate that
// we cannot detect it. // we cannot detect it.
size_t GetThreadCount() { size_t GetThreadCount() {
#if GTEST_OS_MAC const task_t task = mach_task_self();
mach_msg_type_number_t thread_count; mach_msg_type_number_t thread_count;
thread_act_port_array_t thread_list; thread_act_array_t thread_list;
kern_return_t status = task_threads(mach_task_self(), const kern_return_t status = task_threads(task, &thread_list, &thread_count);
&thread_list, &thread_count); if (status == KERN_SUCCESS) {
return status == KERN_SUCCESS ? static_cast<size_t>(thread_count) : 0; // task_threads allocates resources in thread_list and we need to free them
// to avoid leaks.
vm_deallocate(task,
reinterpret_cast<vm_address_t>(thread_list),
sizeof(thread_t) * thread_count);
return static_cast<size_t>(thread_count);
} else {
return 0;
}
}
#else #else
size_t GetThreadCount() {
// There's no portable way to detect the number of threads, so we just // There's no portable way to detect the number of threads, so we just
// return 0 to indicate that we cannot detect it. // return 0 to indicate that we cannot detect it.
return 0; return 0;
#endif // GTEST_OS_MAC
} }
#endif // GTEST_OS_MAC
#if GTEST_USES_POSIX_RE #if GTEST_USES_POSIX_RE
// Implements RE. Currently only needed for death tests. // Implements RE. Currently only needed for death tests.

View File

@ -58,8 +58,8 @@ BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure'
THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE' THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE'
# Path to the gtest_break_on_failure_unittest_ program. # Path to the gtest_break_on_failure_unittest_ program.
EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(), EXE_PATH = gtest_test_utils.GetTestExecutablePath(
'gtest_break_on_failure_unittest_') 'gtest_break_on_failure_unittest_')
# Utilities. # Utilities.

View File

@ -38,11 +38,11 @@ import os
import sys import sys
import unittest import unittest
IS_WINDOWS = os.name = 'nt'
COLOR_ENV_VAR = 'GTEST_COLOR' COLOR_ENV_VAR = 'GTEST_COLOR'
COLOR_FLAG = 'gtest_color' COLOR_FLAG = 'gtest_color'
COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_color_test_')
'gtest_color_test_')
def SetEnvVar(env_var, value): def SetEnvVar(env_var, value):
@ -69,11 +69,12 @@ class GTestColorTest(unittest.TestCase):
def testNoEnvVarNoFlag(self): def testNoEnvVarNoFlag(self):
"""Tests the case when there's neither GTEST_COLOR nor --gtest_color.""" """Tests the case when there's neither GTEST_COLOR nor --gtest_color."""
self.assert_(not UsesColor('dumb', None, None)) if not IS_WINDOWS:
self.assert_(not UsesColor('emacs', None, None)) self.assert_(not UsesColor('dumb', None, None))
self.assert_(not UsesColor('xterm-mono', None, None)) self.assert_(not UsesColor('emacs', None, None))
self.assert_(not UsesColor('unknown', None, None)) self.assert_(not UsesColor('xterm-mono', None, None))
self.assert_(not UsesColor(None, None, None)) self.assert_(not UsesColor('unknown', None, None))
self.assert_(not UsesColor(None, None, None))
self.assert_(UsesColor('cygwin', None, None)) self.assert_(UsesColor('cygwin', None, None))
self.assert_(UsesColor('xterm', None, None)) self.assert_(UsesColor('xterm', None, None))
self.assert_(UsesColor('xterm-color', None, None)) self.assert_(UsesColor('xterm-color', None, None))
@ -83,7 +84,8 @@ class GTestColorTest(unittest.TestCase):
self.assert_(not UsesColor('dumb', None, 'no')) self.assert_(not UsesColor('dumb', None, 'no'))
self.assert_(not UsesColor('xterm-color', None, 'no')) self.assert_(not UsesColor('xterm-color', None, 'no'))
self.assert_(not UsesColor('emacs', None, 'auto')) if not IS_WINDOWS:
self.assert_(not UsesColor('emacs', None, 'auto'))
self.assert_(UsesColor('xterm', None, 'auto')) self.assert_(UsesColor('xterm', None, 'auto'))
self.assert_(UsesColor('dumb', None, 'yes')) self.assert_(UsesColor('dumb', None, 'yes'))
self.assert_(UsesColor('xterm', None, 'yes')) self.assert_(UsesColor('xterm', None, 'yes'))
@ -93,7 +95,8 @@ class GTestColorTest(unittest.TestCase):
self.assert_(not UsesColor('dumb', 'no', None)) self.assert_(not UsesColor('dumb', 'no', None))
self.assert_(not UsesColor('xterm-color', 'no', None)) self.assert_(not UsesColor('xterm-color', 'no', None))
self.assert_(not UsesColor('dumb', 'auto', None)) if not IS_WINDOWS:
self.assert_(not UsesColor('dumb', 'auto', None))
self.assert_(UsesColor('xterm-color', 'auto', None)) self.assert_(UsesColor('xterm-color', 'auto', None))
self.assert_(UsesColor('dumb', 'yes', None)) self.assert_(UsesColor('dumb', 'yes', None))
self.assert_(UsesColor('xterm-color', 'yes', None)) self.assert_(UsesColor('xterm-color', 'yes', None))

View File

@ -41,18 +41,7 @@ import unittest
IS_WINDOWS = os.name == 'nt' IS_WINDOWS = os.name == 'nt'
IS_LINUX = os.name == 'posix' IS_LINUX = os.name == 'posix'
if IS_WINDOWS: COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_')
BUILD_DIRS = [
'build.dbg\\',
'build.opt\\',
'build.dbg8\\',
'build.opt8\\',
]
COMMAND = 'gtest_env_var_test_.exe'
if IS_LINUX:
COMMAND = os.path.join(gtest_test_utils.GetBuildDir(),
'gtest_env_var_test_')
def AssertEq(expected, actual): def AssertEq(expected, actual):
@ -104,34 +93,19 @@ def TestEnvVarAffectsFlag(command):
TestFlag(command, 'print_time', '1', '0') TestFlag(command, 'print_time', '1', '0')
TestFlag(command, 'repeat', '999', '1') TestFlag(command, 'repeat', '999', '1')
TestFlag(command, 'throw_on_failure', '1', '0') TestFlag(command, 'throw_on_failure', '1', '0')
TestFlag(command, 'death_test_style', 'threadsafe', 'fast')
if IS_WINDOWS: if IS_WINDOWS:
TestFlag(command, 'catch_exceptions', '1', '0') TestFlag(command, 'catch_exceptions', '1', '0')
if IS_LINUX: if IS_LINUX:
TestFlag(command, 'stack_trace_depth', '0', '100') TestFlag(command, 'stack_trace_depth', '0', '100')
TestFlag(command, 'death_test_style', 'thread-safe', 'fast')
TestFlag(command, 'death_test_use_fork', '1', '0') TestFlag(command, 'death_test_use_fork', '1', '0')
if IS_WINDOWS: class GTestEnvVarTest(unittest.TestCase):
def testEnvVarAffectsFlag(self):
def main(): TestEnvVarAffectsFlag(COMMAND)
for build_dir in BUILD_DIRS:
command = build_dir + COMMAND
print 'Testing with %s . . .' % (command,)
TestEnvVarAffectsFlag(command)
return 0
if __name__ == '__main__':
main()
if IS_LINUX: if __name__ == '__main__':
gtest_test_utils.Main()
class GTestEnvVarTest(unittest.TestCase):
def testEnvVarAffectsFlag(self):
TestEnvVarAffectsFlag(COMMAND)
if __name__ == '__main__':
gtest_test_utils.Main()

View File

@ -52,6 +52,8 @@ import gtest_test_utils
# Constants. # Constants.
IS_WINDOWS = os.name == 'nt'
# The environment variable for specifying the test filters. # The environment variable for specifying the test filters.
FILTER_ENV_VAR = 'GTEST_FILTER' FILTER_ENV_VAR = 'GTEST_FILTER'
@ -67,8 +69,7 @@ FILTER_FLAG = 'gtest_filter'
ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests' ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests'
# Command to run the gtest_filter_unittest_ program. # Command to run the gtest_filter_unittest_ program.
COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_')
'gtest_filter_unittest_')
# Regex for determining whether parameterized tests are enabled in the binary. # Regex for determining whether parameterized tests are enabled in the binary.
PARAM_TEST_REGEX = re.compile(r'/ParamTest') PARAM_TEST_REGEX = re.compile(r'/ParamTest')
@ -204,23 +205,36 @@ class GTestFilterUnitTest(unittest.TestCase):
self.assertEqual(len(set_var), len(full_partition)) self.assertEqual(len(set_var), len(full_partition))
self.assertEqual(sets.Set(set_var), sets.Set(full_partition)) self.assertEqual(sets.Set(set_var), sets.Set(full_partition))
def AdjustForParameterizedTests(self, tests_to_run):
"""Adjust tests_to_run in case value parameterized tests are disabled
in the binary.
"""
global param_tests_present
if not param_tests_present:
return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS))
else:
return tests_to_run
def RunAndVerify(self, gtest_filter, tests_to_run): def RunAndVerify(self, gtest_filter, tests_to_run):
"""Runs gtest_flag_unittest_ with the given filter, and verifies """Runs gtest_flag_unittest_ with the given filter, and verifies
that the right set of tests were run. that the right set of tests were run.
""" """
# Adjust tests_to_run in case value parameterized tests are disabled tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# in the binary.
global param_tests_present
if not param_tests_present:
tests_to_run = list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS))
# First, tests using GTEST_FILTER. # First, tests using GTEST_FILTER.
SetEnvVar(FILTER_ENV_VAR, gtest_filter) # Windows removes empty variables from the environment when passing it
tests_run = Run(COMMAND)[0] # to a new process. This means it is impossible to pass an empty filter
SetEnvVar(FILTER_ENV_VAR, None) # into a process using the GTEST_FILTER environment variable. However,
# we can still test the case when the variable is not supplied (i.e.,
self.AssertSetEqual(tests_run, tests_to_run) # gtest_filter is None).
# pylint: disable-msg=C6403
if not IS_WINDOWS or gtest_filter != '':
SetEnvVar(FILTER_ENV_VAR, gtest_filter)
tests_run = Run(COMMAND)[0]
SetEnvVar(FILTER_ENV_VAR, None)
self.AssertSetEqual(tests_run, tests_to_run)
# pylint: enable-msg=C6403
# Next, tests using --gtest_filter. # Next, tests using --gtest_filter.
@ -239,21 +253,33 @@ class GTestFilterUnitTest(unittest.TestCase):
on each shard should be identical to tests_to_run, without duplicates. on each shard should be identical to tests_to_run, without duplicates.
If check_exit_0, make sure that all shards returned 0. If check_exit_0, make sure that all shards returned 0.
""" """
SetEnvVar(FILTER_ENV_VAR, gtest_filter) tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
partition = []
for i in range(0, total_shards):
(tests_run, exit_code) = RunWithSharding(total_shards, i, command)
if check_exit_0:
self.assert_(exit_code is None)
partition.append(tests_run)
self.AssertPartitionIsValid(tests_to_run, partition) # Windows removes empty variables from the environment when passing it
SetEnvVar(FILTER_ENV_VAR, None) # to a new process. This means it is impossible to pass an empty filter
# into a process using the GTEST_FILTER environment variable. However,
# we can still test the case when the variable is not supplied (i.e.,
# gtest_filter is None).
# pylint: disable-msg=C6403
if not IS_WINDOWS or gtest_filter != '':
SetEnvVar(FILTER_ENV_VAR, gtest_filter)
partition = []
for i in range(0, total_shards):
(tests_run, exit_code) = RunWithSharding(total_shards, i, command)
if check_exit_0:
self.assert_(exit_code is None)
partition.append(tests_run)
self.AssertPartitionIsValid(tests_to_run, partition)
SetEnvVar(FILTER_ENV_VAR, None)
# pylint: enable-msg=C6403
def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run): def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run):
"""Runs gtest_flag_unittest_ with the given filter, and enables """Runs gtest_flag_unittest_ with the given filter, and enables
disabled tests. Verifies that the right set of tests were run. disabled tests. Verifies that the right set of tests were run.
""" """
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# Construct the command line. # Construct the command line.
command = '%s --%s' % (COMMAND, ALSO_RUN_DISABED_TESTS_FLAG) command = '%s --%s' % (COMMAND, ALSO_RUN_DISABED_TESTS_FLAG)
if gtest_filter is not None: if gtest_filter is not None:
@ -263,8 +289,10 @@ class GTestFilterUnitTest(unittest.TestCase):
self.AssertSetEqual(tests_run, tests_to_run) self.AssertSetEqual(tests_run, tests_to_run)
def setUp(self): def setUp(self):
"""Sets up test case. Determines whether value-parameterized tests are """Sets up test case.
enabled in the binary and sets flags accordingly.
Determines whether value-parameterized tests are enabled in the binary and
sets the flags accordingly.
""" """
global param_tests_present global param_tests_present
if param_tests_present is None: if param_tests_present is None:

View File

@ -47,12 +47,7 @@ import unittest
IS_WINDOWS = os.name == 'nt' IS_WINDOWS = os.name == 'nt'
if IS_WINDOWS: PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_')
PROGRAM = 'gtest_help_test_.exe'
else:
PROGRAM = 'gtest_help_test_'
PROGRAM_PATH = os.path.join(gtest_test_utils.GetBuildDir(), PROGRAM)
FLAG_PREFIX = '--gtest_' FLAG_PREFIX = '--gtest_'
CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions' CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions'
DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style' DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style'

View File

@ -52,8 +52,7 @@ import unittest
LIST_TESTS_FLAG = 'gtest_list_tests' LIST_TESTS_FLAG = 'gtest_list_tests'
# Path to the gtest_list_tests_unittest_ program. # Path to the gtest_list_tests_unittest_ program.
EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(), EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_list_tests_unittest_')
'gtest_list_tests_unittest_');
# The expected output when running gtest_list_tests_unittest_ with # The expected output when running gtest_list_tests_unittest_ with
# --gtest_list_tests # --gtest_list_tests

View File

@ -54,16 +54,15 @@ GENGOLDEN_FLAG = '--gengolden'
IS_WINDOWS = os.name == 'nt' IS_WINDOWS = os.name == 'nt'
if IS_WINDOWS: if IS_WINDOWS:
PROGRAM = r'..\build.dbg8\gtest_output_test_.exe'
GOLDEN_NAME = 'gtest_output_test_golden_win.txt' GOLDEN_NAME = 'gtest_output_test_golden_win.txt'
else: else:
PROGRAM = 'gtest_output_test_'
GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' GOLDEN_NAME = 'gtest_output_test_golden_lin.txt'
PROGRAM_PATH = os.path.join(gtest_test_utils.GetBuildDir(), PROGRAM) PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_output_test_')
# At least one command we exercise must not have the # At least one command we exercise must not have the
# --gtest_internal_skip_environment_and_ad_hoc_tests flag. # --gtest_internal_skip_environment_and_ad_hoc_tests flag.
COMMAND_LIST_TESTS = ({}, PROGRAM_PATH + ' --gtest_list_tests')
COMMAND_WITH_COLOR = ({}, PROGRAM_PATH + ' --gtest_color=yes') COMMAND_WITH_COLOR = ({}, PROGRAM_PATH + ' --gtest_color=yes')
COMMAND_WITH_TIME = ({}, PROGRAM_PATH + ' --gtest_print_time ' COMMAND_WITH_TIME = ({}, PROGRAM_PATH + ' --gtest_print_time '
'--gtest_internal_skip_environment_and_ad_hoc_tests ' '--gtest_internal_skip_environment_and_ad_hoc_tests '
@ -76,8 +75,7 @@ COMMAND_WITH_SHARDING = ({'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'},
' --gtest_internal_skip_environment_and_ad_hoc_tests ' ' --gtest_internal_skip_environment_and_ad_hoc_tests '
' --gtest_filter="PassingTest.*"') ' --gtest_filter="PassingTest.*"')
GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME)
GOLDEN_NAME)
def ToUnixLineEnding(s): def ToUnixLineEnding(s):
@ -119,15 +117,35 @@ def RemoveTime(output):
def RemoveTestCounts(output): def RemoveTestCounts(output):
"""Removes test counts from a Google Test program's output.""" """Removes test counts from a Google Test program's output."""
output = re.sub(r'\d+ tests, listed below',
'? tests, listed below', output)
output = re.sub(r'\d+ FAILED TESTS',
'? FAILED TESTS', output)
output = re.sub(r'\d+ tests from \d+ test cases', output = re.sub(r'\d+ tests from \d+ test cases',
'? tests from ? test cases', output) '? tests from ? test cases', output)
return re.sub(r'\d+ tests\.', '? tests.', output) return re.sub(r'\d+ tests\.', '? tests.', output)
def RemoveDeathTests(output): def RemoveMatchingTests(test_output, pattern):
"""Removes death test information from a Google Test program's output.""" """Removes typed test information from a Google Test program's output.
return re.sub(r'\n.*DeathTest.*', '', output) This function strips not only the beginning and the end of a test but also all
output in between.
Args:
test_output: A string containing the test output.
pattern: A string that matches names of test cases to remove.
Returns:
Contents of test_output with removed test case whose names match pattern.
"""
test_output = re.sub(
r'\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % (
pattern, pattern),
'',
test_output)
return re.sub(r'.*%s.*\n' % pattern, '', test_output)
def NormalizeOutput(output): def NormalizeOutput(output):
@ -220,7 +238,19 @@ def GetOutputOfAllCommands():
GetCommandOutput(COMMAND_WITH_SHARDING)) GetCommandOutput(COMMAND_WITH_SHARDING))
test_list = GetShellCommandOutput(COMMAND_LIST_TESTS, '')
SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list
SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list
class GTestOutputTest(unittest.TestCase): class GTestOutputTest(unittest.TestCase):
def RemoveUnsupportedTests(self, test_output):
if not SUPPORTS_DEATH_TESTS:
test_output = RemoveMatchingTests(test_output, 'DeathTest')
if not SUPPORTS_TYPED_TESTS:
test_output = RemoveMatchingTests(test_output, 'TypedTest')
return test_output
def testOutput(self): def testOutput(self):
output = GetOutputOfAllCommands() output = GetOutputOfAllCommands()
golden_file = open(GOLDEN_PATH, 'rb') golden_file = open(GOLDEN_PATH, 'rb')
@ -229,16 +259,25 @@ class GTestOutputTest(unittest.TestCase):
# We want the test to pass regardless of death tests being # We want the test to pass regardless of death tests being
# supported or not. # supported or not.
self.assert_(output == golden or if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS:
RemoveTestCounts(output) == self.assert_(golden == output)
RemoveTestCounts(RemoveDeathTests(golden))) else:
print RemoveTestCounts(self.RemoveUnsupportedTests(golden))
self.assert_(RemoveTestCounts(self.RemoveUnsupportedTests(golden)) ==
RemoveTestCounts(output))
if __name__ == '__main__': if __name__ == '__main__':
if sys.argv[1:] == [GENGOLDEN_FLAG]: if sys.argv[1:] == [GENGOLDEN_FLAG]:
output = GetOutputOfAllCommands() if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS:
golden_file = open(GOLDEN_PATH, 'wb') output = GetOutputOfAllCommands()
golden_file.write(output) golden_file = open(GOLDEN_PATH, 'wb')
golden_file.close() golden_file.write(output)
golden_file.close()
else:
print >> sys.stderr, ('Unable to write a golden file when compiled in an '
'environment that does not support death tests and '
'typed tests. Are you using VC 7.1?')
sys.exit(1)
else: else:
gtest_test_utils.Main() gtest_test_utils.Main()

View File

@ -44,10 +44,10 @@ except:
import popen2 import popen2
_SUBPROCESS_MODULE_AVAILABLE = False _SUBPROCESS_MODULE_AVAILABLE = False
IS_WINDOWS = os.name == 'nt'
# Initially maps a flag to its default value. After # Initially maps a flag to its default value. After
# _ParseAndStripGTestFlags() is called, maps a flag to its actual # _ParseAndStripGTestFlags() is called, maps a flag to its actual value.
# value.
_flag_map = {'gtest_source_dir': os.path.dirname(sys.argv[0]), _flag_map = {'gtest_source_dir': os.path.dirname(sys.argv[0]),
'gtest_build_dir': os.path.dirname(sys.argv[0])} 'gtest_build_dir': os.path.dirname(sys.argv[0])}
_gtest_flags_are_parsed = False _gtest_flags_are_parsed = False
@ -103,6 +103,38 @@ def GetBuildDir():
return os.path.abspath(GetFlag('gtest_build_dir')) return os.path.abspath(GetFlag('gtest_build_dir'))
def GetTestExecutablePath(executable_name):
"""Returns the absolute path of the test binary given its name.
The function will print a message and abort the program if the resulting file
doesn't exist.
Args:
executable_name: name of the test binary that the test script runs.
Returns:
The absolute path of the test binary.
"""
path = os.path.abspath(os.path.join(GetBuildDir(), executable_name))
if IS_WINDOWS and not path.endswith('.exe'):
path += '.exe'
if not os.path.exists(path):
message = (
'Unable to find the test binary. Please make sure to provide path\n'
'to the binary via the --gtest_build_dir flag or the GTEST_BUILD_DIR\n'
'environment variable. For convenient use, invoke this script via\n'
'mk_test.py.\n'
# TODO(vladl@google.com): change mk_test.py to test.py after renaming
# the file.
'Please run mk_test.py -h for help.')
print >> sys.stderr, message
sys.exit(1)
return path
def GetExitStatus(exit_code): def GetExitStatus(exit_code):
"""Returns the argument to exit(), or -1 if exit() wasn't called. """Returns the argument to exit(), or -1 if exit() wasn't called.

View File

@ -49,8 +49,8 @@ THROW_ON_FAILURE = 'gtest_throw_on_failure'
# Path to the gtest_throw_on_failure_test_ program, compiled with # Path to the gtest_throw_on_failure_test_ program, compiled with
# exceptions disabled. # exceptions disabled.
EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(), EXE_PATH = gtest_test_utils.GetTestExecutablePath(
'gtest_throw_on_failure_test_') 'gtest_throw_on_failure_test_')
# Utilities. # Utilities.

View File

@ -34,25 +34,11 @@
__author__ = 'wan@google.com (Zhanyong Wan)' __author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils import gtest_test_utils
import os
import sys import sys
import unittest import unittest
IS_WINDOWS = os.name == 'nt'
IS_LINUX = os.name == 'posix'
if IS_WINDOWS: COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_')
BUILD_DIRS = [
'build.dbg\\',
'build.opt\\',
'build.dbg8\\',
'build.opt8\\',
]
COMMAND = 'gtest_uninitialized_test_.exe'
if IS_LINUX:
COMMAND = os.path.join(gtest_test_utils.GetBuildDir(),
'gtest_uninitialized_test_')
def Assert(condition): def Assert(condition):
@ -77,25 +63,10 @@ def TestExitCodeAndOutput(command):
Assert('InitGoogleTest' in p.output) Assert('InitGoogleTest' in p.output)
if IS_WINDOWS: class GTestUninitializedTest(unittest.TestCase):
def testExitCodeAndOutput(self):
def main(): TestExitCodeAndOutput(COMMAND)
for build_dir in BUILD_DIRS:
command = build_dir + COMMAND
print 'Testing with %s . . .' % (command,)
TestExitCodeAndOutput(command)
return 0
if __name__ == '__main__':
main()
if IS_LINUX: if __name__ == '__main__':
gtest_test_utils.Main()
class GTestUninitializedTest(unittest.TestCase):
def testExitCodeAndOutput(self):
TestExitCodeAndOutput(COMMAND)
if __name__ == '__main__':
gtest_test_utils.Main()

View File

@ -98,8 +98,7 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase):
self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_XML_2) self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_XML_2)
def _TestOutFile(self, test_name, expected_xml): def _TestOutFile(self, test_name, expected_xml):
gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name)
test_name)
command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_] command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_]
p = gtest_test_utils.Subprocess(command, working_dir=tempfile.mkdtemp()) p = gtest_test_utils.Subprocess(command, working_dir=tempfile.mkdtemp())
self.assert_(p.exited) self.assert_(p.exited)

View File

@ -121,10 +121,9 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
default name if no name is explicitly specified. default name if no name is explicitly specified.
""" """
temp_dir = tempfile.mkdtemp() temp_dir = tempfile.mkdtemp()
output_file = os.path.join(temp_dir, output_file = os.path.join(temp_dir, GTEST_DEFAULT_OUTPUT_FILE)
GTEST_DEFAULT_OUTPUT_FILE) gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), "gtest_no_test_unittest")
"gtest_no_test_unittest")
try: try:
os.remove(output_file) os.remove(output_file)
except OSError, e: except OSError, e:
@ -148,8 +147,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
""" """
xml_path = os.path.join(tempfile.mkdtemp(), gtest_prog_name + "out.xml") xml_path = os.path.join(tempfile.mkdtemp(), gtest_prog_name + "out.xml")
gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
gtest_prog_name)
command = [gtest_prog_path, "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path)] command = [gtest_prog_path, "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path)]
p = gtest_test_utils.Subprocess(command) p = gtest_test_utils.Subprocess(command)

View File

@ -150,7 +150,7 @@ class GTestXMLTestCase(unittest.TestCase):
for child in element.childNodes: for child in element.childNodes:
if child.nodeType == Node.CDATA_SECTION_NODE: if child.nodeType == Node.CDATA_SECTION_NODE:
# Removes the source line number. # Removes the source line number.
cdata = re.sub(r"^.*/(.*:)\d+\n", "\\1*\n", child.nodeValue) cdata = re.sub(r"^.*[/\\](.*:)\d+\n", "\\1*\n", child.nodeValue)
# Removes the actual stack trace. # Removes the actual stack trace.
child.nodeValue = re.sub(r"\nStack trace:\n(.|\n)*", child.nodeValue = re.sub(r"\nStack trace:\n(.|\n)*",
"", cdata) "", cdata)