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 (at) google.com (Zhanyong Wan) 31 32 // Tests that Google Mock constructs can be used in a large number of 33 // threads concurrently. 34 35 #include "gmock/gmock.h" 36 #include "gtest/gtest.h" 37 38 namespace testing { 39 namespace { 40 41 // From <gtest/internal/gtest-port.h>. 42 using ::testing::internal::ThreadWithParam; 43 44 // The maximum number of test threads (not including helper threads) 45 // to create. 46 const int kMaxTestThreads = 50; 47 48 // How many times to repeat a task in a test thread. 49 const int kRepeat = 50; 50 51 class MockFoo { 52 public: 53 MOCK_METHOD1(Bar, int(int n)); // NOLINT 54 MOCK_METHOD2(Baz, char(const char* s1, const internal::string& s2)); // NOLINT 55 }; 56 57 // Helper for waiting for the given thread to finish and then deleting it. 58 template <typename T> 59 void JoinAndDelete(ThreadWithParam<T>* t) { 60 t->Join(); 61 delete t; 62 } 63 64 using internal::linked_ptr; 65 66 // Helper classes for testing using linked_ptr concurrently. 67 68 class Base { 69 public: 70 explicit Base(int a_x) : x_(a_x) {} 71 virtual ~Base() {} 72 int x() const { return x_; } 73 private: 74 int x_; 75 }; 76 77 class Derived1 : public Base { 78 public: 79 Derived1(int a_x, int a_y) : Base(a_x), y_(a_y) {} 80 int y() const { return y_; } 81 private: 82 int y_; 83 }; 84 85 class Derived2 : public Base { 86 public: 87 Derived2(int a_x, int a_z) : Base(a_x), z_(a_z) {} 88 int z() const { return z_; } 89 private: 90 int z_; 91 }; 92 93 linked_ptr<Derived1> pointer1(new Derived1(1, 2)); 94 linked_ptr<Derived2> pointer2(new Derived2(3, 4)); 95 96 struct Dummy {}; 97 98 // Tests that we can copy from a linked_ptr and read it concurrently. 99 void TestConcurrentCopyAndReadLinkedPtr(Dummy /* dummy */) { 100 // Reads pointer1 and pointer2 while they are being copied from in 101 // another thread. 102 EXPECT_EQ(1, pointer1->x()); 103 EXPECT_EQ(2, pointer1->y()); 104 EXPECT_EQ(3, pointer2->x()); 105 EXPECT_EQ(4, pointer2->z()); 106 107 // Copies from pointer1. 108 linked_ptr<Derived1> p1(pointer1); 109 EXPECT_EQ(1, p1->x()); 110 EXPECT_EQ(2, p1->y()); 111 112 // Assigns from pointer2 where the LHS was empty. 113 linked_ptr<Base> p2; 114 p2 = pointer1; 115 EXPECT_EQ(1, p2->x()); 116 117 // Assigns from pointer2 where the LHS was not empty. 118 p2 = pointer2; 119 EXPECT_EQ(3, p2->x()); 120 } 121 122 const linked_ptr<Derived1> p0(new Derived1(1, 2)); 123 124 // Tests that we can concurrently modify two linked_ptrs that point to 125 // the same object. 126 void TestConcurrentWriteToEqualLinkedPtr(Dummy /* dummy */) { 127 // p1 and p2 point to the same, shared thing. One thread resets p1. 128 // Another thread assigns to p2. This will cause the same 129 // underlying "ring" to be updated concurrently. 130 linked_ptr<Derived1> p1(p0); 131 linked_ptr<Derived1> p2(p0); 132 133 EXPECT_EQ(1, p1->x()); 134 EXPECT_EQ(2, p1->y()); 135 136 EXPECT_EQ(1, p2->x()); 137 EXPECT_EQ(2, p2->y()); 138 139 p1.reset(); 140 p2 = p0; 141 142 EXPECT_EQ(1, p2->x()); 143 EXPECT_EQ(2, p2->y()); 144 } 145 146 // Tests that different mock objects can be used in their respective 147 // threads. This should generate no Google Test failure. 148 void TestConcurrentMockObjects(Dummy /* dummy */) { 149 // Creates a mock and does some typical operations on it. 150 MockFoo foo; 151 ON_CALL(foo, Bar(_)) 152 .WillByDefault(Return(1)); 153 ON_CALL(foo, Baz(_, _)) 154 .WillByDefault(Return('b')); 155 ON_CALL(foo, Baz(_, "you")) 156 .WillByDefault(Return('a')); 157 158 EXPECT_CALL(foo, Bar(0)) 159 .Times(AtMost(3)); 160 EXPECT_CALL(foo, Baz(_, _)); 161 EXPECT_CALL(foo, Baz("hi", "you")) 162 .WillOnce(Return('z')) 163 .WillRepeatedly(DoDefault()); 164 165 EXPECT_EQ(1, foo.Bar(0)); 166 EXPECT_EQ(1, foo.Bar(0)); 167 EXPECT_EQ('z', foo.Baz("hi", "you")); 168 EXPECT_EQ('a', foo.Baz("hi", "you")); 169 EXPECT_EQ('b', foo.Baz("hi", "me")); 170 } 171 172 // Tests invoking methods of the same mock object in multiple threads. 173 174 struct Helper1Param { 175 MockFoo* mock_foo; 176 int* count; 177 }; 178 179 void Helper1(Helper1Param param) { 180 for (int i = 0; i < kRepeat; i++) { 181 const char ch = param.mock_foo->Baz("a", "b"); 182 if (ch == 'a') { 183 // It was an expected call. 184 (*param.count)++; 185 } else { 186 // It was an excessive call. 187 EXPECT_EQ('\0', ch); 188 } 189 190 // An unexpected call. 191 EXPECT_EQ('\0', param.mock_foo->Baz("x", "y")) << "Expected failure."; 192 193 // An uninteresting call. 194 EXPECT_EQ(1, param.mock_foo->Bar(5)); 195 } 196 } 197 198 // This should generate 3*kRepeat + 1 failures in total. 199 void TestConcurrentCallsOnSameObject(Dummy /* dummy */) { 200 MockFoo foo; 201 202 ON_CALL(foo, Bar(_)) 203 .WillByDefault(Return(1)); 204 EXPECT_CALL(foo, Baz(_, "b")) 205 .Times(kRepeat) 206 .WillRepeatedly(Return('a')); 207 EXPECT_CALL(foo, Baz(_, "c")); // Expected to be unsatisfied. 208 209 // This chunk of code should generate kRepeat failures about 210 // excessive calls, and 2*kRepeat failures about unexpected calls. 211 int count1 = 0; 212 const Helper1Param param = { &foo, &count1 }; 213 ThreadWithParam<Helper1Param>* const t = 214 new ThreadWithParam<Helper1Param>(Helper1, param, NULL); 215 216 int count2 = 0; 217 const Helper1Param param2 = { &foo, &count2 }; 218 Helper1(param2); 219 JoinAndDelete(t); 220 221 EXPECT_EQ(kRepeat, count1 + count2); 222 223 // foo's destructor should generate one failure about unsatisfied 224 // expectation. 225 } 226 227 // Tests using the same mock object in multiple threads when the 228 // expectations are partially ordered. 229 230 void Helper2(MockFoo* foo) { 231 for (int i = 0; i < kRepeat; i++) { 232 foo->Bar(2); 233 foo->Bar(3); 234 } 235 } 236 237 // This should generate no Google Test failures. 238 void TestPartiallyOrderedExpectationsWithThreads(Dummy /* dummy */) { 239 MockFoo foo; 240 Sequence s1, s2; 241 242 { 243 InSequence dummy; 244 EXPECT_CALL(foo, Bar(0)); 245 EXPECT_CALL(foo, Bar(1)) 246 .InSequence(s1, s2); 247 } 248 249 EXPECT_CALL(foo, Bar(2)) 250 .Times(2*kRepeat) 251 .InSequence(s1) 252 .RetiresOnSaturation(); 253 EXPECT_CALL(foo, Bar(3)) 254 .Times(2*kRepeat) 255 .InSequence(s2); 256 257 { 258 InSequence dummy; 259 EXPECT_CALL(foo, Bar(2)) 260 .InSequence(s1, s2); 261 EXPECT_CALL(foo, Bar(4)); 262 } 263 264 foo.Bar(0); 265 foo.Bar(1); 266 267 ThreadWithParam<MockFoo*>* const t = 268 new ThreadWithParam<MockFoo*>(Helper2, &foo, NULL); 269 Helper2(&foo); 270 JoinAndDelete(t); 271 272 foo.Bar(2); 273 foo.Bar(4); 274 } 275 276 // Tests using Google Mock constructs in many threads concurrently. 277 TEST(StressTest, CanUseGMockWithThreads) { 278 void (*test_routines[])(Dummy dummy) = { 279 &TestConcurrentCopyAndReadLinkedPtr, 280 &TestConcurrentWriteToEqualLinkedPtr, 281 &TestConcurrentMockObjects, 282 &TestConcurrentCallsOnSameObject, 283 &TestPartiallyOrderedExpectationsWithThreads, 284 }; 285 286 const int kRoutines = sizeof(test_routines)/sizeof(test_routines[0]); 287 const int kCopiesOfEachRoutine = kMaxTestThreads / kRoutines; 288 const int kTestThreads = kCopiesOfEachRoutine * kRoutines; 289 ThreadWithParam<Dummy>* threads[kTestThreads] = {}; 290 for (int i = 0; i < kTestThreads; i++) { 291 // Creates a thread to run the test function. 292 threads[i] = 293 new ThreadWithParam<Dummy>(test_routines[i % kRoutines], Dummy(), NULL); 294 GTEST_LOG_(INFO) << "Thread #" << i << " running . . ."; 295 } 296 297 // At this point, we have many threads running. 298 for (int i = 0; i < kTestThreads; i++) { 299 JoinAndDelete(threads[i]); 300 } 301 302 // Ensures that the correct number of failures have been reported. 303 const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); 304 const TestResult& result = *info->result(); 305 const int kExpectedFailures = (3*kRepeat + 1)*kCopiesOfEachRoutine; 306 GTEST_CHECK_(kExpectedFailures == result.total_part_count()) 307 << "Expected " << kExpectedFailures << " failures, but got " 308 << result.total_part_count(); 309 } 310 311 } // namespace 312 } // namespace testing 313 314 int main(int argc, char **argv) { 315 testing::InitGoogleMock(&argc, argv); 316 317 const int exit_code = RUN_ALL_TESTS(); // Expected to fail. 318 GTEST_CHECK_(exit_code != 0) << "RUN_ALL_TESTS() did not fail as expected"; 319 320 printf("\nPASS\n"); 321 return 0; 322 } 323