summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-06-17 21:06:27 (GMT)
committerzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-06-17 21:06:27 (GMT)
commit532dc2de35f2cef191bc91c3587a9f8f4974756f (patch)
tree1dd721d45ddd731134dda23f8368781979dc0b09 /test
parent210ea10e7ad6e27342c7d9a46c2844a9bcbad396 (diff)
downloadgoogletest-532dc2de35f2cef191bc91c3587a9f8f4974756f.zip
googletest-532dc2de35f2cef191bc91c3587a9f8f4974756f.tar.gz
googletest-532dc2de35f2cef191bc91c3587a9f8f4974756f.tar.bz2
Implements a subset of TR1 tuple needed by gtest and gmock (by Zhanyong Wan); cleaned up the Python tests (by Vlad Losev); made run_tests.py invokable from any directory (by Vlad Losev).
Diffstat (limited to 'test')
-rw-r--r--test/gtest-tuple_test.cc288
-rwxr-xr-xtest/gtest_break_on_failure_unittest.py3
-rwxr-xr-xtest/gtest_color_test.py7
-rwxr-xr-xtest/gtest_env_var_test.py12
-rwxr-xr-xtest/gtest_filter_unittest.py72
-rwxr-xr-xtest/gtest_help_test.py5
-rwxr-xr-xtest/gtest_list_tests_unittest.py7
-rwxr-xr-xtest/gtest_nc_test.py5
-rwxr-xr-xtest/gtest_output_test.py87
-rwxr-xr-xtest/gtest_test_utils.py37
-rwxr-xr-xtest/gtest_throw_on_failure_test.py5
-rwxr-xr-xtest/gtest_uninitialized_test.py4
-rwxr-xr-xtest/gtest_xml_outfiles_test.py15
-rwxr-xr-xtest/gtest_xml_output_unittest.py31
-rwxr-xr-xtest/gtest_xml_test_utils.py7
-rwxr-xr-xtest/run_tests_test.py50
16 files changed, 524 insertions, 111 deletions
diff --git a/test/gtest-tuple_test.cc b/test/gtest-tuple_test.cc
new file mode 100644
index 0000000..3829118
--- /dev/null
+++ b/test/gtest-tuple_test.cc
@@ -0,0 +1,288 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#include <gtest/internal/gtest-tuple.h>
+#include <utility>
+#include <gtest/gtest.h>
+
+namespace {
+
+using ::std::tr1::get;
+using ::std::tr1::make_tuple;
+using ::std::tr1::tuple;
+using ::std::tr1::tuple_element;
+using ::std::tr1::tuple_size;
+using ::testing::StaticAssertTypeEq;
+
+// Tests that tuple_element<K, tuple<T0, T1, ..., TN> >::type returns TK.
+TEST(tuple_element_Test, ReturnsElementType) {
+ StaticAssertTypeEq<int, tuple_element<0, tuple<int, char> >::type>();
+ StaticAssertTypeEq<int&, tuple_element<1, tuple<double, int&> >::type>();
+ StaticAssertTypeEq<bool, tuple_element<2, tuple<double, int, bool> >::type>();
+}
+
+// Tests that tuple_size<T>::value gives the number of fields in tuple
+// type T.
+TEST(tuple_size_Test, ReturnsNumberOfFields) {
+ EXPECT_EQ(0, +tuple_size<tuple<> >::value);
+ EXPECT_EQ(1, +tuple_size<tuple<void*> >::value);
+ EXPECT_EQ(1, +tuple_size<tuple<char> >::value);
+ EXPECT_EQ(1, +(tuple_size<tuple<tuple<int, double> > >::value));
+ EXPECT_EQ(2, +(tuple_size<tuple<int&, const char> >::value));
+ EXPECT_EQ(3, +(tuple_size<tuple<char*, void, const bool&> >::value));
+}
+
+// Tests comparing a tuple with itself.
+TEST(ComparisonTest, ComparesWithSelf) {
+ const tuple<int, char, bool> a(5, 'a', false);
+
+ EXPECT_TRUE(a == a);
+ EXPECT_FALSE(a != a);
+}
+
+// Tests comparing two tuples with the same value.
+TEST(ComparisonTest, ComparesEqualTuples) {
+ const tuple<int, bool> a(5, true), b(5, true);
+
+ EXPECT_TRUE(a == b);
+ EXPECT_FALSE(a != b);
+}
+
+// Tests comparing two different tuples that have no reference fields.
+TEST(ComparisonTest, ComparesUnequalTuplesWithoutReferenceFields) {
+ typedef tuple<const int, char> FooTuple;
+
+ const FooTuple a(0, 'x');
+ const FooTuple b(1, 'a');
+
+ EXPECT_TRUE(a != b);
+ EXPECT_FALSE(a == b);
+
+ const FooTuple c(1, 'b');
+
+ EXPECT_TRUE(b != c);
+ EXPECT_FALSE(b == c);
+}
+
+// Tests comparing two different tuples that have reference fields.
+TEST(ComparisonTest, ComparesUnequalTuplesWithReferenceFields) {
+ typedef tuple<int&, const char&> FooTuple;
+
+ int i = 5;
+ const char ch = 'a';
+ const FooTuple a(i, ch);
+
+ int j = 6;
+ const FooTuple b(j, ch);
+
+ EXPECT_TRUE(a != b);
+ EXPECT_FALSE(a == b);
+
+ j = 5;
+ const char ch2 = 'b';
+ const FooTuple c(j, ch2);
+
+ EXPECT_TRUE(b != c);
+ EXPECT_FALSE(b == c);
+}
+
+// Tests that a tuple field with a reference type is an alias of the
+// variable it's supposed to reference.
+TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) {
+ int n = 0;
+ tuple<bool, int&> t(true, n);
+
+ n = 1;
+ EXPECT_EQ(n, get<1>(t))
+ << "Changing a underlying variable should update the reference field.";
+
+ // Makes sure that the implementation doesn't do anything funny with
+ // the & operator for the return type of get<>().
+ EXPECT_EQ(&n, &(get<1>(t)))
+ << "The address of a reference field should equal the address of "
+ << "the underlying variable.";
+
+ get<1>(t) = 2;
+ EXPECT_EQ(2, n)
+ << "Changing a reference field should update the underlying variable.";
+}
+
+// Tests tuple's default constructor.
+TEST(TupleConstructorTest, DefaultConstructor) {
+ // We are just testing that the following compiles.
+ tuple<> empty;
+ tuple<int> one_field;
+ tuple<double, char, bool*> three_fields;
+}
+
+// Tests constructing a tuple from its fields.
+TEST(TupleConstructorTest, ConstructsFromFields) {
+ int n = 1;
+ // Reference field.
+ tuple<int&> a(n);
+ EXPECT_EQ(&n, &(get<0>(a)));
+
+ // Non-reference fields.
+ tuple<int, char> b(5, 'a');
+ EXPECT_EQ(5, get<0>(b));
+ EXPECT_EQ('a', get<1>(b));
+
+ // Const reference field.
+ const int m = 2;
+ tuple<bool, const int&> c(true, m);
+ EXPECT_TRUE(get<0>(c));
+ EXPECT_EQ(&m, &(get<1>(c)));
+}
+
+// Tests tuple's copy constructor.
+TEST(TupleConstructorTest, CopyConstructor) {
+ tuple<double, bool> a(0.0, true);
+ tuple<double, bool> b(a);
+
+ EXPECT_DOUBLE_EQ(0.0, get<0>(b));
+ EXPECT_TRUE(get<1>(b));
+}
+
+// Tests constructing a tuple from another tuple that has a compatible
+// but different type.
+TEST(TupleConstructorTest, ConstructsFromDifferentTupleType) {
+ tuple<int, int, char> a(0, 1, 'a');
+ tuple<double, long, int> b(a);
+
+ EXPECT_DOUBLE_EQ(0.0, get<0>(b));
+ EXPECT_EQ(1, get<1>(b));
+ EXPECT_EQ('a', get<2>(b));
+}
+
+// Tests constructing a 2-tuple from an std::pair.
+TEST(TupleConstructorTest, ConstructsFromPair) {
+ ::std::pair<int, char> a(1, 'a');
+ tuple<int, char> b(a);
+ tuple<int, const char&> c(a);
+}
+
+// Tests assigning a tuple to another tuple with the same type.
+TEST(TupleAssignmentTest, AssignsToSameTupleType) {
+ const tuple<int, long> a(5, 7L);
+ tuple<int, long> b;
+ b = a;
+ EXPECT_EQ(5, get<0>(b));
+ EXPECT_EQ(7L, get<1>(b));
+}
+
+// Tests assigning a tuple to another tuple with a different but
+// compatible type.
+TEST(TupleAssignmentTest, AssignsToDifferentTupleType) {
+ const tuple<int, long, bool> a(1, 7L, true);
+ tuple<long, int, bool> b;
+ b = a;
+ EXPECT_EQ(1L, get<0>(b));
+ EXPECT_EQ(7, get<1>(b));
+ EXPECT_TRUE(get<2>(b));
+}
+
+// Tests assigning an std::pair to a 2-tuple.
+TEST(TupleAssignmentTest, AssignsFromPair) {
+ const ::std::pair<int, bool> a(5, true);
+ tuple<int, bool> b;
+ b = a;
+ EXPECT_EQ(5, get<0>(b));
+ EXPECT_TRUE(get<1>(b));
+
+ tuple<long, bool> c;
+ c = a;
+ EXPECT_EQ(5L, get<0>(c));
+ EXPECT_TRUE(get<1>(c));
+}
+
+// A fixture for testing big tuples.
+class BigTupleTest : public testing::Test {
+ protected:
+ typedef tuple<int, int, int, int, int, int, int, int, int, int> BigTuple;
+
+ BigTupleTest() :
+ a_(1, 0, 0, 0, 0, 0, 0, 0, 0, 2),
+ b_(1, 0, 0, 0, 0, 0, 0, 0, 0, 3) {}
+
+ BigTuple a_, b_;
+};
+
+// Tests constructing big tuples.
+TEST_F(BigTupleTest, Construction) {
+ BigTuple a;
+ BigTuple b(b_);
+}
+
+// Tests that get<N>(t) returns the N-th (0-based) field of tuple t.
+TEST_F(BigTupleTest, get) {
+ EXPECT_EQ(1, get<0>(a_));
+ EXPECT_EQ(2, get<9>(a_));
+
+ // Tests that get() works on a const tuple too.
+ const BigTuple a(a_);
+ EXPECT_EQ(1, get<0>(a));
+ EXPECT_EQ(2, get<9>(a));
+}
+
+// Tests comparing big tuples.
+TEST_F(BigTupleTest, Comparisons) {
+ EXPECT_TRUE(a_ == a_);
+ EXPECT_FALSE(a_ != a_);
+
+ EXPECT_TRUE(a_ != b_);
+ EXPECT_FALSE(a_ == b_);
+}
+
+TEST(MakeTupleTest, WorksForScalarTypes) {
+ tuple<bool, int> a;
+ a = make_tuple(true, 5);
+ EXPECT_TRUE(get<0>(a));
+ EXPECT_EQ(5, get<1>(a));
+
+ tuple<char, int, long> b;
+ b = make_tuple('a', 'b', 5);
+ EXPECT_EQ('a', get<0>(b));
+ EXPECT_EQ('b', get<1>(b));
+ EXPECT_EQ(5, get<2>(b));
+}
+
+TEST(MakeTupleTest, WorksForPointers) {
+ int a[] = { 1, 2, 3, 4 };
+ const char* const str = "hi";
+ int* const p = a;
+
+ tuple<const char*, int*> t;
+ t = make_tuple(str, p);
+ EXPECT_EQ(str, get<0>(t));
+ EXPECT_EQ(p, get<1>(t));
+}
+
+} // namespace
diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py
index cae288a..218d371 100755
--- a/test/gtest_break_on_failure_unittest.py
+++ b/test/gtest_break_on_failure_unittest.py
@@ -43,7 +43,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils
import os
import sys
-import unittest
# Constants.
@@ -94,7 +93,7 @@ def Run(command):
# The tests.
-class GTestBreakOnFailureUnitTest(unittest.TestCase):
+class GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase):
"""Tests using the GTEST_BREAK_ON_FAILURE environment variable or
the --gtest_break_on_failure flag to turn assertion failures into
segmentation faults.
diff --git a/test/gtest_color_test.py b/test/gtest_color_test.py
index 1b68630..f617dc5 100755
--- a/test/gtest_color_test.py
+++ b/test/gtest_color_test.py
@@ -33,10 +33,9 @@
__author__ = 'wan@google.com (Zhanyong Wan)'
-import gtest_test_utils
import os
-import sys
-import unittest
+import gtest_test_utils
+
IS_WINDOWS = os.name = 'nt'
@@ -65,7 +64,7 @@ def UsesColor(term, color_env_var, color_flag):
return gtest_test_utils.GetExitStatus(os.system(cmd))
-class GTestColorTest(unittest.TestCase):
+class GTestColorTest(gtest_test_utils.TestCase):
def testNoEnvVarNoFlag(self):
"""Tests the case when there's neither GTEST_COLOR nor --gtest_color."""
diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py
index 35e8041..54719fa 100755
--- a/test/gtest_env_var_test.py
+++ b/test/gtest_env_var_test.py
@@ -33,13 +33,12 @@
__author__ = 'wan@google.com (Zhanyong Wan)'
-import gtest_test_utils
import os
-import sys
-import unittest
+import gtest_test_utils
+
IS_WINDOWS = os.name == 'nt'
-IS_LINUX = os.name == 'posix'
+IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_')
@@ -97,12 +96,13 @@ def TestEnvVarAffectsFlag(command):
if IS_WINDOWS:
TestFlag(command, 'catch_exceptions', '1', '0')
+
if IS_LINUX:
- TestFlag(command, 'stack_trace_depth', '0', '100')
TestFlag(command, 'death_test_use_fork', '1', '0')
+ TestFlag(command, 'stack_trace_depth', '0', '100')
-class GTestEnvVarTest(unittest.TestCase):
+class GTestEnvVarTest(gtest_test_utils.TestCase):
def testEnvVarAffectsFlag(self):
TestEnvVarAffectsFlag(COMMAND)
diff --git a/test/gtest_filter_unittest.py b/test/gtest_filter_unittest.py
index 6002fac..4e9556b 100755
--- a/test/gtest_filter_unittest.py
+++ b/test/gtest_filter_unittest.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2005, Google Inc.
-# All rights reserved.
+# Copyright 2005 Google Inc. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@@ -46,8 +45,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
import sets
-import tempfile
-import unittest
import gtest_test_utils
# Constants.
@@ -133,9 +130,7 @@ def SetEnvVar(env_var, value):
def Run(command):
- """Runs a Google Test program and returns a list of full names of the
- tests that were run along with the test exit code.
- """
+ """Runs a test program and returns its exit code and a list of tests run."""
stdout_file = os.popen(command, 'r')
tests_run = []
@@ -169,9 +164,7 @@ def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs):
def RunWithSharding(total_shards, shard_index, command):
- """Runs the Google Test program shard and returns a list of full names of the
- tests that were run along with the exit code.
- """
+ """Runs a test program shard and returns exit code and a list of tests run."""
extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index),
TOTAL_SHARDS_ENV_VAR: str(total_shards)}
@@ -180,10 +173,8 @@ def RunWithSharding(total_shards, shard_index, command):
# The unit test.
-class GTestFilterUnitTest(unittest.TestCase):
- """Tests using the GTEST_FILTER environment variable or the
- --gtest_filter flag to filter tests.
- """
+class GTestFilterUnitTest(gtest_test_utils.TestCase):
+ """Tests GTEST_FILTER env variable or --gtest_filter flag to filter tests."""
# Utilities.
@@ -206,9 +197,8 @@ class GTestFilterUnitTest(unittest.TestCase):
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.
- """
+ """Adjust tests_to_run in case value parameterized tests are disabled."""
+
global param_tests_present
if not param_tests_present:
return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS))
@@ -216,9 +206,8 @@ class GTestFilterUnitTest(unittest.TestCase):
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.
- """
+ """Checks that the binary runs correct set of tests for the given filter."""
+
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# First, tests using GTEST_FILTER.
@@ -248,11 +237,21 @@ class GTestFilterUnitTest(unittest.TestCase):
def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run,
command=COMMAND, check_exit_0=False):
- """Runs all shards of gtest_flag_unittest_ with the given filter, and
+ """Checks that binary runs correct tests for the given filter and shard.
+
+ Runs all shards of gtest_filter_unittest_ with the given filter, and
verifies that the right set of tests were run. The union of tests run
on each shard should be identical to tests_to_run, without duplicates.
- If check_exit_0, make sure that all shards returned 0.
+
+ Args:
+ gtest_filter: A filter to apply to the tests.
+ total_shards: A total number of shards to split test run into.
+ tests_to_run: A set of tests expected to run.
+ command: A command to invoke the test binary.
+ check_exit_0: When set to a true value, make sure that all shards
+ return 0.
"""
+
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# Windows removes empty variables from the environment when passing it
@@ -275,9 +274,16 @@ class GTestFilterUnitTest(unittest.TestCase):
# pylint: enable-msg=C6403
def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run):
- """Runs gtest_flag_unittest_ with the given filter, and enables
+ """Checks that the binary runs correct set of tests for the given filter.
+
+ Runs gtest_filter_unittest_ with the given filter, and enables
disabled tests. Verifies that the right set of tests were run.
+
+ Args:
+ gtest_filter: A filter to apply to the tests.
+ tests_to_run: A set of tests expected to run.
"""
+
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# Construct the command line.
@@ -294,6 +300,7 @@ class GTestFilterUnitTest(unittest.TestCase):
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:
param_tests_present = PARAM_TEST_REGEX.search(
@@ -305,9 +312,8 @@ class GTestFilterUnitTest(unittest.TestCase):
self.RunAndVerify(None, ACTIVE_TESTS)
def testDefaultBehaviorWithShards(self):
- """Tests the behavior of not specifying the filter, with sharding
- enabled.
- """
+ """Tests the behavior without the filter, with sharding enabled."""
+
self.RunAndVerifyWithSharding(None, 1, ACTIVE_TESTS)
self.RunAndVerifyWithSharding(None, 2, ACTIVE_TESTS)
self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) - 1, ACTIVE_TESTS)
@@ -520,9 +526,7 @@ class GTestFilterUnitTest(unittest.TestCase):
])
def testFlagOverridesEnvVar(self):
- """Tests that the --gtest_filter flag overrides the GTEST_FILTER
- environment variable.
- """
+ """Tests that the filter flag overrides the filtering env. variable."""
SetEnvVar(FILTER_ENV_VAR, 'Foo*')
command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, '*One')
@@ -534,8 +538,8 @@ class GTestFilterUnitTest(unittest.TestCase):
def testShardStatusFileIsCreated(self):
"""Tests that the shard file is created if specified in the environment."""
- test_tmpdir = tempfile.mkdtemp()
- shard_status_file = os.path.join(test_tmpdir, 'shard_status_file')
+ shard_status_file = os.path.join(gtest_test_utils.GetTempDir(),
+ 'shard_status_file')
self.assert_(not os.path.exists(shard_status_file))
extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
@@ -546,13 +550,12 @@ class GTestFilterUnitTest(unittest.TestCase):
stdout_file.close()
self.assert_(os.path.exists(shard_status_file))
os.remove(shard_status_file)
- os.removedirs(test_tmpdir)
def testShardStatusFileIsCreatedWithListTests(self):
"""Tests that the shard file is created with --gtest_list_tests."""
- test_tmpdir = tempfile.mkdtemp()
- shard_status_file = os.path.join(test_tmpdir, 'shard_status_file2')
+ shard_status_file = os.path.join(gtest_test_utils.GetTempDir(),
+ 'shard_status_file2')
self.assert_(not os.path.exists(shard_status_file))
extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
@@ -564,7 +567,6 @@ class GTestFilterUnitTest(unittest.TestCase):
stdout_file.close()
self.assert_(os.path.exists(shard_status_file))
os.remove(shard_status_file)
- os.removedirs(test_tmpdir)
def testShardingWorksWithDeathTests(self):
"""Tests integration with death tests and sharding."""
diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py
index d81f149..0a2a07b 100755
--- a/test/gtest_help_test.py
+++ b/test/gtest_help_test.py
@@ -39,10 +39,9 @@ SYNOPSIS
__author__ = 'wan@google.com (Zhanyong Wan)'
-import gtest_test_utils
import os
import re
-import unittest
+import gtest_test_utils
IS_WINDOWS = os.name == 'nt'
@@ -83,7 +82,7 @@ def RunWithFlag(flag):
return child.exit_code, child.output
-class GTestHelpTest(unittest.TestCase):
+class GTestHelpTest(gtest_test_utils.TestCase):
"""Tests the --help flag and its equivalent forms."""
def TestHelpFlag(self, flag):
diff --git a/test/gtest_list_tests_unittest.py b/test/gtest_list_tests_unittest.py
index 3d006df..7dca0b8 100755
--- a/test/gtest_list_tests_unittest.py
+++ b/test/gtest_list_tests_unittest.py
@@ -39,11 +39,8 @@ Google Test) the command line flags.
__author__ = 'phanna@google.com (Patrick Hanna)'
-import gtest_test_utils
import os
-import re
-import sys
-import unittest
+import gtest_test_utils
# Constants.
@@ -105,7 +102,7 @@ def Run(command):
# The unit test.
-class GTestListTestsUnitTest(unittest.TestCase):
+class GTestListTestsUnitTest(gtest_test_utils.TestCase):
"""Tests using the --gtest_list_tests flag to list all tests."""
def RunAndVerify(self, flag_value, expected_output, other_flag):
diff --git a/test/gtest_nc_test.py b/test/gtest_nc_test.py
index 6e77d70..06ffb3f 100755
--- a/test/gtest_nc_test.py
+++ b/test/gtest_nc_test.py
@@ -38,6 +38,11 @@ import sys
import unittest
+IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
+if not IS_LINUX:
+ sys.exit(0) # Negative compilation tests are not supported on Windows & Mac.
+
+
class GTestNCTest(unittest.TestCase):
"""Negative compilation test for Google Test."""
diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py
index 2751fa6..91cf915 100755
--- a/test/gtest_output_test.py
+++ b/test/gtest_output_test.py
@@ -44,7 +44,6 @@ import os
import re
import string
import sys
-import unittest
import gtest_test_utils
@@ -84,11 +83,11 @@ def ToUnixLineEnding(s):
return s.replace('\r\n', '\n').replace('\r', '\n')
-def RemoveLocations(output):
+def RemoveLocations(test_output):
"""Removes all file location info from a Google Test program's output.
Args:
- output: the output of a Google Test program.
+ test_output: the output of a Google Test program.
Returns:
output with all file location info (in the form of
@@ -97,10 +96,10 @@ def RemoveLocations(output):
'FILE_NAME:#: '.
"""
- return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', output)
+ return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', test_output)
-def RemoveStackTraces(output):
+def RemoveStackTraceDetails(output):
"""Removes all stack traces from a Google Test program's output."""
# *? means "find the shortest string that matches".
@@ -108,6 +107,13 @@ def RemoveStackTraces(output):
'Stack trace: (omitted)\n\n', output)
+def RemoveStackTraces(output):
+ """Removes all traces of stack traces from a Google Test program's output."""
+
+ # *? means "find the shortest string that matches".
+ return re.sub(r'Stack trace:(.|\n)*?\n\n', '', output)
+
+
def RemoveTime(output):
"""Removes all time information from a Google Test program's output."""
@@ -123,25 +129,28 @@ def RemoveTestCounts(output):
'? FAILED TESTS', output)
output = re.sub(r'\d+ tests from \d+ test cases',
'? tests from ? test cases', output)
+ output = re.sub(r'\d+ tests from ([a-zA-Z_])',
+ r'? tests from \1', output)
return re.sub(r'\d+ tests\.', '? tests.', output)
def RemoveMatchingTests(test_output, pattern):
- """Removes typed test information from a Google Test program's output.
+ """Removes output of specified tests from a Google Test program's output.
- This function strips not only the beginning and the end of a test but also all
- output in between.
+ 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.
+ pattern: A regex string that matches names of test cases or
+ tests to remove.
Returns:
- Contents of test_output with removed test case whose names match pattern.
+ Contents of test_output with tests whose names match pattern removed.
"""
test_output = re.sub(
- r'\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % (
+ r'.*\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % (
pattern, pattern),
'',
test_output)
@@ -153,7 +162,7 @@ def NormalizeOutput(output):
output = ToUnixLineEnding(output)
output = RemoveLocations(output)
- output = RemoveStackTraces(output)
+ output = RemoveStackTraceDetails(output)
output = RemoveTime(output)
return output
@@ -241,14 +250,28 @@ def GetOutputOfAllCommands():
test_list = GetShellCommandOutput(COMMAND_LIST_TESTS, '')
SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list
SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list
+SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list
+SUPPORTS_STACK_TRACES = False
+
+CAN_GENERATE_GOLDEN_FILE = SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS
-class GTestOutputTest(unittest.TestCase):
+class GTestOutputTest(gtest_test_utils.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')
+ if not SUPPORTS_THREADS:
+ test_output = RemoveMatchingTests(test_output,
+ 'ExpectFailureWithThreadsTest')
+ test_output = RemoveMatchingTests(test_output,
+ 'ScopedFakeTestPartResultReporterTest')
+ test_output = RemoveMatchingTests(test_output,
+ 'WorksConcurrently')
+ if not SUPPORTS_STACK_TRACES:
+ test_output = RemoveStackTraces(test_output)
+
return test_output
def testOutput(self):
@@ -262,26 +285,48 @@ class GTestOutputTest(unittest.TestCase):
golden = ToUnixLineEnding(golden_file.read())
golden_file.close()
- # We want the test to pass regardless of death tests being
+ # We want the test to pass regardless of certain features being
# supported or not.
- if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS:
+ if CAN_GENERATE_GOLDEN_FILE:
self.assert_(golden == output)
else:
- self.assert_(RemoveTestCounts(self.RemoveUnsupportedTests(golden)) ==
- RemoveTestCounts(output))
+ normalized_actual = RemoveTestCounts(output)
+ normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests(golden))
+
+ # This code is very handy when debugging test differences so I left it
+ # here, commented.
+ # open(os.path.join(
+ # gtest_test_utils.GetSourceDir(),
+ # '_gtest_output_test_normalized_actual.txt'), 'wb').write(
+ # normalized_actual)
+ # open(os.path.join(
+ # gtest_test_utils.GetSourceDir(),
+ # '_gtest_output_test_normalized_golden.txt'), 'wb').write(
+ # normalized_golden)
+
+ self.assert_(normalized_golden == normalized_actual)
if __name__ == '__main__':
if sys.argv[1:] == [GENGOLDEN_FLAG]:
- if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS:
+ if CAN_GENERATE_GOLDEN_FILE:
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?')
+ message = (
+ """Unable to write a golden file when compiled in an environment
+that does not support all the required features (death tests""")
+ if IS_WINDOWS:
+ message += (
+ """\nand typed tests). Please check that you are using VC++ 8.0 SP1
+or higher as your compiler.""")
+ else:
+ message += """\nand typed tests). Please generate the golden file
+using a binary built with those features enabled."""
+
+ sys.stderr.write(message)
sys.exit(1)
else:
gtest_test_utils.Main()
diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py
index 7dc8c42..45b25cd 100755
--- a/test/gtest_test_utils.py
+++ b/test/gtest_test_utils.py
@@ -33,19 +33,32 @@
__author__ = 'wan@google.com (Zhanyong Wan)'
+import atexit
import os
+import shutil
import sys
+import tempfile
import unittest
+_test_module = unittest
+# Suppresses the 'Import not at the top of the file' lint complaint.
+# pylint: disable-msg=C6204
try:
import subprocess
_SUBPROCESS_MODULE_AVAILABLE = True
except:
import popen2
_SUBPROCESS_MODULE_AVAILABLE = False
+# pylint: enable-msg=C6204
+
IS_WINDOWS = os.name == 'nt'
+# Here we expose a class from a particular module, depending on the
+# environment. The comment suppresses the 'Invalid variable name' lint
+# complaint.
+TestCase = _test_module.TestCase # pylint: disable-msg=C6409
+
# 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]),
@@ -56,7 +69,9 @@ _gtest_flags_are_parsed = False
def _ParseAndStripGTestFlags(argv):
"""Parses and strips Google Test flags from argv. This is idempotent."""
- global _gtest_flags_are_parsed
+ # Suppresses the lint complaint about a global variable since we need it
+ # here to maintain module-wide state.
+ global _gtest_flags_are_parsed # pylint: disable-msg=W0603
if _gtest_flags_are_parsed:
return
@@ -103,6 +118,24 @@ def GetBuildDir():
return os.path.abspath(GetFlag('gtest_build_dir'))
+_temp_dir = None
+
+def _RemoveTempDir():
+ if _temp_dir:
+ shutil.rmtree(_temp_dir, ignore_errors=True)
+
+atexit.register(_RemoveTempDir)
+
+
+def GetTempDir():
+ """Returns a directory for temporary files."""
+
+ global _temp_dir
+ if not _temp_dir:
+ _temp_dir = tempfile.mkdtemp()
+ return _temp_dir
+
+
def GetTestExecutablePath(executable_name):
"""Returns the absolute path of the test binary given its name.
@@ -223,4 +256,4 @@ def Main():
# unittest.main(). Otherwise the latter will be confused by the
# --gtest_* flags.
_ParseAndStripGTestFlags(sys.argv)
- unittest.main()
+ _test_module.main()
diff --git a/test/gtest_throw_on_failure_test.py b/test/gtest_throw_on_failure_test.py
index e952da5..5678ffe 100755
--- a/test/gtest_throw_on_failure_test.py
+++ b/test/gtest_throw_on_failure_test.py
@@ -37,9 +37,8 @@ Google Test) with different environments and command line flags.
__author__ = 'wan@google.com (Zhanyong Wan)'
-import gtest_test_utils
import os
-import unittest
+import gtest_test_utils
# Constants.
@@ -78,7 +77,7 @@ def Run(command):
# The tests. TODO(wan@google.com): refactor the class to share common
# logic with code in gtest_break_on_failure_unittest.py.
-class ThrowOnFailureTest(unittest.TestCase):
+class ThrowOnFailureTest(gtest_test_utils.TestCase):
"""Tests the throw-on-failure mode."""
def RunAndVerify(self, env_var_value, flag_value, should_fail):
diff --git a/test/gtest_uninitialized_test.py b/test/gtest_uninitialized_test.py
index 19b92e9..6ae57ee 100755
--- a/test/gtest_uninitialized_test.py
+++ b/test/gtest_uninitialized_test.py
@@ -34,8 +34,6 @@
__author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils
-import sys
-import unittest
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_')
@@ -63,7 +61,7 @@ def TestExitCodeAndOutput(command):
Assert('InitGoogleTest' in p.output)
-class GTestUninitializedTest(unittest.TestCase):
+class GTestUninitializedTest(gtest_test_utils.TestCase):
def testExitCodeAndOutput(self):
TestExitCodeAndOutput(COMMAND)
diff --git a/test/gtest_xml_outfiles_test.py b/test/gtest_xml_outfiles_test.py
index 9d62793..0fe947f 100755
--- a/test/gtest_xml_outfiles_test.py
+++ b/test/gtest_xml_outfiles_test.py
@@ -33,17 +33,14 @@
__author__ = "keith.ray@gmail.com (Keith Ray)"
-import gtest_test_utils
import os
-import sys
-import tempfile
-import unittest
-
from xml.dom import minidom, Node
+import gtest_test_utils
import gtest_xml_test_utils
+GTEST_OUTPUT_SUBDIR = "xml_outfiles"
GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_"
GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_"
@@ -71,7 +68,8 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase):
# We want the trailing '/' that the last "" provides in os.path.join, for
# telling Google Test to create an output directory instead of a single file
# for xml output.
- self.output_dir_ = os.path.join(tempfile.mkdtemp(), "")
+ self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(),
+ GTEST_OUTPUT_SUBDIR, "")
self.DeleteFilesAndDir()
def tearDown(self):
@@ -87,7 +85,7 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase):
except os.error:
pass
try:
- os.removedirs(self.output_dir_)
+ os.rmdir(self.output_dir_)
except os.error:
pass
@@ -100,7 +98,8 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase):
def _TestOutFile(self, test_name, expected_xml):
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())
+ p = gtest_test_utils.Subprocess(command,
+ working_dir=gtest_test_utils.GetTempDir())
self.assert_(p.exited)
self.assertEquals(0, p.exit_code)
diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py
index 622251e..a0cd4d0 100755
--- a/test/gtest_xml_output_unittest.py
+++ b/test/gtest_xml_output_unittest.py
@@ -34,19 +34,24 @@
__author__ = 'eefacm@gmail.com (Sean Mcafee)'
import errno
-import gtest_test_utils
import os
import sys
-import tempfile
-import unittest
-
from xml.dom import minidom, Node
+import gtest_test_utils
import gtest_xml_test_utils
+
GTEST_OUTPUT_FLAG = "--gtest_output"
GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml"
+SUPPORTS_STACK_TRACES = False
+
+if SUPPORTS_STACK_TRACES:
+ STACK_TRACE_TEMPLATE = "\nStack trace:\n*"
+else:
+ STACK_TRACE_TEMPLATE = ""
+
EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="13" failures="2" disabled="2" errors="0" time="*" name="AllTests">
<testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
@@ -56,7 +61,7 @@ EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testcase name="Fails" status="run" time="*" classname="FailedTest">
<failure message="Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Value of: 2
-Expected: 1]]></failure>
+Expected: 1%(stack)s]]></failure>
</testcase>
</testsuite>
<testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*">
@@ -64,10 +69,10 @@ Expected: 1]]></failure>
<testcase name="Fails" status="run" time="*" classname="MixedResultTest">
<failure message="Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Value of: 2
-Expected: 1]]></failure>
+Expected: 1%(stack)s]]></failure>
<failure message="Value of: 3&#x0A;Expected: 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Value of: 3
-Expected: 2]]></failure>
+Expected: 2%(stack)s]]></failure>
</testcase>
<testcase name="DISABLED_test" status="notrun" time="*" classname="MixedResultTest"/>
</testsuite>
@@ -85,7 +90,7 @@ Expected: 2]]></failure>
<testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/>
<testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/>
</testsuite>
-</testsuites>"""
+</testsuites>""" % {'stack': STACK_TRACE_TEMPLATE}
EXPECTED_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
@@ -120,8 +125,8 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
Confirms that Google Test produces an XML output file with the expected
default name if no name is explicitly specified.
"""
- temp_dir = tempfile.mkdtemp()
- output_file = os.path.join(temp_dir, GTEST_DEFAULT_OUTPUT_FILE)
+ output_file = os.path.join(gtest_test_utils.GetTempDir(),
+ GTEST_DEFAULT_OUTPUT_FILE)
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
"gtest_no_test_unittest")
try:
@@ -132,7 +137,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
p = gtest_test_utils.Subprocess(
[gtest_prog_path, "%s=xml" % GTEST_OUTPUT_FLAG],
- working_dir=temp_dir)
+ working_dir=gtest_test_utils.GetTempDir())
self.assert_(p.exited)
self.assertEquals(0, p.exit_code)
self.assert_(os.path.isfile(output_file))
@@ -145,8 +150,8 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
XML document. Furthermore, the program's exit code must be
expected_exit_code.
"""
-
- xml_path = os.path.join(tempfile.mkdtemp(), gtest_prog_name + "out.xml")
+ xml_path = os.path.join(gtest_test_utils.GetTempDir(),
+ gtest_prog_name + "out.xml")
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
command = [gtest_prog_path, "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path)]
diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py
index 64eebb1..1811c40 100755
--- a/test/gtest_xml_test_utils.py
+++ b/test/gtest_xml_test_utils.py
@@ -34,14 +34,15 @@
__author__ = 'eefacm@gmail.com (Sean Mcafee)'
import re
-import unittest
-
from xml.dom import minidom, Node
+import gtest_test_utils
+
+
GTEST_OUTPUT_FLAG = "--gtest_output"
GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml"
-class GTestXMLTestCase(unittest.TestCase):
+class GTestXMLTestCase(gtest_test_utils.TestCase):
"""
Base class for tests of Google Test's XML output functionality.
"""
diff --git a/test/run_tests_test.py b/test/run_tests_test.py
index 1d9f3b7..b55739e 100755
--- a/test/run_tests_test.py
+++ b/test/run_tests_test.py
@@ -48,6 +48,8 @@ class FakePath(object):
self.tree = {}
self.path_separator = os.sep
+ # known_paths contains either absolute or relative paths. Relative paths
+ # are absolutized with self.current_dir.
if known_paths:
self._AddPaths(known_paths)
@@ -91,8 +93,11 @@ class FakePath(object):
return tree
+ def normpath(self, path):
+ return os.path.normpath(path)
+
def abspath(self, path):
- return os.path.normpath(os.path.join(self.current_dir, path))
+ return self.normpath(os.path.join(self.current_dir, path))
def isfile(self, path):
return self.PathElement(self.abspath(path)) == 1
@@ -157,7 +162,8 @@ class GetTestsToRunTest(unittest.TestCase):
'test/gtest_color_test.py']))
self.fake_configurations = ['dbg', 'opt']
self.test_runner = run_tests.TestRunner(injected_os=self.fake_os,
- injected_subprocess=None)
+ injected_subprocess=None,
+ injected_script_dir='.')
def testBinaryTestsOnly(self):
"""Exercises GetTestsToRun with parameters designating binary tests only."""
@@ -388,7 +394,8 @@ class GetTestsToRunTest(unittest.TestCase):
'scons/build/opt/scons/gtest_nontest.exe',
'test/']))
self.test_runner = run_tests.TestRunner(injected_os=self.fake_os,
- injected_subprocess=None)
+ injected_subprocess=None,
+ injected_script_dir='.')
self.AssertResultsEqual(
self.test_runner.GetTestsToRun(
[],
@@ -397,6 +404,43 @@ class GetTestsToRunTest(unittest.TestCase):
available_configurations=self.fake_configurations),
([], []))
+ def testWorksFromDifferentDir(self):
+ """Exercises GetTestsToRun from a directory different from run_test.py's."""
+
+ # Here we simulate an test script in directory /d/ called from the
+ # directory /a/b/c/.
+ self.fake_os = FakeOs(FakePath(
+ current_dir=os.path.abspath('/a/b/c'),
+ known_paths=['/a/b/c/',
+ '/d/scons/build/dbg/scons/gtest_unittest',
+ '/d/scons/build/opt/scons/gtest_unittest',
+ '/d/test/gtest_color_test.py']))
+ self.fake_configurations = ['dbg', 'opt']
+ self.test_runner = run_tests.TestRunner(injected_os=self.fake_os,
+ injected_subprocess=None,
+ injected_script_dir='/d/')
+ # A binary test.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_unittest'],
+ '',
+ False,
+ available_configurations=self.fake_configurations),
+ ([],
+ [('/d/scons/build/dbg/scons',
+ '/d/scons/build/dbg/scons/gtest_unittest')]))
+
+ # A Python test.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_color_test.py'],
+ '',
+ False,
+ available_configurations=self.fake_configurations),
+ ([('/d/scons/build/dbg/scons', '/d/test/gtest_color_test.py')],
+ []))
+
+
def testNonTestBinary(self):
"""Exercises GetTestsToRun with a non-test parameter."""