gmock_stress_test.cc 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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. // Tests that Google Mock constructs can be used in a large number of
  30. // threads concurrently.
  31. #include "gmock/gmock.h"
  32. #include "gtest/gtest.h"
  33. namespace testing {
  34. namespace {
  35. // From gtest-port.h.
  36. using ::testing::internal::ThreadWithParam;
  37. // The maximum number of test threads (not including helper threads)
  38. // to create.
  39. const int kMaxTestThreads = 50;
  40. // How many times to repeat a task in a test thread.
  41. const int kRepeat = 50;
  42. class MockFoo {
  43. public:
  44. MOCK_METHOD1(Bar, int(int n)); // NOLINT
  45. MOCK_METHOD2(Baz, char(const char* s1, const std::string& s2)); // NOLINT
  46. };
  47. // Helper for waiting for the given thread to finish and then deleting it.
  48. template <typename T>
  49. void JoinAndDelete(ThreadWithParam<T>* t) {
  50. t->Join();
  51. delete t;
  52. }
  53. struct Dummy {};
  54. // Tests that different mock objects can be used in their respective
  55. // threads. This should generate no Google Test failure.
  56. void TestConcurrentMockObjects(Dummy /* dummy */) {
  57. // Creates a mock and does some typical operations on it.
  58. MockFoo foo;
  59. ON_CALL(foo, Bar(_)).WillByDefault(Return(1));
  60. ON_CALL(foo, Baz(_, _)).WillByDefault(Return('b'));
  61. ON_CALL(foo, Baz(_, "you")).WillByDefault(Return('a'));
  62. EXPECT_CALL(foo, Bar(0)).Times(AtMost(3));
  63. EXPECT_CALL(foo, Baz(_, _));
  64. EXPECT_CALL(foo, Baz("hi", "you"))
  65. .WillOnce(Return('z'))
  66. .WillRepeatedly(DoDefault());
  67. EXPECT_EQ(1, foo.Bar(0));
  68. EXPECT_EQ(1, foo.Bar(0));
  69. EXPECT_EQ('z', foo.Baz("hi", "you"));
  70. EXPECT_EQ('a', foo.Baz("hi", "you"));
  71. EXPECT_EQ('b', foo.Baz("hi", "me"));
  72. }
  73. // Tests invoking methods of the same mock object in multiple threads.
  74. struct Helper1Param {
  75. MockFoo* mock_foo;
  76. int* count;
  77. };
  78. void Helper1(Helper1Param param) {
  79. for (int i = 0; i < kRepeat; i++) {
  80. const char ch = param.mock_foo->Baz("a", "b");
  81. if (ch == 'a') {
  82. // It was an expected call.
  83. (*param.count)++;
  84. } else {
  85. // It was an excessive call.
  86. EXPECT_EQ('\0', ch);
  87. }
  88. // An unexpected call.
  89. EXPECT_EQ('\0', param.mock_foo->Baz("x", "y")) << "Expected failure.";
  90. // An uninteresting call.
  91. EXPECT_EQ(1, param.mock_foo->Bar(5));
  92. }
  93. }
  94. // This should generate 3*kRepeat + 1 failures in total.
  95. void TestConcurrentCallsOnSameObject(Dummy /* dummy */) {
  96. MockFoo foo;
  97. ON_CALL(foo, Bar(_)).WillByDefault(Return(1));
  98. EXPECT_CALL(foo, Baz(_, "b")).Times(kRepeat).WillRepeatedly(Return('a'));
  99. EXPECT_CALL(foo, Baz(_, "c")); // Expected to be unsatisfied.
  100. // This chunk of code should generate kRepeat failures about
  101. // excessive calls, and 2*kRepeat failures about unexpected calls.
  102. int count1 = 0;
  103. const Helper1Param param = {&foo, &count1};
  104. ThreadWithParam<Helper1Param>* const t =
  105. new ThreadWithParam<Helper1Param>(Helper1, param, nullptr);
  106. int count2 = 0;
  107. const Helper1Param param2 = {&foo, &count2};
  108. Helper1(param2);
  109. JoinAndDelete(t);
  110. EXPECT_EQ(kRepeat, count1 + count2);
  111. // foo's destructor should generate one failure about unsatisfied
  112. // expectation.
  113. }
  114. // Tests using the same mock object in multiple threads when the
  115. // expectations are partially ordered.
  116. void Helper2(MockFoo* foo) {
  117. for (int i = 0; i < kRepeat; i++) {
  118. foo->Bar(2);
  119. foo->Bar(3);
  120. }
  121. }
  122. // This should generate no Google Test failures.
  123. void TestPartiallyOrderedExpectationsWithThreads(Dummy /* dummy */) {
  124. MockFoo foo;
  125. Sequence s1, s2;
  126. {
  127. InSequence dummy;
  128. EXPECT_CALL(foo, Bar(0));
  129. EXPECT_CALL(foo, Bar(1)).InSequence(s1, s2);
  130. }
  131. EXPECT_CALL(foo, Bar(2))
  132. .Times(2 * kRepeat)
  133. .InSequence(s1)
  134. .RetiresOnSaturation();
  135. EXPECT_CALL(foo, Bar(3)).Times(2 * kRepeat).InSequence(s2);
  136. {
  137. InSequence dummy;
  138. EXPECT_CALL(foo, Bar(2)).InSequence(s1, s2);
  139. EXPECT_CALL(foo, Bar(4));
  140. }
  141. foo.Bar(0);
  142. foo.Bar(1);
  143. ThreadWithParam<MockFoo*>* const t =
  144. new ThreadWithParam<MockFoo*>(Helper2, &foo, nullptr);
  145. Helper2(&foo);
  146. JoinAndDelete(t);
  147. foo.Bar(2);
  148. foo.Bar(4);
  149. }
  150. // Tests using Google Mock constructs in many threads concurrently.
  151. TEST(StressTest, CanUseGMockWithThreads) {
  152. void (*test_routines[])(Dummy dummy) = {
  153. &TestConcurrentMockObjects,
  154. &TestConcurrentCallsOnSameObject,
  155. &TestPartiallyOrderedExpectationsWithThreads,
  156. };
  157. const int kRoutines = sizeof(test_routines) / sizeof(test_routines[0]);
  158. const int kCopiesOfEachRoutine = kMaxTestThreads / kRoutines;
  159. const int kTestThreads = kCopiesOfEachRoutine * kRoutines;
  160. ThreadWithParam<Dummy>* threads[kTestThreads] = {};
  161. for (int i = 0; i < kTestThreads; i++) {
  162. // Creates a thread to run the test function.
  163. threads[i] = new ThreadWithParam<Dummy>(test_routines[i % kRoutines],
  164. Dummy(), nullptr);
  165. GTEST_LOG_(INFO) << "Thread #" << i << " running . . .";
  166. }
  167. // At this point, we have many threads running.
  168. for (int i = 0; i < kTestThreads; i++) {
  169. JoinAndDelete(threads[i]);
  170. }
  171. // Ensures that the correct number of failures have been reported.
  172. const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
  173. const TestResult& result = *info->result();
  174. const int kExpectedFailures = (3 * kRepeat + 1) * kCopiesOfEachRoutine;
  175. GTEST_CHECK_(kExpectedFailures == result.total_part_count())
  176. << "Expected " << kExpectedFailures << " failures, but got "
  177. << result.total_part_count();
  178. }
  179. } // namespace
  180. } // namespace testing
  181. int main(int argc, char** argv) {
  182. testing::InitGoogleMock(&argc, argv);
  183. const int exit_code = RUN_ALL_TESTS(); // Expected to fail.
  184. GTEST_CHECK_(exit_code != 0) << "RUN_ALL_TESTS() did not fail as expected";
  185. printf("\nPASS\n");
  186. return 0;
  187. }