Renames ThreadStartSempahore to Notificaton (by Vlad Losev); adds threading tests for SCOPED_TRACE() (by Vlad Losev); replaces native pthread calls with gtest's threading constructs (by Vlad Losev); fixes flakiness in CountedDestructor (by Vlad Losev); minor MSVC 7.1 clean-up (by Zhanyong Wan).

This commit is contained in:
zhanyong.wan 2010-03-04 22:15:53 +00:00
parent 0928f00c6b
commit 12a92c26fc
12 changed files with 359 additions and 179 deletions

View File

@ -463,13 +463,10 @@
#include <vector> // NOLINT
#endif
// Determines whether to support value-parameterized tests.
#if defined(__GNUC__) || (_MSC_VER >= 1400)
// TODO(vladl@google.com): get the implementation rid of vector and list
// to compile on MSVC 7.1.
// We don't support MSVC 7.1 with exceptions disabled now. Therefore
// all the compilers we care about are adequate for supporting
// value-parameterized tests.
#define GTEST_HAS_PARAM_TEST 1
#endif // defined(__GNUC__) || (_MSC_VER >= 1400)
// Determines whether to support type-driven tests.
@ -774,6 +771,97 @@ const ::std::vector<String>& GetArgvs();
#if GTEST_HAS_PTHREAD
// Sleeps for (roughly) n milli-seconds. This function is only for
// testing Google Test's own constructs. Don't use it in user tests,
// either directly or indirectly.
inline void SleepMilliseconds(int n) {
const timespec time = {
0, // 0 seconds.
n * 1000L * 1000L, // And n ms.
};
nanosleep(&time, NULL);
}
// Allows a controller thread to pause execution of newly created
// threads until notified. Instances of this class must be created
// and destroyed in the controller thread.
//
// This class is only for testing Google Test's own constructs. Do not
// use it in user tests, either directly or indirectly.
class Notification {
public:
Notification() : notified_(false) {}
// Notifies all threads created with this notification to start. Must
// be called from the controller thread.
void Notify() { notified_ = true; }
// Blocks until the controller thread notifies. Must be called from a test
// thread.
void WaitForNotification() {
while(!notified_) {
SleepMilliseconds(10);
}
}
private:
volatile bool notified_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
};
// Helper class for testing Google Test's multi-threading constructs.
// To use it, derive a class template ThreadWithParam<T> from
// ThreadWithParamBase<T> and implement thread creation and startup in
// the constructor and joining the thread in JoinUnderlyingThread().
// Then you can write:
//
// void ThreadFunc(int param) { /* Do things with param */ }
// Notification thread_can_start;
// ...
// // The thread_can_start parameter is optional; you can supply NULL.
// ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);
// thread_can_start.Notify();
//
// These classes are only for testing Google Test's own constructs. Do
// not use them in user tests, either directly or indirectly.
template <typename T>
class ThreadWithParamBase {
public:
typedef void (*UserThreadFunc)(T);
ThreadWithParamBase(
UserThreadFunc func, T param, Notification* thread_can_start)
: func_(func),
param_(param),
thread_can_start_(thread_can_start),
finished_(false) {}
virtual ~ThreadWithParamBase() {}
void Join() {
if (!finished_) {
JoinUnderlyingThread();
finished_ = true;
}
}
virtual void JoinUnderlyingThread() = 0;
void ThreadMain() {
if (thread_can_start_ != NULL)
thread_can_start_->WaitForNotification();
func_(param_);
}
protected:
const UserThreadFunc func_; // User-supplied thread function.
const T param_; // User-supplied parameter to the thread function.
// When non-NULL, used to block execution until the controller thread
// notifies.
Notification* const thread_can_start_;
bool finished_; // true iff we know that the thread function has finished.
};
// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is
// true.
#include <pthread.h>
@ -936,99 +1024,32 @@ class ThreadLocal {
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
};
// Sleeps for (roughly) n milli-seconds. This function is only for
// testing Google Test's own constructs. Don't use it in user tests,
// either directly or indirectly.
inline void SleepMilliseconds(int n) {
const timespec time = {
0, // 0 seconds.
n * 1000L * 1000L, // And n ms.
};
nanosleep(&time, NULL);
}
// Allows a controller thread to pause execution of newly created
// threads until signalled. Instances of this class must be created
// and destroyed in the controller thread.
//
// This class is only for testing Google Test's own constructs. Do not
// use it in user tests, either directly or indirectly.
class ThreadStartSemaphore {
public:
ThreadStartSemaphore() : signalled_(false) {}
// Signals to all threads created with this semaphore to start. Must
// be called from the controller thread.
void Signal() { signalled_ = true; }
// Blocks until the controller thread signals. Must be called from a test
// thread.
void Wait() {
while(!signalled_) {
SleepMilliseconds(10);
}
}
private:
volatile bool signalled_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadStartSemaphore);
};
// Helper class for testing Google Test's multi-threading constructs.
// Use:
//
// void ThreadFunc(int param) { /* Do things with param */ }
// ThreadStartSemaphore semaphore;
// ...
// // The semaphore parameter is optional; you can supply NULL.
// ThreadWithParam<int> thread(&ThreadFunc, 5, &semaphore);
// semaphore.Signal(); // Allows the thread to start.
//
// This class is only for testing Google Test's own constructs. Do not
// use it in user tests, either directly or indirectly.
template <typename T>
class ThreadWithParam {
class ThreadWithParam : public ThreadWithParamBase<T> {
public:
typedef void (*UserThreadFunc)(T);
ThreadWithParam(UserThreadFunc func, T param, ThreadStartSemaphore* semaphore)
: func_(func),
param_(param),
start_semaphore_(semaphore),
finished_(false) {
ThreadWithParam(void (*func)(T), T param, Notification* thread_can_start)
: ThreadWithParamBase<T>(func, param, thread_can_start) {
// The thread can be created only after all fields except thread_
// have been initialized.
GTEST_CHECK_POSIX_SUCCESS_(
pthread_create(&thread_, 0, ThreadMainStatic, this));
}
~ThreadWithParam() { Join(); }
virtual ~ThreadWithParam() { this->Join(); }
void Join() {
if (!finished_) {
GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));
finished_ = true;
}
virtual void JoinUnderlyingThread() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));
}
private:
void ThreadMain() {
if (start_semaphore_ != NULL)
start_semaphore_->Wait();
func_(param_);
}
static void* ThreadMainStatic(void* thread_with_param) {
static_cast<ThreadWithParam<T>*>(thread_with_param)->ThreadMain();
return NULL; // We are not interested in the thread exit code.
}
const UserThreadFunc func_; // User-supplied thread function.
const T param_; // User-supplied parameter to the thread function.
// When non-NULL, used to block execution until the controller thread
// signals.
ThreadStartSemaphore* const start_semaphore_;
bool finished_; // Has the thread function finished?
pthread_t thread_; // The native thread object.
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
};
#define GTEST_IS_THREADSAFE 1

