1 //------------------------------------------------------------------------------
2 // LockTargetTester.cpp
3 //
4 //------------------------------------------------------------------------------
5
6 // Standard Includes -----------------------------------------------------------
7 #include <stdio.h>
8
9 // System Includes -------------------------------------------------------------
10 #include <Message.h>
11 #include <OS.h>
12
13 #include <Handler.h>
14 #include <Looper.h>
15 #include <Messenger.h>
16
17 // Project Includes ------------------------------------------------------------
18 #include <TestUtils.h>
19 #include <ThreadedTestCaller.h>
20 #include <cppunit/TestSuite.h>
21
22 // Local Includes --------------------------------------------------------------
23 #include "Helpers.h"
24 #include "LockTargetTester.h"
25 #include "SMTarget.h"
26
27 // Local Defines ---------------------------------------------------------------
28
29 // Globals ---------------------------------------------------------------------
30
31 //------------------------------------------------------------------------------
32
33 // constructor
LockTargetTester()34 LockTargetTester::LockTargetTester()
35 : BThreadedTestCase(),
36 fHandler(NULL),
37 fLooper(NULL)
38 {
39 }
40
41 // constructor
LockTargetTester(std::string name)42 LockTargetTester::LockTargetTester(std::string name)
43 : BThreadedTestCase(name),
44 fHandler(NULL),
45 fLooper(NULL)
46 {
47 }
48
49 // destructor
~LockTargetTester()50 LockTargetTester::~LockTargetTester()
51 {
52 if (fLooper) {
53 fLooper->Lock();
54 if (fHandler) {
55 fLooper->RemoveHandler(fHandler);
56 delete fHandler;
57 }
58 fLooper->Quit();
59 }
60 }
61
62 /*
63 bool LockTarget() const
64 @case 1 this is uninitialized
65 @results should return false.
66 */
LockTargetTest1()67 void LockTargetTester::LockTargetTest1()
68 {
69 BMessenger messenger;
70 CHK(messenger.LockTarget() == false);
71 }
72
73 /*
74 bool LockTarget() const
75 @case 2 this is initialized to local target with preferred handler,
76 looper is not locked
77 @results should lock the looper and return true.
78 */
LockTargetTest2()79 void LockTargetTester::LockTargetTest2()
80 {
81 status_t result = B_OK;
82 BLooper *looper = new BLooper;
83 looper->Run();
84 LooperQuitter quitter(looper);
85 BMessenger messenger(NULL, looper, &result);
86 CHK(messenger.LockTarget() == true);
87 CHK(looper->IsLocked() == true);
88 looper->Unlock();
89 CHK(looper->IsLocked() == false);
90 }
91
92 /*
93 bool LockTarget() const
94 @case 3 this is initialized to local target with specific handler,
95 looper is not locked
96 @results should lock the looper and return true.
97 */
LockTargetTest3()98 void LockTargetTester::LockTargetTest3()
99 {
100 // create looper and handler
101 status_t result = B_OK;
102 BLooper *looper = new BLooper;
103 looper->Run();
104 LooperQuitter quitter(looper);
105 BHandler *handler = new BHandler;
106 HandlerDeleter deleter(handler);
107 CHK(looper->Lock());
108 looper->AddHandler(handler);
109 looper->Unlock();
110 // create the messenger and do the checks
111 BMessenger messenger(handler, NULL, &result);
112 CHK(messenger.LockTarget() == true);
113 CHK(looper->IsLocked() == true);
114 looper->Unlock();
115 CHK(looper->IsLocked() == false);
116 }
117
118 /*
119 bool LockTarget() const
120 @case 4 this is initialized to local target with preferred handler,
121 looper is locked by another thread
122 @results should block until the looper is unlocked, lock it and
123 return true.
124 @thread A - locks the looper
125 - waits 100ms
126 - unlocks the looper
127 */
LockTargetTest4A()128 void LockTargetTester::LockTargetTest4A()
129 {
130 CHK(fLooper->Lock() == true);
131 snooze(100000);
132 fLooper->Unlock();
133 }
134
135 /*
136 bool LockTarget() const
137 @case 4 this is initialized to local target with preferred handler,
138 looper is locked by another thread
139 @results should block until the looper is unlocked, lock it and
140 return true.
141 @thread B - waits 50ms (until thread A has acquired the looper lock)
142 - tries to lock the looper via messenger and blocks
143 - acquires the lock successfully after 50ms
144 - unlocks the looper
145 */
LockTargetTest4B()146 void LockTargetTester::LockTargetTest4B()
147 {
148 enum { JITTER = 10000 }; // Maybe critical on slow machines.
149 snooze(50000);
150 BMessenger messenger(NULL, fLooper);
151 bigtime_t time = system_time();
152 CHK(messenger.LockTarget() == true);
153 time = system_time() - time - 50000;
154 CHK(fLooper->IsLocked() == true);
155 fLooper->Unlock();
156 CHK(fLooper->IsLocked() == false);
157 CHK(time > -JITTER && time < JITTER);
158 }
159
160 /*
161 bool LockTarget() const
162 @case 5 this is initialized to local target with specific handler,
163 looper is locked by another thread
164 @results should block until the looper is unlocked, lock it and
165 return true.
166 @thread A - locks the looper
167 - waits 100ms
168 - unlocks the looper
169 */
LockTargetTest5A()170 void LockTargetTester::LockTargetTest5A()
171 {
172 CHK(fLooper->Lock() == true);
173 snooze(100000);
174 fLooper->Unlock();
175 }
176
177 /*
178 bool LockTarget() const
179 @case 5 this is initialized to local target with specific handler,
180 looper is locked by another thread
181 @results should block until the looper is unlocked, lock it and
182 return true.
183 @thread B - waits 50ms (until thread A has acquired the looper lock)
184 - tries to lock the looper via messenger and blocks
185 - acquires the lock successfully after 50ms
186 - unlocks the looper
187 */
LockTargetTest5B()188 void LockTargetTester::LockTargetTest5B()
189 {
190 enum { JITTER = 10000 }; // Maybe critical on slow machines.
191 snooze(50000);
192 BMessenger messenger(fHandler, NULL);
193 bigtime_t time = system_time();
194 CHK(messenger.LockTarget() == true);
195 time = system_time() - time - 50000;
196 CHK(fLooper->IsLocked() == true);
197 fLooper->Unlock();
198 CHK(fLooper->IsLocked() == false);
199 CHK(time > -JITTER && time < JITTER);
200 }
201
202 /*
203 bool LockTarget() const
204 @case 6 this is initialized to remote target with preferred
205 handler, looper is not locked
206 @results should not lock the looper and return false.
207 */
LockTargetTest6()208 void LockTargetTester::LockTargetTest6()
209 {
210 RemoteSMTarget target(true);
211 BMessenger messenger(target.Messenger());
212 CHK(messenger.LockTarget() == false);
213 }
214
215 /*
216 bool LockTarget() const
217 @case 7 this is initialized to remote target with specific handler,
218 looper is not locked
219 @results should not lock the looper and return false.
220 */
LockTargetTest7()221 void LockTargetTester::LockTargetTest7()
222 {
223 RemoteSMTarget target(false);
224 BMessenger messenger(target.Messenger());
225 CHK(messenger.LockTarget() == false);
226 }
227
228
Suite()229 Test* LockTargetTester::Suite()
230 {
231 typedef BThreadedTestCaller<LockTargetTester> TC;
232
233 TestSuite* testSuite = new TestSuite;
234
235 ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest1);
236 ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest2);
237 ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest3);
238 // test4
239 LockTargetTester *test4
240 = new LockTargetTester("LockTargetTest4");
241 test4->fLooper = new BLooper;
242 test4->fLooper->Run();
243 // test4 test caller
244 TC *caller4 = new TC("BMessenger::LockTargetTest4", test4);
245 caller4->addThread("A", &LockTargetTester::LockTargetTest4A);
246 caller4->addThread("B", &LockTargetTester::LockTargetTest4B);
247 testSuite->addTest(caller4);
248 // test5
249 LockTargetTester *test5
250 = new LockTargetTester("LockTargetTest5");
251 // create looper and handler
252 test5->fLooper = new BLooper;
253 test5->fLooper->Run();
254 test5->fHandler = new BHandler;
255 if (test5->fLooper->Lock()) {
256 test5->fLooper->AddHandler(test5->fHandler);
257 test5->fLooper->Unlock();
258 } else
259 printf("ERROR: Can't init LockTargetTester test5!\n");
260 // test5 test caller
261 TC *caller5 = new TC("BMessenger::LockTargetTest5", test5);
262 caller5->addThread("A", &LockTargetTester::LockTargetTest5A);
263 caller5->addThread("B", &LockTargetTester::LockTargetTest5B);
264 testSuite->addTest(caller5);
265 // tests 6-7
266 ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest6);
267 ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest7);
268
269 return testSuite;
270 }
271
272
273