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
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
SemaphoreLockCountTest1(std::string name)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
~SemaphoreLockCountTest1()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
CheckLockRequests(int expected)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
TestThread1(void)87 void 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
TestThread2(void)131 void 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
TestThread3(void)158 void 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
suite(void)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