gmock_stress_test.cc revision 13481
113481Sgiacomo.travaglini@arm.com// Copyright 2007, Google Inc. 213481Sgiacomo.travaglini@arm.com// All rights reserved. 313481Sgiacomo.travaglini@arm.com// 413481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without 513481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are 613481Sgiacomo.travaglini@arm.com// met: 713481Sgiacomo.travaglini@arm.com// 813481Sgiacomo.travaglini@arm.com// * Redistributions of source code must retain the above copyright 913481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer. 1013481Sgiacomo.travaglini@arm.com// * Redistributions in binary form must reproduce the above 1113481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer 1213481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the 1313481Sgiacomo.travaglini@arm.com// distribution. 1413481Sgiacomo.travaglini@arm.com// * Neither the name of Google Inc. nor the names of its 1513481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from 1613481Sgiacomo.travaglini@arm.com// this software without specific prior written permission. 1713481Sgiacomo.travaglini@arm.com// 1813481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1913481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2013481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2113481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2213481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2313481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2413481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2513481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2613481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2713481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2813481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2913481Sgiacomo.travaglini@arm.com// 3013481Sgiacomo.travaglini@arm.com// Author: wan@google.com (Zhanyong Wan) 3113481Sgiacomo.travaglini@arm.com 3213481Sgiacomo.travaglini@arm.com// Tests that Google Mock constructs can be used in a large number of 3313481Sgiacomo.travaglini@arm.com// threads concurrently. 3413481Sgiacomo.travaglini@arm.com 3513481Sgiacomo.travaglini@arm.com#include "gmock/gmock.h" 3613481Sgiacomo.travaglini@arm.com#include "gtest/gtest.h" 3713481Sgiacomo.travaglini@arm.com 3813481Sgiacomo.travaglini@arm.comnamespace testing { 3913481Sgiacomo.travaglini@arm.comnamespace { 4013481Sgiacomo.travaglini@arm.com 4113481Sgiacomo.travaglini@arm.com// From <gtest/internal/gtest-port.h>. 4213481Sgiacomo.travaglini@arm.comusing ::testing::internal::ThreadWithParam; 4313481Sgiacomo.travaglini@arm.com 4413481Sgiacomo.travaglini@arm.com// The maximum number of test threads (not including helper threads) 4513481Sgiacomo.travaglini@arm.com// to create. 4613481Sgiacomo.travaglini@arm.comconst int kMaxTestThreads = 50; 4713481Sgiacomo.travaglini@arm.com 4813481Sgiacomo.travaglini@arm.com// How many times to repeat a task in a test thread. 4913481Sgiacomo.travaglini@arm.comconst int kRepeat = 50; 5013481Sgiacomo.travaglini@arm.com 5113481Sgiacomo.travaglini@arm.comclass MockFoo { 5213481Sgiacomo.travaglini@arm.com public: 5313481Sgiacomo.travaglini@arm.com MOCK_METHOD1(Bar, int(int n)); // NOLINT 5413481Sgiacomo.travaglini@arm.com MOCK_METHOD2(Baz, char(const char* s1, const internal::string& s2)); // NOLINT 5513481Sgiacomo.travaglini@arm.com}; 5613481Sgiacomo.travaglini@arm.com 5713481Sgiacomo.travaglini@arm.com// Helper for waiting for the given thread to finish and then deleting it. 5813481Sgiacomo.travaglini@arm.comtemplate <typename T> 5913481Sgiacomo.travaglini@arm.comvoid JoinAndDelete(ThreadWithParam<T>* t) { 6013481Sgiacomo.travaglini@arm.com t->Join(); 6113481Sgiacomo.travaglini@arm.com delete t; 6213481Sgiacomo.travaglini@arm.com} 6313481Sgiacomo.travaglini@arm.com 6413481Sgiacomo.travaglini@arm.comusing internal::linked_ptr; 6513481Sgiacomo.travaglini@arm.com 6613481Sgiacomo.travaglini@arm.com// Helper classes for testing using linked_ptr concurrently. 6713481Sgiacomo.travaglini@arm.com 6813481Sgiacomo.travaglini@arm.comclass Base { 6913481Sgiacomo.travaglini@arm.com public: 7013481Sgiacomo.travaglini@arm.com explicit Base(int a_x) : x_(a_x) {} 7113481Sgiacomo.travaglini@arm.com virtual ~Base() {} 7213481Sgiacomo.travaglini@arm.com int x() const { return x_; } 7313481Sgiacomo.travaglini@arm.com private: 7413481Sgiacomo.travaglini@arm.com int x_; 7513481Sgiacomo.travaglini@arm.com}; 7613481Sgiacomo.travaglini@arm.com 7713481Sgiacomo.travaglini@arm.comclass Derived1 : public Base { 7813481Sgiacomo.travaglini@arm.com public: 7913481Sgiacomo.travaglini@arm.com Derived1(int a_x, int a_y) : Base(a_x), y_(a_y) {} 8013481Sgiacomo.travaglini@arm.com int y() const { return y_; } 8113481Sgiacomo.travaglini@arm.com private: 8213481Sgiacomo.travaglini@arm.com int y_; 8313481Sgiacomo.travaglini@arm.com}; 8413481Sgiacomo.travaglini@arm.com 8513481Sgiacomo.travaglini@arm.comclass Derived2 : public Base { 8613481Sgiacomo.travaglini@arm.com public: 8713481Sgiacomo.travaglini@arm.com Derived2(int a_x, int a_z) : Base(a_x), z_(a_z) {} 8813481Sgiacomo.travaglini@arm.com int z() const { return z_; } 8913481Sgiacomo.travaglini@arm.com private: 9013481Sgiacomo.travaglini@arm.com int z_; 9113481Sgiacomo.travaglini@arm.com}; 9213481Sgiacomo.travaglini@arm.com 9313481Sgiacomo.travaglini@arm.comlinked_ptr<Derived1> pointer1(new Derived1(1, 2)); 9413481Sgiacomo.travaglini@arm.comlinked_ptr<Derived2> pointer2(new Derived2(3, 4)); 9513481Sgiacomo.travaglini@arm.com 9613481Sgiacomo.travaglini@arm.comstruct Dummy {}; 9713481Sgiacomo.travaglini@arm.com 9813481Sgiacomo.travaglini@arm.com// Tests that we can copy from a linked_ptr and read it concurrently. 9913481Sgiacomo.travaglini@arm.comvoid TestConcurrentCopyAndReadLinkedPtr(Dummy /* dummy */) { 10013481Sgiacomo.travaglini@arm.com // Reads pointer1 and pointer2 while they are being copied from in 10113481Sgiacomo.travaglini@arm.com // another thread. 10213481Sgiacomo.travaglini@arm.com EXPECT_EQ(1, pointer1->x()); 10313481Sgiacomo.travaglini@arm.com EXPECT_EQ(2, pointer1->y()); 10413481Sgiacomo.travaglini@arm.com EXPECT_EQ(3, pointer2->x()); 10513481Sgiacomo.travaglini@arm.com EXPECT_EQ(4, pointer2->z()); 10613481Sgiacomo.travaglini@arm.com 10713481Sgiacomo.travaglini@arm.com // Copies from pointer1. 10813481Sgiacomo.travaglini@arm.com linked_ptr<Derived1> p1(pointer1); 10913481Sgiacomo.travaglini@arm.com EXPECT_EQ(1, p1->x()); 11013481Sgiacomo.travaglini@arm.com EXPECT_EQ(2, p1->y()); 11113481Sgiacomo.travaglini@arm.com 11213481Sgiacomo.travaglini@arm.com // Assigns from pointer2 where the LHS was empty. 11313481Sgiacomo.travaglini@arm.com linked_ptr<Base> p2; 11413481Sgiacomo.travaglini@arm.com p2 = pointer1; 11513481Sgiacomo.travaglini@arm.com EXPECT_EQ(1, p2->x()); 11613481Sgiacomo.travaglini@arm.com 11713481Sgiacomo.travaglini@arm.com // Assigns from pointer2 where the LHS was not empty. 11813481Sgiacomo.travaglini@arm.com p2 = pointer2; 11913481Sgiacomo.travaglini@arm.com EXPECT_EQ(3, p2->x()); 12013481Sgiacomo.travaglini@arm.com} 12113481Sgiacomo.travaglini@arm.com 12213481Sgiacomo.travaglini@arm.comconst linked_ptr<Derived1> p0(new Derived1(1, 2)); 12313481Sgiacomo.travaglini@arm.com 12413481Sgiacomo.travaglini@arm.com// Tests that we can concurrently modify two linked_ptrs that point to 12513481Sgiacomo.travaglini@arm.com// the same object. 12613481Sgiacomo.travaglini@arm.comvoid TestConcurrentWriteToEqualLinkedPtr(Dummy /* dummy */) { 12713481Sgiacomo.travaglini@arm.com // p1 and p2 point to the same, shared thing. One thread resets p1. 12813481Sgiacomo.travaglini@arm.com // Another thread assigns to p2. This will cause the same 12913481Sgiacomo.travaglini@arm.com // underlying "ring" to be updated concurrently. 13013481Sgiacomo.travaglini@arm.com linked_ptr<Derived1> p1(p0); 13113481Sgiacomo.travaglini@arm.com linked_ptr<Derived1> p2(p0); 13213481Sgiacomo.travaglini@arm.com 13313481Sgiacomo.travaglini@arm.com EXPECT_EQ(1, p1->x()); 13413481Sgiacomo.travaglini@arm.com EXPECT_EQ(2, p1->y()); 13513481Sgiacomo.travaglini@arm.com 13613481Sgiacomo.travaglini@arm.com EXPECT_EQ(1, p2->x()); 13713481Sgiacomo.travaglini@arm.com EXPECT_EQ(2, p2->y()); 13813481Sgiacomo.travaglini@arm.com 13913481Sgiacomo.travaglini@arm.com p1.reset(); 14013481Sgiacomo.travaglini@arm.com p2 = p0; 14113481Sgiacomo.travaglini@arm.com 14213481Sgiacomo.travaglini@arm.com EXPECT_EQ(1, p2->x()); 14313481Sgiacomo.travaglini@arm.com EXPECT_EQ(2, p2->y()); 14413481Sgiacomo.travaglini@arm.com} 14513481Sgiacomo.travaglini@arm.com 14613481Sgiacomo.travaglini@arm.com// Tests that different mock objects can be used in their respective 14713481Sgiacomo.travaglini@arm.com// threads. This should generate no Google Test failure. 14813481Sgiacomo.travaglini@arm.comvoid TestConcurrentMockObjects(Dummy /* dummy */) { 14913481Sgiacomo.travaglini@arm.com // Creates a mock and does some typical operations on it. 15013481Sgiacomo.travaglini@arm.com MockFoo foo; 15113481Sgiacomo.travaglini@arm.com ON_CALL(foo, Bar(_)) 15213481Sgiacomo.travaglini@arm.com .WillByDefault(Return(1)); 15313481Sgiacomo.travaglini@arm.com ON_CALL(foo, Baz(_, _)) 15413481Sgiacomo.travaglini@arm.com .WillByDefault(Return('b')); 15513481Sgiacomo.travaglini@arm.com ON_CALL(foo, Baz(_, "you")) 15613481Sgiacomo.travaglini@arm.com .WillByDefault(Return('a')); 15713481Sgiacomo.travaglini@arm.com 15813481Sgiacomo.travaglini@arm.com EXPECT_CALL(foo, Bar(0)) 15913481Sgiacomo.travaglini@arm.com .Times(AtMost(3)); 16013481Sgiacomo.travaglini@arm.com EXPECT_CALL(foo, Baz(_, _)); 16113481Sgiacomo.travaglini@arm.com EXPECT_CALL(foo, Baz("hi", "you")) 16213481Sgiacomo.travaglini@arm.com .WillOnce(Return('z')) 16313481Sgiacomo.travaglini@arm.com .WillRepeatedly(DoDefault()); 16413481Sgiacomo.travaglini@arm.com 16513481Sgiacomo.travaglini@arm.com EXPECT_EQ(1, foo.Bar(0)); 16613481Sgiacomo.travaglini@arm.com EXPECT_EQ(1, foo.Bar(0)); 16713481Sgiacomo.travaglini@arm.com EXPECT_EQ('z', foo.Baz("hi", "you")); 16813481Sgiacomo.travaglini@arm.com EXPECT_EQ('a', foo.Baz("hi", "you")); 16913481Sgiacomo.travaglini@arm.com EXPECT_EQ('b', foo.Baz("hi", "me")); 17013481Sgiacomo.travaglini@arm.com} 17113481Sgiacomo.travaglini@arm.com 17213481Sgiacomo.travaglini@arm.com// Tests invoking methods of the same mock object in multiple threads. 17313481Sgiacomo.travaglini@arm.com 17413481Sgiacomo.travaglini@arm.comstruct Helper1Param { 17513481Sgiacomo.travaglini@arm.com MockFoo* mock_foo; 17613481Sgiacomo.travaglini@arm.com int* count; 17713481Sgiacomo.travaglini@arm.com}; 17813481Sgiacomo.travaglini@arm.com 17913481Sgiacomo.travaglini@arm.comvoid Helper1(Helper1Param param) { 18013481Sgiacomo.travaglini@arm.com for (int i = 0; i < kRepeat; i++) { 18113481Sgiacomo.travaglini@arm.com const char ch = param.mock_foo->Baz("a", "b"); 18213481Sgiacomo.travaglini@arm.com if (ch == 'a') { 18313481Sgiacomo.travaglini@arm.com // It was an expected call. 18413481Sgiacomo.travaglini@arm.com (*param.count)++; 18513481Sgiacomo.travaglini@arm.com } else { 18613481Sgiacomo.travaglini@arm.com // It was an excessive call. 18713481Sgiacomo.travaglini@arm.com EXPECT_EQ('\0', ch); 18813481Sgiacomo.travaglini@arm.com } 18913481Sgiacomo.travaglini@arm.com 19013481Sgiacomo.travaglini@arm.com // An unexpected call. 19113481Sgiacomo.travaglini@arm.com EXPECT_EQ('\0', param.mock_foo->Baz("x", "y")) << "Expected failure."; 19213481Sgiacomo.travaglini@arm.com 19313481Sgiacomo.travaglini@arm.com // An uninteresting call. 19413481Sgiacomo.travaglini@arm.com EXPECT_EQ(1, param.mock_foo->Bar(5)); 19513481Sgiacomo.travaglini@arm.com } 19613481Sgiacomo.travaglini@arm.com} 19713481Sgiacomo.travaglini@arm.com 19813481Sgiacomo.travaglini@arm.com// This should generate 3*kRepeat + 1 failures in total. 19913481Sgiacomo.travaglini@arm.comvoid TestConcurrentCallsOnSameObject(Dummy /* dummy */) { 20013481Sgiacomo.travaglini@arm.com MockFoo foo; 20113481Sgiacomo.travaglini@arm.com 20213481Sgiacomo.travaglini@arm.com ON_CALL(foo, Bar(_)) 20313481Sgiacomo.travaglini@arm.com .WillByDefault(Return(1)); 20413481Sgiacomo.travaglini@arm.com EXPECT_CALL(foo, Baz(_, "b")) 20513481Sgiacomo.travaglini@arm.com .Times(kRepeat) 20613481Sgiacomo.travaglini@arm.com .WillRepeatedly(Return('a')); 20713481Sgiacomo.travaglini@arm.com EXPECT_CALL(foo, Baz(_, "c")); // Expected to be unsatisfied. 20813481Sgiacomo.travaglini@arm.com 20913481Sgiacomo.travaglini@arm.com // This chunk of code should generate kRepeat failures about 21013481Sgiacomo.travaglini@arm.com // excessive calls, and 2*kRepeat failures about unexpected calls. 21113481Sgiacomo.travaglini@arm.com int count1 = 0; 21213481Sgiacomo.travaglini@arm.com const Helper1Param param = { &foo, &count1 }; 21313481Sgiacomo.travaglini@arm.com ThreadWithParam<Helper1Param>* const t = 21413481Sgiacomo.travaglini@arm.com new ThreadWithParam<Helper1Param>(Helper1, param, NULL); 21513481Sgiacomo.travaglini@arm.com 21613481Sgiacomo.travaglini@arm.com int count2 = 0; 21713481Sgiacomo.travaglini@arm.com const Helper1Param param2 = { &foo, &count2 }; 21813481Sgiacomo.travaglini@arm.com Helper1(param2); 21913481Sgiacomo.travaglini@arm.com JoinAndDelete(t); 22013481Sgiacomo.travaglini@arm.com 22113481Sgiacomo.travaglini@arm.com EXPECT_EQ(kRepeat, count1 + count2); 22213481Sgiacomo.travaglini@arm.com 22313481Sgiacomo.travaglini@arm.com // foo's destructor should generate one failure about unsatisfied 22413481Sgiacomo.travaglini@arm.com // expectation. 22513481Sgiacomo.travaglini@arm.com} 22613481Sgiacomo.travaglini@arm.com 22713481Sgiacomo.travaglini@arm.com// Tests using the same mock object in multiple threads when the 22813481Sgiacomo.travaglini@arm.com// expectations are partially ordered. 22913481Sgiacomo.travaglini@arm.com 23013481Sgiacomo.travaglini@arm.comvoid Helper2(MockFoo* foo) { 23113481Sgiacomo.travaglini@arm.com for (int i = 0; i < kRepeat; i++) { 23213481Sgiacomo.travaglini@arm.com foo->Bar(2); 23313481Sgiacomo.travaglini@arm.com foo->Bar(3); 23413481Sgiacomo.travaglini@arm.com } 23513481Sgiacomo.travaglini@arm.com} 23613481Sgiacomo.travaglini@arm.com 23713481Sgiacomo.travaglini@arm.com// This should generate no Google Test failures. 23813481Sgiacomo.travaglini@arm.comvoid TestPartiallyOrderedExpectationsWithThreads(Dummy /* dummy */) { 23913481Sgiacomo.travaglini@arm.com MockFoo foo; 24013481Sgiacomo.travaglini@arm.com Sequence s1, s2; 24113481Sgiacomo.travaglini@arm.com 24213481Sgiacomo.travaglini@arm.com { 24313481Sgiacomo.travaglini@arm.com InSequence dummy; 24413481Sgiacomo.travaglini@arm.com EXPECT_CALL(foo, Bar(0)); 24513481Sgiacomo.travaglini@arm.com EXPECT_CALL(foo, Bar(1)) 24613481Sgiacomo.travaglini@arm.com .InSequence(s1, s2); 24713481Sgiacomo.travaglini@arm.com } 24813481Sgiacomo.travaglini@arm.com 24913481Sgiacomo.travaglini@arm.com EXPECT_CALL(foo, Bar(2)) 25013481Sgiacomo.travaglini@arm.com .Times(2*kRepeat) 25113481Sgiacomo.travaglini@arm.com .InSequence(s1) 25213481Sgiacomo.travaglini@arm.com .RetiresOnSaturation(); 25313481Sgiacomo.travaglini@arm.com EXPECT_CALL(foo, Bar(3)) 25413481Sgiacomo.travaglini@arm.com .Times(2*kRepeat) 25513481Sgiacomo.travaglini@arm.com .InSequence(s2); 25613481Sgiacomo.travaglini@arm.com 25713481Sgiacomo.travaglini@arm.com { 25813481Sgiacomo.travaglini@arm.com InSequence dummy; 25913481Sgiacomo.travaglini@arm.com EXPECT_CALL(foo, Bar(2)) 26013481Sgiacomo.travaglini@arm.com .InSequence(s1, s2); 26113481Sgiacomo.travaglini@arm.com EXPECT_CALL(foo, Bar(4)); 26213481Sgiacomo.travaglini@arm.com } 26313481Sgiacomo.travaglini@arm.com 26413481Sgiacomo.travaglini@arm.com foo.Bar(0); 26513481Sgiacomo.travaglini@arm.com foo.Bar(1); 26613481Sgiacomo.travaglini@arm.com 26713481Sgiacomo.travaglini@arm.com ThreadWithParam<MockFoo*>* const t = 26813481Sgiacomo.travaglini@arm.com new ThreadWithParam<MockFoo*>(Helper2, &foo, NULL); 26913481Sgiacomo.travaglini@arm.com Helper2(&foo); 27013481Sgiacomo.travaglini@arm.com JoinAndDelete(t); 27113481Sgiacomo.travaglini@arm.com 27213481Sgiacomo.travaglini@arm.com foo.Bar(2); 27313481Sgiacomo.travaglini@arm.com foo.Bar(4); 27413481Sgiacomo.travaglini@arm.com} 27513481Sgiacomo.travaglini@arm.com 27613481Sgiacomo.travaglini@arm.com// Tests using Google Mock constructs in many threads concurrently. 27713481Sgiacomo.travaglini@arm.comTEST(StressTest, CanUseGMockWithThreads) { 27813481Sgiacomo.travaglini@arm.com void (*test_routines[])(Dummy dummy) = { 27913481Sgiacomo.travaglini@arm.com &TestConcurrentCopyAndReadLinkedPtr, 28013481Sgiacomo.travaglini@arm.com &TestConcurrentWriteToEqualLinkedPtr, 28113481Sgiacomo.travaglini@arm.com &TestConcurrentMockObjects, 28213481Sgiacomo.travaglini@arm.com &TestConcurrentCallsOnSameObject, 28313481Sgiacomo.travaglini@arm.com &TestPartiallyOrderedExpectationsWithThreads, 28413481Sgiacomo.travaglini@arm.com }; 28513481Sgiacomo.travaglini@arm.com 28613481Sgiacomo.travaglini@arm.com const int kRoutines = sizeof(test_routines)/sizeof(test_routines[0]); 28713481Sgiacomo.travaglini@arm.com const int kCopiesOfEachRoutine = kMaxTestThreads / kRoutines; 28813481Sgiacomo.travaglini@arm.com const int kTestThreads = kCopiesOfEachRoutine * kRoutines; 28913481Sgiacomo.travaglini@arm.com ThreadWithParam<Dummy>* threads[kTestThreads] = {}; 29013481Sgiacomo.travaglini@arm.com for (int i = 0; i < kTestThreads; i++) { 29113481Sgiacomo.travaglini@arm.com // Creates a thread to run the test function. 29213481Sgiacomo.travaglini@arm.com threads[i] = 29313481Sgiacomo.travaglini@arm.com new ThreadWithParam<Dummy>(test_routines[i % kRoutines], Dummy(), NULL); 29413481Sgiacomo.travaglini@arm.com GTEST_LOG_(INFO) << "Thread #" << i << " running . . ."; 29513481Sgiacomo.travaglini@arm.com } 29613481Sgiacomo.travaglini@arm.com 29713481Sgiacomo.travaglini@arm.com // At this point, we have many threads running. 29813481Sgiacomo.travaglini@arm.com for (int i = 0; i < kTestThreads; i++) { 29913481Sgiacomo.travaglini@arm.com JoinAndDelete(threads[i]); 30013481Sgiacomo.travaglini@arm.com } 30113481Sgiacomo.travaglini@arm.com 30213481Sgiacomo.travaglini@arm.com // Ensures that the correct number of failures have been reported. 30313481Sgiacomo.travaglini@arm.com const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); 30413481Sgiacomo.travaglini@arm.com const TestResult& result = *info->result(); 30513481Sgiacomo.travaglini@arm.com const int kExpectedFailures = (3*kRepeat + 1)*kCopiesOfEachRoutine; 30613481Sgiacomo.travaglini@arm.com GTEST_CHECK_(kExpectedFailures == result.total_part_count()) 30713481Sgiacomo.travaglini@arm.com << "Expected " << kExpectedFailures << " failures, but got " 30813481Sgiacomo.travaglini@arm.com << result.total_part_count(); 30913481Sgiacomo.travaglini@arm.com} 31013481Sgiacomo.travaglini@arm.com 31113481Sgiacomo.travaglini@arm.com} // namespace 31213481Sgiacomo.travaglini@arm.com} // namespace testing 31313481Sgiacomo.travaglini@arm.com 31413481Sgiacomo.travaglini@arm.comint main(int argc, char **argv) { 31513481Sgiacomo.travaglini@arm.com testing::InitGoogleMock(&argc, argv); 31613481Sgiacomo.travaglini@arm.com 31713481Sgiacomo.travaglini@arm.com const int exit_code = RUN_ALL_TESTS(); // Expected to fail. 31813481Sgiacomo.travaglini@arm.com GTEST_CHECK_(exit_code != 0) << "RUN_ALL_TESTS() did not fail as expected"; 31913481Sgiacomo.travaglini@arm.com 32013481Sgiacomo.travaglini@arm.com printf("\nPASS\n"); 32113481Sgiacomo.travaglini@arm.com return 0; 32213481Sgiacomo.travaglini@arm.com} 323