View File

@ -51,14 +51,13 @@ namespace internal {
// String - a UTF-8 string class.
//
// We cannot use std::string as Microsoft's STL implementation in
// Visual C++ 7.1 has problems when exception is disabled. There is a
// hack to work around this, but we've seen cases where the hack fails
// to work.
// For historic reasons, we don't use std::string.
//
// Also, String is different from std::string in that it can represent
// both NULL and the empty string, while std::string cannot represent
// NULL.
// TODO(wan@google.com): replace this class with std::string or
// implement it in terms of the latter.
//
// Note that String can represent both NULL and the empty string,
// while std::string cannot represent NULL.
//
// NULL and the empty string are considered different. NULL is less
// than anything (including the empty string) except itself.

View File

@ -121,12 +121,12 @@ INSTANTIATE_TEST_CASE_P(
#else
// Google Test doesn't support value-parameterized tests on some platforms
// and compilers, such as MSVC 7.1. If we use conditional compilation to
// compile out all code referring to the gtest_main library, MSVC linker
// will not link that library at all and consequently complain about
// missing entry point defined in that library (fatal error LNK1561:
// entry point must be defined). This dummy test keeps gtest_main linked in.
// Google Test may not support value-parameterized tests with some
// compilers. If we use conditional compilation to compile out all
// code referring to the gtest_main library, MSVC linker will not link
// that library at all and consequently complain about missing entry
// point defined in that library (fatal error LNK1561: entry point
// must be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
#endif // GTEST_HAS_PARAM_TEST

View File

@ -162,12 +162,12 @@ INSTANTIATE_TEST_CASE_P(MeaningfulTestParameters,
#else
// Google Test doesn't support Combine() on some platforms and compilers,
// such as MSVC 7.1. If we use conditional compilation to compile out
// all code referring to the gtest_main library, MSVC linker will not
// link that library at all and consequently complain about missing entry
// point defined in that library (fatal error LNK1561: entry point must
// be defined). This dummy test keeps gtest_main linked in.
// Google Test may not support Combine() with some compilers. If we
// use conditional compilation to compile out all code referring to
// the gtest_main library, MSVC linker will not link that library at
// all and consequently complain about missing entry point defined in
// that library (fatal error LNK1561: entry point must be
// defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {}
#endif // GTEST_HAS_COMBINE

View File

@ -1037,8 +1037,6 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
// Splits a given string on a given delimiter, populating a given
// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have
// ::std::string, so we can use it here.
// TODO(vladl@google.com): Get rid of std::vector to be able to build on
// Visual C++ 7.1 with exceptions disabled.
static void SplitString(const ::std::string& str, char delimiter,
::std::vector< ::std::string>* dest) {
::std::vector< ::std::string> parsed;

View File

@ -803,7 +803,7 @@ TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) {
{ MutexLock lock(&m); }
m.AssertHeld();
},
"The current thread is not holding the mutex @.+");
"thread .*hold");
}
TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) {
@ -859,16 +859,16 @@ TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
const int kCycleCount = 20;
const int kThreadCount = 7;
scoped_ptr<ThreadType> counting_threads[kThreadCount];
ThreadStartSemaphore semaphore;
Notification threads_can_start;
// Creates and runs kThreadCount threads that increment locked_counter
// kCycleCount times each.
for (int i = 0; i < kThreadCount; ++i) {
counting_threads[i].reset(new ThreadType(&CountingThreadFunc,
make_pair(&locked_counter,
kCycleCount),
&semaphore));
&threads_can_start));
}
semaphore.Signal(); // Starts the threads.
threads_can_start.Notify();
for (int i = 0; i < kThreadCount; ++i)
counting_threads[i]->Join();
@ -901,16 +901,29 @@ TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) {
EXPECT_STREQ("foo", result.c_str());
}
class CountedDestructor {
// DestructorTracker keeps track of whether the class instances have been
// destroyed. The static synchronization mutex has to be defined outside
// of the class, due to syntax of its definition.
static GTEST_DEFINE_STATIC_MUTEX_(destructor_tracker_mutex);
static std::vector<bool> g_destroyed;
class DestructorTracker {
public:
~CountedDestructor() { counter_++; }
static int counter() { return counter_; }
static void set_counter(int value) { counter_ = value; }
DestructorTracker() : index_(GetNewIndex()) {}
~DestructorTracker() {
MutexLock lock(&destructor_tracker_mutex);
g_destroyed[index_] = true;
}
private:
static int counter_;
static int GetNewIndex() {
MutexLock lock(&destructor_tracker_mutex);
g_destroyed.push_back(false);
return g_destroyed.size() - 1;
}
const int index_;
};
int CountedDestructor::counter_ = 0;
template <typename T>
void CallThreadLocalGet(ThreadLocal<T>* threadLocal) {
@ -918,16 +931,19 @@ void CallThreadLocalGet(ThreadLocal<T>* threadLocal) {
}
TEST(ThreadLocalTest, DestroysManagedObjectsNoLaterThanSelf) {
CountedDestructor::set_counter(0);
g_destroyed.clear();
{
ThreadLocal<CountedDestructor> thread_local;
ThreadWithParam<ThreadLocal<CountedDestructor>*> thread(
&CallThreadLocalGet<CountedDestructor>, &thread_local, NULL);
ThreadLocal<DestructorTracker> thread_local;
ThreadWithParam<ThreadLocal<DestructorTracker>*> thread(
&CallThreadLocalGet<DestructorTracker>, &thread_local, NULL);
thread.Join();
}
// There should be 2 desctuctor calls as ThreadLocal also contains a member
// T - used as a prototype for copy ctr version.
EXPECT_EQ(2, CountedDestructor::counter());
// Verifies that all DestructorTracker objects there were have been
// destroyed.
for (size_t i = 0; i < g_destroyed.size(); ++i)
EXPECT_TRUE(g_destroyed[i]) << "at index " << i;
g_destroyed.clear();
}
TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) {

View File

@ -349,12 +349,12 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes);
#if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P)
// Google Test doesn't support type-parameterized tests on some platforms
// and compilers, such as MSVC 7.1. If we use conditional compilation to
// compile out all code referring to the gtest_main library, MSVC linker
// will not link that library at all and consequently complain about
// missing entry point defined in that library (fatal error LNK1561:
// entry point must be defined). This dummy test keeps gtest_main linked in.
// Google Test may not support type-parameterized tests with some
// compilers. If we use conditional compilation to compile out all
// code referring to the gtest_main library, MSVC linker will not link
// that library at all and consequently complain about missing entry
// point defined in that library (fatal error LNK1561: entry point
// must be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {}
#endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P)

View File

@ -282,7 +282,7 @@ class GTestOutputTest(gtest_test_utils.TestCase):
normalized_golden = RemoveTypeInfoDetails(golden)
if CAN_GENERATE_GOLDEN_FILE:
self.assert_(normalized_golden == normalized_actual)
self.assertEqual(normalized_golden, normalized_actual)
else:
normalized_actual = RemoveTestCounts(normalized_actual)
normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests(
@ -299,7 +299,7 @@ class GTestOutputTest(gtest_test_utils.TestCase):
'_gtest_output_test_normalized_golden.txt'), 'wb').write(
normalized_golden)
self.assert_(normalized_golden == normalized_actual)
self.assertEqual(normalized_golden, normalized_actual)
if __name__ == '__main__':

