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

This commit is contained in:
zhanyong.wan
2009-06-17 21:06:27 +00:00
parent 210ea10e7a
commit 532dc2de35
23 changed files with 1941 additions and 161 deletions

288
test/gtest-tuple_test.cc Normal file
View File

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

View File

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

View File

@@ -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."""

View File

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

View File

@@ -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."""

View File

@@ -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):

View File

@@ -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):

View File

@@ -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."""

View File

@@ -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()

View File

@@ -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()

View File

@@ -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):

View File

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

View File

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

View File

@@ -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)]

View File

@@ -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.
"""

View File

@@ -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."""