1 /* 2 $Id: BenaphoreLockCountTest1.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $ 3 4 This file implements a test class for testing BLocker functionality. 5 It tests use cases "Count Lock Requests" for a benaphore style BLocker. 6 7 The test works by: 8 - checking the lock requests 9 - acquiring the lock 10 - checking the lock requests 11 - staring a thread which times out acquiring the lock and then blocks 12 again waiting for the lock 13 - checking the lock requests 14 - start a second thread which times out acquiring the lock and then blocks 15 again waiting for the lock 16 - checking the lock requests 17 - release the lock 18 - each blocked thread acquires the lock, checks the lock requests and releases 19 the lock before terminating 20 - the main thread checks the lock requests one last time 21 22 */ 23 24 25 #include "BenaphoreLockCountTest1.h" 26 27 #include <cppunit/Test.h> 28 #include <cppunit/TestSuite.h> 29 30 #include <Locker.h> 31 32 #include <ThreadedTestCaller.h> 33 34 35 // This constant is used to determine the number of microseconds to 36 // sleep during major steps of the test. 37 38 const bigtime_t SNOOZE_TIME = 100000; 39 40 41 /* 42 * Method: BenaphoreLockCountTest1::BenaphoreLockCountTest1() 43 * Descr: This is the constructor for this test class. 44 */ 45 46 47 BenaphoreLockCountTest1::BenaphoreLockCountTest1(std::string name) : 48 LockerTestCase(name, true) 49 { 50 } 51 52 53 /* 54 * Method: BenaphoreLockCountTest1::~BenaphoreLockTestCountTest1() 55 * Descr: This is the destructor for this test class. 56 */ 57 58 59 BenaphoreLockCountTest1::~BenaphoreLockCountTest1() 60 { 61 } 62 63 64 /* 65 * Method: BenaphoreLockCountTest1::CheckLockRequests() 66 * Descr: This member function checks the actual number of lock requests 67 * that the BLocker thinks are outstanding versus the number 68 * passed in. If they match, true is returned. 69 */ 70 71 bool BenaphoreLockCountTest1::CheckLockRequests(int expected) 72 { 73 int actual = theLocker->CountLockRequests(); 74 return(actual == expected); 75 } 76 77 78 /* 79 * Method: BenaphoreLockCountTest1::TestThread1() 80 * Descr: This member function performs the main portion of the test. 81 * It first acquires thread2Lock and thread3Lock. This ensures 82 * that thread2 and thread3 will block until this thread wants 83 * them to start running. It then checks the lock count, acquires 84 * the lock and checks the lock count again. It unlocks each 85 * of the other two threads in turn and rechecks the lock count. 86 * Finally, it releases the lock and sleeps for a short while 87 * for the other two threads to finish. At the end, it checks 88 * the lock count on final time. 89 */ 90 91 void BenaphoreLockCountTest1::TestThread1(void) 92 { 93 SafetyLock theSafetyLock1(theLocker); 94 SafetyLock theSafetyLock2(&thread2Lock); 95 SafetyLock theSafetyLock3(&thread3Lock); 96 97 CPPUNIT_ASSERT(thread2Lock.Lock()); 98 NextSubTest(); 99 CPPUNIT_ASSERT(thread3Lock.Lock()); 100 NextSubTest(); 101 102 CPPUNIT_ASSERT(CheckLockRequests(0)); 103 NextSubTest(); 104 CPPUNIT_ASSERT(theLocker->Lock()); 105 NextSubTest(); 106 107 CPPUNIT_ASSERT(CheckLockRequests(1)); 108 NextSubTest(); 109 110 thread2Lock.Unlock(); 111 NextSubTest(); 112 snooze(SNOOZE_TIME); 113 NextSubTest(); 114 CPPUNIT_ASSERT(CheckLockRequests(3)); 115 NextSubTest(); 116 117 thread3Lock.Unlock(); 118 NextSubTest(); 119 snooze(SNOOZE_TIME); 120 NextSubTest(); 121 CPPUNIT_ASSERT(CheckLockRequests(5)); 122 NextSubTest(); 123 124 theLocker->Unlock(); 125 NextSubTest(); 126 snooze(SNOOZE_TIME); 127 NextSubTest(); 128 CPPUNIT_ASSERT(CheckLockRequests(2)); 129 NextSubTest(); 130 } 131 132 133 /* 134 * Method: BenaphoreLockCountTest1::TestThread2() 135 * Descr: This member function defines the actions of the second thread of 136 * the test. First it sleeps for a short while and then blocks on 137 * the thread2Lock. When the first thread releases it, this thread 138 * begins its testing. It times out attempting to acquire the main 139 * lock and then blocks to acquire the lock. Once that lock is 140 * acquired, the lock count is checked before finishing this thread. 141 */ 142 143 void BenaphoreLockCountTest1::TestThread2(void) 144 { 145 SafetyLock theSafetyLock1(theLocker); 146 147 snooze(SNOOZE_TIME / 10); 148 NextSubTest(); 149 CPPUNIT_ASSERT(thread2Lock.Lock()); 150 NextSubTest(); 151 152 CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT); 153 NextSubTest(); 154 CPPUNIT_ASSERT(theLocker->Lock()); 155 NextSubTest(); 156 int actual = theLocker->CountLockRequests(); 157 NextSubTest(); 158 CPPUNIT_ASSERT((actual == 3) || (actual == 4)); 159 NextSubTest(); 160 theLocker->Unlock(); 161 NextSubTest(); 162 } 163 164 165 /* 166 * Method: BenaphoreLockCountTest1::TestThread3() 167 * Descr: This member function defines the actions of the second thread of 168 * the test. First it sleeps for a short while and then blocks on 169 * the thread3Lock. When the first thread releases it, this thread 170 * begins its testing. It times out attempting to acquire the main 171 * lock and then blocks to acquire the lock. Once that lock is 172 * acquired, the lock count is checked before finishing this thread. 173 */ 174 175 void BenaphoreLockCountTest1::TestThread3(void) 176 { 177 SafetyLock theSafetyLock1(theLocker); 178 179 snooze(SNOOZE_TIME / 10); 180 NextSubTest(); 181 CPPUNIT_ASSERT(thread3Lock.Lock()); 182 NextSubTest(); 183 184 CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT); 185 NextSubTest(); 186 CPPUNIT_ASSERT(theLocker->Lock()); 187 NextSubTest(); 188 int actual = theLocker->CountLockRequests(); 189 NextSubTest(); 190 CPPUNIT_ASSERT((actual == 3) || (actual == 4)); 191 NextSubTest(); 192 theLocker->Unlock(); 193 NextSubTest(); 194 } 195 196 197 /* 198 * Method: BenaphoreLockCountTest1::suite() 199 * Descr: This static member function returns a test caller for performing 200 * the "BenaphoreLockCountTest1" test. The test caller 201 * is created as a ThreadedTestCaller (typedef'd as 202 * BenaphoreLockCountTest1Caller) with three independent threads. 203 */ 204 205 CppUnit::Test *BenaphoreLockCountTest1::suite(void) 206 { 207 BenaphoreLockCountTest1 *theTest = new BenaphoreLockCountTest1(""); 208 BThreadedTestCaller<BenaphoreLockCountTest1> *threadedTest = 209 new BThreadedTestCaller<BenaphoreLockCountTest1>("BLocker::Benaphore Lock Count Test #1", theTest); 210 threadedTest->addThread("A", &BenaphoreLockCountTest1::TestThread1); 211 threadedTest->addThread("B", &BenaphoreLockCountTest1::TestThread2); 212 threadedTest->addThread("C", &BenaphoreLockCountTest1::TestThread3); 213 return(threadedTest); 214 } 215 216