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