gmock_stress_test.cc
Go to the documentation of this file.
00001 // Copyright 2007, Google Inc.
00002 // All rights reserved.
00003 //
00004 // Redistribution and use in source and binary forms, with or without
00005 // modification, are permitted provided that the following conditions are
00006 // met:
00007 //
00008 //     * Redistributions of source code must retain the above copyright
00009 // notice, this list of conditions and the following disclaimer.
00010 //     * Redistributions in binary form must reproduce the above
00011 // copyright notice, this list of conditions and the following disclaimer
00012 // in the documentation and/or other materials provided with the
00013 // distribution.
00014 //     * Neither the name of Google Inc. nor the names of its
00015 // contributors may be used to endorse or promote products derived from
00016 // this software without specific prior written permission.
00017 //
00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00019 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00021 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00022 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00023 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00024 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00025 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00026 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00028 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 //
00030 // Author: wan@google.com (Zhanyong Wan)
00031 
00032 // Tests that Google Mock constructs can be used in a large number of
00033 // threads concurrently.
00034 
00035 #include "gmock/gmock.h"
00036 #include "gtest/gtest.h"
00037 
00038 namespace testing {
00039 namespace {
00040 
00041 // From <gtest/internal/gtest-port.h>.
00042 using ::testing::internal::ThreadWithParam;
00043 
00044 // The maximum number of test threads (not including helper threads)
00045 // to create.
00046 const int kMaxTestThreads = 50;
00047 
00048 // How many times to repeat a task in a test thread.
00049 const int kRepeat = 50;
00050 
00051 class MockFoo {
00052  public:
00053   MOCK_METHOD1(Bar, int(int n));  // NOLINT
00054   MOCK_METHOD2(Baz, char(const char* s1, const internal::string& s2));  // NOLINT
00055 };
00056 
00057 // Helper for waiting for the given thread to finish and then deleting it.
00058 template <typename T>
00059 void JoinAndDelete(ThreadWithParam<T>* t) {
00060   t->Join();
00061   delete t;
00062 }
00063 
00064 using internal::linked_ptr;
00065 
00066 // Helper classes for testing using linked_ptr concurrently.
00067 
00068 class Base {
00069  public:
00070   explicit Base(int a_x) : x_(a_x) {}
00071   virtual ~Base() {}
00072   int x() const { return x_; }
00073  private:
00074   int x_;
00075 };
00076 
00077 class Derived1 : public Base {
00078  public:
00079   Derived1(int a_x, int a_y) : Base(a_x), y_(a_y) {}
00080   int y() const { return y_; }
00081  private:
00082   int y_;
00083 };
00084 
00085 class Derived2 : public Base {
00086  public:
00087   Derived2(int a_x, int a_z) : Base(a_x), z_(a_z) {}
00088   int z() const { return z_; }
00089  private:
00090   int z_;
00091 };
00092 
00093 linked_ptr<Derived1> pointer1(new Derived1(1, 2));
00094 linked_ptr<Derived2> pointer2(new Derived2(3, 4));
00095 
00096 struct Dummy {};
00097 
00098 // Tests that we can copy from a linked_ptr and read it concurrently.
00099 void TestConcurrentCopyAndReadLinkedPtr(Dummy /* dummy */) {
00100   // Reads pointer1 and pointer2 while they are being copied from in
00101   // another thread.
00102   EXPECT_EQ(1, pointer1->x());
00103   EXPECT_EQ(2, pointer1->y());
00104   EXPECT_EQ(3, pointer2->x());
00105   EXPECT_EQ(4, pointer2->z());
00106 
00107   // Copies from pointer1.
00108   linked_ptr<Derived1> p1(pointer1);
00109   EXPECT_EQ(1, p1->x());
00110   EXPECT_EQ(2, p1->y());
00111 
00112   // Assigns from pointer2 where the LHS was empty.
00113   linked_ptr<Base> p2;
00114   p2 = pointer1;
00115   EXPECT_EQ(1, p2->x());
00116 
00117   // Assigns from pointer2 where the LHS was not empty.
00118   p2 = pointer2;
00119   EXPECT_EQ(3, p2->x());
00120 }
00121 
00122 const linked_ptr<Derived1> p0(new Derived1(1, 2));
00123 
00124 // Tests that we can concurrently modify two linked_ptrs that point to
00125 // the same object.
00126 void TestConcurrentWriteToEqualLinkedPtr(Dummy /* dummy */) {
00127   // p1 and p2 point to the same, shared thing.  One thread resets p1.
00128   // Another thread assigns to p2.  This will cause the same
00129   // underlying "ring" to be updated concurrently.
00130   linked_ptr<Derived1> p1(p0);
00131   linked_ptr<Derived1> p2(p0);
00132 
00133   EXPECT_EQ(1, p1->x());
00134   EXPECT_EQ(2, p1->y());
00135 
00136   EXPECT_EQ(1, p2->x());
00137   EXPECT_EQ(2, p2->y());
00138 
00139   p1.reset();
00140   p2 = p0;
00141 
00142   EXPECT_EQ(1, p2->x());
00143   EXPECT_EQ(2, p2->y());
00144 }
00145 
00146 // Tests that different mock objects can be used in their respective
00147 // threads.  This should generate no Google Test failure.
00148 void TestConcurrentMockObjects(Dummy /* dummy */) {
00149   // Creates a mock and does some typical operations on it.
00150   MockFoo foo;
00151   ON_CALL(foo, Bar(_))
00152       .WillByDefault(Return(1));
00153   ON_CALL(foo, Baz(_, _))
00154       .WillByDefault(Return('b'));
00155   ON_CALL(foo, Baz(_, "you"))
00156       .WillByDefault(Return('a'));
00157 
00158   EXPECT_CALL(foo, Bar(0))
00159       .Times(AtMost(3));
00160   EXPECT_CALL(foo, Baz(_, _));
00161   EXPECT_CALL(foo, Baz("hi", "you"))
00162       .WillOnce(Return('z'))
00163       .WillRepeatedly(DoDefault());
00164 
00165   EXPECT_EQ(1, foo.Bar(0));
00166   EXPECT_EQ(1, foo.Bar(0));
00167   EXPECT_EQ('z', foo.Baz("hi", "you"));
00168   EXPECT_EQ('a', foo.Baz("hi", "you"));
00169   EXPECT_EQ('b', foo.Baz("hi", "me"));
00170 }
00171 
00172 // Tests invoking methods of the same mock object in multiple threads.
00173 
00174 struct Helper1Param {
00175   MockFoo* mock_foo;
00176   int* count;
00177 };
00178 
00179 void Helper1(Helper1Param param) {
00180   for (int i = 0; i < kRepeat; i++) {
00181     const char ch = param.mock_foo->Baz("a", "b");
00182     if (ch == 'a') {
00183       // It was an expected call.
00184       (*param.count)++;
00185     } else {
00186       // It was an excessive call.
00187       EXPECT_EQ('\0', ch);
00188     }
00189 
00190     // An unexpected call.
00191     EXPECT_EQ('\0', param.mock_foo->Baz("x", "y")) << "Expected failure.";
00192 
00193     // An uninteresting call.
00194     EXPECT_EQ(1, param.mock_foo->Bar(5));
00195   }
00196 }
00197 
00198 // This should generate 3*kRepeat + 1 failures in total.
00199 void TestConcurrentCallsOnSameObject(Dummy /* dummy */) {
00200   MockFoo foo;
00201 
00202   ON_CALL(foo, Bar(_))
00203       .WillByDefault(Return(1));
00204   EXPECT_CALL(foo, Baz(_, "b"))
00205       .Times(kRepeat)
00206       .WillRepeatedly(Return('a'));
00207   EXPECT_CALL(foo, Baz(_, "c"));  // Expected to be unsatisfied.
00208 
00209   // This chunk of code should generate kRepeat failures about
00210   // excessive calls, and 2*kRepeat failures about unexpected calls.
00211   int count1 = 0;
00212   const Helper1Param param = { &foo, &count1 };
00213   ThreadWithParam<Helper1Param>* const t =
00214       new ThreadWithParam<Helper1Param>(Helper1, param, NULL);
00215 
00216   int count2 = 0;
00217   const Helper1Param param2 = { &foo, &count2 };
00218   Helper1(param2);
00219   JoinAndDelete(t);
00220 
00221   EXPECT_EQ(kRepeat, count1 + count2);
00222 
00223   // foo's destructor should generate one failure about unsatisfied
00224   // expectation.
00225 }
00226 
00227 // Tests using the same mock object in multiple threads when the
00228 // expectations are partially ordered.
00229 
00230 void Helper2(MockFoo* foo) {
00231   for (int i = 0; i < kRepeat; i++) {
00232     foo->Bar(2);
00233     foo->Bar(3);
00234   }
00235 }
00236 
00237 // This should generate no Google Test failures.
00238 void TestPartiallyOrderedExpectationsWithThreads(Dummy /* dummy */) {
00239   MockFoo foo;
00240   Sequence s1, s2;
00241 
00242   {
00243     InSequence dummy;
00244     EXPECT_CALL(foo, Bar(0));
00245     EXPECT_CALL(foo, Bar(1))
00246         .InSequence(s1, s2);
00247   }
00248 
00249   EXPECT_CALL(foo, Bar(2))
00250       .Times(2*kRepeat)
00251       .InSequence(s1)
00252       .RetiresOnSaturation();
00253   EXPECT_CALL(foo, Bar(3))
00254       .Times(2*kRepeat)
00255       .InSequence(s2);
00256 
00257   {
00258     InSequence dummy;
00259     EXPECT_CALL(foo, Bar(2))
00260         .InSequence(s1, s2);
00261     EXPECT_CALL(foo, Bar(4));
00262   }
00263 
00264   foo.Bar(0);
00265   foo.Bar(1);
00266 
00267   ThreadWithParam<MockFoo*>* const t =
00268       new ThreadWithParam<MockFoo*>(Helper2, &foo, NULL);
00269   Helper2(&foo);
00270   JoinAndDelete(t);
00271 
00272   foo.Bar(2);
00273   foo.Bar(4);
00274 }
00275 
00276 // Tests using Google Mock constructs in many threads concurrently.
00277 TEST(StressTest, CanUseGMockWithThreads) {
00278   void (*test_routines[])(Dummy dummy) = {
00279     &TestConcurrentCopyAndReadLinkedPtr,
00280     &TestConcurrentWriteToEqualLinkedPtr,
00281     &TestConcurrentMockObjects,
00282     &TestConcurrentCallsOnSameObject,
00283     &TestPartiallyOrderedExpectationsWithThreads,
00284   };
00285 
00286   const int kRoutines = sizeof(test_routines)/sizeof(test_routines[0]);
00287   const int kCopiesOfEachRoutine = kMaxTestThreads / kRoutines;
00288   const int kTestThreads = kCopiesOfEachRoutine * kRoutines;
00289   ThreadWithParam<Dummy>* threads[kTestThreads] = {};
00290   for (int i = 0; i < kTestThreads; i++) {
00291     // Creates a thread to run the test function.
00292     threads[i] =
00293         new ThreadWithParam<Dummy>(test_routines[i % kRoutines], Dummy(), NULL);
00294     GTEST_LOG_(INFO) << "Thread #" << i << " running . . .";
00295   }
00296 
00297   // At this point, we have many threads running.
00298   for (int i = 0; i < kTestThreads; i++) {
00299     JoinAndDelete(threads[i]);
00300   }
00301 
00302   // Ensures that the correct number of failures have been reported.
00303   const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
00304   const TestResult& result = *info->result();
00305   const int kExpectedFailures = (3*kRepeat + 1)*kCopiesOfEachRoutine;
00306   GTEST_CHECK_(kExpectedFailures == result.total_part_count())
00307       << "Expected " << kExpectedFailures << " failures, but got "
00308       << result.total_part_count();
00309 }
00310 
00311 }  // namespace
00312 }  // namespace testing
00313 
00314 int main(int argc, char **argv) {
00315   testing::InitGoogleMock(&argc, argv);
00316 
00317   const int exit_code = RUN_ALL_TESTS();  // Expected to fail.
00318   GTEST_CHECK_(exit_code != 0) << "RUN_ALL_TESTS() did not fail as expected";
00319 
00320   printf("\nPASS\n");
00321   return 0;
00322 }


ros_opcua_impl_freeopcua
Author(s): Denis Štogl
autogenerated on Sat Jun 8 2019 18:24:43