View File

@ -46,15 +46,17 @@
#include <stdlib.h>
#if GTEST_HAS_PTHREAD
#include <pthread.h>
#endif // GTEST_HAS_PTHREAD
#if GTEST_IS_THREADSAFE
using testing::ScopedFakeTestPartResultReporter;
using testing::TestPartResultArray;
using testing::internal::Notification;
using testing::internal::ThreadWithParam;
#endif
namespace posix = ::testing::internal::posix;
using testing::internal::String;
using testing::internal::scoped_ptr;
// Tests catching fatal failures.
@ -214,6 +216,83 @@ TEST(SCOPED_TRACETest, CanBeRepeated) {
<< "trace point A, B, and D.";
}
#if GTEST_IS_THREADSAFE
// Tests that SCOPED_TRACE()s can be used concurrently from multiple
// threads. Namely, an assertion should be affected by
// SCOPED_TRACE()s in its own thread only.
// Here's the sequence of actions that happen in the test:
//
// Thread A (main) | Thread B (spawned)
// ===============================|================================
// spawns thread B |
// -------------------------------+--------------------------------
// waits for n1 | SCOPED_TRACE("Trace B");
// | generates failure #1
// | notifies n1
// -------------------------------+--------------------------------
// SCOPED_TRACE("Trace A"); | waits for n2
// generates failure #2 |
// notifies n2 |
// -------------------------------|--------------------------------
// waits for n3 | generates failure #3
// | trace B dies
// | generates failure #4
// | notifies n3
// -------------------------------|--------------------------------
// generates failure #5 | finishes
// trace A dies |
// generates failure #6 |
// -------------------------------|--------------------------------
// waits for thread B to finish |
struct CheckPoints {
Notification n1;
Notification n2;
Notification n3;
};
static void ThreadWithScopedTrace(CheckPoints* check_points) {
{
SCOPED_TRACE("Trace B");
ADD_FAILURE()
<< "Expected failure #1 (in thread B, only trace B alive).";
check_points->n1.Notify();
check_points->n2.WaitForNotification();
ADD_FAILURE()
<< "Expected failure #3 (in thread B, trace A & B both alive).";
} // Trace B dies here.
ADD_FAILURE()
<< "Expected failure #4 (in thread B, only trace A alive).";
check_points->n3.Notify();
}
TEST(SCOPED_TRACETest, WorksConcurrently) {
printf("(expecting 6 failures)\n");
CheckPoints check_points;
ThreadWithParam<CheckPoints*> thread(&ThreadWithScopedTrace,
&check_points,
NULL);
check_points.n1.WaitForNotification();
{
SCOPED_TRACE("Trace A");
ADD_FAILURE()
<< "Expected failure #2 (in thread A, trace A & B both alive).";
check_points.n2.Notify();
check_points.n3.WaitForNotification();
ADD_FAILURE()
<< "Expected failure #5 (in thread A, only trace A alive).";
} // Trace A dies here.
ADD_FAILURE()
<< "Expected failure #6 (in thread A, no trace alive).";
thread.Join();
}
#endif // GTEST_IS_THREADSAFE
TEST(DisabledTestsWarningTest,
DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning) {
// This test body is intentionally empty. Its sole purpose is for
@ -479,6 +558,63 @@ TEST_F(ExceptionInTearDownTest, ExceptionInTearDown) {
#endif // GTEST_OS_WINDOWS
#if GTEST_IS_THREADSAFE
// A unary function that may die.
void DieIf(bool should_die) {
GTEST_CHECK_(!should_die) << " - death inside DieIf().";
}
// Tests running death tests in a multi-threaded context.
// Used for coordination between the main and the spawn thread.
struct SpawnThreadNotifications {
SpawnThreadNotifications() {}
Notification spawn_thread_started;
Notification spawn_thread_ok_to_terminate;
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(SpawnThreadNotifications);
};
// The function to be executed in the thread spawn by the
// MultipleThreads test (below).
static void ThreadRoutine(SpawnThreadNotifications* notifications) {
// Signals the main thread that this thread has started.
notifications->spawn_thread_started.Notify();
// Waits for permission to finish from the main thread.
notifications->spawn_thread_ok_to_terminate.WaitForNotification();
}
// This is a death-test test, but it's not named with a DeathTest
// suffix. It starts threads which might interfere with later
// death tests, so it must run after all other death tests.
class DeathTestAndMultiThreadsTest : public testing::Test {
protected:
// Starts a thread and waits for it to begin.
virtual void SetUp() {
thread_.reset(new ThreadWithParam<SpawnThreadNotifications*>(
&ThreadRoutine, &notifications_, NULL));
notifications_.spawn_thread_started.WaitForNotification();
}
// Tells the thread to finish, and reaps it.
// Depending on the version of the thread library in use,
// a manager thread might still be left running that will interfere
// with later death tests. This is unfortunate, but this class
// cleans up after itself as best it can.
virtual void TearDown() {
notifications_.spawn_thread_ok_to_terminate.Notify();
}
private:
SpawnThreadNotifications notifications_;
scoped_ptr<ThreadWithParam<SpawnThreadNotifications*> > thread_;
};
#endif // GTEST_IS_THREADSAFE
// The MixedUpTestCaseTest test case verifies that Google Test will fail a
// test if it uses a different fixture class than what other tests in
// the same test case use. It deliberately contains two fixture
@ -849,23 +985,13 @@ TEST_F(ExpectFailureTest, ExpectNonFatalFailure) {
"failure.");
}
#if GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD
#if GTEST_IS_THREADSAFE
class ExpectFailureWithThreadsTest : public ExpectFailureTest {
protected:
static void AddFailureInOtherThread(FailureMode failure) {
pthread_t tid;
pthread_create(&tid,
NULL,
ExpectFailureWithThreadsTest::FailureThread,
&failure);
pthread_join(tid, NULL);
}
private:
static void* FailureThread(void* attr) {
FailureMode* failure = static_cast<FailureMode*>(attr);
AddFailure(*failure);
return NULL;
ThreadWithParam<FailureMode> thread(&AddFailure, failure, NULL);
thread.Join();
}
};
@ -901,7 +1027,7 @@ TEST_F(ScopedFakeTestPartResultReporterTest, InterceptOnlyCurrentThread) {
EXPECT_EQ(0, results.size()) << "This shouldn't fail.";
}
#endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD
#endif // GTEST_IS_THREADSAFE
TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) {
// Expected fatal failure, but succeeds.

View File

@ -7,7 +7,7 @@ Expected: true
gtest_output_test_.cc:#: Failure
Value of: 3
Expected: 2
[==========] Running 59 tests from 25 test cases.
[==========] Running 60 tests from 25 test cases.
[----------] Global test environment set-up.
FooEnvironment::SetUp() called.
BarEnvironment::SetUp() called.
@ -65,7 +65,7 @@ i == 3
gtest_output_test_.cc:#: Failure
Expected: (3) >= (a[i]), actual: 3 vs 6
[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions
[----------] 5 tests from SCOPED_TRACETest
[----------] 6 tests from SCOPED_TRACETest
[ RUN ] SCOPED_TRACETest.ObeysScopes
(expected to fail)
gtest_output_test_.cc:#: Failure
@ -148,6 +148,35 @@ gtest_output_test_.cc:#: D
gtest_output_test_.cc:#: B
gtest_output_test_.cc:#: A
[ FAILED ] SCOPED_TRACETest.CanBeRepeated
[ RUN ] SCOPED_TRACETest.WorksConcurrently
(expecting 6 failures)
gtest_output_test_.cc:#: Failure
Failed
Expected failure #1 (in thread B, only trace B alive).
Google Test trace:
gtest_output_test_.cc:#: Trace B
gtest_output_test_.cc:#: Failure
Failed
Expected failure #2 (in thread A, trace A & B both alive).
Google Test trace:
gtest_output_test_.cc:#: Trace A
gtest_output_test_.cc:#: Failure
Failed
Expected failure #3 (in thread B, trace A & B both alive).
Google Test trace:
gtest_output_test_.cc:#: Trace B
gtest_output_test_.cc:#: Failure
Failed
Expected failure #4 (in thread B, only trace A alive).
gtest_output_test_.cc:#: Failure
Failed
Expected failure #5 (in thread A, only trace A alive).
Google Test trace:
gtest_output_test_.cc:#: Trace A
gtest_output_test_.cc:#: Failure
Failed
Expected failure #6 (in thread A, no trace alive).
[ FAILED ] SCOPED_TRACETest.WorksConcurrently
[----------] 1 test from NonFatalFailureInFixtureConstructorTest
[ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor
(expecting 5 failures)
@ -544,9 +573,9 @@ FooEnvironment::TearDown() called.
gtest_output_test_.cc:#: Failure
Failed
Expected fatal failure.
[==========] 59 tests from 25 test cases ran.
[==========] 60 tests from 25 test cases ran.
[ PASSED ] 21 tests.
[ FAILED ] 38 tests, listed below:
[ FAILED ] 39 tests, listed below:
[ FAILED ] FatalFailureTest.FatalFailureInSubroutine
[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine
[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine
@ -556,6 +585,7 @@ Expected fatal failure.
[ FAILED ] SCOPED_TRACETest.WorksInSubroutine
[ FAILED ] SCOPED_TRACETest.CanBeNested
[ FAILED ] SCOPED_TRACETest.CanBeRepeated
[ FAILED ] SCOPED_TRACETest.WorksConcurrently
[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor
[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor
[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp
@ -586,7 +616,7 @@ Expected fatal failure.
[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure
[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread
38 FAILED TESTS
39 FAILED TESTS
 YOU HAVE 1 DISABLED TEST
Note: Google Test filter = FatalFailureTest.*:LoggingTest.*

View File

@ -49,16 +49,15 @@
namespace testing {
namespace {
using internal::scoped_ptr;
using internal::Notification;
using internal::String;
using internal::TestPropertyKeyIs;
using internal::ThreadStartSemaphore;
using internal::ThreadWithParam;
using internal::scoped_ptr;
// In order to run tests in this file, for platforms where Google Test is
// thread safe, implement ThreadWithParam and ThreadStartSemaphore. See the
// description of their API in gtest-port.h, where they are defined for
// already supported platforms.
// thread safe, implement ThreadWithParam. See the description of its API
// in gtest-port.h, where it is defined for already supported platforms.
// How many threads to create?
const int kThreadCount = 50;
@ -129,11 +128,13 @@ void CheckTestFailureCount(int expected_failures) {
TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) {
{
scoped_ptr<ThreadWithParam<int> > threads[kThreadCount];
ThreadStartSemaphore semaphore;
Notification threads_can_start;
for (int i = 0; i != kThreadCount; i++)
threads[i].reset(new ThreadWithParam<int>(&ManyAsserts, i, &semaphore));
threads[i].reset(new ThreadWithParam<int>(&ManyAsserts,
i,
&threads_can_start));
semaphore.Signal(); // Starts all the threads.
threads_can_start.Notify();
// Blocks until all the threads are done.
for (int i = 0; i != kThreadCount; i++)

View File

@ -71,10 +71,6 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
#include <stdlib.h>
#include <time.h>
#if GTEST_HAS_PTHREAD
#include <pthread.h>
#endif // GTEST_HAS_PTHREAD
#include <map>
namespace testing {
@ -191,6 +187,10 @@ using testing::internal::CaptureStdout;
using testing::internal::GetCapturedStdout;
#endif // GTEST_HAS_STREAM_REDIRECTION_
#if GTEST_IS_THREADSAFE
using testing::internal::ThreadWithParam;
#endif
class TestingVector : public std::vector<int> {
};
@ -1283,25 +1283,14 @@ TEST_F(ScopedFakeTestPartResultReporterTest, DeprecatedConstructor) {
EXPECT_EQ(1, results.size());
}
#if GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD
#if GTEST_IS_THREADSAFE
class ScopedFakeTestPartResultReporterWithThreadsTest
: public ScopedFakeTestPartResultReporterTest {
protected:
static void AddFailureInOtherThread(FailureMode failure) {
pthread_t tid;
pthread_create(&tid,
NULL,
ScopedFakeTestPartResultReporterWithThreadsTest::
FailureThread,
&failure);
pthread_join(tid, NULL);
}
private:
static void* FailureThread(void* attr) {
FailureMode* failure = static_cast<FailureMode*>(attr);
AddFailure(*failure);
return NULL;
ThreadWithParam<FailureMode> thread(&AddFailure, failure, NULL);
thread.Join();
}
};
@ -1324,7 +1313,7 @@ TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest,
EXPECT_TRUE(results.GetTestPartResult(3).fatally_failed());
}
#endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD
#endif // GTEST_IS_THREADSAFE
// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. Makes sure that they
// work even if the failure is generated in a called function rather than
@ -1435,7 +1424,7 @@ TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) {
}, "");
}
#if GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD
#if GTEST_IS_THREADSAFE
typedef ScopedFakeTestPartResultReporterWithThreadsTest
ExpectFailureWithThreadsTest;
@ -1450,7 +1439,7 @@ TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) {
AddFailureInOtherThread(NONFATAL_FAILURE), "Expected non-fatal failure.");
}
#endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD
#endif // GTEST_IS_THREADSAFE
// Tests the TestProperty class.