Added BRoster::Broadcast() tests and test app.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1535 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2002-10-15 22:24:36 +00:00
parent bd6419bd44
commit 6df9b41c0d
7 changed files with 699 additions and 12 deletions

View File

@ -68,6 +68,7 @@ CommonTestLib libapptest.so
# BMessageRunner
MessageRunnerTest.cpp
BMessageRunnerTester.cpp
BroadcastTester.cpp
GetInfoTester.cpp
MessageRunnerTestHelpers.cpp
SetCountTester.cpp

View File

@ -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!

View File

@ -0,0 +1,440 @@
//------------------------------------------------------------------------------
// BroadcastTester.cpp
//
//------------------------------------------------------------------------------
// Standard Includes -----------------------------------------------------------
#include <stdio.h>
#include <utime.h>
// System Includes -------------------------------------------------------------
#include <be/app/Message.h>
#include <be/kernel/OS.h>
#include <AppFileInfo.h>
#include <Application.h>
#include <File.h>
#include <FindDirectory.h>
#include <Handler.h>
#include <Looper.h>
#include <Message.h>
#include <MessageQueue.h>
#include <Path.h>
#include <Roster.h>
#include <String.h>
// Project Includes ------------------------------------------------------------
#include <TestShell.h>
#include <TestUtils.h>
#include <cppunit/TestAssert.h>
// 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<RosterLaunchApp*>(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<RosterLaunchApp*>(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;
}

View File

@ -0,0 +1,45 @@
//------------------------------------------------------------------------------
// BroadcastTester.h
//
//------------------------------------------------------------------------------
#ifndef BROADCAST_TESTER_H
#define BROADCAST_TESTER_H
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
// Project Includes ------------------------------------------------------------
#include <TestCase.h>
// 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

View File

@ -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());

View File

@ -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 ;

View File

@ -0,0 +1,188 @@
// RosterBroadcastTestApp1.cpp
#include <stdio.h>
#include <string.h>
#include <Application.h>
#include <Entry.h>
#include <File.h>
#include <Message.h>
#include <Messenger.h>
#include <OS.h>
#include <Resources.h>
#include <Roster.h>
#include <String.h>
#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;
}