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
LockTargetWithTimeoutTester()33 LockTargetWithTimeoutTester::LockTargetWithTimeoutTester()
34 : BThreadedTestCase(),
35 fHandler(NULL),
36 fLooper(NULL)
37 {
38 }
39
40 // constructor
LockTargetWithTimeoutTester(std::string name)41 LockTargetWithTimeoutTester::LockTargetWithTimeoutTester(std::string name)
42 : BThreadedTestCase(name),
43 fHandler(NULL),
44 fLooper(NULL)
45 {
46 }
47
48 // destructor
~LockTargetWithTimeoutTester()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 */
LockTargetWithTimeoutTest1()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 */
LockTargetWithTimeoutTest2()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 */
LockTargetWithTimeoutTest3()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 */
LockTargetWithTimeoutTest4A()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 */
LockTargetWithTimeoutTest4B()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 */
LockTargetWithTimeoutTest5A()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 */
LockTargetWithTimeoutTest5B()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 */
LockTargetWithTimeoutTest6A()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 */
LockTargetWithTimeoutTest6B()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 */
LockTargetWithTimeoutTest7A()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 */
LockTargetWithTimeoutTest7B()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 */
LockTargetWithTimeoutTest8()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 */
LockTargetWithTimeoutTest9()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
Suite()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