xref: /haiku/src/tests/kits/support/blocker/BenaphoreLockCountTest1.cpp (revision 239222b2369c39dc52df52b0a7cdd6cc0a91bc92)
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