197403Sobrien//------------------------------------------------------------------------------
297403Sobrien//	MessengerComparissonTester.cpp
3132720Skan//
497403Sobrien//------------------------------------------------------------------------------
5132720Skan
697403Sobrien// Standard Includes -----------------------------------------------------------
7132720Skan#include <stdio.h>
897403Sobrien
997403Sobrien// System Includes -------------------------------------------------------------
1097403Sobrien#include <Message.h>
1197403Sobrien#include <OS.h>
12132720Skan
1397403Sobrien#include <Handler.h>
1497403Sobrien#include <Looper.h>
1597403Sobrien#include <Messenger.h>
1697403Sobrien
1797403Sobrien// Project Includes ------------------------------------------------------------
18132720Skan#include <TestUtils.h>
19169691Skan#include <ThreadedTestCaller.h>
20169691Skan#include <cppunit/TestSuite.h>
2197403Sobrien
2297403Sobrien// Local Includes --------------------------------------------------------------
2397403Sobrien#include "Helpers.h"
2497403Sobrien#include "MessengerComparissonTester.h"
2597403Sobrien#include "SMTarget.h"
2697403Sobrien
2797403Sobrien// Local Defines ---------------------------------------------------------------
2897403Sobrien
2997403Sobrien// Globals ---------------------------------------------------------------------
3097403Sobrien
3197403Sobrien//------------------------------------------------------------------------------
3297403Sobrien
3397403Sobrienstruct FakeMessenger {
3497403Sobrien	port_id	fPort;
3597403Sobrien	int32	fHandlerToken;
3697403Sobrien	team_id	fTeam;
3797403Sobrien	int32	extra0;
3897403Sobrien	int32	extra1;
3997403Sobrien	bool	fPreferredTarget;
4097403Sobrien	bool	extra2;
4197403Sobrien	bool	extra3;
4297403Sobrien	bool	extra4;
4397403Sobrien};
4497403Sobrien
45132720Skanstatic
4697403Sobrienbool
4797403Sobrienoperator<(const FakeMessenger& a, const FakeMessenger& b)
48132720Skan{
49132720Skan	// significance:
50132720Skan	// * fPort
51132720Skan	// * fHandlerToken
52132720Skan	// * fPreferredTarget
53132720Skan	// fTeam is insignificant
54132720Skan	return (a.fPort < b.fPort
5597403Sobrien			|| a.fPort == b.fPort
5697403Sobrien				&& (a.fHandlerToken < b.fHandlerToken
57132720Skan					|| a.fHandlerToken == b.fHandlerToken
5897403Sobrien						&& !a.fPreferredTarget && b.fPreferredTarget));
5997403Sobrien}
6097403Sobrien
6197403Sobrienstatic
6297403Sobrienbool
6397403Sobrienoperator!=(const FakeMessenger& a, const FakeMessenger& b)
6497403Sobrien{
6597403Sobrien	return (a < b || b < a);
6697403Sobrien}
6797403Sobrien
6897403Sobrienstatic
6997403Sobrienbool
7097403Sobrienoperator==(const FakeMessenger& a, const FakeMessenger& b)
7197403Sobrien{
7297403Sobrien	return !(a != b);
73169691Skan}
74169691Skan
7597403Sobrien// constructor
7697403SobrienMessengerComparissonTester::MessengerComparissonTester()
7797403Sobrien	: BThreadedTestCase(),
7897403Sobrien	  fHandler(NULL),
7997403Sobrien	  fLooper(NULL)
8097403Sobrien{
8197403Sobrien}
8297403Sobrien
8397403Sobrien// constructor
8497403SobrienMessengerComparissonTester::MessengerComparissonTester(std::string name)
85169691Skan	: BThreadedTestCase(name),
86169691Skan	  fHandler(NULL),
8797403Sobrien	  fLooper(NULL)
8897403Sobrien{
8997403Sobrien}
9097403Sobrien
9197403Sobrien// destructor
92132720SkanMessengerComparissonTester::~MessengerComparissonTester()
93132720Skan{
94132720Skan	if (fLooper) {
9597403Sobrien		fLooper->Lock();
9697403Sobrien		if (fHandler) {
9797403Sobrien			fLooper->RemoveHandler(fHandler);
9897403Sobrien			delete fHandler;
99169691Skan		}
100169691Skan		fLooper->Quit();
101169691Skan	}
10297403Sobrien}
10397403Sobrien
10497403Sobrien/*
10597403Sobrien	bool operator==(const BMessenger &other) const
10697403Sobrien	bool operator!=(const BMessenger &a, const BMessenger &b)
10797403Sobrien	@case 1			this (a) and other (b) are uninitialized
10897403Sobrien	@results		should return true/false.
10997403Sobrien */
11097403Sobrienvoid MessengerComparissonTester::ComparissonTest1()
11197403Sobrien{
11297403Sobrien	BMessenger a;
11397403Sobrien	BMessenger b;
11497403Sobrien	CHK(a == b);
11597403Sobrien	CHK(b == a);
11697403Sobrien	CHK(!(a != b));
11797403Sobrien	CHK(!(b != a));
11897403Sobrien}
11997403Sobrien
12097403Sobrien/*
12197403Sobrien	bool operator==(const BMessenger &other) const
12297403Sobrien	bool operator!=(const BMessenger &a, const BMessenger &b)
123169691Skan	@case 1			this (a) is initialized, other (b) is uninitialized,
124169691Skan					and vice versa
12597403Sobrien	@results		should return false/true.
12697403Sobrien */
12797403Sobrienvoid MessengerComparissonTester::ComparissonTest2()
12897403Sobrien{
12997403Sobrien	// create looper
130132720Skan	BLooper *looper = new BLooper;
131132720Skan	looper->Run();
13297403Sobrien	LooperQuitter quitter(looper);
13397403Sobrien	// create messenger
13497403Sobrien	BMessenger a(NULL, looper);
13597403Sobrien	BMessenger b;
13697403Sobrien	CHK(a != b);
137169691Skan	CHK(b != a);
138169691Skan	CHK(!(a == b));
139169691Skan	CHK(!(b == a));
14097403Sobrien}
14197403Sobrien
14297403Sobrien/*
14397403Sobrien	bool operator==(const BMessenger &other) const
14497403Sobrien	bool operator!=(const BMessenger &a, const BMessenger &b)
14597403Sobrien	bool operator<(const BMessenger &a, const BMessenger &b)
14697403Sobrien	@case 3			this and other are initialized, different cases:
14797403Sobrien					- same object => true
14897403Sobrien					- different objects same target => true
14997403Sobrien					- looper preferred handler vs. same looper but the looper
15097403Sobrien					  itself as handler => false
15197403Sobrien					- looper preferred handler vs. other looper preferred
15297403Sobrien					  handler => false
15397403Sobrien					- looper preferred handler vs. other looper specific
15497403Sobrien					  handler => false
15597403Sobrien					- local looper vs. remote looper => false
15697403Sobrien */
15797403Sobrienvoid MessengerComparissonTester::ComparissonTest3()
158169691Skan{
15997403Sobrien	// messenger1: looper and handler
16097403Sobrien	BLooper *looper1 = new BLooper;
16197403Sobrien	looper1->Run();
162169691Skan	LooperQuitter quitter1(looper1);
163169691Skan	BHandler *handler1 = new BHandler;
16497403Sobrien	HandlerDeleter deleter1(handler1);
16597403Sobrien	CHK(looper1->Lock());
16697403Sobrien	looper1->AddHandler(handler1);
16797403Sobrien	looper1->Unlock();
16897403Sobrien	BMessenger messenger1(handler1, looper1);
16997403Sobrien	BMessenger messenger1a(handler1, looper1);
17097403Sobrien	// messenger2: looper (1)
17197403Sobrien	BMessenger messenger2(NULL, looper1);
17297403Sobrien	BMessenger messenger2a(NULL, looper1);
17397403Sobrien	// messenger3: looper and handler
17497403Sobrien	BLooper *looper2 = new BLooper;
17597403Sobrien	looper2->Run();
17697403Sobrien	LooperQuitter quitter2(looper2);
17797403Sobrien	BHandler *handler2 = new BHandler;
17897403Sobrien	HandlerDeleter deleter2(handler2);
17997403Sobrien	CHK(looper2->Lock());
18097403Sobrien	looper2->AddHandler(handler2);
18197403Sobrien	looper2->Unlock();
182169691Skan	BMessenger messenger3(handler2, looper2);
18397403Sobrien	BMessenger messenger3a(handler2, looper2);
18497403Sobrien	// messenger4: looper (2)
18597403Sobrien	BMessenger messenger4(NULL, looper2);
186169691Skan	BMessenger messenger4a(NULL, looper2);
18797403Sobrien	// remote targets
18897403Sobrien	RemoteSMTarget remoteTarget1(false);
18997403Sobrien	RemoteSMTarget remoteTarget2(true);
19097403Sobrien	BMessenger messenger5(remoteTarget1.Messenger());
191169691Skan	BMessenger messenger5a(remoteTarget1.Messenger());
192169691Skan	BMessenger messenger6(remoteTarget2.Messenger());
19397403Sobrien	BMessenger messenger6a(remoteTarget2.Messenger());
19497403Sobrien
19597403Sobrien	// targets -- test data
19697403Sobrien	struct target {
19797403Sobrien		BMessenger	&messenger;
19897403Sobrien		int32		id;			// identifies the target
19997403Sobrien	} targets[] = {
20097403Sobrien		{ messenger1,	1 },
20197403Sobrien		{ messenger1a,	1 },
20297403Sobrien		{ messenger2,	2 },
20397403Sobrien		{ messenger2,	2 },
20497403Sobrien		{ messenger3,	3 },
20597403Sobrien		{ messenger3a,	3 },
20697403Sobrien		{ messenger4,	4 },
20797403Sobrien		{ messenger4a,	4 },
20897403Sobrien		{ messenger5,	5 },
20997403Sobrien		{ messenger5a,	5 },
21097403Sobrien		{ messenger6,	6 },
21197403Sobrien		{ messenger6a,	6 },
21297403Sobrien	};
213169691Skan	int32 targetCount = sizeof(targets) / sizeof(target);
21497403Sobrien
21597403Sobrien	// test
21697403Sobrien	for (int32 i = 0; i < targetCount; i++) {
21797403Sobrien		NextSubTest();
21897403Sobrien		const target &target1 = targets[i];
21997403Sobrien		const BMessenger &a = target1.messenger;
22097403Sobrien		for (int32 k = 0; k < targetCount; k++) {
221169691Skan			const target &target2 = targets[k];
22297403Sobrien			const BMessenger &b = target2.messenger;
22397403Sobrien			bool areEqual = (target1.id == target2.id);
22497403Sobrien			CHK((a == b) == areEqual);
22597403Sobrien			CHK((b == a) == areEqual);
22697403Sobrien			CHK((a != b) == !areEqual);
22797403Sobrien			CHK((b != a) == !areEqual);
22897403Sobrien		}
22997403Sobrien	}
23097403Sobrien}
23197403Sobrien
23297403Sobrien// Compare
23397403Sobrien//
23497403Sobrien// Helper function for LessTest1().
23597403Sobrienstatic inline
23697403Sobrienvoid
23797403SobrienCompare(const FakeMessenger &fake1, const FakeMessenger &fake2,
23897403Sobrien		const BMessenger &messenger1, const BMessenger &messenger2)
23997403Sobrien{
24097403Sobrien	CHK((messenger1 == messenger2) == (fake1 == fake2));
24197403Sobrien	CHK((messenger1 != messenger2) == (fake1 != fake2));
24297403Sobrien	CHK((messenger1 < messenger2) == (fake1 < fake2));
24397403Sobrien}
24497403Sobrien
24597403Sobrien/*
24697403Sobrien	bool operator<(const BMessenger &a, const BMessenger &b)
24797403Sobrien	@case 1			set fields of a and b manually
24897403Sobrien	@results		should return whatever the reference implementation
24997403Sobrien					returns.
25097403Sobrien */
25197403Sobrienvoid MessengerComparissonTester::LessTest1()
25297403Sobrien{
25397403Sobrien	port_id ports[] = { -1, 0, 1 } ;
25497403Sobrien	int32 tokens[] = { -1, 0, 1 } ;
25597403Sobrien	team_id teams[] = { -1, 0, 1 } ;
256169691Skan	bool preferreds[] = { false, true } ;
25797403Sobrien	int32 portCount = sizeof(ports) / sizeof(port_id);
25897403Sobrien	int32 tokenCount = sizeof(tokens) / sizeof(int32);
25997403Sobrien	int32 teamCount = sizeof(teams) / sizeof(team_id);
26097403Sobrien	int32 preferredCount = 2;
26197403Sobrien	for (int32 p1 = 0; p1 < portCount; p1++) {
26297403Sobrien		port_id port1 = ports[p1];
26397403Sobrien		for (int32 to1 = 0; to1 < tokenCount; to1++) {
26497403Sobrien			int32 token1 = tokens[to1];
26597403Sobrien			for (int32 te1 = 0; te1 < teamCount; te1++) {
26697403Sobrien				team_id team1 = teams[te1];
26797403Sobrien				for (int32 pr1 = 0; pr1 < preferredCount; pr1++) {
26897403Sobrien					bool preferred1 = preferreds[pr1];
26997403Sobrien					FakeMessenger fake1;
27097403Sobrien					fake1.fPort = port1;
27197403Sobrien					fake1.fHandlerToken = token1;
27297403Sobrien					fake1.fTeam = team1;
27397403Sobrien					fake1.fPreferredTarget = preferred1;
27497403Sobrien					BMessenger &messenger1 = *(BMessenger*)&fake1;
27597403Sobrien					for (int32 p2 = 0; p2 < portCount; p2++) {
27697403Sobrien						port_id port2 = ports[p2];
27797403Sobrien						for (int32 to2 = 0; to2 < tokenCount; to2++) {
27897403Sobrien							int32 token2 = tokens[to2];
27997403Sobrien							for (int32 te2 = 0; te2 < teamCount; te2++) {
28097403Sobrien								team_id team2 = teams[te2];
28197403Sobrien								for (int32 pr2 = 0; pr2 < preferredCount;
28297403Sobrien									 pr2++) {
28397403Sobrien									bool preferred2 = preferreds[pr2];
28497403Sobrien									FakeMessenger fake2;
285169691Skan									fake2.fPort = port2;
28697403Sobrien									fake2.fHandlerToken = token2;
28797403Sobrien									fake2.fTeam = team2;
28897403Sobrien									fake2.fPreferredTarget = preferred2;
28997403Sobrien									BMessenger &messenger2
29097403Sobrien										= *(BMessenger*)&fake2;
29197403Sobrien									Compare(fake1, fake2, messenger1,
29297403Sobrien											messenger2);
29397403Sobrien								}
29497403Sobrien							}
29597403Sobrien						}
296169691Skan					}
29797403Sobrien				}
29897403Sobrien			}
299132720Skan		}
300132720Skan	}
301132720Skan}
302132720Skan
30397403Sobrien
30497403SobrienTest* MessengerComparissonTester::Suite()
30597403Sobrien{
30697403Sobrien	typedef BThreadedTestCaller<MessengerComparissonTester> TC;
30797403Sobrien
30897403Sobrien	TestSuite* testSuite = new TestSuite;
30997403Sobrien
31097403Sobrien	ADD_TEST4(BMessenger, testSuite, MessengerComparissonTester, ComparissonTest1);
31197403Sobrien	ADD_TEST4(BMessenger, testSuite, MessengerComparissonTester, ComparissonTest2);
31297403Sobrien	ADD_TEST4(BMessenger, testSuite, MessengerComparissonTester, ComparissonTest3);
31397403Sobrien	ADD_TEST4(BMessenger, testSuite, MessengerComparissonTester, LessTest1);
31497403Sobrien
31597403Sobrien	return testSuite;
31697403Sobrien}
31797403Sobrien
31897403Sobrien
31997403Sobrien