#include <stdio.h>
#include <Message.h>
#include <OS.h>
#include <Handler.h>
#include <Looper.h>
#include <Messenger.h>
#include <TestUtils.h>
#include <ThreadedTestCaller.h>
#include <cppunit/TestSuite.h>
#include "Helpers.h"
#include "MessengerComparissonTester.h"
#include "SMTarget.h"
struct FakeMessenger {
port_id fPort;
int32 fHandlerToken;
team_id fTeam;
int32 extra0;
int32 extra1;
bool fPreferredTarget;
bool extra2;
bool extra3;
bool extra4;
};
static
bool
operator<(const FakeMessenger& a, const FakeMessenger& b)
{
return (a.fPort < b.fPort
|| a.fPort == b.fPort
&& (a.fHandlerToken < b.fHandlerToken
|| a.fHandlerToken == b.fHandlerToken
&& !a.fPreferredTarget && b.fPreferredTarget));
}
static
bool
operator!=(const FakeMessenger& a, const FakeMessenger& b)
{
return (a < b || b < a);
}
static
bool
operator==(const FakeMessenger& a, const FakeMessenger& b)
{
return !(a != b);
}
MessengerComparissonTester::MessengerComparissonTester()
: BThreadedTestCase(),
fHandler(NULL),
fLooper(NULL)
{
}
MessengerComparissonTester::MessengerComparissonTester(std::string name)
: BThreadedTestCase(name),
fHandler(NULL),
fLooper(NULL)
{
}
MessengerComparissonTester::~MessengerComparissonTester()
{
if (fLooper) {
fLooper->Lock();
if (fHandler) {
fLooper->RemoveHandler(fHandler);
delete fHandler;
}
fLooper->Quit();
}
}
bool operator==(const BMessenger &other) const
bool operator!=(const BMessenger &a, const BMessenger &b)
@case 1 this (a) and other (b) are uninitialized
@results should return true/false.
*/
void MessengerComparissonTester::ComparissonTest1()
{
BMessenger a;
BMessenger b;
CHK(a == b);
CHK(b == a);
CHK(!(a != b));
CHK(!(b != a));
}
bool operator==(const BMessenger &other) const
bool operator!=(const BMessenger &a, const BMessenger &b)
@case 1 this (a) is initialized, other (b) is uninitialized,
and vice versa
@results should return false/true.
*/
void MessengerComparissonTester::ComparissonTest2()
{
BLooper *looper = new BLooper;
looper->Run();
LooperQuitter quitter(looper);
BMessenger a(NULL, looper);
BMessenger b;
CHK(a != b);
CHK(b != a);
CHK(!(a == b));
CHK(!(b == a));
}
bool operator==(const BMessenger &other) const
bool operator!=(const BMessenger &a, const BMessenger &b)
bool operator<(const BMessenger &a, const BMessenger &b)
@case 3 this and other are initialized, different cases:
- same object => true
- different objects same target => true
- looper preferred handler vs. same looper but the looper
itself as handler => false
- looper preferred handler vs. other looper preferred
handler => false
- looper preferred handler vs. other looper specific
handler => false
- local looper vs. remote looper => false
*/
void MessengerComparissonTester::ComparissonTest3()
{
BLooper *looper1 = new BLooper;
looper1->Run();
LooperQuitter quitter1(looper1);
BHandler *handler1 = new BHandler;
HandlerDeleter deleter1(handler1);
CHK(looper1->Lock());
looper1->AddHandler(handler1);
looper1->Unlock();
BMessenger messenger1(handler1, looper1);
BMessenger messenger1a(handler1, looper1);
BMessenger messenger2(NULL, looper1);
BMessenger messenger2a(NULL, looper1);
BLooper *looper2 = new BLooper;
looper2->Run();
LooperQuitter quitter2(looper2);
BHandler *handler2 = new BHandler;
HandlerDeleter deleter2(handler2);
CHK(looper2->Lock());
looper2->AddHandler(handler2);
looper2->Unlock();
BMessenger messenger3(handler2, looper2);
BMessenger messenger3a(handler2, looper2);
BMessenger messenger4(NULL, looper2);
BMessenger messenger4a(NULL, looper2);
RemoteSMTarget remoteTarget1(false);
RemoteSMTarget remoteTarget2(true);
BMessenger messenger5(remoteTarget1.Messenger());
BMessenger messenger5a(remoteTarget1.Messenger());
BMessenger messenger6(remoteTarget2.Messenger());
BMessenger messenger6a(remoteTarget2.Messenger());
struct target {
BMessenger &messenger;
int32 id;
} targets[] = {
{ messenger1, 1 },
{ messenger1a, 1 },
{ messenger2, 2 },
{ messenger2, 2 },
{ messenger3, 3 },
{ messenger3a, 3 },
{ messenger4, 4 },
{ messenger4a, 4 },
{ messenger5, 5 },
{ messenger5a, 5 },
{ messenger6, 6 },
{ messenger6a, 6 },
};
int32 targetCount = sizeof(targets) / sizeof(target);
for (int32 i = 0; i < targetCount; i++) {
NextSubTest();
const target &target1 = targets[i];
const BMessenger &a = target1.messenger;
for (int32 k = 0; k < targetCount; k++) {
const target &target2 = targets[k];
const BMessenger &b = target2.messenger;
bool areEqual = (target1.id == target2.id);
CHK((a == b) == areEqual);
CHK((b == a) == areEqual);
CHK((a != b) == !areEqual);
CHK((b != a) == !areEqual);
}
}
}
static inline
void
Compare(const FakeMessenger &fake1, const FakeMessenger &fake2,
const BMessenger &messenger1, const BMessenger &messenger2)
{
CHK((messenger1 == messenger2) == (fake1 == fake2));
CHK((messenger1 != messenger2) == (fake1 != fake2));
CHK((messenger1 < messenger2) == (fake1 < fake2));
}
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 MessengerComparissonTester::LessTest1()
{
port_id ports[] = { -1, 0, 1 } ;
int32 tokens[] = { -1, 0, 1 } ;
team_id teams[] = { -1, 0, 1 } ;
bool preferreds[] = { false, true } ;
int32 portCount = sizeof(ports) / sizeof(port_id);
int32 tokenCount = sizeof(tokens) / sizeof(int32);
int32 teamCount = sizeof(teams) / sizeof(team_id);
int32 preferredCount = 2;
for (int32 p1 = 0; p1 < portCount; p1++) {
port_id port1 = ports[p1];
for (int32 to1 = 0; to1 < tokenCount; to1++) {
int32 token1 = tokens[to1];
for (int32 te1 = 0; te1 < teamCount; te1++) {
team_id team1 = teams[te1];
for (int32 pr1 = 0; pr1 < preferredCount; pr1++) {
bool preferred1 = preferreds[pr1];
FakeMessenger fake1;
fake1.fPort = port1;
fake1.fHandlerToken = token1;
fake1.fTeam = team1;
fake1.fPreferredTarget = preferred1;
BMessenger &messenger1 = *(BMessenger*)&fake1;
for (int32 p2 = 0; p2 < portCount; p2++) {
port_id port2 = ports[p2];
for (int32 to2 = 0; to2 < tokenCount; to2++) {
int32 token2 = tokens[to2];
for (int32 te2 = 0; te2 < teamCount; te2++) {
team_id team2 = teams[te2];
for (int32 pr2 = 0; pr2 < preferredCount;
pr2++) {
bool preferred2 = preferreds[pr2];
FakeMessenger fake2;
fake2.fPort = port2;
fake2.fHandlerToken = token2;
fake2.fTeam = team2;
fake2.fPreferredTarget = preferred2;
BMessenger &messenger2
= *(BMessenger*)&fake2;
Compare(fake1, fake2, messenger1,
messenger2);
}
}
}
}
}
}
}
}
}
Test* MessengerComparissonTester::Suite()
{
typedef BThreadedTestCaller<MessengerComparissonTester> TC;
TestSuite* testSuite = new TestSuite;
ADD_TEST4(BMessenger, testSuite, MessengerComparissonTester, ComparissonTest1);
ADD_TEST4(BMessenger, testSuite, MessengerComparissonTester, ComparissonTest2);
ADD_TEST4(BMessenger, testSuite, MessengerComparissonTester, ComparissonTest3);
ADD_TEST4(BMessenger, testSuite, MessengerComparissonTester, LessTest1);
return testSuite;
}