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 33struct 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 45static 46bool 47operator<(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 61static 62bool 63operator!=(const FakeMessenger& a, const FakeMessenger& b) 64{ 65 return (a < b || b < a); 66} 67 68static 69bool 70operator==(const FakeMessenger& a, const FakeMessenger& b) 71{ 72 return !(a != b); 73} 74 75// constructor 76MessengerComparissonTester::MessengerComparissonTester() 77 : BThreadedTestCase(), 78 fHandler(NULL), 79 fLooper(NULL) 80{ 81} 82 83// constructor 84MessengerComparissonTester::MessengerComparissonTester(std::string name) 85 : BThreadedTestCase(name), 86 fHandler(NULL), 87 fLooper(NULL) 88{ 89} 90 91// destructor 92MessengerComparissonTester::~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 */ 110void 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 */ 127void 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 */ 157void 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(). 235static inline 236void 237Compare(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 */ 251void 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 304Test* 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