1//------------------------------------------------------------------------------
2//	SetIntervalTester.cpp
3//
4//------------------------------------------------------------------------------
5
6// Standard Includes -----------------------------------------------------------
7#include <algorithm>
8#include <stdio.h>
9
10// System Includes -------------------------------------------------------------
11#include <Application.h>
12#include <Handler.h>
13#include <Looper.h>
14#include <Message.h>
15#include <MessageRunner.h>
16#include <Messenger.h>
17#include <OS.h>
18
19// Project Includes ------------------------------------------------------------
20#include <TestShell.h>
21#include <TestUtils.h>
22#include <cppunit/TestAssert.h>
23
24// Local Includes --------------------------------------------------------------
25#include "MessageRunnerTestHelpers.h"
26#include "SetIntervalTester.h"
27
28// Local Defines ---------------------------------------------------------------
29
30// Globals ---------------------------------------------------------------------
31
32//------------------------------------------------------------------------------
33
34
35using namespace std;
36
37
38static const char *kTesterSignature
39	= "application/x-vnd.obos-messagerunner-setinterval-test";
40
41static const bigtime_t kMinTimeInterval = 50000;
42
43// check_message_runner_info
44static
45void
46check_message_runner_info(const BMessageRunner &runner, status_t error,
47						  bigtime_t interval = 0, int32 count = 0)
48{
49	bigtime_t runnerInterval = 0;
50	int32 runnerCount = 0;
51	CHK(runner.GetInfo(&runnerInterval, &runnerCount) == error);
52	if (error == B_OK) {
53		CHK(runnerInterval == interval);
54		CHK(runnerCount == count);
55	}
56}
57
58/*
59	status_t SetInterval(bigtime_t interval)
60	@case 1			object is not properly initialized, interval > 0
61	@results		Should return B_BAD_VALUE.
62					InitCheck() should return B_ERROR.
63					GetInfo() should return B_BAD_VALUE.
64 */
65void SetIntervalTester::SetInterval1()
66{
67	MessageRunnerTestApp app(kTesterSignature);
68	BMessenger target;
69	BMessage message(MSG_RUNNER_MESSAGE);
70	bigtime_t interval = 100000;
71	int32 count = 0;
72	BMessageRunner runner(target, &message, interval, count);
73	CHK(runner.InitCheck() == B_ERROR);
74	check_message_runner_info(runner, B_BAD_VALUE);
75	bigtime_t newInterval = 100000;
76	CHK(runner.SetInterval(newInterval) == B_BAD_VALUE);
77	CHK(runner.InitCheck() == B_ERROR);
78	check_message_runner_info(runner, B_BAD_VALUE);
79}
80
81/*
82	status_t SetInterval(bigtime_t interval)
83	@case 2			object was properly initialized, but has already delivered
84					all its messages and thus became unusable, interval > 0
85	@results		Should return B_BAD_VALUE.
86					InitCheck() should return B_OK.
87					GetInfo() should return B_BAD_VALUE.
88 */
89void SetIntervalTester::SetInterval2()
90{
91	MessageRunnerTestApp app(kTesterSignature);
92	BMessenger target;
93	BMessage message(MSG_RUNNER_MESSAGE);
94	bigtime_t interval = 50000;
95	int32 count = 1;
96	BMessageRunner runner(target, &message, interval, count);
97	CHK(runner.InitCheck() == B_OK);
98	check_message_runner_info(runner, B_OK, interval, count);
99	snooze(count * interval + 10000);
100	// set new interval
101	bigtime_t newInterval = 100000;
102	CHK(runner.SetInterval(newInterval) == B_BAD_VALUE);
103	CHK(runner.InitCheck() == B_OK);
104	check_message_runner_info(runner, B_BAD_VALUE);
105}
106
107/*
108	status_t SetInterval(bigtime_t interval)
109	@case 3			object is properly initialized and has still one message
110					to deliver, interval > 0
111	@results		Should return B_OK.
112					InitCheck() should return B_OK.
113					GetInfo() should return B_OK and the new interval.
114					The timer is reset. The last message arives after the time
115					specified by interval has passed.
116 */
117void SetIntervalTester::SetInterval3()
118{
119	MessageRunnerTestApp app(kTesterSignature);
120	MessageRunnerTestLooper *looper = app.TestLooper();
121	BMessenger target(looper);
122	BMessage message(MSG_RUNNER_MESSAGE);
123	bigtime_t interval = 50000;
124	int32 count = 5;
125	BMessageRunner runner(target, &message, interval, count);
126	bigtime_t startTime = system_time();
127	CHK(runner.InitCheck() == B_OK);
128	interval = max(interval, kMinTimeInterval);
129	check_message_runner_info(runner, B_OK, interval, count);
130	snooze((count - 1) * interval + 10000);
131	CHK(looper->CheckMessages(startTime, interval, count - 1));
132	CHK(app.CountReplies() == count - 1);
133	// set new interval
134	bigtime_t newInterval = 100000;
135	CHK(runner.SetInterval(newInterval) == B_OK);
136	CHK(runner.InitCheck() == B_OK);
137	check_message_runner_info(runner, B_OK, newInterval, 1);
138	startTime = system_time();
139	snooze(2 * newInterval + 10000);
140	CHK(looper->CheckMessages(count - 1, startTime, newInterval, 1));
141	CHK(app.CountReplies() == count);
142}
143
144/*
145	status_t SetInterval(bigtime_t interval)
146	@case 4			object is properly initialized and has still some messages
147					to deliver, interval > 0
148	@results		Should return B_OK.
149					InitCheck() should return B_OK.
150					GetInfo() should return B_OK and the new interval.
151					The timer is reset. The messages start to arive after
152					the time specified by interval.
153 */
154void SetIntervalTester::SetInterval4()
155{
156	MessageRunnerTestApp app(kTesterSignature);
157	MessageRunnerTestLooper *looper = app.TestLooper();
158	BMessenger target(looper);
159	BMessage message(MSG_RUNNER_MESSAGE);
160	bigtime_t interval = 50000;
161	int32 count = 5;
162	BMessageRunner runner(target, &message, interval, count);
163	bigtime_t startTime = system_time();
164	CHK(runner.InitCheck() == B_OK);
165	interval = max(interval, kMinTimeInterval);
166	check_message_runner_info(runner, B_OK, interval, count);
167	snooze(1 * interval + 10000);
168	CHK(looper->CheckMessages(startTime, interval, 1));
169	CHK(app.CountReplies() == 1);
170	// set new interval
171	bigtime_t newInterval = 70000;
172	CHK(runner.SetInterval(newInterval) == B_OK);
173	CHK(runner.InitCheck() == B_OK);
174	check_message_runner_info(runner, B_OK, newInterval, count - 1);
175	startTime = system_time();
176	snooze(count * newInterval + 10000);
177	CHK(looper->CheckMessages(1, startTime, newInterval, count - 1));
178	CHK(app.CountReplies() == count);
179}
180
181/*
182	status_t SetInterval(bigtime_t interval)
183	@case 5			object is properly initialized and has still an unlimited
184					number of messages to deliver, interval > 0
185	@results		Should return B_OK.
186					InitCheck() should return B_OK.
187					GetInfo() should return B_OK and the new interval.
188					The timer is reset. The messages start to arive after
189					the time specified by interval.
190 */
191void SetIntervalTester::SetInterval5()
192{
193	MessageRunnerTestApp app(kTesterSignature);
194	MessageRunnerTestLooper *looper = app.TestLooper();
195	BMessenger target(looper);
196	BMessage message(MSG_RUNNER_MESSAGE);
197	bigtime_t interval = 50000;
198	int32 count = -1;
199	BMessageRunner runner(target, &message, interval, count);
200	bigtime_t startTime = system_time();
201	CHK(runner.InitCheck() == B_OK);
202	interval = max(interval, kMinTimeInterval);
203	check_message_runner_info(runner, B_OK, interval, count);
204	snooze(1 * interval + 10000);
205	CHK(looper->CheckMessages(startTime, interval, 1));
206	CHK(app.CountReplies() == 1);
207	// set new interval
208	bigtime_t newInterval = 70000;
209	CHK(runner.SetInterval(newInterval) == B_OK);
210	CHK(runner.InitCheck() == B_OK);
211	check_message_runner_info(runner, B_OK, newInterval, -1);
212	startTime = system_time();
213	int32 checkCount = 5;
214	snooze(checkCount * newInterval + 10000);
215	CHK(looper->CheckMessages(1, startTime, newInterval, checkCount));
216	CHK(app.CountReplies() == checkCount + 1);
217}
218
219/*
220	status_t SetInterval(bigtime_t interval)
221	@case 6			object is properly initialized and has still some messages
222					to deliver, interval == 0
223	@results		Should return B_OK.
224					InitCheck() should return B_OK.
225					R5: GetInfo() should return B_BAD_VALUE.
226						All messages are delivered, but at weird times.
227					Haiku: GetInfo() should return B_OK and the minimal
228						  interval. The timer is reset. The messages start to
229						  arive after the time specified by the minimal
230						  interval.
231 */
232void SetIntervalTester::SetInterval6()
233{
234	MessageRunnerTestApp app(kTesterSignature);
235	MessageRunnerTestLooper *looper = app.TestLooper();
236	BMessenger target(looper);
237	BMessage message(MSG_RUNNER_MESSAGE);
238	bigtime_t interval = 70000;
239	int32 count = 5;
240	BMessageRunner runner(target, &message, interval, count);
241	bigtime_t startTime = system_time();
242	CHK(runner.InitCheck() == B_OK);
243	interval = max(interval, kMinTimeInterval);
244	check_message_runner_info(runner, B_OK, interval, count);
245	snooze(1 * interval + 10000);
246	CHK(looper->CheckMessages(startTime, interval, 1));
247	CHK(app.CountReplies() == 1);
248	// set new interval
249	bigtime_t newInterval = 0;
250	CHK(runner.SetInterval(newInterval) == B_OK);
251	newInterval = max(newInterval, kMinTimeInterval);
252	CHK(runner.InitCheck() == B_OK);
253#ifdef TEST_R5
254	check_message_runner_info(runner, B_BAD_VALUE);
255	snooze(count * interval + 10000);
256#else
257	check_message_runner_info(runner, B_OK, newInterval, count - 1);
258	startTime = system_time();
259	snooze(count * newInterval + 10000);
260	CHK(looper->CheckMessages(1, startTime, newInterval, count - 1));
261#endif
262	CHK(app.CountReplies() == count);
263}
264
265/*
266	status_t SetInterval(bigtime_t interval)
267	@case 7			object is properly initialized and has still some messages
268					to deliver, interval < 0
269	@results		Should return B_OK.
270					InitCheck() should return B_OK.
271					R5: GetInfo() should return B_BAD_VALUE.
272						All messages are delivered, but at weird times.
273					Haiku: GetInfo() should return B_OK and the minimal
274						  interval. The timer is reset. The messages start to
275						  arive after the time specified by the minimal
276						  interval.
277 */
278void SetIntervalTester::SetInterval7()
279{
280	MessageRunnerTestApp app(kTesterSignature);
281	MessageRunnerTestLooper *looper = app.TestLooper();
282	BMessenger target(looper);
283	BMessage message(MSG_RUNNER_MESSAGE);
284	bigtime_t interval = 70000;
285	int32 count = 5;
286	BMessageRunner runner(target, &message, interval, count);
287	bigtime_t startTime = system_time();
288	CHK(runner.InitCheck() == B_OK);
289	interval = max(interval, kMinTimeInterval);
290	check_message_runner_info(runner, B_OK, interval, count);
291	snooze(1 * interval + 10000);
292	CHK(looper->CheckMessages(startTime, interval, 1));
293	CHK(app.CountReplies() == 1);
294	// set new interval
295	bigtime_t newInterval = -1;
296	CHK(runner.SetInterval(newInterval) == B_OK);
297	newInterval = max(newInterval, kMinTimeInterval);
298	CHK(runner.InitCheck() == B_OK);
299#ifdef TEST_R5
300	check_message_runner_info(runner, B_BAD_VALUE);
301	snooze(count * interval + 10000);
302#else
303	check_message_runner_info(runner, B_OK, newInterval, count - 1);
304	startTime = system_time();
305	snooze(count * newInterval + 10000);
306	CHK(looper->CheckMessages(1, startTime, newInterval, count - 1));
307#endif
308	CHK(app.CountReplies() == count);
309}
310
311
312Test* SetIntervalTester::Suite()
313{
314	TestSuite* SuiteOfTests = new TestSuite;
315
316	ADD_TEST4(BMessageRunner, SuiteOfTests, SetIntervalTester, SetInterval1);
317	ADD_TEST4(BMessageRunner, SuiteOfTests, SetIntervalTester, SetInterval2);
318	ADD_TEST4(BMessageRunner, SuiteOfTests, SetIntervalTester, SetInterval3);
319	ADD_TEST4(BMessageRunner, SuiteOfTests, SetIntervalTester, SetInterval4);
320	ADD_TEST4(BMessageRunner, SuiteOfTests, SetIntervalTester, SetInterval5);
321	ADD_TEST4(BMessageRunner, SuiteOfTests, SetIntervalTester, SetInterval6);
322	ADD_TEST4(BMessageRunner, SuiteOfTests, SetIntervalTester, SetInterval7);
323
324	return SuiteOfTests;
325}
326
327