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