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