xref: /haiku/src/tests/kits/app/bmessagerunner/MessageRunnerTestHelpers.cpp (revision dace24c6255b30ff7f266dd08e43441f517851d3)
1*dace24c6SIngo Weinhold // MessageRunnerTestHelpers.cpp
2*dace24c6SIngo Weinhold 
3*dace24c6SIngo Weinhold #include <stdio.h>
4*dace24c6SIngo Weinhold 
5*dace24c6SIngo Weinhold #include <Autolock.h>
6*dace24c6SIngo Weinhold 
7*dace24c6SIngo Weinhold #include "MessageRunnerTestHelpers.h"
8*dace24c6SIngo Weinhold 
9*dace24c6SIngo Weinhold enum {
10*dace24c6SIngo Weinhold 	JITTER	= 10000,
11*dace24c6SIngo Weinhold };
12*dace24c6SIngo Weinhold 
13*dace24c6SIngo Weinhold // constructor
MessageRunnerTestHandler()14*dace24c6SIngo Weinhold MessageRunnerTestHandler::MessageRunnerTestHandler()
15*dace24c6SIngo Weinhold 	: BHandler("message runner test handler"),
16*dace24c6SIngo Weinhold 	  fReplyCount()
17*dace24c6SIngo Weinhold {
18*dace24c6SIngo Weinhold }
19*dace24c6SIngo Weinhold 
20*dace24c6SIngo Weinhold // destructor
~MessageRunnerTestHandler()21*dace24c6SIngo Weinhold MessageRunnerTestHandler::~MessageRunnerTestHandler()
22*dace24c6SIngo Weinhold {
23*dace24c6SIngo Weinhold }
24*dace24c6SIngo Weinhold 
25*dace24c6SIngo Weinhold // MessageReceived
26*dace24c6SIngo Weinhold void
MessageReceived(BMessage * message)27*dace24c6SIngo Weinhold MessageRunnerTestHandler::MessageReceived(BMessage *message)
28*dace24c6SIngo Weinhold {
29*dace24c6SIngo Weinhold 	switch (message->what) {
30*dace24c6SIngo Weinhold 		case MSG_REPLY:
31*dace24c6SIngo Weinhold 			fReplyCount++;
32*dace24c6SIngo Weinhold 			break;
33*dace24c6SIngo Weinhold 	}
34*dace24c6SIngo Weinhold }
35*dace24c6SIngo Weinhold 
36*dace24c6SIngo Weinhold 
37*dace24c6SIngo Weinhold ///////////////////////////
38*dace24c6SIngo Weinhold // MessageRunnerTestLooper
39*dace24c6SIngo Weinhold 
40*dace24c6SIngo Weinhold struct MessageRunnerTestLooper::MessageInfo {
41*dace24c6SIngo Weinhold 	bigtime_t	time;
42*dace24c6SIngo Weinhold };
43*dace24c6SIngo Weinhold 
44*dace24c6SIngo Weinhold // constructor
MessageRunnerTestLooper()45*dace24c6SIngo Weinhold MessageRunnerTestLooper::MessageRunnerTestLooper()
46*dace24c6SIngo Weinhold 	: BLooper(),
47*dace24c6SIngo Weinhold 	  fMessageInfos()
48*dace24c6SIngo Weinhold {
49*dace24c6SIngo Weinhold }
50*dace24c6SIngo Weinhold 
51*dace24c6SIngo Weinhold // destructor
~MessageRunnerTestLooper()52*dace24c6SIngo Weinhold MessageRunnerTestLooper::~MessageRunnerTestLooper()
53*dace24c6SIngo Weinhold {
54*dace24c6SIngo Weinhold 	for (int32 i = 0; MessageInfo *info = MessageInfoAt(i); i++)
55*dace24c6SIngo Weinhold 		delete info;
56*dace24c6SIngo Weinhold }
57*dace24c6SIngo Weinhold 
58*dace24c6SIngo Weinhold // MessageReceived
59*dace24c6SIngo Weinhold void
MessageReceived(BMessage * message)60*dace24c6SIngo Weinhold MessageRunnerTestLooper::MessageReceived(BMessage *message)
61*dace24c6SIngo Weinhold {
62*dace24c6SIngo Weinhold 	switch (message->what) {
63*dace24c6SIngo Weinhold 		case MSG_RUNNER_MESSAGE:
64*dace24c6SIngo Weinhold 		{
65*dace24c6SIngo Weinhold 			MessageInfo *info = new MessageInfo;
66*dace24c6SIngo Weinhold 			info->time = system_time();
67*dace24c6SIngo Weinhold 			fMessageInfos.AddItem(info);
68*dace24c6SIngo Weinhold 			message->SendReply(MSG_REPLY);
69*dace24c6SIngo Weinhold 			break;
70*dace24c6SIngo Weinhold 		}
71*dace24c6SIngo Weinhold 	}
72*dace24c6SIngo Weinhold }
73*dace24c6SIngo Weinhold 
74*dace24c6SIngo Weinhold // CheckMessages
75*dace24c6SIngo Weinhold bool
CheckMessages(bigtime_t startTime,bigtime_t interval,int32 count)76*dace24c6SIngo Weinhold MessageRunnerTestLooper::CheckMessages(bigtime_t startTime, bigtime_t interval,
77*dace24c6SIngo Weinhold 									   int32 count)
78*dace24c6SIngo Weinhold {
79*dace24c6SIngo Weinhold 	return CheckMessages(0, startTime, interval, count);
80*dace24c6SIngo Weinhold }
81*dace24c6SIngo Weinhold 
82*dace24c6SIngo Weinhold // CheckMessages
83*dace24c6SIngo Weinhold bool
CheckMessages(int32 skip,bigtime_t startTime,bigtime_t interval,int32 count)84*dace24c6SIngo Weinhold MessageRunnerTestLooper::CheckMessages(int32 skip, bigtime_t startTime,
85*dace24c6SIngo Weinhold 									   bigtime_t interval, int32 count)
86*dace24c6SIngo Weinhold {
87*dace24c6SIngo Weinhold 	BAutolock _lock(this);
88*dace24c6SIngo Weinhold 	bool result = (fMessageInfos.CountItems() == count + skip);
89*dace24c6SIngo Weinhold if (!result) {
90*dace24c6SIngo Weinhold printf("message counts don't match: %ld vs. %ld\n", fMessageInfos.CountItems(),
91*dace24c6SIngo Weinhold count + skip);
92*dace24c6SIngo Weinhold }
93*dace24c6SIngo Weinhold 	for (int32 i = 0; result && i < count; i++) {
94*dace24c6SIngo Weinhold 		MessageInfo *info = MessageInfoAt(i + skip);
95*dace24c6SIngo Weinhold 		bigtime_t expectedTime = startTime + (i + 1) * interval;
96*dace24c6SIngo Weinhold 		result = (expectedTime - JITTER < info->time
97*dace24c6SIngo Weinhold 				  && info->time < expectedTime + JITTER);
98*dace24c6SIngo Weinhold if (!result)
99*dace24c6SIngo Weinhold printf("message out of time: %lld vs. %lld\n", info->time, expectedTime);
100*dace24c6SIngo Weinhold 	}
101*dace24c6SIngo Weinhold 	return result;
102*dace24c6SIngo Weinhold }
103*dace24c6SIngo Weinhold 
104*dace24c6SIngo Weinhold // MessageInfoAt
105*dace24c6SIngo Weinhold MessageRunnerTestLooper::MessageInfo*
MessageInfoAt(int32 index) const106*dace24c6SIngo Weinhold MessageRunnerTestLooper::MessageInfoAt(int32 index) const
107*dace24c6SIngo Weinhold {
108*dace24c6SIngo Weinhold 	return static_cast<MessageInfo*>(fMessageInfos.ItemAt(index));
109*dace24c6SIngo Weinhold }
110*dace24c6SIngo Weinhold 
111*dace24c6SIngo Weinhold 
112*dace24c6SIngo Weinhold ////////////////////////
113*dace24c6SIngo Weinhold // MessageRunnerTestApp
114*dace24c6SIngo Weinhold 
115*dace24c6SIngo Weinhold // constructor
MessageRunnerTestApp(const char * signature)116*dace24c6SIngo Weinhold MessageRunnerTestApp::MessageRunnerTestApp(const char *signature)
117*dace24c6SIngo Weinhold 	: BApplication(signature),
118*dace24c6SIngo Weinhold 	  fThread(-1),
119*dace24c6SIngo Weinhold 	  fReplyCount(0),
120*dace24c6SIngo Weinhold 	  fLooper(NULL),
121*dace24c6SIngo Weinhold 	  fHandler(NULL)
122*dace24c6SIngo Weinhold {
123*dace24c6SIngo Weinhold 	// create a looper
124*dace24c6SIngo Weinhold 	fLooper = new MessageRunnerTestLooper;
125*dace24c6SIngo Weinhold 	fLooper->Run();
126*dace24c6SIngo Weinhold 	// create a handler
127*dace24c6SIngo Weinhold 	fHandler = new MessageRunnerTestHandler;
128*dace24c6SIngo Weinhold 	AddHandler(fHandler);
129*dace24c6SIngo Weinhold 	// start out message loop in a different thread
130*dace24c6SIngo Weinhold 	Unlock();
131*dace24c6SIngo Weinhold 	fThread = spawn_thread(_ThreadEntry, "message runner app thread",
132*dace24c6SIngo Weinhold 						   B_NORMAL_PRIORITY, this);
133*dace24c6SIngo Weinhold 	resume_thread(fThread);
134*dace24c6SIngo Weinhold }
135*dace24c6SIngo Weinhold 
136*dace24c6SIngo Weinhold // destructor
~MessageRunnerTestApp()137*dace24c6SIngo Weinhold MessageRunnerTestApp::~MessageRunnerTestApp()
138*dace24c6SIngo Weinhold {
139*dace24c6SIngo Weinhold 	// quit the looper
140*dace24c6SIngo Weinhold 	fLooper->Lock();
141*dace24c6SIngo Weinhold 	fLooper->Quit();
142*dace24c6SIngo Weinhold 	// shut down our message loop
143*dace24c6SIngo Weinhold 	BMessage reply;
144*dace24c6SIngo Weinhold 	PostMessage(B_QUIT_REQUESTED);
145*dace24c6SIngo Weinhold 	int32 dummy;
146*dace24c6SIngo Weinhold 	wait_for_thread(fThread, &dummy);
147*dace24c6SIngo Weinhold 	// delete the handler
148*dace24c6SIngo Weinhold 	Lock();
149*dace24c6SIngo Weinhold 	RemoveHandler(fHandler);
150*dace24c6SIngo Weinhold 	delete fHandler;
151*dace24c6SIngo Weinhold }
152*dace24c6SIngo Weinhold 
153*dace24c6SIngo Weinhold // MessageReceived
154*dace24c6SIngo Weinhold void
MessageReceived(BMessage * message)155*dace24c6SIngo Weinhold MessageRunnerTestApp::MessageReceived(BMessage *message)
156*dace24c6SIngo Weinhold {
157*dace24c6SIngo Weinhold 	switch (message->what) {
158*dace24c6SIngo Weinhold 		case MSG_REPLY:
159*dace24c6SIngo Weinhold 			fReplyCount++;
160*dace24c6SIngo Weinhold 			break;
161*dace24c6SIngo Weinhold 	}
162*dace24c6SIngo Weinhold }
163*dace24c6SIngo Weinhold 
164*dace24c6SIngo Weinhold // QuitRequested
165*dace24c6SIngo Weinhold bool
QuitRequested()166*dace24c6SIngo Weinhold MessageRunnerTestApp::QuitRequested()
167*dace24c6SIngo Weinhold {
168*dace24c6SIngo Weinhold 	return true;
169*dace24c6SIngo Weinhold }
170*dace24c6SIngo Weinhold 
171*dace24c6SIngo Weinhold // _ThreadEntry
172*dace24c6SIngo Weinhold int32
_ThreadEntry(void * data)173*dace24c6SIngo Weinhold MessageRunnerTestApp::_ThreadEntry(void *data)
174*dace24c6SIngo Weinhold {
175*dace24c6SIngo Weinhold 	MessageRunnerTestApp *app = static_cast<MessageRunnerTestApp*>(data);
176*dace24c6SIngo Weinhold 	app->Lock();
177*dace24c6SIngo Weinhold 	app->Run();
178*dace24c6SIngo Weinhold 	return 0;
179*dace24c6SIngo Weinhold }
180*dace24c6SIngo Weinhold 
181