diff --git a/src/tests/kits/app/Jamfile b/src/tests/kits/app/Jamfile index 06e9caef4b..cfe9728a65 100644 --- a/src/tests/kits/app/Jamfile +++ b/src/tests/kits/app/Jamfile @@ -16,6 +16,11 @@ CommonTestLib libapptest.so LockTargetWithTimeoutTester.cpp MessengerAssignmentTester.cpp MessengerComparissonTester.cpp + SendMessageTester.cpp + SMInvoker.cpp + SMLooper.cpp + SMReplyTarget.cpp + SMTarget.cpp TargetTester.cpp : libopenbeos.so diff --git a/src/tests/kits/app/bmessenger/BMessengerCases b/src/tests/kits/app/bmessenger/BMessengerCases index 367032589e..627cbd0f0f 100644 --- a/src/tests/kits/app/bmessenger/BMessengerCases +++ b/src/tests/kits/app/bmessenger/BMessengerCases @@ -180,5 +180,61 @@ bool operator!=(const BMessenger &a, const BMessenger &b) included in == cases bool operator<(const BMessenger &a, const BMessenger &b) -TODO +case 1: set fields of a and b manually => + should return whatever the reference implementation returns. + +status_t SendMessage(uint32 command, BHandler *replyTo) const +case 1: this is uninitialized, replyTo is NULL => + should return B_BAD_PORT_ID. +case 2: this is uninitialized, replyTo points to a valid handler => + should return B_BAD_PORT_ID. +case 3: this is initialized to a local target with preferred handler, + replyTo is NULL => + should deliver the message and return B_OK. +case 4: this is initialized to a local target with preferred handler, + replyTo points to a valid handler => + should deliver the message and return B_OK, a reply should be posted + to the reply handler. +case 5: this is initialized to a local target with specific handler, + replyTo is NULL => + should deliver the message and return B_OK. +case 6: this is initialized to a local target with specific handler, + replyTo points to a valid handler => + should deliver the message and return B_OK, a reply should be posted + to the reply handler. +TODO: remote targets... + +status_t SendMessage(BMessage *message, BHandler *replyTo, + bigtime_t timeout) const +case 1: message is NULL, replyTo is NULL, timeout is B_INFINITE_TIMEOUT => + should return B_BAD_VALUE. +other cases similar to those of SendMessage(uint32, BHandler *). Each one with +a timeout of B_INFINITE_TIMEOUT, 0 and some ms. For the last two +timeouts in failure cases B_WOULD_BLOCK/B_TIMED_OUT should be returned. + +status_t SendMessage(BMessage *message, BMessenger replyTo, + bigtime_t timeout) const +cases similar to those of SendMessage(BMessage *, BHandler *, bigtime_t). +An invalid replyTo messenger causes the same behavior as a NULL handler. + +status_t SendMessage(uint32 command, BMessage *reply) const +case 1: this is uninitialized, reply is NULL => + should return B_BAD_PORT_ID or B_BAD_VALUE. +case 2: this is uninitialized, replyTo points to a valid message => + should return B_BAD_PORT_ID. +case 3: this is initialized to a local target with preferred handler, + reply is NULL => + should return B_BAD_VALUE. +case 4: this is initialized to a local target with preferred handler, + reply points to a valid message => + should deliver the message, wait for a reply and return B_OK, + reply should contain the reply. + +status_t SendMessage(BMessage *message, BMessage *reply, + bigtime_t deliveryTimeout, + bigtime_t replyTimeout) const +cases similar to those of SendMessage(uint32, BMessage *). deliveryTimeout and +replyTimeout are B_INFINITE_TIMEOUT, 0 or some ms. In timeout cases +B_WOULD_BLOCK/B_TIMED_OUT should be returned. + diff --git a/src/tests/kits/app/bmessenger/MessengerTest.cpp b/src/tests/kits/app/bmessenger/MessengerTest.cpp index 3ee6d324bd..9f72eb7c16 100644 --- a/src/tests/kits/app/bmessenger/MessengerTest.cpp +++ b/src/tests/kits/app/bmessenger/MessengerTest.cpp @@ -4,6 +4,7 @@ #include "LockTargetWithTimeoutTester.h" #include "MessengerAssignmentTester.h" #include "MessengerComparissonTester.h" +#include "SendMessageTester.h" #include "TargetTester.h" CppUnit::Test* MessengerTestSuite() @@ -14,6 +15,7 @@ CppUnit::Test* MessengerTestSuite() testSuite->addTest(LockTargetWithTimeoutTester::Suite()); testSuite->addTest(MessengerAssignmentTester::Suite()); testSuite->addTest(MessengerComparissonTester::Suite()); + testSuite->addTest(SendMessageTester::Suite()); testSuite->addTest(TBMessengerTester::Suite()); testSuite->addTest(TargetTester::Suite()); diff --git a/src/tests/kits/app/bmessenger/SMInvoker.cpp b/src/tests/kits/app/bmessenger/SMInvoker.cpp new file mode 100644 index 0000000000..d84959f8df --- /dev/null +++ b/src/tests/kits/app/bmessenger/SMInvoker.cpp @@ -0,0 +1,123 @@ +// SMInvoker.cpp + +#include "SMInvoker.h" +#include "SMMessages.h" + +// SMInvoker + +// constructor +SMInvoker::SMInvoker() + : fReplyMessage(NULL) +{ +} + +// destructor +SMInvoker::~SMInvoker() +{ + delete fReplyMessage; +} + +// ReplySuccess +bool +SMInvoker::ReplySuccess() +{ + return (fReplyMessage && fReplyMessage->what == MSG_REPLY); +} + +// DirectReply +bool +SMInvoker::DirectReply() +{ + return fReplyMessage; +} + + +// SMInvoker1 + +// constructor +SMInvoker1::SMInvoker1(bool useReplyTo) + : SMInvoker(), + fUseReplyTo(useReplyTo) +{ +} + +// Invoke +status_t +SMInvoker1::Invoke(BMessenger &target, BHandler *replyHandler, + BMessenger &replyMessenger) +{ + BHandler *replyTo = (fUseReplyTo ? replyHandler : NULL); + status_t result = target.SendMessage(MSG_TEST, replyTo); + return result; +} + + +// SMInvoker2 + +// constructor +SMInvoker2::SMInvoker2(bool useMessage, bool useReplyTo, bigtime_t timeout) + : SMInvoker(), + fUseMessage(useMessage), + fUseReplyTo(useReplyTo), + fTimeout(timeout) +{ +} + +// Invoke +status_t +SMInvoker2::Invoke(BMessenger &target, BHandler *replyHandler, + BMessenger &replyMessenger) +{ + BHandler *replyTo = (fUseReplyTo ? replyHandler : NULL); + BMessage _message(MSG_TEST); + BMessage *message = (fUseMessage ? &_message : NULL); + status_t result = target.SendMessage(message, replyTo, fTimeout); + return result; +} + + +// SMInvoker3 + +// constructor +SMInvoker3::SMInvoker3(bool useMessage, bool useReplyTo, bigtime_t timeout) + : SMInvoker(), + fUseMessage(useMessage), + fUseReplyTo(useReplyTo), + fTimeout(timeout) +{ +} + +// Invoke +status_t +SMInvoker3::Invoke(BMessenger &target, BHandler *replyHandler, + BMessenger &replyMessenger) +{ + BMessenger badMessenger; + BMessenger &replyTo = (fUseReplyTo ? replyMessenger : badMessenger); + BMessage _message(MSG_TEST); + BMessage *message = (fUseMessage ? &_message : NULL); + status_t result = target.SendMessage(message, replyTo, fTimeout); + return result; +} + + +// SMInvoker4 + +// constructor +SMInvoker4::SMInvoker4(bool useReply) + : SMInvoker(), + fUseReply(useReply) +{ +} + +// Invoke +status_t +SMInvoker4::Invoke(BMessenger &target, BHandler *replyHandler, + BMessenger &replyMessenger) +{ + if (fUseReply) + fReplyMessage = new BMessage(0UL); + status_t result = target.SendMessage(MSG_TEST, fReplyMessage); + return result; +} + diff --git a/src/tests/kits/app/bmessenger/SMInvoker.h b/src/tests/kits/app/bmessenger/SMInvoker.h new file mode 100644 index 0000000000..30a8b314f3 --- /dev/null +++ b/src/tests/kits/app/bmessenger/SMInvoker.h @@ -0,0 +1,75 @@ +// SMInvoker.h + +#ifndef SM_INVOKER_H +#define SM_INVOKER_H + +#include + +class SMInvoker { +public: + SMInvoker(); + virtual ~SMInvoker(); + + virtual status_t Invoke(BMessenger &target, BHandler *replyHandler, + BMessenger &replyMessenger) = 0; + + bool ReplySuccess(); + bool DirectReply(); + +protected: + BMessage *fReplyMessage; +}; + +// Invoker for SendMessage(uint32, BHandler *) +class SMInvoker1 : public SMInvoker { +public: + SMInvoker1(bool useReplyTo); + + virtual status_t Invoke(BMessenger &target, BHandler *replyHandler, + BMessenger &replyMessenger); + +private: + bool fUseReplyTo; +}; + +// Invoker for SendMessage(BMessage *, BHandler *, bigtime_t) +class SMInvoker2 : public SMInvoker { +public: + SMInvoker2(bool useMessage, bool useReplyTo, bigtime_t timeout); + + virtual status_t Invoke(BMessenger &target, BHandler *replyHandler, + BMessenger &replyMessenger); + +private: + bool fUseMessage; + bool fUseReplyTo; + bigtime_t fTimeout; +}; + +// Invoker for SendMessage(BMessage *, BMessenger, bigtime_t) +class SMInvoker3 : public SMInvoker { +public: + SMInvoker3(bool useMessage, bool useReplyTo, bigtime_t timeout); + + virtual status_t Invoke(BMessenger &target, BHandler *replyHandler, + BMessenger &replyMessenger); + +private: + bool fUseMessage; + bool fUseReplyTo; + bigtime_t fTimeout; +}; + +// Invoker for SendMessage(uint32, BMessage *) +class SMInvoker4 : public SMInvoker { +public: + SMInvoker4(bool useReply); + + virtual status_t Invoke(BMessenger &target, BHandler *replyHandler, + BMessenger &replyMessenger); + +private: + bool fUseReply; +}; + +#endif // SM_INVOKER_H diff --git a/src/tests/kits/app/bmessenger/SMLooper.cpp b/src/tests/kits/app/bmessenger/SMLooper.cpp new file mode 100644 index 0000000000..29c438fb8d --- /dev/null +++ b/src/tests/kits/app/bmessenger/SMLooper.cpp @@ -0,0 +1,153 @@ +// SMLooper.cpp + +#include + +#include "SMLooper.h" +#include "SMMessages.h" + +// SMLooper + +// constructor +SMLooper::SMLooper() + : BLooper(NULL, B_NORMAL_PRIORITY, 1), + fUnblockTime(0), + fReplyDelay(0), + fDeliveryTime(-1), + fReplyTime(-1) +{ +} + +// destructor +SMLooper::~SMLooper() +{ +} + +// MessageReceived +void +SMLooper::MessageReceived(BMessage *message) +{ + switch (message->what) { + case MSG_BLOCK: + { + bigtime_t now = system_time(); + if (now < fUnblockTime) { + // port capacity is 1 => the following message blocks the + // port until return from MessageReceived(). + PostMessage(MSG_UNBLOCK, this); + snooze_until(fUnblockTime, B_SYSTEM_TIMEBASE); + } + break; + } + case MSG_UNBLOCK: + break; + case MSG_TEST: + SetDeliveryTime(system_time()); + if (fReplyDelay > 0) + snooze(fReplyDelay); + message->SendReply(MSG_REPLY); + break; + case MSG_REPLY: + fReplyTime = system_time(); + break; + default: + BLooper::MessageReceived(message); + break; + } +} + +// BlockUntil +void +SMLooper::BlockUntil(bigtime_t unblockTime) +{ + fUnblockTime = unblockTime; + PostMessage(MSG_BLOCK, this); +} + +// SetReplyDelay +void +SMLooper::SetReplyDelay(bigtime_t replyDelay) +{ + fReplyDelay = replyDelay; +} + +// ReplyDelay +bigtime_t +SMLooper::ReplyDelay() const +{ + return fReplyDelay; +} + +// DeliverySuccess +bool +SMLooper::DeliverySuccess() const +{ + return (fDeliveryTime >= 0); +} + +// SetDeliveryTime +void +SMLooper::SetDeliveryTime(bigtime_t deliveryTime) +{ + fDeliveryTime = deliveryTime; +} + +// DeliveryTime +bigtime_t +SMLooper::DeliveryTime() const +{ + return fDeliveryTime; +} + +// ReplySuccess +bool +SMLooper::ReplySuccess() const +{ + return (fReplyTime >= 0); +} + +// SetReplyTime +void +SMLooper::SetReplyTime(bigtime_t replyTime) +{ + fReplyTime = replyTime; +} + +// ReplyTime +bigtime_t +SMLooper::ReplyTime() const +{ + return fReplyTime; +} + + +// SMHandler + +// constructor +SMHandler::SMHandler() + : BHandler() +{ +} + +// MessageReceived +void +SMHandler::MessageReceived(BMessage *message) +{ + switch (message->what) { + case MSG_TEST: + if (SMLooper *looper = dynamic_cast(Looper())) { + looper->SetDeliveryTime(system_time()); + if (looper->ReplyDelay() > 0) + snooze(looper->ReplyDelay()); + } + message->SendReply(MSG_REPLY); + break; + case MSG_REPLY: + if (SMLooper *looper = dynamic_cast(Looper())) + looper->SetReplyTime(system_time()); + break; + default: + BHandler::MessageReceived(message); + break; + } +} + diff --git a/src/tests/kits/app/bmessenger/SMLooper.h b/src/tests/kits/app/bmessenger/SMLooper.h new file mode 100644 index 0000000000..9144e85a5d --- /dev/null +++ b/src/tests/kits/app/bmessenger/SMLooper.h @@ -0,0 +1,43 @@ +// SMLooper.h + +#ifndef SM_LOOPER_H +#define SM_LOOPER_H + +#include +#include + +class SMLooper : public BLooper { +public: + SMLooper(); + virtual ~SMLooper(); + + virtual void MessageReceived(BMessage *message); + + void BlockUntil(bigtime_t unblockTime); + + void SetReplyDelay(bigtime_t replyDelay); + bigtime_t ReplyDelay() const; + + bool DeliverySuccess() const; + void SetDeliveryTime(bigtime_t deliveryTime); + bigtime_t DeliveryTime() const; + + bool ReplySuccess() const; + void SetReplyTime(bigtime_t replyTime); + bigtime_t ReplyTime() const; + +private: + bigtime_t fUnblockTime; + bigtime_t fReplyDelay; + bigtime_t fDeliveryTime; + bigtime_t fReplyTime; +}; + +class SMHandler : public BHandler { +public: + SMHandler(); + + virtual void MessageReceived(BMessage *message); +}; + +#endif // SM_LOOPER_H diff --git a/src/tests/kits/app/bmessenger/SMMessages.h b/src/tests/kits/app/bmessenger/SMMessages.h new file mode 100644 index 0000000000..244f27730c --- /dev/null +++ b/src/tests/kits/app/bmessenger/SMMessages.h @@ -0,0 +1,13 @@ +// SMMessages.h +#ifndef SM_MESSAGES_H +#define SM_MESSAGES_H + +// message constants +enum { + MSG_BLOCK = 'blck', + MSG_UNBLOCK = 'unbl', + MSG_TEST = 'test', + MSG_REPLY = 'rply', +}; + +#endif // SM_MESSAGES_H diff --git a/src/tests/kits/app/bmessenger/SMReplyTarget.cpp b/src/tests/kits/app/bmessenger/SMReplyTarget.cpp new file mode 100644 index 0000000000..82b2784c0f --- /dev/null +++ b/src/tests/kits/app/bmessenger/SMReplyTarget.cpp @@ -0,0 +1,58 @@ +// SMReplyTarget.cpp + +#include +#include + +#include "SMReplyTarget.h" +#include "SMLooper.h" + +// constructor +SMReplyTarget::SMReplyTarget(bool preferred) + : fHandler(NULL), + fLooper(NULL) +{ + // create looper and handler + fLooper = new SMLooper; + fLooper->Run(); + if (!preferred) { + fHandler = new SMHandler; + CHK(fLooper->Lock()); + fLooper->AddHandler(fHandler); + fLooper->Unlock(); + } +} + +// destructor +SMReplyTarget::~SMReplyTarget() +{ + if (fLooper) { + fLooper->Lock(); + if (fHandler) { + fLooper->RemoveHandler(fHandler); + delete fHandler; + } + fLooper->Quit(); + } +} + +// Handler +BHandler * +SMReplyTarget::Handler() +{ + return fHandler; +} + +// Messenger +BMessenger +SMReplyTarget::Messenger() +{ + return BMessenger(fHandler, fLooper); +} + +// ReplySuccess +bool +SMReplyTarget::ReplySuccess() +{ + return fLooper->ReplySuccess(); +} + diff --git a/src/tests/kits/app/bmessenger/SMReplyTarget.h b/src/tests/kits/app/bmessenger/SMReplyTarget.h new file mode 100644 index 0000000000..2dcfe6312c --- /dev/null +++ b/src/tests/kits/app/bmessenger/SMReplyTarget.h @@ -0,0 +1,26 @@ +// SMReplyTarget.h + +#ifndef SM_REPLY_TARGET_H +#define SM_REPLY_TARGET_H + +#include + +class SMHandler; +class SMLooper; + +class SMReplyTarget { +public: + SMReplyTarget(bool preferred = false); + virtual ~SMReplyTarget(); + + virtual BHandler *Handler(); + virtual BMessenger Messenger(); + + virtual bool ReplySuccess(); + +private: + SMHandler *fHandler; + SMLooper *fLooper; +}; + +#endif // SM_REPLY_TARGET_H diff --git a/src/tests/kits/app/bmessenger/SMTarget.cpp b/src/tests/kits/app/bmessenger/SMTarget.cpp new file mode 100644 index 0000000000..604f95cc7e --- /dev/null +++ b/src/tests/kits/app/bmessenger/SMTarget.cpp @@ -0,0 +1,109 @@ +// SMTarget.cpp + +#include +#include + +#include "SMTarget.h" +#include "SMLooper.h" + +// SMTarget + +// constructor +SMTarget::SMTarget() +{ +} + +// destructor +SMTarget::~SMTarget() +{ +} + +// Init +void +SMTarget::Init(bigtime_t unblockTime, bigtime_t replyDelay) +{ +} + +// Handler +BHandler * +SMTarget::Handler() +{ + return NULL; +} + +// Messenger +BMessenger +SMTarget::Messenger() +{ + return BMessenger(); +} + +// DeliverySuccess +bool +SMTarget::DeliverySuccess() +{ + return false; +} + + +// LocalSMTarget + +// constructor +LocalSMTarget::LocalSMTarget(bool preferred) + : SMTarget(), + fHandler(NULL), + fLooper(NULL) +{ + // create looper and handler + fLooper = new SMLooper; + fLooper->Run(); + if (!preferred) { + fHandler = new SMHandler; + CHK(fLooper->Lock()); + fLooper->AddHandler(fHandler); + fLooper->Unlock(); + } +} + +// destructor +LocalSMTarget::~LocalSMTarget() +{ + if (fLooper) { + fLooper->Lock(); + if (fHandler) { + fLooper->RemoveHandler(fHandler); + delete fHandler; + } + fLooper->Quit(); + } +} + +// Init +void +LocalSMTarget::Init(bigtime_t unblockTime, bigtime_t replyDelay) +{ + fLooper->SetReplyDelay(replyDelay); + fLooper->BlockUntil(unblockTime); +} + +// Handler +BHandler * +LocalSMTarget::Handler() +{ + return fHandler; +} + +// Messenger +BMessenger +LocalSMTarget::Messenger() +{ + return BMessenger(fHandler, fLooper); +} + +// DeliverySuccess +bool +LocalSMTarget::DeliverySuccess() +{ + return fLooper->DeliverySuccess(); +} + diff --git a/src/tests/kits/app/bmessenger/SMTarget.h b/src/tests/kits/app/bmessenger/SMTarget.h new file mode 100644 index 0000000000..d4cdc9525a --- /dev/null +++ b/src/tests/kits/app/bmessenger/SMTarget.h @@ -0,0 +1,42 @@ +// SMTarget.h + +#ifndef SM_TARGET_H +#define SM_TARGET_H + +#include + +class SMHandler; +class SMLooper; + +// SMTarget +class SMTarget { +public: + SMTarget(); + virtual ~SMTarget(); + + virtual void Init(bigtime_t unblockTime, bigtime_t replyDelay); + + virtual BHandler *Handler(); + virtual BMessenger Messenger(); + virtual bool DeliverySuccess(); +}; + +// LocalSMTarget +class LocalSMTarget : public SMTarget { +public: + LocalSMTarget(bool preferred); + virtual ~LocalSMTarget(); + + virtual void Init(bigtime_t unblockTime, bigtime_t replyDelay); + + virtual BHandler *Handler(); + virtual BMessenger Messenger(); + + virtual bool DeliverySuccess(); + +private: + SMHandler *fHandler; + SMLooper *fLooper; +}; + +#endif // SM_TARGET_H diff --git a/src/tests/kits/app/bmessenger/SendMessageTester.cpp b/src/tests/kits/app/bmessenger/SendMessageTester.cpp new file mode 100644 index 0000000000..df9b1531ef --- /dev/null +++ b/src/tests/kits/app/bmessenger/SendMessageTester.cpp @@ -0,0 +1,396 @@ +//------------------------------------------------------------------------------ +// SendMessageTester.cpp +// +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- +#include + +// System Includes ------------------------------------------------------------- +#include +#include + +#include +#include +#include + +// Project Includes ------------------------------------------------------------ +#include +#include +#include + +// Local Includes -------------------------------------------------------------- +#include "Helpers.h" +#include "SendMessageTester.h" +#include "SMInvoker.h" +#include "SMLooper.h" +#include "SMReplyTarget.h" +#include "SMTarget.h" + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +// procedure: +// * init target (block/timeout), construct messenger +// (- uninitialized) +// - local +// - preferred +// - specific +// - remote +// - preferred +// - specific +// * init parameters +// - reply handler +// - reply messenger +// * invoke SM() +// * compare result +// * compare time +// * get + compare reply +// - no reply +// - reply handler +// - reply per reference + +// SM() params: +// +// status_t SendMessage(uint32 command, BHandler *replyTo = NULL) const; +// * command +// * useReplyTo +// +// status_t SendMessage(BMessage *message, BHandler *replyTo = NULL, +// bigtime_t timeout = B_INFINITE_TIMEOUT) const; +// * message (command?) +// * useReplyTo +// * timeout +// +// status_t SendMessage(BMessage *message, BMessenger replyTo, +// bigtime_t timeout = B_INFINITE_TIMEOUT) const; +// * message (command?) +// * useReplyTo +// * timeout +// +// status_t SendMessage(uint32 command, BMessage *reply) const; +// * command +// * useReply +// +// status_t SendMessage(BMessage *message, BMessage *reply, +// bigtime_t deliveryTimeout = B_INFINITE_TIMEOUT, +// bigtime_t replyTimeout = B_INFINITE_TIMEOUT) const; +// * message (command?) +// * useReply +// * deliveryTimeout +// * replyTimeout +// + +// Tester params: +// +// target: +// - invalid +// - local +// - preferred +// - specific +// - remote +// - preferred +// - specific +// +// target behavior: +// - unblock after ms +// - reply after ms +// +// SM() result +// +// delivery success +// +// SM() return time + + +enum target_kind { + TARGET_UNINITIALIZED, + TARGET_LOCAL_PREFERRED, + TARGET_LOCAL_SPECIFIC, + // ... +}; + + +class SMTester { +public: +// target: +// - invalid +// - local +// - preferred +// - specific +// - remote +// - preferred +// - specific +// +// target behavior: +// - unblock after ms +// - reply after ms +// +// SM() result +// +// SM() return time + SMTester(target_kind targetKind) + : fTargetKind(targetKind) + { + } + + ~SMTester() + { + } + + void Run(SMInvoker &invoker, bigtime_t targetUnblock, + bigtime_t targetReply, status_t result, bool deliverySuccess, + bool replySuccess, bigtime_t duration) + { +// NextSubTest(); +printf("SMTester::Run(%lld, %lld, %lx, %d, %d, %lld)\n", targetUnblock, +targetReply, result, deliverySuccess, replySuccess, duration); + enum { JITTER = 10000 }; + enum { SETUP_LATENCY = 100000 }; + enum { DELIVERY_LATENCY = 10000 }; + enum { TARGET_HEAD_START = 1000 }; + if (targetUnblock == 0) + targetUnblock = -TARGET_HEAD_START; + // create the target + SMTarget *target = NULL; + switch (fTargetKind) { + case TARGET_UNINITIALIZED: + target = new SMTarget; + break; + case TARGET_LOCAL_PREFERRED: + target = new LocalSMTarget(true); + break; + case TARGET_LOCAL_SPECIFIC: + target = new LocalSMTarget(false); + break; + } + AutoDeleter deleter(target); + // create the reply target + SMReplyTarget replyTarget; + // init the target and send the message + BHandler *replyHandler = replyTarget.Handler(); + BMessenger replyMessenger = replyTarget.Messenger(); + bigtime_t startTime = system_time() + SETUP_LATENCY; + target->Init(startTime + targetUnblock, targetReply); + BMessenger targetMessenger = target->Messenger(); + snooze_until(startTime, B_SYSTEM_TIMEBASE); + status_t actualResult = invoker.Invoke(targetMessenger, replyHandler, + replyMessenger); + bigtime_t actualDuration = system_time() - startTime; +printf("duration: %lld vs %lld\n", actualDuration, duration); + // We need to wait for the reply, if reply mode is asynchronous. + snooze_until(startTime + targetUnblock + targetReply + + 2 * DELIVERY_LATENCY, B_SYSTEM_TIMEBASE); + bool actualReplySuccess = invoker.ReplySuccess(); + if (!invoker.DirectReply()) + actualReplySuccess = replyTarget.ReplySuccess(); + // check the results +if (actualResult != result) +printf("result: %lx vs %lx\n", actualResult, result); + CHK(actualResult == result); + CHK(target->DeliverySuccess() == deliverySuccess); + CHK(actualReplySuccess == replySuccess); + CHK(actualDuration > duration - JITTER + && actualDuration < duration + JITTER); + } + +private: + target_kind fTargetKind; +}; + + +//------------------------------------------------------------------------------ + +// constructor +SendMessageTester::SendMessageTester() + : BThreadedTestCase(), + fHandler(NULL), + fLooper(NULL) +{ +} + +// constructor +SendMessageTester::SendMessageTester(std::string name) + : BThreadedTestCase(name), + fHandler(NULL), + fLooper(NULL) +{ +} + +// destructor +SendMessageTester::~SendMessageTester() +{ + if (fLooper) { + fLooper->Lock(); + if (fHandler) { + fLooper->RemoveHandler(fHandler); + delete fHandler; + } + fLooper->Quit(); + } +} + +// TestUninitialized +static +void +TestUninitialized() +{ + SMTester tester(TARGET_UNINITIALIZED); + // status_t SendMessage(uint32 command, BHandler *replyTo) const + { + SMInvoker1 invoker1(false); + SMInvoker1 invoker2(true); + tester.Run(invoker1, 0, 0, B_BAD_PORT_ID, false, false, 0); + tester.Run(invoker2, 0, 0, B_BAD_PORT_ID, false, false, 0); + } + // status_t SendMessage(BMessage *message, BHandler *replyTo, + // bigtime_t timeout) const + { + SMInvoker2 invoker1(true, false, B_INFINITE_TIMEOUT); + SMInvoker2 invoker2(true, true, B_INFINITE_TIMEOUT); + tester.Run(invoker1, 0, 0, B_BAD_PORT_ID, false, false, 0); + tester.Run(invoker2, 0, 0, B_BAD_PORT_ID, false, false, 0); + } + // status_t SendMessage(BMessage *message, BMessenger replyTo, + // bigtime_t timeout) const + { + SMInvoker3 invoker1(true, false, B_INFINITE_TIMEOUT); + SMInvoker3 invoker2(true, true, B_INFINITE_TIMEOUT); + tester.Run(invoker1, 0, 0, B_BAD_PORT_ID, false, false, 0); + tester.Run(invoker2, 0, 0, B_BAD_PORT_ID, false, false, 0); + } + // status_t SendMessage(uint32 command, BMessage *reply) const + { + SMInvoker4 invoker1(false); + SMInvoker4 invoker2(true); +// We check the parameters first. +#ifdef TEST_OBOS + tester.Run(invoker1, 0, 0, B_BAD_VALUE, false, false, 0); +#else + tester.Run(invoker1, 0, 0, B_BAD_PORT_ID, false, false, 0); +#endif + tester.Run(invoker2, 0, 0, B_BAD_PORT_ID, false, false, 0); + } +} + +// TestInitialized +static +void +TestInitialized(SMTester &tester) +{ + // status_t SendMessage(uint32 command, BHandler *replyTo) const + { + SMInvoker1 invoker1(false); + SMInvoker1 invoker2(true); + tester.Run(invoker1, 0, 0, B_OK, true, false, 0); + tester.Run(invoker2, 0, 0, B_OK, true, true, 0); + } + // status_t SendMessage(BMessage *message, BHandler *replyTo, + // bigtime_t timeout) const + { +// R5 crashes when passing a NULL message. +#ifndef TEST_R5 + SMInvoker2 invoker1(false, false, B_INFINITE_TIMEOUT); + tester.Run(invoker1, 0, 0, B_BAD_VALUE, false, false, 0); +#endif + } + { + SMInvoker2 invoker1(true, false, B_INFINITE_TIMEOUT); + SMInvoker2 invoker2(true, true, B_INFINITE_TIMEOUT); + tester.Run(invoker1, 0, 0, B_OK, true, false, 0); + tester.Run(invoker2, 0, 0, B_OK, true, true, 0); + } + { + SMInvoker2 invoker1(true, false, 0); + SMInvoker2 invoker2(true, true, 0); + tester.Run(invoker1, 0, 0, B_OK, true, false, 0); + tester.Run(invoker2, 0, 0, B_OK, true, true, 0); + tester.Run(invoker1, 20000, 0, B_WOULD_BLOCK, false, false, 0); + tester.Run(invoker2, 20000, 0, B_WOULD_BLOCK, false, false, 0); + } + { + SMInvoker2 invoker1(true, false, 20000); + SMInvoker2 invoker2(true, true, 20000); + tester.Run(invoker1, 10000, 0, B_OK, true, false, 10000); + tester.Run(invoker2, 10000, 0, B_OK, true, true, 10000); + tester.Run(invoker1, 40000, 0, B_TIMED_OUT, false, false, 20000); + tester.Run(invoker2, 40000, 0, B_TIMED_OUT, false, false, 20000); + } + // status_t SendMessage(BMessage *message, BMessenger replyTo, + // bigtime_t timeout) const + { +// R5 crashes when passing a NULL message. +#ifndef TEST_R5 + SMInvoker3 invoker1(false, false, B_INFINITE_TIMEOUT); + tester.Run(invoker1, 0, 0, B_BAD_VALUE, false, false, 0); +#endif + } + { + SMInvoker3 invoker1(true, false, B_INFINITE_TIMEOUT); + SMInvoker3 invoker2(true, true, B_INFINITE_TIMEOUT); + tester.Run(invoker1, 0, 0, B_OK, true, false, 0); + tester.Run(invoker2, 0, 0, B_OK, true, true, 0); + } + { + SMInvoker3 invoker1(true, false, 0); + SMInvoker3 invoker2(true, true, 0); + tester.Run(invoker1, 0, 0, B_OK, true, false, 0); + tester.Run(invoker2, 0, 0, B_OK, true, true, 0); + tester.Run(invoker1, 20000, 0, B_WOULD_BLOCK, false, false, 0); + tester.Run(invoker2, 20000, 0, B_WOULD_BLOCK, false, false, 0); + } + { + SMInvoker3 invoker1(true, false, 20000); + SMInvoker3 invoker2(true, true, 20000); + tester.Run(invoker1, 10000, 0, B_OK, true, false, 10000); + tester.Run(invoker2, 10000, 0, B_OK, true, true, 10000); + tester.Run(invoker1, 40000, 0, B_TIMED_OUT, false, false, 20000); + tester.Run(invoker2, 40000, 0, B_TIMED_OUT, false, false, 20000); + } + // status_t SendMessage(uint32 command, BMessage *reply) const + { +// R5 crashes when passing a NULL reply message +#ifndef TEST_R5 + SMInvoker4 invoker1(false); +#endif + SMInvoker4 invoker2(true); +#ifndef TEST_R5 + tester.Run(invoker1, 20000, 20000, B_BAD_VALUE, false, false, 0); +#endif + tester.Run(invoker2, 20000, 20000, B_OK, true, true, 40000); + } +} + +/* + bool operator<(const BMessenger &a, const BMessenger &b) + @case 1 set fields of a and b manually + @results should return whatever the reference implementation + returns. + */ +void SendMessageTester::SendMessageTest1() +{ + TestUninitialized(); + target_kind targetKinds[] = { + TARGET_LOCAL_PREFERRED, + TARGET_LOCAL_SPECIFIC + }; + int32 targetKindCount = sizeof(targetKinds) / sizeof(target_kind); + for (int32 i = 0; i < targetKindCount; i++) { + SMTester tester(targetKinds[i]); + TestInitialized(tester); + } +} + + +Test* SendMessageTester::Suite() +{ + typedef BThreadedTestCaller TC; + + TestSuite* testSuite = new TestSuite; + + ADD_TEST(testSuite, SendMessageTester, SendMessageTest1); + + return testSuite; +} + diff --git a/src/tests/kits/app/bmessenger/SendMessageTester.h b/src/tests/kits/app/bmessenger/SendMessageTester.h new file mode 100644 index 0000000000..7935f4afaf --- /dev/null +++ b/src/tests/kits/app/bmessenger/SendMessageTester.h @@ -0,0 +1,43 @@ +//------------------------------------------------------------------------------ +// SendMessageTester.h +// +//------------------------------------------------------------------------------ + +#ifndef SEND_MESSAGE_TESTER_H +#define SEND_MESSAGE_TESTER_H + +// Standard Includes ----------------------------------------------------------- + +// System Includes ------------------------------------------------------------- + +// Project Includes ------------------------------------------------------------ +#include + +// Local Includes -------------------------------------------------------------- +#include "../common.h" + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +class BHandler; +class BLooper; + +class SendMessageTester : public BThreadedTestCase +{ +public: + SendMessageTester(); + SendMessageTester(std::string name); + virtual ~SendMessageTester(); + + void SendMessageTest1(); + + static Test* Suite(); + +private: + BHandler *fHandler; + BLooper *fLooper; +}; + +#endif // SEND_MESSAGE_TESTER_H +