Extended the Launch() helpers.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1300 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2002-09-29 22:15:53 +00:00
parent 45994f62b8
commit 01cf44b71c
2 changed files with 279 additions and 6 deletions
@@ -4,9 +4,11 @@
#include <string.h>
#include <Autolock.h>
#include <Entry.h>
#include <List.h>
#include <Message.h>
#include <Messenger.h>
#include <Path.h>
#include "LaunchTesterHelper.h"
#include "RosterTestAppDefs.h"
@@ -14,12 +16,20 @@
/////////////////
// LaunchContext
const char *LaunchContext::kStandardArgv[] = {
"Some", "nice", "arguments"
};
const int32 LaunchContext::kStandardArgc
= sizeof(kStandardArgv) / sizeof(const char*);
// Message
class LaunchContext::Message {
public:
BMessage message;
bigtime_t when;
};
// AppInfo
class LaunchContext::AppInfo {
public:
AppInfo(team_id team)
@@ -68,6 +78,11 @@ public:
fMessages.AddItem(message);
}
LaunchContext::Message *RemoveMessage(int32 index)
{
return (LaunchContext::Message*)fMessages.RemoveItem(index);
}
LaunchContext::Message *MessageAt(int32 index) const
{
return (LaunchContext::Message*)fMessages.ItemAt(index);
@@ -109,14 +124,34 @@ LaunchContext::~LaunchContext()
// cleanup
for (int32 i = 0; AppInfo *info = AppInfoAt(i); i++)
delete info;
for (int32 i = 0;
BMessage *message = (BMessage*)fStandardMessages.ItemAt(i);
i++) {
delete message;
}
}
// ()
status_t
LaunchContext::operator()(const char *type, team_id *team)
{
BMessage message1(MSG_1);
BMessage message2(MSG_2);
BMessage message3(MSG_3);
BList messages;
messages.AddItem(&message1);
messages.AddItem(&message2);
messages.AddItem(&message3);
return (*this)(type, &messages, kStandardArgc, kStandardArgv, team);
}
// ()
status_t
LaunchContext::operator()(const char *type, BList *messages, int32 argc,
const char **argv, team_id *team)
{
BAutolock _lock(fLock);
status_t result = fCaller(type, team);
status_t result = fCaller(type, messages, argc, argv, team);
if (result == B_OK) {
if (team)
CreateAppInfo(*team);
@@ -136,6 +171,8 @@ LaunchContext::operator()(const char *type, team_id *team)
void
LaunchContext::HandleMessage(BMessage *message)
{
//printf("LaunchContext::HandleMessage(%6ld: %.4s)\n",
//message->ReturnAddress().Team(), (char*)&message->what);
BAutolock _lock(fLock);
switch (message->what) {
case MSG_STARTED:
@@ -207,10 +244,8 @@ LaunchContext::NextMessageFrom(team_id team, int32 &cookie, bigtime_t *time)
BAutolock _lock(fLock);
BMessage *message = NULL;
if (AppInfo *info = AppInfoFor(team)) {
if (Message *contextMessage = info->MessageAt(cookie++)) {
message = new BMessage(contextMessage->message);
delete contextMessage;
}
if (Message *contextMessage = info->MessageAt(cookie++))
message = &contextMessage->message;
}
return message;
}
@@ -223,6 +258,206 @@ LaunchContext::CheckNextMessage(team_id team, int32 &cookie, uint32 what)
return (message && message->what == what);
}
// CheckArgvMessage
bool
LaunchContext::CheckArgvMessage(team_id team, int32 &cookie,
const entry_ref *appRef, bool useRef)
{
bool result = true;
if (fCaller.SupportsArgv()) {
result = CheckArgvMessage(team, cookie, appRef, kStandardArgc,
kStandardArgv, useRef);
}
return result;
}
// CheckArgvMessage
bool
LaunchContext::CheckArgvMessage(team_id team, int32 &cookie,
const entry_ref *appRef, int32 argc,
const char **argv, bool useRef)
{
const entry_ref *ref = (useRef ? fCaller.Ref() : NULL);
return CheckArgvMessage(team, cookie, appRef, ref , argc, argv);
}
// CheckArgvMessage
bool
LaunchContext::CheckArgvMessage(team_id team, int32 &cookie,
const entry_ref *appRef,
const entry_ref *ref , int32 argc,
const char **argv)
{
BMessage *message = NextMessageFrom(team, cookie);
bool result = (message && message->what == MSG_ARGV_RECEIVED);
int32 additionalRef = (ref ? 1 : 0);
// check argc
int32 foundArgc = -1;
if (result) {
result = (message->FindInt32("argc", &foundArgc) == B_OK
&& foundArgc == argc + 1 + additionalRef);
if (!result)
printf("argc differ: %ld vs %ld + 1 + %ld\n", foundArgc, argc, additionalRef);
}
// check argv[0] (the app file name)
if (result) {
BPath path;
const char *arg = NULL;
result = (path.SetTo(appRef) == B_OK
&& message->FindString("argv", 0, &arg) == B_OK
&& path == arg);
if (!result)
printf("app paths differ: `%s' vs `%s'\n", arg, path.Path());
}
// check remaining argv
for (int32 i = 1; result && i < argc; i++) {
const char *arg = NULL;
result = (message->FindString("argv", i, &arg) == B_OK
&& !strcmp(arg, argv[i - 1]));
if (!result)
printf("arg[%ld] differ: `%s' vs `%s'\n", i, arg, argv[i - 1]);
}
// check additional ref
if (result && additionalRef) {
BPath path;
const char *arg = NULL;
result = (path.SetTo(ref) == B_OK
&& message->FindString("argv", argc + 1, &arg) == B_OK
&& path == arg);
if (!result)
printf("app paths differ: `%s' vs `%s'\n", arg, path.Path());
}
return result;
}
// RemoveStandardArgvMessage
bool
LaunchContext::RemoveStandardArgvMessage(team_id team, const entry_ref *appRef)
{
return RemoveArgvMessage(team, appRef, kStandardArgc, kStandardArgv);
}
// RemoveArgvMessage
bool
LaunchContext::RemoveArgvMessage(team_id team, const entry_ref *appRef,
int32 argc, const char **argv)
{
BAutolock _lock(fLock);
bool result = true;
if (fCaller.SupportsArgv()) {
result = false;
int32 cookie = 0;
while (BMessage *message = NextMessageFrom(team, cookie)) {
if (message->what == MSG_ARGV_RECEIVED) {
int32 index = --cookie;
result = CheckArgvMessage(team, cookie, appRef, argc, argv);
delete AppInfoFor(team)->RemoveMessage(index);
break;
}
}
}
return result;
}
// CheckMessageMessages
bool
LaunchContext::CheckMessageMessages(team_id team, int32 &cookie)
{
BAutolock _lock(fLock);
bool result = true;
for (int32 i = 0; i < 3; i++)
result &= CheckMessageMessage(team, cookie, i);
return result;
}
// CheckMessageMessage
bool
LaunchContext::CheckMessageMessage(team_id team, int32 &cookie, int32 index)
{
bool result = true;
if (fCaller.SupportsMessages() > index && index < 3) {
uint32 commands[] = { MSG_1, MSG_2, MSG_3 };
BMessage message(commands[index]);
result = CheckMessageMessage(team, cookie, &message);
}
return result;
}
// CheckMessageMessage
bool
LaunchContext::CheckMessageMessage(team_id team, int32 &cookie,
const BMessage *expectedMessage)
{
BMessage *message = NextMessageFrom(team, cookie);
bool result = (message && message->what == MSG_MESSAGE_RECEIVED);
if (result) {
BMessage sentMessage;
result = (message->FindMessage("message", &sentMessage) == B_OK
&& sentMessage.what == expectedMessage->what);
}
return result;
}
// CheckRefsMessage
bool
LaunchContext::CheckRefsMessage(team_id team, int32 &cookie)
{
bool result = true;
if (fCaller.SupportsRefs())
result = CheckRefsMessage(team, cookie, fCaller.Ref());
return result;
}
// CheckRefsMessage
bool
LaunchContext::CheckRefsMessage(team_id team, int32 &cookie,
const entry_ref *refs, int32 count)
{
BMessage *message = NextMessageFrom(team, cookie);
bool result = (message && message->what == MSG_REFS_RECEIVED);
if (result) {
entry_ref ref;
for (int32 i = 0; result && i < count; i++) {
result = (message->FindRef("refs", i, &ref) == B_OK
&& ref == refs[i]);
}
}
return result;
}
// RemoveRefsMessage
bool
LaunchContext::RemoveRefsMessage(team_id team)
{
BAutolock _lock(fLock);
bool result = true;
if (fCaller.SupportsRefs()) {
result = false;
int32 cookie = 0;
while (BMessage *message = NextMessageFrom(team, cookie)) {
if (message->what == MSG_REFS_RECEIVED) {
int32 index = --cookie;
result = CheckRefsMessage(team, cookie);
delete AppInfoFor(team)->RemoveMessage(index);
break;
}
}
}
return result;
}
// StandardMessages
BList*
LaunchContext::StandardMessages()
{
if (fStandardMessages.IsEmpty()) {
fStandardMessages.AddItem(new BMessage(MSG_1));
fStandardMessages.AddItem(new BMessage(MSG_2));
fStandardMessages.AddItem(new BMessage(MSG_3));
}
return &fStandardMessages;
}
// AppInfoAt
LaunchContext::AppInfo*
LaunchContext::AppInfoAt(int32 index) const
@@ -4,14 +4,26 @@
#define LAUNCH_TESTER_HELPER_H
#include <Application.h>
#include <List.h>
#include <Locker.h>
#include <MessageQueue.h>
#include <OS.h>
enum {
MSG_1 = 'msg1',
MSG_2 = 'msg2',
MSG_3 = 'msg3',
};
// LaunchCaller
class LaunchCaller {
public:
virtual status_t operator()(const char *type, team_id *team) = 0;
virtual status_t operator()(const char *type, BList *messages, int32 argc,
const char **argv, team_id *team) = 0;
virtual int32 SupportsMessages() const { return 1; }
virtual bool SupportsArgv() const { return SupportsMessages() == 0; }
virtual bool SupportsRefs() const { return false; }
virtual const entry_ref *Ref() const { return NULL; }
};
// LaunchContext
@@ -21,6 +33,8 @@ public:
~LaunchContext();
status_t operator()(const char *type, team_id *team);
status_t operator()(const char *type, BList *messages, int32 argc,
const char **argv, team_id *team);
void HandleMessage(BMessage *message);
@@ -31,6 +45,29 @@ public:
BMessage *NextMessageFrom(team_id team, int32 &cookie,
bigtime_t *time = NULL);
bool CheckNextMessage(team_id team, int32 &cookie, uint32 what);
bool CheckArgvMessage(team_id team, int32 &cookie,
const entry_ref *appRef, bool useRef = true);
bool CheckArgvMessage(team_id team, int32 &cookie, const entry_ref *appRef,
int32 argc, const char **argv, bool useRef = true);
bool CheckArgvMessage(team_id team, int32 &cookie, const entry_ref *appRef,
const entry_ref *ref, int32 argc, const char **argv);
bool RemoveStandardArgvMessage(team_id team, const entry_ref *appRef);
bool RemoveArgvMessage(team_id team, const entry_ref *appRef, int32 argc,
const char **argv);
bool CheckMessageMessages(team_id team, int32 &cookie);
bool CheckMessageMessage(team_id team, int32 &cookie, int32 index);
bool CheckMessageMessage(team_id team, int32 &cookie,
const BMessage *message);
bool CheckRefsMessage(team_id team, int32 &cookie);
bool CheckRefsMessage(team_id team, int32 &cookie, const entry_ref *refs,
int32 count = 1);
bool RemoveRefsMessage(team_id team);
BList *StandardMessages();
public:
static const char *kStandardArgv[];
static const int32 kStandardArgc;
private:
class Message;
@@ -55,6 +92,7 @@ private:
thread_id fAppThread;
thread_id fTerminator;
bool fTerminating;
BList fStandardMessages;
};
// RosterLaunchApp