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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user