diff --git a/src/tests/kits/app/Jamfile b/src/tests/kits/app/Jamfile index efabf1ec1b..6d2eb09d24 100644 --- a/src/tests/kits/app/Jamfile +++ b/src/tests/kits/app/Jamfile @@ -68,6 +68,7 @@ CommonTestLib libapptest.so # BMessageRunner MessageRunnerTest.cpp BMessageRunnerTester.cpp + BroadcastTester.cpp GetInfoTester.cpp MessageRunnerTestHelpers.cpp SetCountTester.cpp diff --git a/src/tests/kits/app/broster/BRosterCases b/src/tests/kits/app/broster/BRosterCases index f4e3fc8c89..e7c4e6a3f1 100644 --- a/src/tests/kits/app/broster/BRosterCases +++ b/src/tests/kits/app/broster/BRosterCases @@ -562,3 +562,24 @@ case 14:ref is valid and refers to an executable without signature => Should return B_OK and set team to the ID of the team running the application's executable. +status_t Broadcast(BMessage *message) const +case 1: NULL message => + Should return B_BAD_VALUE. +case 2: valid message, several apps, one is B_ARGV_ONLY => + Should return B_OK and send the message to all (including the + B_ARGV_ONLY) apps. + Replies go to be_app_messenger. + +status_t Broadcast(BMessage *message, BMessenger replyTo) const +case 1: NULL message => + Should return B_BAD_VALUE. +case 2: valid message, several apps, one is B_ARGV_ONLY, valid replyTo => + Should return B_OK and send the message to all (including the + B_ARGV_ONLY) apps. + Replies go to the specified messenger. +case 3: valid message, several apps, one is B_ARGV_ONLY, invalid replyTo => + Should return B_OK and send the message to all (including the + B_ARGV_ONLY) apps. + Replies go to the roster! + + diff --git a/src/tests/kits/app/broster/BroadcastTester.cpp b/src/tests/kits/app/broster/BroadcastTester.cpp new file mode 100644 index 0000000000..a2f2fd5c71 --- /dev/null +++ b/src/tests/kits/app/broster/BroadcastTester.cpp @@ -0,0 +1,440 @@ +//------------------------------------------------------------------------------ +// BroadcastTester.cpp +// +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- +#include +#include + +// System Includes ------------------------------------------------------------- +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Project Includes ------------------------------------------------------------ +#include +#include +#include + +// Local Includes -------------------------------------------------------------- +#include "AppRunner.h" +#include "BroadcastTester.h" +#include "LaunchTesterHelper.h" +#include "RosterTestAppDefs.h" + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +//------------------------------------------------------------------------------ + +static const char *testerSignature + = "application/x-vnd.obos-roster-broadcast-test"; +static const char *appType1 = "application/x-vnd.obos-roster-broadcast-app1"; +static const char *appType2 = "application/x-vnd.obos-roster-broadcast-app2"; +static const char *appType3 = "application/x-vnd.obos-roster-broadcast-app3"; +static const char *appType4 = "application/x-vnd.obos-roster-broadcast-app4"; + +static const char *testDir = "/tmp/testdir"; +static const char *appFile1 = "/tmp/testdir/app1"; +static const char *appFile2 = "/tmp/testdir/app2"; +static const char *appFile3 = "/tmp/testdir/app3"; +static const char *appFile4 = "/tmp/testdir/app4"; + + +// ref_for_path +static +entry_ref +ref_for_path(const char *filename, bool traverse = true) +{ + entry_ref ref; + BEntry entry; + CHK(entry.SetTo(filename, traverse) == B_OK); + CHK(entry.GetRef(&ref) == B_OK); + return ref; +} + +// create_app +static +entry_ref +create_app(const char *filename, const char *signature, + bool install = false, bool makeExecutable = true, + uint32 appFlags = B_SINGLE_LAUNCH) +{ + BString testApp; + CHK(find_test_app("RosterBroadcastTestApp1", &testApp) == B_OK); + system((string("cp ") + testApp.String() + " " + filename).c_str()); + if (makeExecutable) + system((string("chmod a+x ") + filename).c_str()); + BFile file; + CHK(file.SetTo(filename, B_READ_WRITE) == B_OK); + BAppFileInfo appFileInfo; + CHK(appFileInfo.SetTo(&file) == B_OK); + if (signature) + CHK(appFileInfo.SetSignature(signature) == B_OK); + CHK(appFileInfo.SetAppFlags(appFlags) == B_OK); + if (install && signature) + CHK(BMimeType(signature).Install() == B_OK); + // We write the signature into a separate attribute, just in case we + // decide to also test files without BEOS:APP_SIG attribute. + BString signatureString(signature); + file.WriteAttrString("signature", &signatureString); + return ref_for_path(filename); +} + + +// setUp +void +BroadcastTester::setUp() +{ + RosterLaunchApp *app = new RosterLaunchApp(testerSignature); + fApplication = app; + app->SetHandler(new RosterBroadcastHandler); + system((string("mkdir ") + testDir).c_str()); +} + +// tearDown +void +BroadcastTester::tearDown() +{ + BMimeType(appType1).Delete(); + BMimeType(appType2).Delete(); + BMimeType(appType3).Delete(); + BMimeType(appType4).Delete(); + delete fApplication; + system((string("rm -rf ") + testDir).c_str()); +} + +// SimpleAppLauncher +class SimpleAppLauncher : public LaunchCaller { +public: + SimpleAppLauncher() : fRef() {} + SimpleAppLauncher(const entry_ref &ref) : fRef(ref) {} + virtual ~SimpleAppLauncher() {} + virtual status_t operator()(const char *type, BList *messages, int32 argc, + const char **argv, team_id *team) + { + return be_roster->Launch(&fRef, (BMessage*)NULL, team); + } + virtual bool SupportsRefs() const { return true; } + virtual const entry_ref *Ref() const { return &fRef; } + + virtual LaunchCaller *CloneInternal() + { + return new SimpleAppLauncher; + } + +protected: + entry_ref fRef; +}; + +/* + status_t Broadcast(BMessage *message) const + @case 1 NULL message + @results Should return B_BAD_VALUE. +*/ +void BroadcastTester::BroadcastTestA1() +{ +// R5: crashes when passing a NULL message. +#ifndef TEST_R5 + CHK(be_roster->Broadcast(NULL) == B_BAD_VALUE); +#endif +} + +/* + status_t Broadcast(BMessage *message) const + @case 2 valid message, several apps, one is B_ARGV_ONLY + @results Should return B_OK and send the message to all (including + the B_ARGV_ONLY) apps. Replies go to be_app_messenger. +*/ +void BroadcastTester::BroadcastTestA2() +{ + LaunchContext context; + BRoster roster; + // launch app 1 + entry_ref ref1(create_app(appFile1, appType1)); + SimpleAppLauncher caller1(ref1); + team_id team1; + CHK(context(caller1, appType1, &team1) == B_OK); + // launch app 2 + entry_ref ref2(create_app(appFile2, appType2, false, true, + B_SINGLE_LAUNCH | B_ARGV_ONLY)); + SimpleAppLauncher caller2(ref2); + team_id team2; + CHK(context(caller2, appType2, &team2) == B_OK); + // launch app 3 + entry_ref ref3(create_app(appFile3, appType3)); + SimpleAppLauncher caller3(ref3); + team_id team3; + CHK(context(caller3, appType3, &team3) == B_OK); + // launch app 4 + entry_ref ref4(create_app(appFile4, appType4)); + SimpleAppLauncher caller4(ref4); + team_id team4; + CHK(context(caller4, appType4, &team4) == B_OK); + // wait for the apps to run + context.WaitForMessage(team1, MSG_READY_TO_RUN); + context.WaitForMessage(team2, MSG_READY_TO_RUN); + context.WaitForMessage(team3, MSG_READY_TO_RUN); + context.WaitForMessage(team4, MSG_READY_TO_RUN); + // broadcast a message + BMessage message(MSG_1); + CHK(roster.Broadcast(&message) == B_OK); + // wait for the apps to report the receipt of the message + context.WaitForMessage(team1, MSG_MESSAGE_RECEIVED); + context.WaitForMessage(team2, MSG_MESSAGE_RECEIVED); + context.WaitForMessage(team3, MSG_MESSAGE_RECEIVED); + context.WaitForMessage(team4, MSG_MESSAGE_RECEIVED); + // check the messages + context.Terminate(); + // app 1 + int32 cookie = 0; + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller1, team1, cookie, &ref1, false)); + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_READY_TO_RUN)); + CHK(context.CheckMessageMessage(caller1, team1, cookie, &message)); + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_2)); + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_TERMINATED)); + // app 2 + cookie = 0; + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller2, team2, cookie, &ref2, false)); + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_READY_TO_RUN)); + CHK(context.CheckMessageMessage(caller2, team2, cookie, &message)); + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_2)); + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_TERMINATED)); + // app 3 + cookie = 0; + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller3, team3, cookie, &ref3, false)); + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_READY_TO_RUN)); + CHK(context.CheckMessageMessage(caller3, team3, cookie, &message)); + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_2)); + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_TERMINATED)); + // app 4 + cookie = 0; + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller4, team4, cookie, &ref4, false)); + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_READY_TO_RUN)); + CHK(context.CheckMessageMessage(caller4, team4, cookie, &message)); + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_2)); + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_TERMINATED)); +} + +/* + status_t Broadcast(BMessage *message, BMessenger replyTo) const + @case 1 NULL message + @results Should return B_BAD_VALUE. +*/ +void BroadcastTester::BroadcastTestB1() +{ +// R5: crashes when passing a NULL message. +#ifndef TEST_R5 + BMessenger replyTo(dynamic_cast(be_app)->Handler()); + CHK(be_roster->Broadcast(NULL, replyTo) == B_BAD_VALUE); +#endif +} + +/* + status_t Broadcast(BMessage *message, BMessenger replyTo) const + @case 2 valid message, several apps, one is B_ARGV_ONLY + @results Should return B_OK and send the message to all (including + the B_ARGV_ONLY) apps. Replies go to the specified + messenger. +*/ +void BroadcastTester::BroadcastTestB2() +{ + LaunchContext context; + BRoster roster; + // launch app 1 + entry_ref ref1(create_app(appFile1, appType1)); + SimpleAppLauncher caller1(ref1); + team_id team1; + CHK(context(caller1, appType1, &team1) == B_OK); + // launch app 2 + entry_ref ref2(create_app(appFile2, appType2, false, true, + B_SINGLE_LAUNCH | B_ARGV_ONLY)); + SimpleAppLauncher caller2(ref2); + team_id team2; + CHK(context(caller2, appType2, &team2) == B_OK); + // launch app 3 + entry_ref ref3(create_app(appFile3, appType3)); + SimpleAppLauncher caller3(ref3); + team_id team3; + CHK(context(caller3, appType3, &team3) == B_OK); + // launch app 4 + entry_ref ref4(create_app(appFile4, appType4)); + SimpleAppLauncher caller4(ref4); + team_id team4; + CHK(context(caller4, appType4, &team4) == B_OK); + // wait for the apps to run + context.WaitForMessage(team1, MSG_READY_TO_RUN); + context.WaitForMessage(team2, MSG_READY_TO_RUN); + context.WaitForMessage(team3, MSG_READY_TO_RUN); + context.WaitForMessage(team4, MSG_READY_TO_RUN); + // broadcast a message + BMessage message(MSG_1); + BMessenger replyTo(dynamic_cast(be_app)->Handler()); + CHK(roster.Broadcast(&message, replyTo) == B_OK); + // wait for the apps to report the receipt of the message + context.WaitForMessage(team1, MSG_MESSAGE_RECEIVED); + context.WaitForMessage(team2, MSG_MESSAGE_RECEIVED); + context.WaitForMessage(team3, MSG_MESSAGE_RECEIVED); + context.WaitForMessage(team4, MSG_MESSAGE_RECEIVED); + // check the messages + context.Terminate(); + // app 1 + int32 cookie = 0; + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller1, team1, cookie, &ref1, false)); + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_READY_TO_RUN)); + CHK(context.CheckMessageMessage(caller1, team1, cookie, &message)); + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_REPLY)); + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_TERMINATED)); + // app 2 + cookie = 0; + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller2, team2, cookie, &ref2, false)); + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_READY_TO_RUN)); + CHK(context.CheckMessageMessage(caller2, team2, cookie, &message)); + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_REPLY)); + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_TERMINATED)); + // app 3 + cookie = 0; + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller3, team3, cookie, &ref3, false)); + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_READY_TO_RUN)); + CHK(context.CheckMessageMessage(caller3, team3, cookie, &message)); + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_REPLY)); + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_TERMINATED)); + // app 4 + cookie = 0; + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller4, team4, cookie, &ref4, false)); + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_READY_TO_RUN)); + CHK(context.CheckMessageMessage(caller4, team4, cookie, &message)); + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_REPLY)); + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_TERMINATED)); +} + +/* + status_t Broadcast(BMessage *message, BMessenger replyTo) const + @case 3 valid message, several apps, one is B_ARGV_ONLY, + invalid replyTo + @results Should return B_OK and send the message to all (including + the B_ARGV_ONLY) apps. Replies go to the roster! +*/ +void BroadcastTester::BroadcastTestB3() +{ + LaunchContext context; + BRoster roster; + // launch app 1 + entry_ref ref1(create_app(appFile1, appType1)); + SimpleAppLauncher caller1(ref1); + team_id team1; + CHK(context(caller1, appType1, &team1) == B_OK); + // launch app 2 + entry_ref ref2(create_app(appFile2, appType2, false, true, + B_SINGLE_LAUNCH | B_ARGV_ONLY)); + SimpleAppLauncher caller2(ref2); + team_id team2; + CHK(context(caller2, appType2, &team2) == B_OK); + // launch app 3 + entry_ref ref3(create_app(appFile3, appType3)); + SimpleAppLauncher caller3(ref3); + team_id team3; + CHK(context(caller3, appType3, &team3) == B_OK); + // launch app 4 + entry_ref ref4(create_app(appFile4, appType4)); + SimpleAppLauncher caller4(ref4); + team_id team4; + CHK(context(caller4, appType4, &team4) == B_OK); + // wait for the apps to run + context.WaitForMessage(team1, MSG_READY_TO_RUN); + context.WaitForMessage(team2, MSG_READY_TO_RUN); + context.WaitForMessage(team3, MSG_READY_TO_RUN); + context.WaitForMessage(team4, MSG_READY_TO_RUN); + // broadcast a message + BMessage message(MSG_1); + BMessenger replyTo; + CHK(roster.Broadcast(&message, replyTo) == B_OK); + // wait for the apps to report the receipt of the message + context.WaitForMessage(team1, MSG_MESSAGE_RECEIVED); + context.WaitForMessage(team2, MSG_MESSAGE_RECEIVED); + context.WaitForMessage(team3, MSG_MESSAGE_RECEIVED); + context.WaitForMessage(team4, MSG_MESSAGE_RECEIVED); + // check the messages + context.Terminate(); + // app 1 + int32 cookie = 0; + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller1, team1, cookie, &ref1, false)); + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_READY_TO_RUN)); + CHK(context.CheckMessageMessage(caller1, team1, cookie, &message)); +// CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_2)); + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller1, team1, cookie, MSG_TERMINATED)); + // app 2 + cookie = 0; + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller2, team2, cookie, &ref2, false)); + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_READY_TO_RUN)); + CHK(context.CheckMessageMessage(caller2, team2, cookie, &message)); +// CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_2)); + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_TERMINATED)); + // app 3 + cookie = 0; + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller3, team3, cookie, &ref3, false)); + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_READY_TO_RUN)); + CHK(context.CheckMessageMessage(caller3, team3, cookie, &message)); +// CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_2)); + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller3, team3, cookie, MSG_TERMINATED)); + // app 4 + cookie = 0; + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller4, team4, cookie, &ref4, false)); + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_READY_TO_RUN)); + CHK(context.CheckMessageMessage(caller4, team4, cookie, &message)); +// CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_2)); + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller4, team4, cookie, MSG_TERMINATED)); +} + + +Test* BroadcastTester::Suite() +{ + TestSuite* SuiteOfTests = new TestSuite; + + ADD_TEST4(BRoster, SuiteOfTests, BroadcastTester, BroadcastTestA1); + ADD_TEST4(BRoster, SuiteOfTests, BroadcastTester, BroadcastTestA2); + + ADD_TEST4(BRoster, SuiteOfTests, BroadcastTester, BroadcastTestB1); + ADD_TEST4(BRoster, SuiteOfTests, BroadcastTester, BroadcastTestB2); + ADD_TEST4(BRoster, SuiteOfTests, BroadcastTester, BroadcastTestB3); + + return SuiteOfTests; +} + diff --git a/src/tests/kits/app/broster/BroadcastTester.h b/src/tests/kits/app/broster/BroadcastTester.h new file mode 100644 index 0000000000..39f8fd5954 --- /dev/null +++ b/src/tests/kits/app/broster/BroadcastTester.h @@ -0,0 +1,45 @@ +//------------------------------------------------------------------------------ +// BroadcastTester.h +// +//------------------------------------------------------------------------------ + +#ifndef BROADCAST_TESTER_H +#define BROADCAST_TESTER_H + +// Standard Includes ----------------------------------------------------------- + +// System Includes ------------------------------------------------------------- + +// Project Includes ------------------------------------------------------------ +#include + +// Local Includes -------------------------------------------------------------- +#include "../common.h" + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +class BroadcastTester : public BTestCase +{ + public: + BroadcastTester() {;} + BroadcastTester(std::string name) : BTestCase(name) {;} + + void setUp(); + void tearDown(); + + void BroadcastTestA1(); + void BroadcastTestA2(); + + void BroadcastTestB1(); + void BroadcastTestB2(); + void BroadcastTestB3(); + + static Test* Suite(); + +private: + BApplication *fApplication; +}; + +#endif // BROADCAST_TESTER_H diff --git a/src/tests/kits/app/broster/RosterTest.cpp b/src/tests/kits/app/broster/RosterTest.cpp index f85ca9aafc..784fd83ac9 100644 --- a/src/tests/kits/app/broster/RosterTest.cpp +++ b/src/tests/kits/app/broster/RosterTest.cpp @@ -1,4 +1,5 @@ #include "../common.h" +#include "BroadcastTester.h" #include "FindAppTester.h" #include "GetAppInfoTester.h" #include "GetAppListTester.h" @@ -11,6 +12,7 @@ CppUnit::Test* RosterTestSuite() { CppUnit::TestSuite *testSuite = new CppUnit::TestSuite(); + testSuite->addTest(BroadcastTester::Suite()); testSuite->addTest(FindAppTester::Suite()); testSuite->addTest(GetAppInfoTester::Suite()); testSuite->addTest(GetAppListTester::Suite()); diff --git a/src/tests/kits/app/broster/testapps/Jamfile b/src/tests/kits/app/broster/testapps/Jamfile index e3322ae726..4186990f4d 100644 --- a/src/tests/kits/app/broster/testapps/Jamfile +++ b/src/tests/kits/app/broster/testapps/Jamfile @@ -67,19 +67,9 @@ rule CopyBRosterTestApp # BRoster::Launch() test apps # -#local runTestApp1 = [ FGristFiles AppRunTestApp1$(SUFOBJ) ] ; - -SimpleBRosterTestApp RosterLaunchTestApp1.cpp ; -#SimpleBRosterTestApp RosterLaunchTestApp1.cpp : AppRunTestApp1.rsrc -# : $(commonObjects) ; -#SimpleBRosterTestApp2 AppRunTestApp2 : $(runTestApp1) : AppRunTestApp2.rsrc -# : $(commonObjects) ; - -#CopyBRosterTestApp AppRunTestApp3a : AppRunTestApp3 ; - -# GetRecentAppsTest apps SimpleBRosterTestApp RecentAppsTestQualifyingApp.cpp RecentAppsTestApp.cpp ; SimpleBRosterTestApp RecentAppsTestNonQualifyingApp.cpp RecentAppsTestApp.cpp ; SimpleBRosterTestApp RecentAppsTestEmptyApp.cpp RecentAppsTestApp.cpp ; SimpleBRosterTestApp RecentAppsTestControlApp.cpp RecentAppsTestApp.cpp ; - +SimpleBRosterTestApp RosterBroadcastTestApp1.cpp ; +SimpleBRosterTestApp RosterLaunchTestApp1.cpp ; diff --git a/src/tests/kits/app/broster/testapps/RosterBroadcastTestApp1.cpp b/src/tests/kits/app/broster/testapps/RosterBroadcastTestApp1.cpp new file mode 100644 index 0000000000..cc297079ef --- /dev/null +++ b/src/tests/kits/app/broster/testapps/RosterBroadcastTestApp1.cpp @@ -0,0 +1,188 @@ +// RosterBroadcastTestApp1.cpp + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "RosterTestAppDefs.h" + +BMessenger unitTesterMessenger; + +static const char *kUnitTesterSignature + = "application/x-vnd.obos-roster-broadcast-test"; + +// init_unit_tester_messenger +static +status_t +init_unit_tester_messenger() +{ + // Unfortunately BeOS R5 doesn't update the roster-side information about + // the app looper's port ID once a BApplication has been created, and + // thus we can't construct a BMessenger targeting a BApplication created + // after the first one using the signature/team ID constructor. + // We need to do some hacking. + struct fake_messenger { + port_id fPort; + int32 fHandlerToken; + team_id fTeam; + int32 extra0; + int32 extra1; + bool fPreferredTarget; + bool extra2; + bool extra3; + bool extra4; + } &fake = *(fake_messenger*)&unitTesterMessenger; + // get team + status_t error = B_OK; + fake.fTeam = BRoster().TeamFor(kUnitTesterSignature); + if (fake.fTeam < 0) + error = fake.fTeam; + // find app looper port + bool found = false; + int32 cookie = 0; + port_info info; + while (error == B_OK && !found) { + error = get_next_port_info(fake.fTeam, &cookie, &info); + found = (error == B_OK && !strcmp("AppLooperPort", info.name)); + } + // init messenger + if (error == B_OK) { + fake.fPort = info.port; + fake.fHandlerToken = 0; + fake.fPreferredTarget = true; + } + return error; +} + +// get_app_path +status_t +get_app_path(char *buffer) +{ + status_t error = (buffer ? B_OK : B_BAD_VALUE); + image_info info; + int32 cookie = 0; + bool found = false; + if (error == B_OK) { + while (!found && get_next_image_info(0, &cookie, &info) == B_OK) { + if (info.type == B_APP_IMAGE) { + strncpy(buffer, info.name, B_PATH_NAME_LENGTH); + buffer[B_PATH_NAME_LENGTH] = 0; + found = true; + } + } + } + if (error == B_OK && !found) + error = B_ENTRY_NOT_FOUND; + return error; +} + +// TestApp +class TestApp : public BApplication { +public: + TestApp(const char *signature) : BApplication(signature) + { + } + + virtual void ArgvReceived(int32 argc, char **argv) + { + BMessage message(MSG_ARGV_RECEIVED); + message.AddInt32("argc", argc); + for (int32 i = 0; i < argc; i++) + message.AddString("argv", argv[i]); + unitTesterMessenger.SendMessage(&message); + } + + virtual void RefsReceived(BMessage *_message) + { + BMessage message(*_message); + message.what = MSG_REFS_RECEIVED; + unitTesterMessenger.SendMessage(&message); + } + + virtual void MessageReceived(BMessage *_message) + { + BMessage message(MSG_MESSAGE_RECEIVED); + message.AddMessage("message", _message); + message.AddInt32("sender", _message->ReturnAddress().Team()); + if (_message->what == MSG_1) + message.AddBool("don't ignore", true); + unitTesterMessenger.SendMessage(&message); + if (_message->what == MSG_1) { +// _message->SendReply(MSG_2); + BMessage reply(MSG_2); + _message->SendReply(&reply, be_app_messenger); + } + } + + virtual bool QuitRequested() + { + unitTesterMessenger.SendMessage(MSG_QUIT_REQUESTED); + return true; + } + + virtual void ReadyToRun() + { + unitTesterMessenger.SendMessage(MSG_READY_TO_RUN); + } +}; + +// main +int +main(int argc, char **argv) +{ + // find app file and get signature from resources + char path[B_PATH_NAME_LENGTH]; + status_t error = get_app_path(path); + char signature[B_MIME_TYPE_LENGTH]; + if (error == B_OK) { + // init app file + BFile file; + error = file.SetTo(path, B_READ_ONLY); + // get signature + BString signatureString; + if (error == B_OK) { + if (file.ReadAttrString("signature", &signatureString) == B_OK + && signatureString.Length() > 0) { + strcpy(signature, signatureString.String()); + } else + strcpy(signature, kDefaultTestAppSignature); + } else + printf("ERROR: Couldn't init app file: %s\n", strerror(error)); + } else + printf("ERROR: Couldn't get app ref: %s\n", strerror(error)); + // create the app + TestApp *app = NULL; + if (error == B_OK) { + app = new TestApp(signature); +// unitTesterMessenger = BMessenger(kUnitTesterSignature); + error = init_unit_tester_messenger(); + if (error != B_OK) + printf("ERROR: Couldn't init messenger: %s\n", strerror(error)); + // send started message + BMessage message(MSG_STARTED); + message.AddString("path", path); + unitTesterMessenger.SendMessage(&message); + // send main() args message + BMessage argsMessage(MSG_MAIN_ARGS); + argsMessage.AddInt32("argc", argc); + for (int i = 0; i < argc; i++) + argsMessage.AddString("argv", argv[i]); + unitTesterMessenger.SendMessage(&argsMessage); + // run the app + app->Run(); + delete app; + // send terminated message + unitTesterMessenger.SendMessage(MSG_TERMINATED); + } + return 0; +} +