Implements support for AssertionResult in Boolean assertions such as EXPECT_TRUE; Fixes Google Tests's tuple implementation to default-initialize its fields in the default constructor (by Zhanyong Wan); Populates gtest_stress_test.cc with actual tests.
This commit is contained in:
@@ -135,12 +135,44 @@ TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) {
|
||||
<< "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.
|
||||
// Tests that tuple's default constructor default initializes each field.
|
||||
// This test needs to compile without generating warnings.
|
||||
TEST(TupleConstructorTest, DefaultConstructorDefaultInitializesEachField) {
|
||||
// The TR1 report requires that tuple's default constructor default
|
||||
// initializes each field, even if it's a primitive type. If the
|
||||
// implementation forgets to do this, this test will catch it by
|
||||
// generating warnings about using uninitialized variables (assuming
|
||||
// a decent compiler).
|
||||
|
||||
tuple<> empty;
|
||||
tuple<int> one_field;
|
||||
tuple<double, char, bool*> three_fields;
|
||||
|
||||
tuple<int> a1, b1;
|
||||
b1 = a1;
|
||||
EXPECT_EQ(0, get<0>(b1));
|
||||
|
||||
tuple<int, double> a2, b2;
|
||||
b2 = a2;
|
||||
EXPECT_EQ(0, get<0>(b2));
|
||||
EXPECT_EQ(0.0, get<1>(b2));
|
||||
|
||||
tuple<double, char, bool*> a3, b3;
|
||||
b3 = a3;
|
||||
EXPECT_EQ(0.0, get<0>(b3));
|
||||
EXPECT_EQ('\0', get<1>(b3));
|
||||
EXPECT_EQ(NULL, get<2>(b3));
|
||||
|
||||
tuple<int, int, int, int, int, int, int, int, int, int> a10, b10;
|
||||
b10 = a10;
|
||||
EXPECT_EQ(0, get<0>(b10));
|
||||
EXPECT_EQ(0, get<1>(b10));
|
||||
EXPECT_EQ(0, get<2>(b10));
|
||||
EXPECT_EQ(0, get<3>(b10));
|
||||
EXPECT_EQ(0, get<4>(b10));
|
||||
EXPECT_EQ(0, get<5>(b10));
|
||||
EXPECT_EQ(0, get<6>(b10));
|
||||
EXPECT_EQ(0, get<7>(b10));
|
||||
EXPECT_EQ(0, get<8>(b10));
|
||||
EXPECT_EQ(0, get<9>(b10));
|
||||
}
|
||||
|
||||
// Tests constructing a tuple from its fields.
|
||||
|
||||
@@ -32,9 +32,10 @@
|
||||
// Tests that SCOPED_TRACE() and various Google Test assertions can be
|
||||
// used in a large number of threads concurrently.
|
||||
|
||||
#include <iostream>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// We must define this macro in order to #include
|
||||
// gtest-internal-inl.h. This is how Google Test prevents a user from
|
||||
// accidentally depending on its internal implementation.
|
||||
@@ -42,6 +43,8 @@
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
#if GTEST_IS_THREADSAFE
|
||||
|
||||
namespace testing {
|
||||
namespace {
|
||||
|
||||
@@ -49,6 +52,20 @@ using internal::String;
|
||||
using internal::TestPropertyKeyIs;
|
||||
using internal::Vector;
|
||||
|
||||
// In order to run tests in this file, for platforms where Google Test is
|
||||
// thread safe, implement ThreadWithParam with the following interface:
|
||||
//
|
||||
// template <typename T> class ThreadWithParam {
|
||||
// public:
|
||||
// // Creates the thread. The thread should execute thread_func(param) when
|
||||
// // started by a call to Start().
|
||||
// ThreadWithParam(void (*thread_func)(T), T param);
|
||||
// // Starts the thread.
|
||||
// void Start();
|
||||
// // Waits for the thread to finish.
|
||||
// void Join();
|
||||
// };
|
||||
|
||||
// How many threads to create?
|
||||
const int kThreadCount = 50;
|
||||
|
||||
@@ -77,7 +94,7 @@ void ExpectKeyAndValueWereRecordedForId(const Vector<TestProperty>& properties,
|
||||
// Calls a large number of Google Test assertions, where exactly one of them
|
||||
// will fail.
|
||||
void ManyAsserts(int id) {
|
||||
::std::cout << "Thread #" << id << " running...\n";
|
||||
GTEST_LOG_(INFO) << "Thread #" << id << " running...";
|
||||
|
||||
SCOPED_TRACE(Message() << "Thread #" << id);
|
||||
|
||||
@@ -104,41 +121,125 @@ void ManyAsserts(int id) {
|
||||
}
|
||||
}
|
||||
|
||||
void CheckTestFailureCount(int expected_failures) {
|
||||
const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
|
||||
const TestResult* const result = info->result();
|
||||
GTEST_CHECK_(expected_failures == result->total_part_count())
|
||||
<< "Logged " << result->total_part_count() << " failures "
|
||||
<< " vs. " << expected_failures << " expected";
|
||||
}
|
||||
|
||||
// Tests using SCOPED_TRACE() and Google Test assertions in many threads
|
||||
// concurrently.
|
||||
TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) {
|
||||
// TODO(wan): when Google Test is made thread-safe, run
|
||||
// ManyAsserts() in many threads here.
|
||||
ThreadWithParam<int>* threads[kThreadCount] = {};
|
||||
for (int i = 0; i != kThreadCount; i++) {
|
||||
// Creates a thread to run the ManyAsserts() function.
|
||||
threads[i] = new ThreadWithParam<int>(&ManyAsserts, i);
|
||||
|
||||
// Starts the thread.
|
||||
threads[i]->Start();
|
||||
}
|
||||
|
||||
// At this point, we have many threads running.
|
||||
|
||||
for (int i = 0; i != kThreadCount; i++) {
|
||||
// We block until the thread is done.
|
||||
threads[i]->Join();
|
||||
delete threads[i];
|
||||
threads[i] = NULL;
|
||||
}
|
||||
|
||||
// Ensures that kThreadCount*kThreadCount failures have been reported.
|
||||
const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
|
||||
const TestResult* const result = info->result();
|
||||
|
||||
Vector<TestProperty> properties;
|
||||
// We have no access to the TestResult's list of properties but we can
|
||||
// copy them one by one.
|
||||
for (int i = 0; i < result->test_property_count(); ++i)
|
||||
properties.PushBack(result->GetTestProperty(i));
|
||||
|
||||
EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count())
|
||||
<< "String and int values recorded on each thread, "
|
||||
<< "as well as one shared_key";
|
||||
for (int i = 0; i < kThreadCount; ++i) {
|
||||
ExpectKeyAndValueWereRecordedForId(properties, i, "string");
|
||||
ExpectKeyAndValueWereRecordedForId(properties, i, "int");
|
||||
}
|
||||
CheckTestFailureCount(kThreadCount*kThreadCount);
|
||||
}
|
||||
|
||||
void FailingThread(bool is_fatal) {
|
||||
if (is_fatal)
|
||||
FAIL() << "Fatal failure in some other thread. "
|
||||
<< "(This failure is expected.)";
|
||||
else
|
||||
ADD_FAILURE() << "Non-fatal failure in some other thread. "
|
||||
<< "(This failure is expected.)";
|
||||
}
|
||||
|
||||
void GenerateFatalFailureInAnotherThread(bool is_fatal) {
|
||||
ThreadWithParam<bool> thread(&FailingThread, is_fatal);
|
||||
thread.Start();
|
||||
thread.Join();
|
||||
}
|
||||
|
||||
TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) {
|
||||
// TODO(mheule@google.com): Test this works correctly when Google
|
||||
// Test is made thread-safe.
|
||||
EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
|
||||
// We should only have one failure (the one from
|
||||
// GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE
|
||||
// should succeed.
|
||||
CheckTestFailureCount(1);
|
||||
}
|
||||
|
||||
void AssertNoFatalFailureIgnoresFailuresInOtherThreads() {
|
||||
ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
|
||||
}
|
||||
TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) {
|
||||
// TODO(mheule@google.com): Test this works correctly when Google
|
||||
// Test is made thread-safe.
|
||||
// Using a subroutine, to make sure, that the test continues.
|
||||
AssertNoFatalFailureIgnoresFailuresInOtherThreads();
|
||||
// We should only have one failure (the one from
|
||||
// GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE
|
||||
// should succeed.
|
||||
CheckTestFailureCount(1);
|
||||
}
|
||||
|
||||
TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) {
|
||||
// TODO(mheule@google.com): Test this works correctly when Google
|
||||
// Test is made thread-safe.
|
||||
// This statement should fail, since the current thread doesn't generate a
|
||||
// fatal failure, only another one does.
|
||||
EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected");
|
||||
CheckTestFailureCount(2);
|
||||
}
|
||||
|
||||
TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) {
|
||||
// TODO(wan@google.com): Test this works correctly when Google Test
|
||||
// is made thread-safe.
|
||||
// This statement should succeed, because failures in all threads are
|
||||
// considered.
|
||||
EXPECT_FATAL_FAILURE_ON_ALL_THREADS(
|
||||
GenerateFatalFailureInAnotherThread(true), "expected");
|
||||
CheckTestFailureCount(0);
|
||||
// We need to add a failure, because main() checks that there are failures.
|
||||
// But when only this test is run, we shouldn't have any failures.
|
||||
ADD_FAILURE() << "This is an expected non-fatal failure.";
|
||||
}
|
||||
|
||||
TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) {
|
||||
// TODO(mheule@google.com): Test this works correctly when Google
|
||||
// Test is made thread-safe.
|
||||
// This statement should fail, since the current thread doesn't generate a
|
||||
// fatal failure, only another one does.
|
||||
EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false),
|
||||
"expected");
|
||||
CheckTestFailureCount(2);
|
||||
}
|
||||
|
||||
TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) {
|
||||
// TODO(wan@google.com): Test this works correctly when Google Test
|
||||
// is made thread-safe.
|
||||
// This statement should succeed, because failures in all threads are
|
||||
// considered.
|
||||
EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(
|
||||
GenerateFatalFailureInAnotherThread(false), "expected");
|
||||
CheckTestFailureCount(0);
|
||||
// We need to add a failure, because main() checks that there are failures,
|
||||
// But when only this test is run, we shouldn't have any failures.
|
||||
ADD_FAILURE() << "This is an expected non-fatal failure.";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -147,5 +248,20 @@ TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) {
|
||||
int main(int argc, char **argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
const int result = RUN_ALL_TESTS(); // Expected to fail.
|
||||
GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected";
|
||||
|
||||
printf("\nPASS\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
TEST(StressTest,
|
||||
DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) {
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
#endif // GTEST_IS_THREADSAFE
|
||||
|
||||
@@ -2418,6 +2418,25 @@ AssertionResult AssertIsEven(const char* expr, int n) {
|
||||
return AssertionFailure(msg);
|
||||
}
|
||||
|
||||
// A predicate function that returns AssertionResult for use in
|
||||
// EXPECT/ASSERT_TRUE/FALSE.
|
||||
AssertionResult ResultIsEven(int n) {
|
||||
if (IsEven(n))
|
||||
return AssertionSuccess() << n << " is even";
|
||||
else
|
||||
return AssertionFailure() << n << " is odd";
|
||||
}
|
||||
|
||||
// A predicate function that returns AssertionResult but gives no
|
||||
// explanation why it succeeds. Needed for testing that
|
||||
// EXPECT/ASSERT_FALSE handles such functions correctly.
|
||||
AssertionResult ResultIsEvenNoExplanation(int n) {
|
||||
if (IsEven(n))
|
||||
return AssertionSuccess();
|
||||
else
|
||||
return AssertionFailure() << n << " is odd";
|
||||
}
|
||||
|
||||
// A predicate-formatter functor that asserts the argument is an even
|
||||
// number.
|
||||
struct AssertIsEvenFunctor {
|
||||
@@ -3786,6 +3805,20 @@ TEST(AssertionTest, ASSERT_TRUE) {
|
||||
"2 < 1");
|
||||
}
|
||||
|
||||
// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult.
|
||||
TEST(AssertionTest, AssertTrueWithAssertionResult) {
|
||||
ASSERT_TRUE(ResultIsEven(2));
|
||||
EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)),
|
||||
"Value of: ResultIsEven(3)\n"
|
||||
" Actual: false (3 is odd)\n"
|
||||
"Expected: true");
|
||||
ASSERT_TRUE(ResultIsEvenNoExplanation(2));
|
||||
EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)),
|
||||
"Value of: ResultIsEvenNoExplanation(3)\n"
|
||||
" Actual: false (3 is odd)\n"
|
||||
"Expected: true");
|
||||
}
|
||||
|
||||
// Tests ASSERT_FALSE.
|
||||
TEST(AssertionTest, ASSERT_FALSE) {
|
||||
ASSERT_FALSE(2 < 1); // NOLINT
|
||||
@@ -3795,6 +3828,20 @@ TEST(AssertionTest, ASSERT_FALSE) {
|
||||
"Expected: false");
|
||||
}
|
||||
|
||||
// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult.
|
||||
TEST(AssertionTest, AssertFalseWithAssertionResult) {
|
||||
ASSERT_FALSE(ResultIsEven(3));
|
||||
EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)),
|
||||
"Value of: ResultIsEven(2)\n"
|
||||
" Actual: true (2 is even)\n"
|
||||
"Expected: false");
|
||||
ASSERT_FALSE(ResultIsEvenNoExplanation(3));
|
||||
EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)),
|
||||
"Value of: ResultIsEvenNoExplanation(2)\n"
|
||||
" Actual: true\n"
|
||||
"Expected: false");
|
||||
}
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
// Restores warnings after previous "#pragma option push" supressed them
|
||||
#pragma option pop
|
||||
@@ -4336,6 +4383,20 @@ TEST(ExpectTest, EXPECT_TRUE) {
|
||||
"2 > 3");
|
||||
}
|
||||
|
||||
// Tests EXPECT_TRUE(predicate) for predicates returning AssertionResult.
|
||||
TEST(ExpectTest, ExpectTrueWithAssertionResult) {
|
||||
EXPECT_TRUE(ResultIsEven(2));
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEven(3)),
|
||||
"Value of: ResultIsEven(3)\n"
|
||||
" Actual: false (3 is odd)\n"
|
||||
"Expected: true");
|
||||
EXPECT_TRUE(ResultIsEvenNoExplanation(2));
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEvenNoExplanation(3)),
|
||||
"Value of: ResultIsEvenNoExplanation(3)\n"
|
||||
" Actual: false (3 is odd)\n"
|
||||
"Expected: true");
|
||||
}
|
||||
|
||||
// Tests EXPECT_FALSE.
|
||||
TEST(ExpectTest, EXPECT_FALSE) {
|
||||
EXPECT_FALSE(2 < 1); // NOLINT
|
||||
@@ -4347,6 +4408,20 @@ TEST(ExpectTest, EXPECT_FALSE) {
|
||||
"2 < 3");
|
||||
}
|
||||
|
||||
// Tests EXPECT_FALSE(predicate) for predicates returning AssertionResult.
|
||||
TEST(ExpectTest, ExpectFalseWithAssertionResult) {
|
||||
EXPECT_FALSE(ResultIsEven(3));
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEven(2)),
|
||||
"Value of: ResultIsEven(2)\n"
|
||||
" Actual: true (2 is even)\n"
|
||||
"Expected: false");
|
||||
EXPECT_FALSE(ResultIsEvenNoExplanation(3));
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEvenNoExplanation(2)),
|
||||
"Value of: ResultIsEvenNoExplanation(2)\n"
|
||||
" Actual: true\n"
|
||||
"Expected: false");
|
||||
}
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
// Restores warnings after previous "#pragma option push" supressed them
|
||||
#pragma option pop
|
||||
@@ -4952,6 +5027,63 @@ TEST_F(TestLifeCycleTest, Test2) {
|
||||
|
||||
} // namespace
|
||||
|
||||
// Tests that the copy constructor works when it is NOT optimized away by
|
||||
// the compiler.
|
||||
TEST(AssertionResultTest, CopyConstructorWorksWhenNotOptimied) {
|
||||
// Checks that the copy constructor doesn't try to dereference NULL pointers
|
||||
// in the source object.
|
||||
AssertionResult r1 = AssertionSuccess();
|
||||
AssertionResult r2 = r1;
|
||||
// The following line is added to prevent the compiler from optimizing
|
||||
// away the constructor call.
|
||||
r1 << "abc";
|
||||
|
||||
AssertionResult r3 = r1;
|
||||
EXPECT_EQ(static_cast<bool>(r3), static_cast<bool>(r1));
|
||||
EXPECT_STREQ("abc", r1.message());
|
||||
}
|
||||
|
||||
// Tests that AssertionSuccess and AssertionFailure construct
|
||||
// AssertionResult objects as expected.
|
||||
TEST(AssertionResultTest, ConstructionWorks) {
|
||||
AssertionResult r1 = AssertionSuccess();
|
||||
EXPECT_TRUE(r1);
|
||||
EXPECT_STREQ("", r1.message());
|
||||
|
||||
AssertionResult r2 = AssertionSuccess() << "abc";
|
||||
EXPECT_TRUE(r2);
|
||||
EXPECT_STREQ("abc", r2.message());
|
||||
|
||||
AssertionResult r3 = AssertionFailure();
|
||||
EXPECT_FALSE(r3);
|
||||
EXPECT_STREQ("", r3.message());
|
||||
|
||||
AssertionResult r4 = AssertionFailure() << "def";
|
||||
EXPECT_FALSE(r4);
|
||||
EXPECT_STREQ("def", r4.message());
|
||||
|
||||
AssertionResult r5 = AssertionFailure(Message() << "ghi");
|
||||
EXPECT_FALSE(r5);
|
||||
EXPECT_STREQ("ghi", r5.message());
|
||||
}
|
||||
|
||||
// Tests that the negation fips the predicate result but keeps the message.
|
||||
TEST(AssertionResultTest, NegationWorks) {
|
||||
AssertionResult r1 = AssertionSuccess() << "abc";
|
||||
EXPECT_FALSE(!r1);
|
||||
EXPECT_STREQ("abc", (!r1).message());
|
||||
|
||||
AssertionResult r2 = AssertionFailure() << "def";
|
||||
EXPECT_TRUE(!r2);
|
||||
EXPECT_STREQ("def", (!r2).message());
|
||||
}
|
||||
|
||||
TEST(AssertionResultTest, StreamingWorks) {
|
||||
AssertionResult r = AssertionSuccess();
|
||||
r << "abc" << 'd' << 0 << true;
|
||||
EXPECT_STREQ("abcd0true", r.message());
|
||||
}
|
||||
|
||||
// Tests streaming a user type whose definition and operator << are
|
||||
// both in the global namespace.
|
||||
class Base {
|
||||
|
||||
Reference in New Issue
Block a user