Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "gtest/gtest.h"
00036
00037 #include <iostream>
00038 #include <vector>
00039
00040
00041
00042
00043 #define GTEST_IMPLEMENTATION_ 1
00044 #include "src/gtest-internal-inl.h"
00045 #undef GTEST_IMPLEMENTATION_
00046
00047 #if GTEST_IS_THREADSAFE
00048
00049 namespace testing {
00050 namespace {
00051
00052 using internal::Notification;
00053 using internal::TestPropertyKeyIs;
00054 using internal::ThreadWithParam;
00055 using internal::scoped_ptr;
00056
00057
00058
00059
00060
00061
00062 const int kThreadCount = 50;
00063
00064 std::string IdToKey(int id, const char* suffix) {
00065 Message key;
00066 key << "key_" << id << "_" << suffix;
00067 return key.GetString();
00068 }
00069
00070 std::string IdToString(int id) {
00071 Message id_message;
00072 id_message << id;
00073 return id_message.GetString();
00074 }
00075
00076 void ExpectKeyAndValueWereRecordedForId(
00077 const std::vector<TestProperty>& properties,
00078 int id, const char* suffix) {
00079 TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str());
00080 const std::vector<TestProperty>::const_iterator property =
00081 std::find_if(properties.begin(), properties.end(), matches_key);
00082 ASSERT_TRUE(property != properties.end())
00083 << "expecting " << suffix << " value for id " << id;
00084 EXPECT_STREQ(IdToString(id).c_str(), property->value());
00085 }
00086
00087
00088
00089 void ManyAsserts(int id) {
00090 GTEST_LOG_(INFO) << "Thread #" << id << " running...";
00091
00092 SCOPED_TRACE(Message() << "Thread #" << id);
00093
00094 for (int i = 0; i < kThreadCount; i++) {
00095 SCOPED_TRACE(Message() << "Iteration #" << i);
00096
00097
00098 EXPECT_TRUE(true);
00099 ASSERT_FALSE(false) << "This shouldn't fail.";
00100 EXPECT_STREQ("a", "a");
00101 ASSERT_LE(5, 6);
00102 EXPECT_EQ(i, i) << "This shouldn't fail.";
00103
00104
00105
00106 Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str());
00107 Test::RecordProperty(IdToKey(id, "int").c_str(), id);
00108 Test::RecordProperty("shared_key", IdToString(id).c_str());
00109
00110
00111
00112
00113 EXPECT_LT(i, 0) << "This should always fail.";
00114 }
00115 }
00116
00117 void CheckTestFailureCount(int expected_failures) {
00118 const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
00119 const TestResult* const result = info->result();
00120 GTEST_CHECK_(expected_failures == result->total_part_count())
00121 << "Logged " << result->total_part_count() << " failures "
00122 << " vs. " << expected_failures << " expected";
00123 }
00124
00125
00126
00127 TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) {
00128 {
00129 scoped_ptr<ThreadWithParam<int> > threads[kThreadCount];
00130 Notification threads_can_start;
00131 for (int i = 0; i != kThreadCount; i++)
00132 threads[i].reset(new ThreadWithParam<int>(&ManyAsserts,
00133 i,
00134 &threads_can_start));
00135
00136 threads_can_start.Notify();
00137
00138
00139 for (int i = 0; i != kThreadCount; i++)
00140 threads[i]->Join();
00141 }
00142
00143
00144 const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
00145 const TestResult* const result = info->result();
00146
00147 std::vector<TestProperty> properties;
00148
00149
00150 for (int i = 0; i < result->test_property_count(); ++i)
00151 properties.push_back(result->GetTestProperty(i));
00152
00153 EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count())
00154 << "String and int values recorded on each thread, "
00155 << "as well as one shared_key";
00156 for (int i = 0; i < kThreadCount; ++i) {
00157 ExpectKeyAndValueWereRecordedForId(properties, i, "string");
00158 ExpectKeyAndValueWereRecordedForId(properties, i, "int");
00159 }
00160 CheckTestFailureCount(kThreadCount*kThreadCount);
00161 }
00162
00163 void FailingThread(bool is_fatal) {
00164 if (is_fatal)
00165 FAIL() << "Fatal failure in some other thread. "
00166 << "(This failure is expected.)";
00167 else
00168 ADD_FAILURE() << "Non-fatal failure in some other thread. "
00169 << "(This failure is expected.)";
00170 }
00171
00172 void GenerateFatalFailureInAnotherThread(bool is_fatal) {
00173 ThreadWithParam<bool> thread(&FailingThread, is_fatal, NULL);
00174 thread.Join();
00175 }
00176
00177 TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) {
00178 EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
00179
00180
00181
00182 CheckTestFailureCount(1);
00183 }
00184
00185 void AssertNoFatalFailureIgnoresFailuresInOtherThreads() {
00186 ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
00187 }
00188 TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) {
00189
00190 AssertNoFatalFailureIgnoresFailuresInOtherThreads();
00191
00192
00193
00194 CheckTestFailureCount(1);
00195 }
00196
00197 TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) {
00198
00199
00200 EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected");
00201 CheckTestFailureCount(2);
00202 }
00203
00204 TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) {
00205
00206
00207 EXPECT_FATAL_FAILURE_ON_ALL_THREADS(
00208 GenerateFatalFailureInAnotherThread(true), "expected");
00209 CheckTestFailureCount(0);
00210
00211
00212 ADD_FAILURE() << "This is an expected non-fatal failure.";
00213 }
00214
00215 TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) {
00216
00217
00218 EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false),
00219 "expected");
00220 CheckTestFailureCount(2);
00221 }
00222
00223 TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) {
00224
00225
00226 EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(
00227 GenerateFatalFailureInAnotherThread(false), "expected");
00228 CheckTestFailureCount(0);
00229
00230
00231 ADD_FAILURE() << "This is an expected non-fatal failure.";
00232 }
00233
00234 }
00235 }
00236
00237 int main(int argc, char **argv) {
00238 testing::InitGoogleTest(&argc, argv);
00239
00240 const int result = RUN_ALL_TESTS();
00241 GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected";
00242
00243 printf("\nPASS\n");
00244 return 0;
00245 }
00246
00247 #else
00248 TEST(StressTest,
00249 DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) {
00250 }
00251
00252 int main(int argc, char **argv) {
00253 testing::InitGoogleTest(&argc, argv);
00254 return RUN_ALL_TESTS();
00255 }
00256 #endif // GTEST_IS_THREADSAFE