From f4e4e1c60217af5871ba573bae2118e9ca95ea80 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 18 Oct 2002 14:02:04 +0000 Subject: [PATCH] BRoster watching tests added. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1574 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kits/app/broster/RosterWatchingTester.cpp | 462 ++++++++++++++++++ .../kits/app/broster/RosterWatchingTester.h | 42 ++ .../testapps/RosterWatchingTestApp1.cpp | 188 +++++++ 3 files changed, 692 insertions(+) create mode 100644 src/tests/kits/app/broster/RosterWatchingTester.cpp create mode 100644 src/tests/kits/app/broster/RosterWatchingTester.h create mode 100644 src/tests/kits/app/broster/testapps/RosterWatchingTestApp1.cpp diff --git a/src/tests/kits/app/broster/RosterWatchingTester.cpp b/src/tests/kits/app/broster/RosterWatchingTester.cpp new file mode 100644 index 0000000000..fedec847dd --- /dev/null +++ b/src/tests/kits/app/broster/RosterWatchingTester.cpp @@ -0,0 +1,462 @@ +//------------------------------------------------------------------------------ +// RosterWatchingTester.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 "RosterWatchingTester.h" +#include "LaunchTesterHelper.h" +#include "RosterTestAppDefs.h" + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +//------------------------------------------------------------------------------ + +static const char *testerSignature + = "application/x-vnd.obos-roster-watching-test"; +static const char *appType1 = "application/x-vnd.obos-roster-watching-app1"; +static const char *appType2 = "application/x-vnd.obos-roster-watching-app2"; +static const char *appType3 = "application/x-vnd.obos-roster-watching-app3"; +static const char *appType4 = "application/x-vnd.obos-roster-watching-app4"; +//static const char *appType5 = "application/x-vnd.obos-roster-watching-app5"; + +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"; +//static const char *appFile5 = "/tmp/testdir/app5"; + + +// 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("RosterWatchingTestApp1", &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); +} + +// app_info_for_team +static +app_info +app_info_for_team(team_id team) +{ + app_info info; + CHK(be_roster->GetRunningAppInfo(team, &info) == B_OK); + return info; +} + +// check_watching_message +void +check_watching_message(LaunchContext &context, team_id team, int32 &cookie, + const app_info &info, uint32 messageCode) +{ + // wait for and get the message + CHK(context.WaitForMessage(team, MSG_MESSAGE_RECEIVED, false, + B_INFINITE_TIMEOUT, cookie)); + BMessage *container = context.NextMessageFrom(team, cookie); + CHK(container != NULL); + CHK(container->what == MSG_MESSAGE_RECEIVED); + BMessage message; + CHK(container->FindMessage("message", &message) == B_OK); + // check the message +if (message.what != messageCode) +printf("message.what: %.4s vs messageCode: %.4s\n", (char*)&message.what, +(char*)&messageCode); + CHK(message.what == messageCode); + // team + team_id foundTeam; + CHK(message.FindInt32("be:team", &foundTeam) == B_OK); + CHK(foundTeam == info.team); + // thread + thread_id thread; + CHK(message.FindInt32("be:thread", &thread) == B_OK); + CHK(thread == info.thread); + // signature + const char *signature = NULL; + CHK(message.FindString("be:signature", &signature) == B_OK); + CHK(!strcmp(signature, info.signature)); + // ref + entry_ref ref; + CHK(message.FindRef("be:ref", &ref) == B_OK); + CHK(ref == info.ref); + // flags + uint32 flags; + CHK(message.FindInt32("be:flags", (int32*)&flags) == B_OK); + CHK(flags == info.flags); +} + + +// setUp +void +RosterWatchingTester::setUp() +{ + RosterLaunchApp *app = new RosterLaunchApp(testerSignature); + fApplication = app; + app->SetHandler(new RosterBroadcastHandler); + system((string("mkdir ") + testDir).c_str()); +} + +// tearDown +void +RosterWatchingTester::tearDown() +{ + BMimeType(appType1).Delete(); + BMimeType(appType2).Delete(); + BMimeType(appType3).Delete(); + BMimeType(appType4).Delete(); +// BMimeType(appType5).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 StartWatching(BMessenger target, uint32 eventMask) const + status_t StopWatching(BMessenger target) const + @case 1 {Start,Stop}Watching() with invalid messenger or invalid + flags; StopWatching() non-watching messenger => + @results Should return B_OK; B_BAD_VALUE. +*/ +void RosterWatchingTester::WatchingTest1() +{ + BRoster roster; + BMessenger target; + // not valid, not watching + CHK(roster.StopWatching(target) == B_BAD_VALUE); + // not valid + CHK(roster.StartWatching(target, B_REQUEST_LAUNCHED | B_REQUEST_QUIT + | B_REQUEST_ACTIVATED) == B_OK); + CHK(roster.StopWatching(target) == B_OK); + // invalid flags + CHK(roster.StartWatching(target, 0) == B_OK); + CHK(roster.StopWatching(target) == B_OK); + // valid, but not watching + CHK(roster.StopWatching(be_app_messenger) == B_BAD_VALUE); +} + +/* + status_t StartWatching(BMessenger target, uint32 eventMask) const + status_t StopWatching(BMessenger target) const + @case 2 several apps, several watchers, different eventMasks + @results Should return B_OK... + Watching ends, when target has become invalid and the next watching + message is tried to be sent. +*/ +void RosterWatchingTester::WatchingTest2() +{ + 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); + context.WaitForMessage(team1, MSG_READY_TO_RUN); + BMessenger target1(NULL, team1); + app_info appInfo1(app_info_for_team(team1)); + CHK(roster.StartWatching(target1, B_REQUEST_LAUNCHED | B_REQUEST_QUIT + | B_REQUEST_ACTIVATED) == B_OK); + // messages: app 1 + int32 cookie1 = 0; + CHK(context.CheckNextMessage(caller1, team1, cookie1, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller1, team1, cookie1, &ref1, false)); + CHK(context.CheckNextMessage(caller1, team1, cookie1, MSG_READY_TO_RUN)); + // 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); + context.WaitForMessage(team2, MSG_READY_TO_RUN); + BMessenger target2(context.AppMessengerFor(team2)); + CHK(target2.IsValid()); + app_info appInfo2(app_info_for_team(team2)); + CHK(roster.StartWatching(target2, B_REQUEST_LAUNCHED) == B_OK); + // messages: app 2 + int32 cookie2 = 0; + CHK(context.CheckNextMessage(caller2, team2, cookie2, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller2, team2, cookie2, &ref2, false)); + CHK(context.CheckNextMessage(caller2, team2, cookie2, MSG_READY_TO_RUN)); + // messages: app 1 + check_watching_message(context, team1, cookie1, appInfo2, + B_SOME_APP_LAUNCHED); + // launch app 3 + entry_ref ref3(create_app(appFile3, appType3)); + SimpleAppLauncher caller3(ref3); + team_id team3; + CHK(context(caller3, appType3, &team3) == B_OK); + context.WaitForMessage(team3, MSG_READY_TO_RUN); + BMessenger target3(NULL, team3); + app_info appInfo3(app_info_for_team(team3)); + CHK(roster.StartWatching(target3, B_REQUEST_QUIT) == B_OK); + // messages: app 3 + int32 cookie3 = 0; + CHK(context.CheckNextMessage(caller3, team3, cookie3, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller3, team3, cookie3, &ref3, false)); + CHK(context.CheckNextMessage(caller3, team3, cookie3, MSG_READY_TO_RUN)); + // messages: app 2 + check_watching_message(context, team2, cookie2, appInfo3, + B_SOME_APP_LAUNCHED); + // messages: app 1 + check_watching_message(context, team1, cookie1, appInfo3, + B_SOME_APP_LAUNCHED); + // launch app 4 + entry_ref ref4(create_app(appFile4, appType4)); + SimpleAppLauncher caller4(ref4); + team_id team4; + CHK(context(caller4, appType4, &team4) == B_OK); + context.WaitForMessage(team4, MSG_READY_TO_RUN); + BMessenger target4(NULL, team4); + app_info appInfo4(app_info_for_team(team4)); + // messages: app 4 + int32 cookie4 = 0; + CHK(context.CheckNextMessage(caller4, team4, cookie4, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller4, team4, cookie4, &ref4, false)); + CHK(context.CheckNextMessage(caller4, team4, cookie4, MSG_READY_TO_RUN)); + // messages: app 3 + // none + // messages: app 2 + check_watching_message(context, team2, cookie2, appInfo4, + B_SOME_APP_LAUNCHED); + // messages: app 1 + check_watching_message(context, team1, cookie1, appInfo4, + B_SOME_APP_LAUNCHED); + // terminate app 4 + context.TerminateApp(team4); + // messages: app 3 + check_watching_message(context, team3, cookie3, appInfo4, + B_SOME_APP_QUIT); + // messages: app 2 + // none + // messages: app 1 + check_watching_message(context, team1, cookie1, appInfo4, + B_SOME_APP_QUIT); + // stop watching app 1 + CHK(roster.StopWatching(target1) == B_OK); + // terminate app 2 + context.TerminateApp(team2); + CHK(roster.StopWatching(target2) == B_OK); + // messages: app 3 + check_watching_message(context, team3, cookie3, appInfo2, + B_SOME_APP_QUIT); + // messages: app 1 + // none + // terminate app 3 + context.TerminateApp(team3); +// OBOS handles app termination a bit different. At the point, when the +// application unregisters itself from the registrar, its port is still +// valid. +#ifdef TEST_R5 + CHK(roster.StopWatching(target3) == B_BAD_VALUE); +#else + CHK(roster.StopWatching(target3) == B_OK); +#endif + // messages: app 1 + // none + // remaining messages + context.Terminate(); + // app 1 + CHK(context.CheckNextMessage(caller1, team1, cookie1, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller1, team1, cookie1, MSG_TERMINATED)); + // app 2 + CHK(context.CheckNextMessage(caller2, team2, cookie2, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller2, team2, cookie2, MSG_TERMINATED)); + // app 3 + CHK(context.CheckNextMessage(caller3, team3, cookie3, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller3, team3, cookie3, MSG_TERMINATED)); + // app 4 + CHK(context.CheckNextMessage(caller4, team4, cookie4, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller4, team4, cookie4, MSG_TERMINATED)); +} + +/* + status_t StartWatching(BMessenger target, uint32 eventMask) const + status_t StopWatching(BMessenger target) const + @case 3 call StartWatching() twice, second time with different + masks + @results Should return B_OK. The second call simply overrides the + first one. +*/ +void RosterWatchingTester::WatchingTest3() +{ + 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); + context.WaitForMessage(team1, MSG_READY_TO_RUN); + BMessenger target1(NULL, team1); + app_info appInfo1(app_info_for_team(team1)); + CHK(roster.StartWatching(target1, B_REQUEST_LAUNCHED | B_REQUEST_QUIT + | B_REQUEST_ACTIVATED) == B_OK); + // messages: app 1 + int32 cookie1 = 0; + CHK(context.CheckNextMessage(caller1, team1, cookie1, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller1, team1, cookie1, &ref1, false)); + CHK(context.CheckNextMessage(caller1, team1, cookie1, MSG_READY_TO_RUN)); + // app 1: another StartWatching() with different event mask + CHK(roster.StartWatching(target1, B_REQUEST_QUIT) == 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); + context.WaitForMessage(team2, MSG_READY_TO_RUN); + BMessenger target2(context.AppMessengerFor(team2)); + CHK(target2.IsValid()); + app_info appInfo2(app_info_for_team(team2)); + CHK(roster.StartWatching(target2, B_REQUEST_QUIT) == B_OK); + // messages: app 2 + int32 cookie2 = 0; + CHK(context.CheckNextMessage(caller2, team2, cookie2, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller2, team2, cookie2, &ref2, false)); + CHK(context.CheckNextMessage(caller2, team2, cookie2, MSG_READY_TO_RUN)); + // messages: app 1 + // none + // app 2: another StartWatching() with different event mask + CHK(roster.StartWatching(target2, B_REQUEST_LAUNCHED) == 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); + context.WaitForMessage(team3, MSG_READY_TO_RUN); + BMessenger target3(NULL, team3); + app_info appInfo3(app_info_for_team(team3)); + // messages: app 3 + int32 cookie3 = 0; + CHK(context.CheckNextMessage(caller3, team3, cookie3, MSG_STARTED)); + CHK(context.CheckMainArgsMessage(caller3, team3, cookie3, &ref3, false)); + CHK(context.CheckNextMessage(caller3, team3, cookie3, MSG_READY_TO_RUN)); + // messages: app 2 + check_watching_message(context, team2, cookie2, appInfo3, + B_SOME_APP_LAUNCHED); + // messages: app 1 + // none + // terminate app 3 + context.TerminateApp(team3); + // messages: app 3 + // none + // messages: app 2 + // none + // messages: app 1 + check_watching_message(context, team1, cookie1, appInfo3, + B_SOME_APP_QUIT); + // terminate app 2 + context.TerminateApp(team2); + CHK(roster.StopWatching(target2) == B_OK); + // messages: app 1 + check_watching_message(context, team1, cookie1, appInfo2, + B_SOME_APP_QUIT); + // remaining messages + context.Terminate(); + // app 1 + CHK(context.CheckNextMessage(caller1, team1, cookie1, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller1, team1, cookie1, MSG_TERMINATED)); + // app 2 + CHK(context.CheckNextMessage(caller2, team2, cookie2, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller2, team2, cookie2, MSG_TERMINATED)); + // app 3 + CHK(context.CheckNextMessage(caller3, team3, cookie3, MSG_QUIT_REQUESTED)); + CHK(context.CheckNextMessage(caller3, team3, cookie3, MSG_TERMINATED)); +} + + +Test* RosterWatchingTester::Suite() +{ + TestSuite* SuiteOfTests = new TestSuite; + + ADD_TEST4(BRoster, SuiteOfTests, RosterWatchingTester, WatchingTest1); + ADD_TEST4(BRoster, SuiteOfTests, RosterWatchingTester, WatchingTest2); + ADD_TEST4(BRoster, SuiteOfTests, RosterWatchingTester, WatchingTest3); + + return SuiteOfTests; +} + diff --git a/src/tests/kits/app/broster/RosterWatchingTester.h b/src/tests/kits/app/broster/RosterWatchingTester.h new file mode 100644 index 0000000000..2b14194032 --- /dev/null +++ b/src/tests/kits/app/broster/RosterWatchingTester.h @@ -0,0 +1,42 @@ +//------------------------------------------------------------------------------ +// RosterWatchingTester.h +// +//------------------------------------------------------------------------------ + +#ifndef ROSTER_WATCHING_TESTER_H +#define ROSTER_WATCHING_TESTER_H + +// Standard Includes ----------------------------------------------------------- + +// System Includes ------------------------------------------------------------- + +// Project Includes ------------------------------------------------------------ +#include + +// Local Includes -------------------------------------------------------------- +#include "../common.h" + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +class RosterWatchingTester : public BTestCase +{ + public: + RosterWatchingTester() {;} + RosterWatchingTester(std::string name) : BTestCase(name) {;} + + void setUp(); + void tearDown(); + + void WatchingTest1(); + void WatchingTest2(); + void WatchingTest3(); + + static Test* Suite(); + +private: + BApplication *fApplication; +}; + +#endif // ROSTER_WATCHING_TESTER_H diff --git a/src/tests/kits/app/broster/testapps/RosterWatchingTestApp1.cpp b/src/tests/kits/app/broster/testapps/RosterWatchingTestApp1.cpp new file mode 100644 index 0000000000..07a7df5423 --- /dev/null +++ b/src/tests/kits/app/broster/testapps/RosterWatchingTestApp1.cpp @@ -0,0 +1,188 @@ +// RosterWatchingTestApp1.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-watching-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()); + switch (_message->what) { + case B_SOME_APP_LAUNCHED: + case B_SOME_APP_QUIT: + case B_SOME_APP_ACTIVATED: + message.AddBool("don't ignore", true); + break; + } + unitTesterMessenger.SendMessage(&message); + } + + 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; +} +