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
operator <(const FakeMessenger & a,const FakeMessenger & b)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
operator !=(const FakeMessenger & a,const FakeMessenger & b)63 operator!=(const FakeMessenger& a, const FakeMessenger& b)
64 {
65 return (a < b || b < a);
66 }
67
68 static
69 bool
operator ==(const FakeMessenger & a,const FakeMessenger & b)70 operator==(const FakeMessenger& a, const FakeMessenger& b)
71 {
72 return !(a != b);
73 }
74
75 // constructor
MessengerComparissonTester()76 MessengerComparissonTester::MessengerComparissonTester()
77 : BThreadedTestCase(),
78 fHandler(NULL),
79 fLooper(NULL)
80 {
81 }
82
83 // constructor
MessengerComparissonTester(std::string name)84 MessengerComparissonTester::MessengerComparissonTester(std::string name)
85 : BThreadedTestCase(name),
86 fHandler(NULL),
87 fLooper(NULL)
88 {
89 }
90
91 // destructor
~MessengerComparissonTester()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 */
ComparissonTest1()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 */
ComparissonTest2()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 */
ComparissonTest3()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
Compare(const FakeMessenger & fake1,const FakeMessenger & fake2,const BMessenger & messenger1,const BMessenger & messenger2)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 */
LessTest1()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
Suite()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