xref: /haiku/src/tests/kits/app/bmessenger/LockTargetWithTimeoutTester.cpp (revision 5d9e40fe9252c8f9c5e5e41594545bfa4419fcc7)
1 //------------------------------------------------------------------------------
2 //	LockTargetWithTimeoutTester.cpp
3 //
4 //------------------------------------------------------------------------------
5 
6 // Standard Includes -----------------------------------------------------------
7 #include <stdio.h>
8 
9 // System Includes -------------------------------------------------------------
10 #include <Message.h>
11 #include <OS.h>
12 #include <Handler.h>
13 #include <Looper.h>
14 #include <Messenger.h>
15 
16 // Project Includes ------------------------------------------------------------
17 #include <TestUtils.h>
18 #include <ThreadedTestCaller.h>
19 #include <cppunit/TestSuite.h>
20 
21 // Local Includes --------------------------------------------------------------
22 #include "Helpers.h"
23 #include "LockTargetWithTimeoutTester.h"
24 #include "SMTarget.h"
25 
26 // Local Defines ---------------------------------------------------------------
27 
28 // Globals ---------------------------------------------------------------------
29 
30 //------------------------------------------------------------------------------
31 
32 // constructor
33 LockTargetWithTimeoutTester::LockTargetWithTimeoutTester()
34 	: BThreadedTestCase(),
35 	  fHandler(NULL),
36 	  fLooper(NULL)
37 {
38 }
39 
40 // constructor
41 LockTargetWithTimeoutTester::LockTargetWithTimeoutTester(std::string name)
42 	: BThreadedTestCase(name),
43 	  fHandler(NULL),
44 	  fLooper(NULL)
45 {
46 }
47 
48 // destructor
49 LockTargetWithTimeoutTester::~LockTargetWithTimeoutTester()
50 {
51 	if (fLooper) {
52 		fLooper->Lock();
53 		if (fHandler) {
54 			fLooper->RemoveHandler(fHandler);
55 			delete fHandler;
56 		}
57 		fLooper->Quit();
58 	}
59 }
60 
61 /*
62 	status_t LockTargetWithTimeout(bigtime_t timeout) const
63 	@case 1			this is uninitialized
64 	@results		should return B_BAD_VALUE.
65  */
66 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest1()
67 {
68 	BMessenger messenger;
69 	CHK(messenger.LockTargetWithTimeout(0) == B_BAD_VALUE);
70 }
71 
72 /*
73 	status_t LockTargetWithTimeout(bigtime_t timeout) const
74 	@case 2			this is initialized to local target with preferred handler,
75 					looper is not locked
76 	@results		should lock the looper and return B_OK.
77  */
78 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest2()
79 {
80 	status_t result = B_OK;
81 	BLooper *looper = new BLooper;
82 	looper->Run();
83 	LooperQuitter quitter(looper);
84 	BMessenger messenger(NULL, looper, &result);
85 	CHK(messenger.LockTargetWithTimeout(0) == B_OK);
86 	CHK(looper->IsLocked() == true);
87 	looper->Unlock();
88 	CHK(looper->IsLocked() == false);
89 }
90 
91 /*
92 	status_t LockTargetWithTimeout(bigtime_t timeout) const
93 	@case 3			this is initialized to local target with specific handler,
94 					looper is not locked
95 	@results		should lock the looper and return B_OK.
96  */
97 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest3()
98 {
99 	// create looper and handler
100 	status_t result = B_OK;
101 	BLooper *looper = new BLooper;
102 	looper->Run();
103 	LooperQuitter quitter(looper);
104 	BHandler *handler = new BHandler;
105 	HandlerDeleter deleter(handler);
106 	CHK(looper->Lock());
107 	looper->AddHandler(handler);
108 	looper->Unlock();
109 	// create the messenger and do the checks
110 	BMessenger messenger(handler, NULL, &result);
111 	CHK(messenger.LockTargetWithTimeout(0) == B_OK);
112 	CHK(looper->IsLocked() == true);
113 	looper->Unlock();
114 	CHK(looper->IsLocked() == false);
115 }
116 
117 /*
118 	status_t LockTargetWithTimeout(bigtime_t timeout) const
119 	@case 4			this is initialized to local target with preferred handler,
120 					looper is locked by another thread, timeout is 100ms
121 	@results		should block until the looper is unlocked (after 50ms),
122 					lock it and return B_OK.
123 	@thread A		- locks the looper
124 					- waits 100ms
125 					- unlocks the looper
126  */
127 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest4A()
128 {
129 	CHK(fLooper->Lock() == true);
130 	snooze(100000);
131 	fLooper->Unlock();
132 }
133 
134 /*
135 	status_t LockTargetWithTimeout(bigtime_t timeout) const
136 	@case 4			this is initialized to local target with preferred handler,
137 					looper is locked by another thread, timeout is 100ms
138 	@results		should block until the looper is unlocked (after 50ms),
139 					lock it and return B_OK.
140 	@thread B		- waits 50ms (until thread A has acquired the looper lock)
141 					- tries to lock the looper via messenger and blocks
142 					- acquires the lock successfully after 50ms
143 					- unlocks the looper
144  */
145 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest4B()
146 {
147 	enum { JITTER = 10000 };	// Maybe critical on slow machines.
148 	snooze(50000);
149 	BMessenger messenger(NULL, fLooper);
150 	bigtime_t time = system_time();
151 	CHK(messenger.LockTargetWithTimeout(100000) == B_OK);
152 	time = system_time() - time - 50000;
153 	CHK(fLooper->IsLocked() == true);
154 	fLooper->Unlock();
155 	CHK(fLooper->IsLocked() == false);
156 	CHK(time > -JITTER && time < JITTER);
157 }
158 
159 /*
160 	status_t LockTargetWithTimeout(bigtime_t timeout) const
161 	@case 5			this is initialized to local target with preferred handler,
162 					looper is locked by another thread, timeout is 25ms
163 	@results		should block for 25ms, not until the looper is unlocked
164 					(after 50ms), should return B_TIMED_OUT.
165 	@thread A		- locks the looper
166 					- waits 100ms
167 					- unlocks the looper
168  */
169 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest5A()
170 {
171 	CHK(fLooper->Lock() == true);
172 	snooze(100000);
173 	fLooper->Unlock();
174 }
175 
176 /*
177 	status_t LockTargetWithTimeout(bigtime_t timeout) const
178 	@case 5			this is initialized to local target with preferred handler,
179 					looper is locked by another thread, timeout is 25ms
180 	@results		should block for 25ms, not until the looper is unlocked
181 					(after 50ms), should return B_TIMED_OUT.
182 	@thread B		- waits 50ms (until thread A has acquired the looper lock)
183 					- tries to lock the looper via messenger and blocks
184 					- times out after 25ms
185  */
186 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest5B()
187 {
188 	enum { JITTER = 10000 };	// Maybe critical on slow machines.
189 	snooze(50000);
190 	BMessenger messenger(NULL, fLooper);
191 	bigtime_t time = system_time();
192 	CHK(messenger.LockTargetWithTimeout(25000) == B_TIMED_OUT);
193 	time = system_time() - time - 25000;
194 	CHK(fLooper->IsLocked() == false);
195 	CHK(time > -JITTER && time < JITTER);
196 }
197 
198 /*
199 	status_t LockTargetWithTimeout(bigtime_t timeout) const
200 	@case 6			this is initialized to local target with specific handler,
201 					looper is locked by another thread, timeout is 100ms
202 	@results		should block until the looper is unlocked (after 50ms),
203 					lock it and return B_OK.
204 	@thread A		- locks the looper
205 					- waits 100ms
206 					- unlocks the looper
207  */
208 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest6A()
209 {
210 	CHK(fLooper->Lock() == true);
211 	snooze(100000);
212 	fLooper->Unlock();
213 }
214 
215 /*
216 	status_t LockTargetWithTimeout(bigtime_t timeout) const
217 	@case 6			this is initialized to local target with specific handler,
218 					looper is locked by another thread, timeout is 100ms
219 	@results		should block until the looper is unlocked (after 50ms),
220 					lock it and return B_OK.
221 	@thread B		- waits 50ms (until thread A has acquired the looper lock)
222 					- tries to lock the looper via messenger and blocks
223 					- acquires the lock successfully after 50ms
224 					- unlocks the looper
225  */
226 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest6B()
227 {
228 	enum { JITTER = 10000 };	// Maybe critical on slow machines.
229 	snooze(50000);
230 	BMessenger messenger(fHandler, NULL);
231 	bigtime_t time = system_time();
232 	CHK(messenger.LockTargetWithTimeout(100000) == B_OK);
233 	time = system_time() - time - 50000;
234 	CHK(fLooper->IsLocked() == true);
235 	fLooper->Unlock();
236 	CHK(fLooper->IsLocked() == false);
237 	CHK(time > -JITTER && time < JITTER);
238 }
239 
240 /*
241 	status_t LockTargetWithTimeout(bigtime_t timeout) const
242 	@case 7			this is initialized to local target with specific handler,
243 					looper is locked by another thread, timeout is 25ms
244 	@results		should block for 25ms, not until the looper is unlocked
245 					(after 50ms), should return B_TIMED_OUT.
246 	@thread A		- locks the looper
247 					- waits 100ms
248 					- unlocks the looper
249  */
250 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest7A()
251 {
252 	CHK(fLooper->Lock() == true);
253 	snooze(100000);
254 	fLooper->Unlock();
255 }
256 
257 /*
258 	status_t LockTargetWithTimeout(bigtime_t timeout) const
259 	@case 7			this is initialized to local target with specific handler,
260 					looper is locked by another thread, timeout is 25ms
261 	@results		should block for 25ms, not until the looper is unlocked
262 					(after 50ms), should return B_TIMED_OUT.
263 	@thread B		- waits 50ms (until thread A has acquired the looper lock)
264 					- tries to lock the looper via messenger and blocks
265 					- times out after 25ms
266  */
267 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest7B()
268 {
269 	enum { JITTER = 10000 };	// Maybe critical on slow machines.
270 	snooze(50000);
271 	BMessenger messenger(fHandler, NULL);
272 	bigtime_t time = system_time();
273 	CHK(messenger.LockTargetWithTimeout(25000) == B_TIMED_OUT);
274 	time = system_time() - time - 25000;
275 	CHK(fLooper->IsLocked() == false);
276 	CHK(time > -JITTER && time < JITTER);
277 }
278 
279 /*
280 	status_t LockTargetWithTimeout(bigtime_t timeout) const
281 	@case 8			this is initialized to remote target with preferred
282 					handler, looper is not locked
283 	@results		should not lock the looper and return B_BAD_VALUE.
284  */
285 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest8()
286 {
287 	RemoteSMTarget target(true);
288 	BMessenger messenger(target.Messenger());
289 	CHK(messenger.LockTargetWithTimeout(10000) == B_BAD_VALUE);
290 }
291 
292 /*
293 	status_t LockTargetWithTimeout(bigtime_t timeout) const
294 	@case 9			this is initialized to remote target with specific handler,
295 					looper is not locked
296 	@results		should not lock the looper and return B_BAD_VALUE.
297  */
298 void LockTargetWithTimeoutTester::LockTargetWithTimeoutTest9()
299 {
300 	RemoteSMTarget target(false);
301 	BMessenger messenger(target.Messenger());
302 	CHK(messenger.LockTargetWithTimeout(10000) == B_BAD_VALUE);
303 }
304 
305 
306 Test* LockTargetWithTimeoutTester::Suite()
307 {
308 	typedef BThreadedTestCaller<LockTargetWithTimeoutTester> TC;
309 
310 	TestSuite* testSuite = new TestSuite;
311 
312 	ADD_TEST4(BMessenger, testSuite, LockTargetWithTimeoutTester,
313 			 LockTargetWithTimeoutTest1);
314 	ADD_TEST4(BMessenger, testSuite, LockTargetWithTimeoutTester,
315 			 LockTargetWithTimeoutTest2);
316 	ADD_TEST4(BMessenger, testSuite, LockTargetWithTimeoutTester,
317 			 LockTargetWithTimeoutTest3);
318 	// test4
319 	LockTargetWithTimeoutTester *test4
320 		= new LockTargetWithTimeoutTester("LockTargetWithTimeoutTest4");
321 	test4->fLooper = new BLooper;
322 	test4->fLooper->Run();
323 	// test4 test caller
324 	TC *caller4 = new TC("BMessenger::LockTargetWithTimeoutTest4", test4);
325 	caller4->addThread("A",
326 		&LockTargetWithTimeoutTester::LockTargetWithTimeoutTest4A);
327 	caller4->addThread("B",
328 		&LockTargetWithTimeoutTester::LockTargetWithTimeoutTest4B);
329 	testSuite->addTest(caller4);
330 	// test5
331 	LockTargetWithTimeoutTester *test5
332 		= new LockTargetWithTimeoutTester("LockTargetWithTimeoutTest5");
333 	test5->fLooper = new BLooper;
334 	test5->fLooper->Run();
335 	// test5 test caller
336 	TC *caller5 = new TC("BMessenger::LockTargetWithTimeoutTest5", test5);
337 	caller5->addThread("A",
338 		&LockTargetWithTimeoutTester::LockTargetWithTimeoutTest5A);
339 	caller5->addThread("B",
340 		&LockTargetWithTimeoutTester::LockTargetWithTimeoutTest5B);
341 	testSuite->addTest(caller5);
342 	// test6
343 	LockTargetWithTimeoutTester *test6
344 		= new LockTargetWithTimeoutTester("LockTargetWithTimeoutTest6");
345 	// create looper and handler
346 	test6->fLooper = new BLooper;
347 	test6->fLooper->Run();
348 	test6->fHandler = new BHandler;
349 	if (test6->fLooper->Lock()) {
350 		test6->fLooper->AddHandler(test6->fHandler);
351 		test6->fLooper->Unlock();
352 	} else
353 		printf("ERROR: Can't init LockTargetWithTimeoutTester test6!\n");
354 	// test6 test caller
355 	TC *caller6 = new TC("BMessenger::LockTargetWithTimeoutTest6", test6);
356 	caller6->addThread("A",
357 		&LockTargetWithTimeoutTester::LockTargetWithTimeoutTest6A);
358 	caller6->addThread("B",
359 		&LockTargetWithTimeoutTester::LockTargetWithTimeoutTest6B);
360 	testSuite->addTest(caller6);
361 	// test7
362 	LockTargetWithTimeoutTester *test7
363 		= new LockTargetWithTimeoutTester("LockTargetWithTimeoutTest7");
364 	// create looper and handler
365 	test7->fLooper = new BLooper;
366 	test7->fLooper->Run();
367 	test7->fHandler = new BHandler;
368 	if (test7->fLooper->Lock()) {
369 		test7->fLooper->AddHandler(test7->fHandler);
370 		test7->fLooper->Unlock();
371 	} else
372 		printf("ERROR: Can't init LockTargetWithTimeoutTester test7!\n");
373 	// test7 test caller
374 	TC *caller7 = new TC("BMessenger::LockTargetWithTimeoutTest7", test7);
375 	caller7->addThread("A",
376 		&LockTargetWithTimeoutTester::LockTargetWithTimeoutTest7A);
377 	caller7->addThread("B",
378 		&LockTargetWithTimeoutTester::LockTargetWithTimeoutTest7B);
379 	testSuite->addTest(caller7);
380 	// tests 8-9
381 	ADD_TEST4(BMessenger, testSuite, LockTargetWithTimeoutTester,
382 			 LockTargetWithTimeoutTest8);
383 	ADD_TEST4(BMessenger, testSuite, LockTargetWithTimeoutTester,
384 			 LockTargetWithTimeoutTest9);
385 
386 	return testSuite;
387 }
388 
389 
390