1/* 2 $Id: SemaphoreLockCountTest1.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 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 34const 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 67bool 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 87void SemaphoreLockCountTest1::TestThread1(void) 88{ 89 SafetyLock theSafetyLock1(theLocker); 90 SafetyLock theSafetyLock2(&thread2Lock); 91 SafetyLock theSafetyLock3(&thread3Lock); 92 93 NextSubTest(); 94 CPPUNIT_ASSERT(thread2Lock.Lock()); 95 CPPUNIT_ASSERT(thread3Lock.Lock()); 96 97 NextSubTest(); 98 CPPUNIT_ASSERT(CheckLockRequests(1)); 99 CPPUNIT_ASSERT(theLocker->Lock()); 100 101 NextSubTest(); 102 CPPUNIT_ASSERT(CheckLockRequests(2)); 103 104 NextSubTest(); 105 thread2Lock.Unlock(); 106 snooze(SNOOZE_TIME); 107 CPPUNIT_ASSERT(CheckLockRequests(4)); 108 109 NextSubTest(); 110 thread3Lock.Unlock(); 111 snooze(SNOOZE_TIME); 112 CPPUNIT_ASSERT(CheckLockRequests(6)); 113 114 NextSubTest(); 115 theLocker->Unlock(); 116 snooze(SNOOZE_TIME); 117 CPPUNIT_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 131void SemaphoreLockCountTest1::TestThread2(void) 132{ 133 SafetyLock theSafetyLock1(theLocker); 134 135 NextSubTest(); 136 snooze(SNOOZE_TIME / 10); 137 CPPUNIT_ASSERT(thread2Lock.Lock()); 138 139 NextSubTest(); 140 CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT); 141 CPPUNIT_ASSERT(theLocker->Lock()); 142 int actual = theLocker->CountLockRequests(); 143 CPPUNIT_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 158void SemaphoreLockCountTest1::TestThread3(void) 159{ 160 SafetyLock theSafetyLock1(theLocker); 161 162 NextSubTest(); 163 snooze(SNOOZE_TIME / 10); 164 CPPUNIT_ASSERT(thread3Lock.Lock()); 165 166 NextSubTest(); 167 CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT); 168 CPPUNIT_ASSERT(theLocker->Lock()); 169 int actual = theLocker->CountLockRequests(); 170 CPPUNIT_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 183CppUnit::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