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