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 43static const char *testerSignature 44 = "application/x-vnd.obos-roster-broadcast-test"; 45static const char *appType1 = "application/x-vnd.obos-roster-broadcast-app1"; 46static const char *appType2 = "application/x-vnd.obos-roster-broadcast-app2"; 47static const char *appType3 = "application/x-vnd.obos-roster-broadcast-app3"; 48static const char *appType4 = "application/x-vnd.obos-roster-broadcast-app4"; 49 50static const char *testDir = "/tmp/testdir"; 51static const char *appFile1 = "/tmp/testdir/app1"; 52static const char *appFile2 = "/tmp/testdir/app2"; 53static const char *appFile3 = "/tmp/testdir/app3"; 54static const char *appFile4 = "/tmp/testdir/app4"; 55 56 57// ref_for_path 58static 59entry_ref 60ref_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 70static 71entry_ref 72create_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 99void 100BroadcastTester::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 109void 110BroadcastTester::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 121class SimpleAppLauncher : public LaunchCaller { 122public: 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 139protected: 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*/ 148void 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*/ 162void 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*/ 245void 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*/ 261void 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*/ 347void 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 427Test* 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