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