1 //------------------------------------------------------------------------------ 2 // BroadcastTester.cpp 3 // 4 //------------------------------------------------------------------------------ 5 6 // Standard Includes ----------------------------------------------------------- 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <utime.h> 10 11 // System Includes ------------------------------------------------------------- 12 #include <Message.h> 13 #include <OS.h> 14 #include <AppFileInfo.h> 15 #include <Application.h> 16 #include <File.h> 17 #include <FindDirectory.h> 18 #include <Handler.h> 19 #include <Looper.h> 20 #include <Message.h> 21 #include <MessageQueue.h> 22 #include <Path.h> 23 #include <Roster.h> 24 #include <String.h> 25 26 // Project Includes ------------------------------------------------------------ 27 #include <TestShell.h> 28 #include <TestUtils.h> 29 #include <cppunit/TestAssert.h> 30 31 // Local Includes -------------------------------------------------------------- 32 #include "AppRunner.h" 33 #include "BroadcastTester.h" 34 #include "LaunchTesterHelper.h" 35 #include "RosterTestAppDefs.h" 36 37 // Local Defines --------------------------------------------------------------- 38 39 // Globals --------------------------------------------------------------------- 40 41 //------------------------------------------------------------------------------ 42 43 static const char *testerSignature 44 = "application/x-vnd.obos-roster-broadcast-test"; 45 static const char *appType1 = "application/x-vnd.obos-roster-broadcast-app1"; 46 static const char *appType2 = "application/x-vnd.obos-roster-broadcast-app2"; 47 static const char *appType3 = "application/x-vnd.obos-roster-broadcast-app3"; 48 static const char *appType4 = "application/x-vnd.obos-roster-broadcast-app4"; 49 50 static const char *testDir = "/tmp/testdir"; 51 static const char *appFile1 = "/tmp/testdir/app1"; 52 static const char *appFile2 = "/tmp/testdir/app2"; 53 static const char *appFile3 = "/tmp/testdir/app3"; 54 static const char *appFile4 = "/tmp/testdir/app4"; 55 56 57 // ref_for_path 58 static 59 entry_ref 60 ref_for_path(const char *filename, bool traverse = true) 61 { 62 entry_ref ref; 63 BEntry entry; 64 CHK(entry.SetTo(filename, traverse) == B_OK); 65 CHK(entry.GetRef(&ref) == B_OK); 66 return ref; 67 } 68 69 // create_app 70 static 71 entry_ref 72 create_app(const char *filename, const char *signature, 73 bool install = false, bool makeExecutable = true, 74 uint32 appFlags = B_SINGLE_LAUNCH) 75 { 76 BString testApp; 77 CHK(find_test_app("RosterBroadcastTestApp1", &testApp) == B_OK); 78 system((string("cp ") + testApp.String() + " " + filename).c_str()); 79 if (makeExecutable) 80 system((string("chmod a+x ") + filename).c_str()); 81 BFile file; 82 CHK(file.SetTo(filename, B_READ_WRITE) == B_OK); 83 BAppFileInfo appFileInfo; 84 CHK(appFileInfo.SetTo(&file) == B_OK); 85 if (signature) 86 CHK(appFileInfo.SetSignature(signature) == B_OK); 87 CHK(appFileInfo.SetAppFlags(appFlags) == B_OK); 88 if (install && signature) 89 CHK(BMimeType(signature).Install() == B_OK); 90 // We write the signature into a separate attribute, just in case we 91 // decide to also test files without BEOS:APP_SIG attribute. 92 BString signatureString(signature); 93 file.WriteAttrString("signature", &signatureString); 94 return ref_for_path(filename); 95 } 96 97 98 // setUp 99 void 100 BroadcastTester::setUp() 101 { 102 RosterLaunchApp *app = new RosterLaunchApp(testerSignature); 103 fApplication = app; 104 app->SetHandler(new RosterBroadcastHandler); 105 system((string("mkdir ") + testDir).c_str()); 106 } 107 108 // tearDown 109 void 110 BroadcastTester::tearDown() 111 { 112 BMimeType(appType1).Delete(); 113 BMimeType(appType2).Delete(); 114 BMimeType(appType3).Delete(); 115 BMimeType(appType4).Delete(); 116 delete fApplication; 117 system((string("rm -rf ") + testDir).c_str()); 118 } 119 120 // SimpleAppLauncher 121 class SimpleAppLauncher : public LaunchCaller { 122 public: 123 SimpleAppLauncher() : fRef() {} 124 SimpleAppLauncher(const entry_ref &ref) : fRef(ref) {} 125 virtual ~SimpleAppLauncher() {} 126 virtual status_t operator()(const char *type, BList *messages, int32 argc, 127 const char **argv, team_id *team) 128 { 129 return be_roster->Launch(&fRef, (BMessage*)NULL, team); 130 } 131 virtual bool SupportsRefs() const { return true; } 132 virtual const entry_ref *Ref() const { return &fRef; } 133 134 virtual LaunchCaller *CloneInternal() 135 { 136 return new SimpleAppLauncher; 137 } 138 139 protected: 140 entry_ref fRef; 141 }; 142 143 /* 144 status_t Broadcast(BMessage *message) const 145 @case 1 NULL message 146 @results Should return B_BAD_VALUE. 147 */ 148 void BroadcastTester::BroadcastTestA1() 149 { 150 // R5: crashes when passing a NULL message. 151 #ifndef TEST_R5 152 CHK(be_roster->Broadcast(NULL) == B_BAD_VALUE); 153 #endif 154 } 155 156 /* 157 status_t Broadcast(BMessage *message) const 158 @case 2 valid message, several apps, one is B_ARGV_ONLY 159 @results Should return B_OK and send the message to all (including 160 the B_ARGV_ONLY) apps. Replies go to be_app_messenger. 161 */ 162 void BroadcastTester::BroadcastTestA2() 163 { 164 LaunchContext context; 165 BRoster roster; 166 // launch app 1 167 entry_ref ref1(create_app(appFile1, appType1)); 168 SimpleAppLauncher caller1(ref1); 169 team_id team1; 170 CHK(context(caller1, appType1, &team1) == B_OK); 171 // launch app 2 172 entry_ref ref2(create_app(appFile2, appType2, false, true, 173 B_SINGLE_LAUNCH | B_ARGV_ONLY)); 174 SimpleAppLauncher caller2(ref2); 175 team_id team2; 176 CHK(context(caller2, appType2, &team2) == B_OK); 177 // launch app 3 178 entry_ref ref3(create_app(appFile3, appType3)); 179 SimpleAppLauncher caller3(ref3); 180 team_id team3; 181 CHK(context(caller3, appType3, &team3) == B_OK); 182 // launch app 4 183 entry_ref ref4(create_app(appFile4, appType4)); 184 SimpleAppLauncher caller4(ref4); 185 team_id team4; 186 CHK(context(caller4, appType4, &team4) == B_OK); 187 // wait for the apps to run 188 context.WaitForMessage(team1, MSG_READY_TO_RUN); 189 context.WaitForMessage(team2, MSG_READY_TO_RUN); 190 context.WaitForMessage(team3, MSG_READY_TO_RUN); 191 context.WaitForMessage(team4, MSG_READY_TO_RUN); 192 // broadcast a message 193 BMessage message(MSG_1); 194 CHK(roster.Broadcast(&message) == B_OK); 195 // wait for the apps to report the receipt of the message 196 context.WaitForMessage(team1, MSG_MESSAGE_RECEIVED); 197 context.WaitForMessage(team2, MSG_MESSAGE_RECEIVED); 198 context.WaitForMessage(team3, MSG_MESSAGE_RECEIVED); 199 context.WaitForMessage(team4, MSG_MESSAGE_RECEIVED); 200 // check the messages 201 context.Terminate(); 202 // app 1 203 int32 cookie = 0; 204 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_STARTED)); 205 CHK(context.CheckMainArgsMessage(caller1, team1, cookie, &ref1, false)); 206 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_READY_TO_RUN)); 207 CHK(context.CheckMessageMessage(caller1, team1, cookie, &message)); 208 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_2)); 209 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_QUIT_REQUESTED)); 210 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_TERMINATED)); 211 // app 2 212 cookie = 0; 213 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_STARTED)); 214 CHK(context.CheckMainArgsMessage(caller2, team2, cookie, &ref2, false)); 215 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_READY_TO_RUN)); 216 CHK(context.CheckMessageMessage(caller2, team2, cookie, &message)); 217 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_2)); 218 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_QUIT_REQUESTED)); 219 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_TERMINATED)); 220 // app 3 221 cookie = 0; 222 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_STARTED)); 223 CHK(context.CheckMainArgsMessage(caller3, team3, cookie, &ref3, false)); 224 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_READY_TO_RUN)); 225 CHK(context.CheckMessageMessage(caller3, team3, cookie, &message)); 226 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_2)); 227 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_QUIT_REQUESTED)); 228 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_TERMINATED)); 229 // app 4 230 cookie = 0; 231 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_STARTED)); 232 CHK(context.CheckMainArgsMessage(caller4, team4, cookie, &ref4, false)); 233 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_READY_TO_RUN)); 234 CHK(context.CheckMessageMessage(caller4, team4, cookie, &message)); 235 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_2)); 236 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_QUIT_REQUESTED)); 237 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_TERMINATED)); 238 } 239 240 /* 241 status_t Broadcast(BMessage *message, BMessenger replyTo) const 242 @case 1 NULL message 243 @results Should return B_BAD_VALUE. 244 */ 245 void BroadcastTester::BroadcastTestB1() 246 { 247 // R5: crashes when passing a NULL message. 248 #ifndef TEST_R5 249 BMessenger replyTo(dynamic_cast<RosterLaunchApp*>(be_app)->Handler()); 250 CHK(be_roster->Broadcast(NULL, replyTo) == B_BAD_VALUE); 251 #endif 252 } 253 254 /* 255 status_t Broadcast(BMessage *message, BMessenger replyTo) const 256 @case 2 valid message, several apps, one is B_ARGV_ONLY 257 @results Should return B_OK and send the message to all (including 258 the B_ARGV_ONLY) apps. Replies go to the specified 259 messenger. 260 */ 261 void BroadcastTester::BroadcastTestB2() 262 { 263 LaunchContext context; 264 BRoster roster; 265 // launch app 1 266 entry_ref ref1(create_app(appFile1, appType1)); 267 SimpleAppLauncher caller1(ref1); 268 team_id team1; 269 CHK(context(caller1, appType1, &team1) == B_OK); 270 // launch app 2 271 entry_ref ref2(create_app(appFile2, appType2, false, true, 272 B_SINGLE_LAUNCH | B_ARGV_ONLY)); 273 SimpleAppLauncher caller2(ref2); 274 team_id team2; 275 CHK(context(caller2, appType2, &team2) == B_OK); 276 // launch app 3 277 entry_ref ref3(create_app(appFile3, appType3)); 278 SimpleAppLauncher caller3(ref3); 279 team_id team3; 280 CHK(context(caller3, appType3, &team3) == B_OK); 281 // launch app 4 282 entry_ref ref4(create_app(appFile4, appType4)); 283 SimpleAppLauncher caller4(ref4); 284 team_id team4; 285 CHK(context(caller4, appType4, &team4) == B_OK); 286 // wait for the apps to run 287 context.WaitForMessage(team1, MSG_READY_TO_RUN); 288 context.WaitForMessage(team2, MSG_READY_TO_RUN); 289 context.WaitForMessage(team3, MSG_READY_TO_RUN); 290 context.WaitForMessage(team4, MSG_READY_TO_RUN); 291 // broadcast a message 292 BMessage message(MSG_1); 293 BMessenger replyTo(dynamic_cast<RosterLaunchApp*>(be_app)->Handler()); 294 CHK(roster.Broadcast(&message, replyTo) == B_OK); 295 // wait for the apps to report the receipt of the message 296 context.WaitForMessage(team1, MSG_MESSAGE_RECEIVED); 297 context.WaitForMessage(team2, MSG_MESSAGE_RECEIVED); 298 context.WaitForMessage(team3, MSG_MESSAGE_RECEIVED); 299 context.WaitForMessage(team4, MSG_MESSAGE_RECEIVED); 300 // check the messages 301 context.Terminate(); 302 // app 1 303 int32 cookie = 0; 304 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_STARTED)); 305 CHK(context.CheckMainArgsMessage(caller1, team1, cookie, &ref1, false)); 306 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_READY_TO_RUN)); 307 CHK(context.CheckMessageMessage(caller1, team1, cookie, &message)); 308 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_REPLY)); 309 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_QUIT_REQUESTED)); 310 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_TERMINATED)); 311 // app 2 312 cookie = 0; 313 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_STARTED)); 314 CHK(context.CheckMainArgsMessage(caller2, team2, cookie, &ref2, false)); 315 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_READY_TO_RUN)); 316 CHK(context.CheckMessageMessage(caller2, team2, cookie, &message)); 317 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_REPLY)); 318 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_QUIT_REQUESTED)); 319 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_TERMINATED)); 320 // app 3 321 cookie = 0; 322 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_STARTED)); 323 CHK(context.CheckMainArgsMessage(caller3, team3, cookie, &ref3, false)); 324 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_READY_TO_RUN)); 325 CHK(context.CheckMessageMessage(caller3, team3, cookie, &message)); 326 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_REPLY)); 327 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_QUIT_REQUESTED)); 328 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_TERMINATED)); 329 // app 4 330 cookie = 0; 331 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_STARTED)); 332 CHK(context.CheckMainArgsMessage(caller4, team4, cookie, &ref4, false)); 333 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_READY_TO_RUN)); 334 CHK(context.CheckMessageMessage(caller4, team4, cookie, &message)); 335 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_REPLY)); 336 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_QUIT_REQUESTED)); 337 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_TERMINATED)); 338 } 339 340 /* 341 status_t Broadcast(BMessage *message, BMessenger replyTo) const 342 @case 3 valid message, several apps, one is B_ARGV_ONLY, 343 invalid replyTo 344 @results Should return B_OK and send the message to all (including 345 the B_ARGV_ONLY) apps. Replies go to the roster! 346 */ 347 void BroadcastTester::BroadcastTestB3() 348 { 349 LaunchContext context; 350 BRoster roster; 351 // launch app 1 352 entry_ref ref1(create_app(appFile1, appType1)); 353 SimpleAppLauncher caller1(ref1); 354 team_id team1; 355 CHK(context(caller1, appType1, &team1) == B_OK); 356 // launch app 2 357 entry_ref ref2(create_app(appFile2, appType2, false, true, 358 B_SINGLE_LAUNCH | B_ARGV_ONLY)); 359 SimpleAppLauncher caller2(ref2); 360 team_id team2; 361 CHK(context(caller2, appType2, &team2) == B_OK); 362 // launch app 3 363 entry_ref ref3(create_app(appFile3, appType3)); 364 SimpleAppLauncher caller3(ref3); 365 team_id team3; 366 CHK(context(caller3, appType3, &team3) == B_OK); 367 // launch app 4 368 entry_ref ref4(create_app(appFile4, appType4)); 369 SimpleAppLauncher caller4(ref4); 370 team_id team4; 371 CHK(context(caller4, appType4, &team4) == B_OK); 372 // wait for the apps to run 373 context.WaitForMessage(team1, MSG_READY_TO_RUN); 374 context.WaitForMessage(team2, MSG_READY_TO_RUN); 375 context.WaitForMessage(team3, MSG_READY_TO_RUN); 376 context.WaitForMessage(team4, MSG_READY_TO_RUN); 377 // broadcast a message 378 BMessage message(MSG_1); 379 BMessenger replyTo; 380 CHK(roster.Broadcast(&message, replyTo) == B_OK); 381 // wait for the apps to report the receipt of the message 382 context.WaitForMessage(team1, MSG_MESSAGE_RECEIVED); 383 context.WaitForMessage(team2, MSG_MESSAGE_RECEIVED); 384 context.WaitForMessage(team3, MSG_MESSAGE_RECEIVED); 385 context.WaitForMessage(team4, MSG_MESSAGE_RECEIVED); 386 // check the messages 387 context.Terminate(); 388 // app 1 389 int32 cookie = 0; 390 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_STARTED)); 391 CHK(context.CheckMainArgsMessage(caller1, team1, cookie, &ref1, false)); 392 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_READY_TO_RUN)); 393 CHK(context.CheckMessageMessage(caller1, team1, cookie, &message)); 394 // CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_2)); 395 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_QUIT_REQUESTED)); 396 CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_TERMINATED)); 397 // app 2 398 cookie = 0; 399 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_STARTED)); 400 CHK(context.CheckMainArgsMessage(caller2, team2, cookie, &ref2, false)); 401 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_READY_TO_RUN)); 402 CHK(context.CheckMessageMessage(caller2, team2, cookie, &message)); 403 // CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_2)); 404 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_QUIT_REQUESTED)); 405 CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_TERMINATED)); 406 // app 3 407 cookie = 0; 408 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_STARTED)); 409 CHK(context.CheckMainArgsMessage(caller3, team3, cookie, &ref3, false)); 410 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_READY_TO_RUN)); 411 CHK(context.CheckMessageMessage(caller3, team3, cookie, &message)); 412 // CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_2)); 413 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_QUIT_REQUESTED)); 414 CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_TERMINATED)); 415 // app 4 416 cookie = 0; 417 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_STARTED)); 418 CHK(context.CheckMainArgsMessage(caller4, team4, cookie, &ref4, false)); 419 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_READY_TO_RUN)); 420 CHK(context.CheckMessageMessage(caller4, team4, cookie, &message)); 421 // CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_2)); 422 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_QUIT_REQUESTED)); 423 CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_TERMINATED)); 424 } 425 426 427 Test* BroadcastTester::Suite() 428 { 429 TestSuite* SuiteOfTests = new TestSuite; 430 431 ADD_TEST4(BRoster, SuiteOfTests, BroadcastTester, BroadcastTestA1); 432 ADD_TEST4(BRoster, SuiteOfTests, BroadcastTester, BroadcastTestA2); 433 434 ADD_TEST4(BRoster, SuiteOfTests, BroadcastTester, BroadcastTestB1); 435 ADD_TEST4(BRoster, SuiteOfTests, BroadcastTester, BroadcastTestB2); 436 ADD_TEST4(BRoster, SuiteOfTests, BroadcastTester, BroadcastTestB3); 437 438 return SuiteOfTests; 439 } 440 441