xref: /haiku/src/tests/kits/app/bmessenger/LockTargetTester.cpp (revision 76a5f3484abd9a293483b45f40455c0b58e6f3f0)
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