summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-04-09 02:57:38 +0000
committerzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-04-09 02:57:38 +0000
commit767998dfadaf87c1193d51cf5847a7f147c6e1f7 (patch)
tree968a9d50b23d7ef33cf37aaed77d23f0407fde7d
parent1b171100b3341c01fb377f8202d9eaccbeec1f55 (diff)
downloadgoogletest-767998dfadaf87c1193d51cf5847a7f147c6e1f7.tar.gz
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).
git-svn-id: http://googletest.googlecode.com/svn/trunk@238 861a406c-534a-0410-8894-cb66d6ee9925
-rwxr-xr-xscripts/fuse_gtest_files.py107
-rw-r--r--src/gtest-port.cc28
-rwxr-xr-xtest/gtest_break_on_failure_unittest.py4
-rwxr-xr-xtest/gtest_color_test.py21
-rwxr-xr-xtest/gtest_env_var_test.py40
-rwxr-xr-xtest/gtest_filter_unittest.py76
-rwxr-xr-xtest/gtest_help_test.py7
-rwxr-xr-xtest/gtest_list_tests_unittest.py3
-rwxr-xr-xtest/gtest_output_test.py69
-rwxr-xr-xtest/gtest_test_utils.py38
-rwxr-xr-xtest/gtest_throw_on_failure_test.py4
-rwxr-xr-xtest/gtest_uninitialized_test.py41
-rwxr-xr-xtest/gtest_xml_outfiles_test.py3
-rwxr-xr-xtest/gtest_xml_output_unittest.py10
-rwxr-xr-xtest/gtest_xml_test_utils.py2
15 files changed, 255 insertions, 198 deletions
diff --git a/scripts/fuse_gtest_files.py b/scripts/fuse_gtest_files.py
index edffb1d..148444c 100755
--- a/scripts/fuse_gtest_files.py
+++ b/scripts/fuse_gtest_files.py
@@ -29,7 +29,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# 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.
SYNOPSIS
@@ -42,8 +42,8 @@ SYNOPSIS
two files contain everything you need to use Google Test. Hence
you can "install" Google Test by copying them to wherever you want.
- GTEST_ROOT_DIR can be omitted and defaults to the parent directory
- of the directory holding the fuse_gtest_files.py script.
+ GTEST_ROOT_DIR can be omitted and defaults to the parent
+ directory of the directory holding this script.
EXAMPLES
./fuse_gtest_files.py fused_gtest
@@ -63,13 +63,17 @@ import re
import sets
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/...>'.
INCLUDE_GTEST_FILE_REGEX = re.compile(r'^\s*#\s*include\s*<(gtest/.+)>')
# Regex for matching '#include "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_SPI_H_SEED = 'include/gtest/gtest-spi.h'
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'
-def GetGTestRootDir():
- """Returns the absolute path to the Google Test root directory.
+def VerifyFileExists(directory, relative_path):
+ """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.
- my_dir = os.path.dirname(my_path)
- if not my_dir:
- my_dir = '.'
-
- return os.path.abspath(os.path.join(my_dir, '..'))
+ if not os.path.isfile(os.path.join(directory, relative_path)):
+ print 'ERROR: Cannot find %s in directory %s.' % (relative_path,
+ directory)
+ print ('Please either specify a valid project root directory '
+ 'or omit it on the command line.')
+ sys.exit(1)
def ValidateGTestRootDir(gtest_root):
@@ -99,21 +103,34 @@ def ValidateGTestRootDir(gtest_root):
The function aborts the program on failure.
"""
- def VerifyFileExists(relative_path):
- """Verifies that the given file exists; aborts on failure.
+ VerifyFileExists(gtest_root, GTEST_H_SEED)
+ VerifyFileExists(gtest_root, GTEST_ALL_CC_SEED)
+
+
+def VerifyOutputFile(output_dir, relative_path):
+ """Verifies that the given output file path is valid.
- relative_path is the file path relative to the gtest root.
- """
+ relative_path is relative to the output_dir directory.
+ """
- if not os.path.isfile(os.path.join(gtest_root, relative_path)):
- print 'ERROR: Cannot find %s in directory %s.' % (relative_path,
- gtest_root)
- print ('Please either specify a valid Google Test root 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)
- VerifyFileExists(GTEST_H_SEED)
- VerifyFileExists(GTEST_ALL_CC_SEED)
+ # 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)
def ValidateOutputDir(output_dir):
@@ -122,30 +139,8 @@ def ValidateOutputDir(output_dir):
The function aborts the program on failure.
"""
- def VerifyOutputFile(relative_path):
- """Verifies that the given output file path is valid.
-
- 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)
+ VerifyOutputFile(output_dir, GTEST_H_OUTPUT)
+ VerifyOutputFile(output_dir, GTEST_ALL_CC_OUTPUT)
def FuseGTestH(gtest_root, output_dir):
@@ -177,10 +172,9 @@ def FuseGTestH(gtest_root, output_dir):
output_file.close()
-def FuseGTestAllCc(gtest_root, output_dir):
- """Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir."""
+def FuseGTestAllCcToFile(gtest_root, output_file):
+ """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()
def ProcessFile(gtest_source_file):
@@ -219,10 +213,19 @@ def FuseGTestAllCc(gtest_root, output_dir):
output_file.write(line)
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()
def FuseGTest(gtest_root, output_dir):
+ """Fuses gtest.h and gtest-all.cc."""
+
ValidateGTestRootDir(gtest_root)
ValidateOutputDir(output_dir)
@@ -234,7 +237,7 @@ def main():
argc = len(sys.argv)
if argc == 2:
# fuse_gtest_files.py OUTPUT_DIR
- FuseGTest(GetGTestRootDir(), sys.argv[1])
+ FuseGTest(DEFAULT_GTEST_ROOT_DIR, sys.argv[1])
elif argc == 3:
# fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR
FuseGTest(sys.argv[1], sys.argv[2])
diff --git a/src/gtest-port.cc b/src/gtest-port.cc
index 193f532..3c1e80c 100644
--- a/src/gtest-port.cc
+++ b/src/gtest-port.cc
@@ -45,6 +45,7 @@
#if GTEST_OS_MAC
#include <mach/mach_init.h>
#include <mach/task.h>
+#include <mach/vm_map.h>
#endif // GTEST_OS_MAC
#ifdef _WIN32_WCE
@@ -74,22 +75,37 @@ const int kStdErrFileno = 2;
const int kStdErrFileno = STDERR_FILENO;
#endif // _MSC_VER
+#if GTEST_OS_MAC
+
// Returns the number of threads running in the process, or 0 to indicate that
// we cannot detect it.
size_t GetThreadCount() {
-#if GTEST_OS_MAC
+ const task_t task = mach_task_self();
mach_msg_type_number_t thread_count;
- thread_act_port_array_t thread_list;
- kern_return_t status = task_threads(mach_task_self(),
- &thread_list, &thread_count);
- return status == KERN_SUCCESS ? static_cast<size_t>(thread_count) : 0;
+ thread_act_array_t thread_list;
+ const kern_return_t status = task_threads(task, &thread_list, &thread_count);
+ if (status == KERN_SUCCESS) {
+ // 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
+
+size_t GetThreadCount() {
// 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;
-#endif // GTEST_OS_MAC
}
+#endif // GTEST_OS_MAC
+
#if GTEST_USES_POSIX_RE
// Implements RE. Currently only needed for death tests.
diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py
index 9c2855f..c9dd008 100755
--- a/test/gtest_break_on_failure_unittest.py
+++ b/test/gtest_break_on_failure_unittest.py
@@ -58,8 +58,8 @@ BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure'
THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE'
# Path to the gtest_break_on_failure_unittest_ program.
-EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(),
- 'gtest_break_on_failure_unittest_')
+EXE_PATH = gtest_test_utils.GetTestExecutablePath(
+ 'gtest_break_on_failure_unittest_')
# Utilities.
diff --git a/test/gtest_color_test.py b/test/gtest_color_test.py
index 5260a89..32db4b9 100755
--- a/test/gtest_color_test.py
+++ b/test/gtest_color_test.py
@@ -38,11 +38,11 @@ import os
import sys
import unittest
+IS_WINDOWS = os.name = 'nt'
COLOR_ENV_VAR = 'GTEST_COLOR'
COLOR_FLAG = 'gtest_color'
-COMMAND = os.path.join(gtest_test_utils.GetBuildDir(),
- 'gtest_color_test_')
+COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_color_test_')
def SetEnvVar(env_var, value):
@@ -69,11 +69,12 @@ class GTestColorTest(unittest.TestCase):
def testNoEnvVarNoFlag(self):
"""Tests the case when there's neither GTEST_COLOR nor --gtest_color."""
- self.assert_(not UsesColor('dumb', None, None))
- self.assert_(not UsesColor('emacs', None, None))
- self.assert_(not UsesColor('xterm-mono', None, None))
- self.assert_(not UsesColor('unknown', None, None))
- self.assert_(not UsesColor(None, None, None))
+ if not IS_WINDOWS:
+ self.assert_(not UsesColor('dumb', None, None))
+ self.assert_(not UsesColor('emacs', None, None))
+ self.assert_(not UsesColor('xterm-mono', 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('xterm', 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('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('dumb', 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('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('dumb', 'yes', None))
self.assert_(UsesColor('xterm-color', 'yes', None))
diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py
index c5acc5c..92b9cd8 100755
--- a/test/gtest_env_var_test.py
+++ b/test/gtest_env_var_test.py
@@ -41,18 +41,7 @@ import unittest
IS_WINDOWS = os.name == 'nt'
IS_LINUX = os.name == 'posix'
-if IS_WINDOWS:
- 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_')
+COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_')
def AssertEq(expected, actual):
@@ -104,34 +93,19 @@ def TestEnvVarAffectsFlag(command):
TestFlag(command, 'print_time', '1', '0')
TestFlag(command, 'repeat', '999', '1')
TestFlag(command, 'throw_on_failure', '1', '0')
+ TestFlag(command, 'death_test_style', 'threadsafe', 'fast')
if IS_WINDOWS:
TestFlag(command, 'catch_exceptions', '1', '0')
if IS_LINUX:
TestFlag(command, 'stack_trace_depth', '0', '100')
- TestFlag(command, 'death_test_style', 'thread-safe', 'fast')
TestFlag(command, 'death_test_use_fork', '1', '0')
-if IS_WINDOWS:
-
- def main():
- 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:
-
- class GTestEnvVarTest(unittest.TestCase):
- def testEnvVarAffectsFlag(self):
- TestEnvVarAffectsFlag(COMMAND)
+class GTestEnvVarTest(unittest.TestCase):
+ def testEnvVarAffectsFlag(self):
+ TestEnvVarAffectsFlag(COMMAND)
- if __name__ == '__main__':
- gtest_test_utils.Main()
+if __name__ == '__main__':
+ gtest_test_utils.Main()
diff --git a/test/gtest_filter_unittest.py b/test/gtest_filter_unittest.py
index cd88cdf..6002fac 100755
--- a/test/gtest_filter_unittest.py
+++ b/test/gtest_filter_unittest.py
@@ -52,6 +52,8 @@ import gtest_test_utils
# Constants.
+IS_WINDOWS = os.name == 'nt'
+
# The environment variable for specifying the test filters.
FILTER_ENV_VAR = 'GTEST_FILTER'
@@ -67,8 +69,7 @@ FILTER_FLAG = 'gtest_filter'
ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests'
# Command to run the gtest_filter_unittest_ program.
-COMMAND = os.path.join(gtest_test_utils.GetBuildDir(),
- 'gtest_filter_unittest_')
+COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_')
# Regex for determining whether parameterized tests are enabled in the binary.
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(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):
"""Runs gtest_flag_unittest_ with the given filter, and verifies
that the right set of tests were run.
"""
- # Adjust tests_to_run in case value parameterized tests are disabled
- # 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))
+ tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# First, tests using 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)
+ # Windows removes empty variables from the environment when passing it
+ # 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)
+ 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.
@@ -239,21 +253,33 @@ class GTestFilterUnitTest(unittest.TestCase):
on each shard should be identical to tests_to_run, without duplicates.
If check_exit_0, make sure that all shards returned 0.
"""
- 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)
+ tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
+
+ # Windows removes empty variables from the environment when passing it
+ # 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):
"""Runs gtest_flag_unittest_ with the given filter, and enables
disabled tests. Verifies that the right set of tests were run.
"""
+ tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
+
# Construct the command line.
command = '%s --%s' % (COMMAND, ALSO_RUN_DISABED_TESTS_FLAG)
if gtest_filter is not None:
@@ -263,8 +289,10 @@ class GTestFilterUnitTest(unittest.TestCase):
self.AssertSetEqual(tests_run, tests_to_run)
def setUp(self):
- """Sets up test case. Determines whether value-parameterized tests are
- enabled in the binary and sets flags accordingly.
+ """Sets up test case.
+
+ Determines whether value-parameterized tests are enabled in the binary and
+ sets the flags accordingly.
"""
global param_tests_present
if param_tests_present is None:
diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py
index 6271019..d81f149 100755
--- a/test/gtest_help_test.py
+++ b/test/gtest_help_test.py
@@ -47,12 +47,7 @@ import unittest
IS_WINDOWS = os.name == 'nt'
-if IS_WINDOWS:
- PROGRAM = 'gtest_help_test_.exe'
-else:
- PROGRAM = 'gtest_help_test_'
-
-PROGRAM_PATH = os.path.join(gtest_test_utils.GetBuildDir(), PROGRAM)
+PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_')
FLAG_PREFIX = '--gtest_'
CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions'
DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style'
diff --git a/test/gtest_list_tests_unittest.py b/test/gtest_list_tests_unittest.py
index 9cefa15..147bd73 100755
--- a/test/gtest_list_tests_unittest.py
+++ b/test/gtest_list_tests_unittest.py
@@ -52,8 +52,7 @@ import unittest
LIST_TESTS_FLAG = 'gtest_list_tests'
# Path to the gtest_list_tests_unittest_ program.
-EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(),
- 'gtest_list_tests_unittest_');
+EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_list_tests_unittest_')
# The expected output when running gtest_list_tests_unittest_ with
# --gtest_list_tests
diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py
index f35e002..5289406 100755
--- a/test/gtest_output_test.py
+++ b/test/gtest_output_test.py
@@ -54,16 +54,15 @@ GENGOLDEN_FLAG = '--gengolden'
IS_WINDOWS = os.name == 'nt'
if IS_WINDOWS:
- PROGRAM = r'..\build.dbg8\gtest_output_test_.exe'
GOLDEN_NAME = 'gtest_output_test_golden_win.txt'
else:
- PROGRAM = 'gtest_output_test_'
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
# --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_TIME = ({}, PROGRAM_PATH + ' --gtest_print_time '
'--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_filter="PassingTest.*"')
-GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(),
- GOLDEN_NAME)
+GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME)
def ToUnixLineEnding(s):
@@ -119,15 +117,35 @@ def RemoveTime(output):
def RemoveTestCounts(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',
'? tests from ? test cases', output)
return re.sub(r'\d+ tests\.', '? tests.', output)
-def RemoveDeathTests(output):
- """Removes death test information from a Google Test program's output."""
+def RemoveMatchingTests(test_output, pattern):
+ """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):
@@ -220,7 +238,19 @@ def GetOutputOfAllCommands():
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):
+ 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):
output = GetOutputOfAllCommands()
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
# supported or not.
- self.assert_(output == golden or
- RemoveTestCounts(output) ==
- RemoveTestCounts(RemoveDeathTests(golden)))
+ if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS:
+ self.assert_(golden == output)
+ else:
+ print RemoveTestCounts(self.RemoveUnsupportedTests(golden))
+ self.assert_(RemoveTestCounts(self.RemoveUnsupportedTests(golden)) ==
+ RemoveTestCounts(output))
if __name__ == '__main__':
if sys.argv[1:] == [GENGOLDEN_FLAG]:
- output = GetOutputOfAllCommands()
- golden_file = open(GOLDEN_PATH, 'wb')
- golden_file.write(output)
- golden_file.close()
+ if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS:
+ output = GetOutputOfAllCommands()
+ golden_file = open(GOLDEN_PATH, 'wb')
+ 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:
gtest_test_utils.Main()
diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py
index 8f55b07..7dc8c42 100755
--- a/test/gtest_test_utils.py
+++ b/test/gtest_test_utils.py
@@ -44,10 +44,10 @@ except:
import popen2
_SUBPROCESS_MODULE_AVAILABLE = False
+IS_WINDOWS = os.name == 'nt'
-# Initially maps a flag to its default value. After
-# _ParseAndStripGTestFlags() is called, maps a flag to its actual
-# value.
+# Initially maps a flag to its default value. After
+# _ParseAndStripGTestFlags() is called, maps a flag to its actual value.
_flag_map = {'gtest_source_dir': os.path.dirname(sys.argv[0]),
'gtest_build_dir': os.path.dirname(sys.argv[0])}
_gtest_flags_are_parsed = False
@@ -103,6 +103,38 @@ def GetBuildDir():
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):
"""Returns the argument to exit(), or -1 if exit() wasn't called.
diff --git a/test/gtest_throw_on_failure_test.py b/test/gtest_throw_on_failure_test.py
index a80d617..50172d0 100755
--- a/test/gtest_throw_on_failure_test.py
+++ b/test/gtest_throw_on_failure_test.py
@@ -49,8 +49,8 @@ THROW_ON_FAILURE = 'gtest_throw_on_failure'
# Path to the gtest_throw_on_failure_test_ program, compiled with
# exceptions disabled.
-EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(),
- 'gtest_throw_on_failure_test_')
+EXE_PATH = gtest_test_utils.GetTestExecutablePath(
+ 'gtest_throw_on_failure_test_')
# Utilities.
diff --git a/test/gtest_uninitialized_test.py b/test/gtest_uninitialized_test.py
index a3ba629..19b92e9 100755
--- a/test/gtest_uninitialized_test.py
+++ b/test/gtest_uninitialized_test.py
@@ -34,25 +34,11 @@
__author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils
-import os
import sys
import unittest
-IS_WINDOWS = os.name == 'nt'
-IS_LINUX = os.name == 'posix'
-if IS_WINDOWS:
- 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_')
+COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_')
def Assert(condition):
@@ -77,25 +63,10 @@ def TestExitCodeAndOutput(command):
Assert('InitGoogleTest' in p.output)
-if IS_WINDOWS:
-
- def main():
- 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:
-
- class GTestUninitializedTest(unittest.TestCase):
- def testExitCodeAndOutput(self):
- TestExitCodeAndOutput(COMMAND)
+class GTestUninitializedTest(unittest.TestCase):
+ def testExitCodeAndOutput(self):
+ TestExitCodeAndOutput(COMMAND)
- if __name__ == '__main__':
- gtest_test_utils.Main()
+if __name__ == '__main__':
+ gtest_test_utils.Main()
diff --git a/test/gtest_xml_outfiles_test.py b/test/gtest_xml_outfiles_test.py
index 3e91f6d..9d62793 100755
--- a/test/gtest_xml_outfiles_test.py
+++ b/test/gtest_xml_outfiles_test.py
@@ -98,8 +98,7 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase):
self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_XML_2)
def _TestOutFile(self, test_name, expected_xml):
- gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(),
- test_name)
+ gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name)
command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_]
p = gtest_test_utils.Subprocess(command, working_dir=tempfile.mkdtemp())
self.assert_(p.exited)
diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py
index 4587c41..622251e 100755
--- a/test/gtest_xml_output_unittest.py
+++ b/test/gtest_xml_output_unittest.py
@@ -121,10 +121,9 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
default name if no name is explicitly specified.
"""
temp_dir = tempfile.mkdtemp()
- output_file = os.path.join(temp_dir,
- GTEST_DEFAULT_OUTPUT_FILE)
- gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(),
- "gtest_no_test_unittest")
+ output_file = os.path.join(temp_dir, GTEST_DEFAULT_OUTPUT_FILE)
+ gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
+ "gtest_no_test_unittest")
try:
os.remove(output_file)
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")
- gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(),
- gtest_prog_name)
+ gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
command = [gtest_prog_path, "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path)]
p = gtest_test_utils.Subprocess(command)
diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py
index 00a56cb..64eebb1 100755
--- a/test/gtest_xml_test_utils.py
+++ b/test/gtest_xml_test_utils.py
@@ -150,7 +150,7 @@ class GTestXMLTestCase(unittest.TestCase):
for child in element.childNodes:
if child.nodeType == Node.CDATA_SECTION_NODE:
# 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.
child.nodeValue = re.sub(r"\nStack trace:\n(.|\n)*",
"", cdata)