Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
gtest_stress_test.cc
Go to the documentation of this file.
1// Copyright 2007, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Author: wan@google.com (Zhanyong Wan)
31
32// Tests that SCOPED_TRACE() and various Google Test assertions can be
33// used in a large number of threads concurrently.
34
35#include "gtest/gtest.h"
36
37#include <vector>
38
40
41#if GTEST_IS_THREADSAFE
42
43namespace testing {
44namespace {
45
46using internal::Notification;
47using internal::TestPropertyKeyIs;
48using internal::ThreadWithParam;
49using internal::scoped_ptr;
50
51// In order to run tests in this file, for platforms where Google Test is
52// thread safe, implement ThreadWithParam. See the description of its API
53// in gtest-port.h, where it is defined for already supported platforms.
54
55// How many threads to create?
56const int kThreadCount = 50;
57
58std::string IdToKey(int id, const char* suffix) {
59 Message key;
60 key << "key_" << id << "_" << suffix;
61 return key.GetString();
62}
63
64std::string IdToString(int id) {
65 Message id_message;
66 id_message << id;
67 return id_message.GetString();
68}
69
70void ExpectKeyAndValueWereRecordedForId(
71 const std::vector<TestProperty>& properties,
72 int id, const char* suffix) {
73 TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str());
74 const std::vector<TestProperty>::const_iterator property =
75 std::find_if(properties.begin(), properties.end(), matches_key);
76 ASSERT_TRUE(property != properties.end())
77 << "expecting " << suffix << " value for id " << id;
78 EXPECT_STREQ(IdToString(id).c_str(), property->value());
79}
80
81// Calls a large number of Google Test assertions, where exactly one of them
82// will fail.
83void ManyAsserts(int id) {
84 GTEST_LOG_(INFO) << "Thread #" << id << " running...";
85
86 SCOPED_TRACE(Message() << "Thread #" << id);
87
88 for (int i = 0; i < kThreadCount; i++) {
89 SCOPED_TRACE(Message() << "Iteration #" << i);
90
91 // A bunch of assertions that should succeed.
92 EXPECT_TRUE(true);
93 ASSERT_FALSE(false) << "This shouldn't fail.";
94 EXPECT_STREQ("a", "a");
95 ASSERT_LE(5, 6);
96 EXPECT_EQ(i, i) << "This shouldn't fail.";
97
98 // RecordProperty() should interact safely with other threads as well.
99 // The shared_key forces property updates.
100 Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str());
101 Test::RecordProperty(IdToKey(id, "int").c_str(), id);
102 Test::RecordProperty("shared_key", IdToString(id).c_str());
103
104 // This assertion should fail kThreadCount times per thread. It
105 // is for testing whether Google Test can handle failed assertions in a
106 // multi-threaded context.
107 EXPECT_LT(i, 0) << "This should always fail.";
108 }
109}
110
111void CheckTestFailureCount(int expected_failures) {
112 const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
113 const TestResult* const result = info->result();
114 GTEST_CHECK_(expected_failures == result->total_part_count())
115 << "Logged " << result->total_part_count() << " failures "
116 << " vs. " << expected_failures << " expected";
117}
118
119// Tests using SCOPED_TRACE() and Google Test assertions in many threads
120// concurrently.
121TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) {
122 {
123 scoped_ptr<ThreadWithParam<int> > threads[kThreadCount];
124 Notification threads_can_start;
125 for (int i = 0; i != kThreadCount; i++)
126 threads[i].reset(new ThreadWithParam<int>(&ManyAsserts,
127 i,
128 &threads_can_start));
129
130 threads_can_start.Notify();
131
132 // Blocks until all the threads are done.
133 for (int i = 0; i != kThreadCount; i++)
134 threads[i]->Join();
135 }
136
137 // Ensures that kThreadCount*kThreadCount failures have been reported.
138 const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
139 const TestResult* const result = info->result();
140
141 std::vector<TestProperty> properties;
142 // We have no access to the TestResult's list of properties but we can
143 // copy them one by one.
144 for (int i = 0; i < result->test_property_count(); ++i)
145 properties.push_back(result->GetTestProperty(i));
146
147 EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count())
148 << "String and int values recorded on each thread, "
149 << "as well as one shared_key";
150 for (int i = 0; i < kThreadCount; ++i) {
151 ExpectKeyAndValueWereRecordedForId(properties, i, "string");
152 ExpectKeyAndValueWereRecordedForId(properties, i, "int");
153 }
154 CheckTestFailureCount(kThreadCount*kThreadCount);
155}
156
157void FailingThread(bool is_fatal) {
158 if (is_fatal)
159 FAIL() << "Fatal failure in some other thread. "
160 << "(This failure is expected.)";
161 else
162 ADD_FAILURE() << "Non-fatal failure in some other thread. "
163 << "(This failure is expected.)";
164}
165
166void GenerateFatalFailureInAnotherThread(bool is_fatal) {
167 ThreadWithParam<bool> thread(&FailingThread, is_fatal, NULL);
168 thread.Join();
169}
170
171TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) {
172 EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
173 // We should only have one failure (the one from
174 // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE
175 // should succeed.
176 CheckTestFailureCount(1);
177}
178
179void AssertNoFatalFailureIgnoresFailuresInOtherThreads() {
180 ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
181}
182TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) {
183 // Using a subroutine, to make sure, that the test continues.
184 AssertNoFatalFailureIgnoresFailuresInOtherThreads();
185 // We should only have one failure (the one from
186 // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE
187 // should succeed.
188 CheckTestFailureCount(1);
189}
190
191TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) {
192 // This statement should fail, since the current thread doesn't generate a
193 // fatal failure, only another one does.
194 EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected");
195 CheckTestFailureCount(2);
196}
197
198TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) {
199 // This statement should succeed, because failures in all threads are
200 // considered.
202 GenerateFatalFailureInAnotherThread(true), "expected");
203 CheckTestFailureCount(0);
204 // We need to add a failure, because main() checks that there are failures.
205 // But when only this test is run, we shouldn't have any failures.
206 ADD_FAILURE() << "This is an expected non-fatal failure.";
207}
208
209TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) {
210 // This statement should fail, since the current thread doesn't generate a
211 // fatal failure, only another one does.
212 EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false),
213 "expected");
214 CheckTestFailureCount(2);
215}
216
217TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) {
218 // This statement should succeed, because failures in all threads are
219 // considered.
221 GenerateFatalFailureInAnotherThread(false), "expected");
222 CheckTestFailureCount(0);
223 // We need to add a failure, because main() checks that there are failures,
224 // But when only this test is run, we shouldn't have any failures.
225 ADD_FAILURE() << "This is an expected non-fatal failure.";
226}
227
228} // namespace
229} // namespace testing
230
231int main(int argc, char **argv) {
233
234 const int result = RUN_ALL_TESTS(); // Expected to fail.
235 GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected";
236
237 printf("\nPASS\n");
238 return 0;
239}
240
241#else
242TEST(StressTest,
243 DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) {
244}
245
246int main(int argc, char **argv) {
248 return RUN_ALL_TESTS();
249}
250#endif // GTEST_IS_THREADSAFE
static void RecordProperty(const std::string &key, const std::string &value)
Definition gtest.cc:2253
const TestInfo * current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_)
Definition gtest.cc:4686
static UnitTest * GetInstance()
Definition gtest.cc:4374
uint64_t id
Definition code_cache.cpp:0
#define GTEST_LOG_(severity)
#define GTEST_CHECK_(condition)
#define EXPECT_FATAL_FAILURE(statement, substr)
Definition gtest-spi.h:137
#define EXPECT_NONFATAL_FAILURE(statement, substr)
Definition gtest-spi.h:203
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr)
Definition gtest-spi.h:217
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr)
Definition gtest-spi.h:154
#define EXPECT_NO_FATAL_FAILURE(statement)
Definition gtest.h:2133
#define FAIL()
Definition gtest.h:1858
#define EXPECT_EQ(val1, val2)
Definition gtest.h:1954
#define SCOPED_TRACE(message)
Definition gtest.h:2202
#define ASSERT_NO_FATAL_FAILURE(statement)
Definition gtest.h:2131
#define ASSERT_LE(val1, val2)
Definition gtest.h:1996
#define ASSERT_FALSE(condition)
Definition gtest.h:1904
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition gtest.h:2328
#define EXPECT_TRUE(condition)
Definition gtest.h:1895
#define EXPECT_STREQ(s1, s2)
Definition gtest.h:2027
#define TEST(test_case_name, test_name)
Definition gtest.h:2275
#define ADD_FAILURE()
Definition gtest.h:1844
#define ASSERT_TRUE(condition)
Definition gtest.h:1901
#define EXPECT_LT(val1, val2)
Definition gtest.h:1962
char ** argv
#define INFO(msg)
Definition catch.hpp:217
@ Join
merge all the arguments together into a single string via the delimiter character default(' ')
LOGGING_API void printf(Category category, const char *format,...)
Definition Logging.cpp:30
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition gtest.cc:5787
uint8_t key[16]
Definition yubico_otp.c:41