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