xref: /haiku/src/tests/kits/app/bmessenger/MessengerComparissonTester.cpp (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
1 //------------------------------------------------------------------------------
2 //	MessengerComparissonTester.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 "MessengerComparissonTester.h"
25 #include "SMTarget.h"
26 
27 // Local Defines ---------------------------------------------------------------
28 
29 // Globals ---------------------------------------------------------------------
30 
31 //------------------------------------------------------------------------------
32 
33 struct FakeMessenger {
34 	port_id	fPort;
35 	int32	fHandlerToken;
36 	team_id	fTeam;
37 	int32	extra0;
38 	int32	extra1;
39 	bool	fPreferredTarget;
40 	bool	extra2;
41 	bool	extra3;
42 	bool	extra4;
43 };
44 
45 static
46 bool
47 operator<(const FakeMessenger& a, const FakeMessenger& b)
48 {
49 	// significance:
50 	// * fPort
51 	// * fHandlerToken
52 	// * fPreferredTarget
53 	// fTeam is insignificant
54 	return (a.fPort < b.fPort
55 			|| a.fPort == b.fPort
56 				&& (a.fHandlerToken < b.fHandlerToken
57 					|| a.fHandlerToken == b.fHandlerToken
58 						&& !a.fPreferredTarget && b.fPreferredTarget));
59 }
60 
61 static
62 bool
63 operator!=(const FakeMessenger& a, const FakeMessenger& b)
64 {
65 	return (a < b || b < a);
66 }
67 
68 static
69 bool
70 operator==(const FakeMessenger& a, const FakeMessenger& b)
71 {
72 	return !(a != b);
73 }
74 
75 // constructor
76 MessengerComparissonTester::MessengerComparissonTester()
77 	: BThreadedTestCase(),
78 	  fHandler(NULL),
79 	  fLooper(NULL)
80 {
81 }
82 
83 // constructor
84 MessengerComparissonTester::MessengerComparissonTester(std::string name)
85 	: BThreadedTestCase(name),
86 	  fHandler(NULL),
87 	  fLooper(NULL)
88 {
89 }
90 
91 // destructor
92 MessengerComparissonTester::~MessengerComparissonTester()
93 {
94 	if (fLooper) {
95 		fLooper->Lock();
96 		if (fHandler) {
97 			fLooper->RemoveHandler(fHandler);
98 			delete fHandler;
99 		}
100 		fLooper->Quit();
101 	}
102 }
103 
104 /*
105 	bool operator==(const BMessenger &other) const
106 	bool operator!=(const BMessenger &a, const BMessenger &b)
107 	@case 1			this (a) and other (b) are uninitialized
108 	@results		should return true/false.
109  */
110 void MessengerComparissonTester::ComparissonTest1()
111 {
112 	BMessenger a;
113 	BMessenger b;
114 	CHK(a == b);
115 	CHK(b == a);
116 	CHK(!(a != b));
117 	CHK(!(b != a));
118 }
119 
120 /*
121 	bool operator==(const BMessenger &other) const
122 	bool operator!=(const BMessenger &a, const BMessenger &b)
123 	@case 1			this (a) is initialized, other (b) is uninitialized,
124 					and vice versa
125 	@results		should return false/true.
126  */
127 void MessengerComparissonTester::ComparissonTest2()
128 {
129 	// create looper
130 	BLooper *looper = new BLooper;
131 	looper->Run();
132 	LooperQuitter quitter(looper);
133 	// create messenger
134 	BMessenger a(NULL, looper);
135 	BMessenger b;
136 	CHK(a != b);
137 	CHK(b != a);
138 	CHK(!(a == b));
139 	CHK(!(b == a));
140 }
141 
142 /*
143 	bool operator==(const BMessenger &other) const
144 	bool operator!=(const BMessenger &a, const BMessenger &b)
145 	bool operator<(const BMessenger &a, const BMessenger &b)
146 	@case 3			this and other are initialized, different cases:
147 					- same object => true
148 					- different objects same target => true
149 					- looper preferred handler vs. same looper but the looper
150 					  itself as handler => false
151 					- looper preferred handler vs. other looper preferred
152 					  handler => false
153 					- looper preferred handler vs. other looper specific
154 					  handler => false
155 					- local looper vs. remote looper => false
156  */
157 void MessengerComparissonTester::ComparissonTest3()
158 {
159 	// messenger1: looper and handler
160 	BLooper *looper1 = new BLooper;
161 	looper1->Run();
162 	LooperQuitter quitter1(looper1);
163 	BHandler *handler1 = new BHandler;
164 	HandlerDeleter deleter1(handler1);
165 	CHK(looper1->Lock());
166 	looper1->AddHandler(handler1);
167 	looper1->Unlock();
168 	BMessenger messenger1(handler1, looper1);
169 	BMessenger messenger1a(handler1, looper1);
170 	// messenger2: looper (1)
171 	BMessenger messenger2(NULL, looper1);
172 	BMessenger messenger2a(NULL, looper1);
173 	// messenger3: looper and handler
174 	BLooper *looper2 = new BLooper;
175 	looper2->Run();
176 	LooperQuitter quitter2(looper2);
177 	BHandler *handler2 = new BHandler;
178 	HandlerDeleter deleter2(handler2);
179 	CHK(looper2->Lock());
180 	looper2->AddHandler(handler2);
181 	looper2->Unlock();
182 	BMessenger messenger3(handler2, looper2);
183 	BMessenger messenger3a(handler2, looper2);
184 	// messenger4: looper (2)
185 	BMessenger messenger4(NULL, looper2);
186 	BMessenger messenger4a(NULL, looper2);
187 	// remote targets
188 	RemoteSMTarget remoteTarget1(false);
189 	RemoteSMTarget remoteTarget2(true);
190 	BMessenger messenger5(remoteTarget1.Messenger());
191 	BMessenger messenger5a(remoteTarget1.Messenger());
192 	BMessenger messenger6(remoteTarget2.Messenger());
193 	BMessenger messenger6a(remoteTarget2.Messenger());
194 
195 	// targets -- test data
196 	struct target {
197 		BMessenger	&messenger;
198 		int32		id;			// identifies the target
199 	} targets[] = {
200 		{ messenger1,	1 },
201 		{ messenger1a,	1 },
202 		{ messenger2,	2 },
203 		{ messenger2,	2 },
204 		{ messenger3,	3 },
205 		{ messenger3a,	3 },
206 		{ messenger4,	4 },
207 		{ messenger4a,	4 },
208 		{ messenger5,	5 },
209 		{ messenger5a,	5 },
210 		{ messenger6,	6 },
211 		{ messenger6a,	6 },
212 	};
213 	int32 targetCount = sizeof(targets) / sizeof(target);
214 
215 	// test
216 	for (int32 i = 0; i < targetCount; i++) {
217 		NextSubTest();
218 		const target &target1 = targets[i];
219 		const BMessenger &a = target1.messenger;
220 		for (int32 k = 0; k < targetCount; k++) {
221 			const target &target2 = targets[k];
222 			const BMessenger &b = target2.messenger;
223 			bool areEqual = (target1.id == target2.id);
224 			CHK((a == b) == areEqual);
225 			CHK((b == a) == areEqual);
226 			CHK((a != b) == !areEqual);
227 			CHK((b != a) == !areEqual);
228 		}
229 	}
230 }
231 
232 // Compare
233 //
234 // Helper function for LessTest1().
235 static inline
236 void
237 Compare(const FakeMessenger &fake1, const FakeMessenger &fake2,
238 		const BMessenger &messenger1, const BMessenger &messenger2)
239 {
240 	CHK((messenger1 == messenger2) == (fake1 == fake2));
241 	CHK((messenger1 != messenger2) == (fake1 != fake2));
242 	CHK((messenger1 < messenger2) == (fake1 < fake2));
243 }
244 
245 /*
246 	bool operator<(const BMessenger &a, const BMessenger &b)
247 	@case 1			set fields of a and b manually
248 	@results		should return whatever the reference implementation
249 					returns.
250  */
251 void MessengerComparissonTester::LessTest1()
252 {
253 	port_id ports[] = { -1, 0, 1 } ;
254 	int32 tokens[] = { -1, 0, 1 } ;
255 	team_id teams[] = { -1, 0, 1 } ;
256 	bool preferreds[] = { false, true } ;
257 	int32 portCount = sizeof(ports) / sizeof(port_id);
258 	int32 tokenCount = sizeof(tokens) / sizeof(int32);
259 	int32 teamCount = sizeof(teams) / sizeof(team_id);
260 	int32 preferredCount = 2;
261 	for (int32 p1 = 0; p1 < portCount; p1++) {
262 		port_id port1 = ports[p1];
263 		for (int32 to1 = 0; to1 < tokenCount; to1++) {
264 			int32 token1 = tokens[to1];
265 			for (int32 te1 = 0; te1 < teamCount; te1++) {
266 				team_id team1 = teams[te1];
267 				for (int32 pr1 = 0; pr1 < preferredCount; pr1++) {
268 					bool preferred1 = preferreds[pr1];
269 					FakeMessenger fake1;
270 					fake1.fPort = port1;
271 					fake1.fHandlerToken = token1;
272 					fake1.fTeam = team1;
273 					fake1.fPreferredTarget = preferred1;
274 					BMessenger &messenger1 = *(BMessenger*)&fake1;
275 					for (int32 p2 = 0; p2 < portCount; p2++) {
276 						port_id port2 = ports[p2];
277 						for (int32 to2 = 0; to2 < tokenCount; to2++) {
278 							int32 token2 = tokens[to2];
279 							for (int32 te2 = 0; te2 < teamCount; te2++) {
280 								team_id team2 = teams[te2];
281 								for (int32 pr2 = 0; pr2 < preferredCount;
282 									 pr2++) {
283 									bool preferred2 = preferreds[pr2];
284 									FakeMessenger fake2;
285 									fake2.fPort = port2;
286 									fake2.fHandlerToken = token2;
287 									fake2.fTeam = team2;
288 									fake2.fPreferredTarget = preferred2;
289 									BMessenger &messenger2
290 										= *(BMessenger*)&fake2;
291 									Compare(fake1, fake2, messenger1,
292 											messenger2);
293 								}
294 							}
295 						}
296 					}
297 				}
298 			}
299 		}
300 	}
301 }
302 
303 
304 Test* MessengerComparissonTester::Suite()
305 {
306 	typedef BThreadedTestCaller<MessengerComparissonTester> TC;
307 
308 	TestSuite* testSuite = new TestSuite;
309 
310 	ADD_TEST4(BMessenger, testSuite, MessengerComparissonTester, ComparissonTest1);
311 	ADD_TEST4(BMessenger, testSuite, MessengerComparissonTester, ComparissonTest2);
312 	ADD_TEST4(BMessenger, testSuite, MessengerComparissonTester, ComparissonTest3);
313 	ADD_TEST4(BMessenger, testSuite, MessengerComparissonTester, LessTest1);
314 
315 	return testSuite;
316 }
317 
318 
319