1//------------------------------------------------------------------------------
2//	BMessengerTester.cpp
3//
4//------------------------------------------------------------------------------
5
6// Standard Includes -----------------------------------------------------------
7#include <stdio.h>
8
9// System Includes -------------------------------------------------------------
10#include <Application.h>
11#include <Handler.h>
12#include <Looper.h>
13#include <Message.h>
14#include <Messenger.h>
15#include <OS.h>
16
17#define CHK	CPPUNIT_ASSERT
18
19// Project Includes ------------------------------------------------------------
20#include <TestShell.h>
21#include <TestUtils.h>
22#include <cppunit/TestAssert.h>
23
24// Local Includes --------------------------------------------------------------
25#include "BMessengerTester.h"
26#include "AppRunner.h"
27#include "Helpers.h"
28
29// Local Defines ---------------------------------------------------------------
30
31// Globals ---------------------------------------------------------------------
32
33//------------------------------------------------------------------------------
34
35// check_messenger
36static
37void
38check_messenger(const BMessenger &messenger, bool valid, bool local,
39				team_id team, BLooper *looper = NULL, BHandler *handler = NULL,
40				team_id altTeam = -1)
41{
42	CHK(messenger.IsValid() == valid);
43	CHK(messenger.IsTargetLocal() == local);
44	BLooper *resultLooper = NULL;
45	CHK(messenger.Target(&resultLooper) == handler);
46	CHK(resultLooper == looper);
47	if (altTeam >= 0)
48		CHK(messenger.Team() == team || messenger.Team() == altTeam);
49	else
50{
51if (messenger.Team() != team)
52printf("team is %ld, but should be %ld\n", messenger.Team(), team);
53		CHK(messenger.Team() == team);
54}
55}
56
57static const char *kRunTestApp1Signature
58	= "application/x-vnd.obos-app-run-testapp1";
59//static const char *kBMessengerTestApp1Signature
60//	= "application/x-vnd.obos-bmessenger-testapp1";
61
62
63/*
64	BMessenger()
65	@case 1
66	@results		IsValid() should return false.
67					IsTargetLocal() should return false.
68					Target() should return NULL and NULL for looper.
69					Team() should return -1.
70 */
71void TBMessengerTester::BMessenger1()
72{
73	BMessenger messenger;
74	CHK(messenger.IsValid() == false);
75	CHK(messenger.IsTargetLocal() == false);
76	BLooper *looper;
77	CHK(messenger.Target(&looper) == NULL);
78	CHK(looper == NULL);
79	CHK(messenger.Team() == -1);
80}
81
82/*
83	BMessenger(const BHandler *handler, const BLooper *looper,
84			   status_t *result)
85	@case 1			handler is NULL, looper is NULL, result is NULL
86	@results		IsValid() and IsTargetLocal() should return false
87					Target() should return NULL and NULL for looper.
88					Team() should return -1.
89 */
90void TBMessengerTester::BMessenger2()
91{
92	BMessenger messenger((const BHandler*)NULL, NULL, NULL);
93	CHK(messenger.IsValid() == false);
94	CHK(messenger.IsTargetLocal() == false);
95	BLooper *looper;
96	CHK(messenger.Target(&looper) == NULL);
97	CHK(looper == NULL);
98	CHK(messenger.Team() == -1);
99}
100
101/*
102	BMessenger(const BHandler *handler, const BLooper *looper,
103			   status_t *result)
104	@case 2			handler is NULL, looper is NULL, result is not NULL
105	@results		IsValid() and IsTargetLocal() should return false.
106					Target() should return NULL and NULL for looper.
107					Team() should return -1.
108					result is set to B_BAD_VALUE.
109 */
110void TBMessengerTester::BMessenger3()
111{
112	status_t result = B_OK;
113	BMessenger messenger((const BHandler*)NULL, NULL, &result);
114	CHK(messenger.IsValid() == false);
115	CHK(messenger.IsTargetLocal() == false);
116	BLooper *looper;
117	CHK(messenger.Target(&looper) == NULL);
118	CHK(looper == NULL);
119	CHK(messenger.Team() == -1);
120	CHK(result == B_BAD_VALUE);
121}
122
123/*
124	BMessenger(const BHandler *handler, const BLooper *looper,
125			   status_t *result)
126	@case 3			handler is NULL, looper is not NULL, result is not NULL
127	@results		IsValid() and IsTargetLocal() should return true.
128					Target() should return NULL and the correct value for
129					looper.
130					Team() should return this team.
131					result is set to B_OK.
132 */
133void TBMessengerTester::BMessenger4()
134{
135	status_t result = B_OK;
136	BLooper *looper = new BLooper;
137	looper->Run();
138	LooperQuitter quitter(looper);
139	BMessenger messenger(NULL, looper, &result);
140	CHK(messenger.IsValid() == true);
141	CHK(messenger.IsTargetLocal() == true);
142	BLooper *resultLooper;
143	CHK(messenger.Target(&resultLooper) == NULL);
144	CHK(resultLooper == looper);
145	CHK(messenger.Team() == get_this_team());
146	CHK(result == B_OK);
147}
148
149/*
150	BMessenger(const BHandler *handler, const BLooper *looper,
151			   status_t *result)
152	@case 4			handler is not NULL, looper is NULL, result is not NULL,
153					handler doesn't belong to a looper
154	@results		IsValid() and IsTargetLocal() should return false.
155					Target() should return NULL and NULL for looper.
156					Team() should return -1.
157					result is set to B_MISMATCHED_VALUES.
158 */
159void TBMessengerTester::BMessenger5()
160{
161	status_t result = B_OK;
162	BHandler *handler = new BHandler;
163	HandlerDeleter deleter(handler);
164	BMessenger messenger(handler, NULL, &result);
165	CHK(messenger.IsValid() == false);
166	CHK(messenger.IsTargetLocal() == false);
167	BLooper *resultLooper;
168	CHK(messenger.Target(&resultLooper) == NULL);
169	CHK(resultLooper == NULL);
170	CHK(messenger.Team() == -1);
171	CHK(result == B_MISMATCHED_VALUES);
172}
173
174/*
175	BMessenger(const BHandler *handler, const BLooper *looper,
176			   status_t *result)
177	@case 5			handler is not NULL, looper is NULL, result is not NULL
178					handler does belong to a looper
179	@results		IsValid() and IsTargetLocal() should return true.
180					Target() should return the correct handler and the
181					handler->Looper() for looper.
182					Team() should return this team.
183					result is set to B_OK.
184 */
185void TBMessengerTester::BMessenger6()
186{
187	// create looper and handler
188	status_t result = B_OK;
189	BLooper *looper = new BLooper;
190	looper->Run();
191	LooperQuitter quitter(looper);
192	BHandler *handler = new BHandler;
193	HandlerDeleter deleter(handler);
194	CHK(looper->Lock());
195	looper->AddHandler(handler);
196	looper->Unlock();
197	// create the messenger and do the checks
198	BMessenger messenger(handler, NULL, &result);
199	CHK(messenger.IsValid() == true);
200	CHK(messenger.IsTargetLocal() == true);
201	BLooper *resultLooper;
202	CHK(messenger.Target(&resultLooper) == handler);
203	CHK(resultLooper == looper);
204	CHK(messenger.Team() == get_this_team());
205//printf("result: %lx\n", result);
206	CHK(result == B_OK);
207}
208
209/*
210	BMessenger(const BHandler *handler, const BLooper *looper,
211			   status_t *result)
212	@case 6			handler is not NULL, looper is not NULL, result is not NULL
213					handler does belong to the looper
214	@results		IsValid() and IsTargetLocal() should return true.
215					Target() should return the correct handler and the correct value
216					for looper.
217					Team() should return this team.
218					result is set to B_OK.
219 */
220void TBMessengerTester::BMessenger7()
221{
222	// create looper and handler
223	status_t result = B_OK;
224	BLooper *looper = new BLooper;
225	looper->Run();
226	LooperQuitter quitter(looper);
227	BHandler *handler = new BHandler;
228	HandlerDeleter deleter(handler);
229	CHK(looper->Lock());
230	looper->AddHandler(handler);
231	looper->Unlock();
232	// create the messenger and do the checks
233	BMessenger messenger(handler, looper, &result);
234	CHK(messenger.IsValid() == true);
235	CHK(messenger.IsTargetLocal() == true);
236	BLooper *resultLooper;
237	CHK(messenger.Target(&resultLooper) == handler);
238	CHK(resultLooper == looper);
239	CHK(messenger.Team() == get_this_team());
240//printf("result: %lx\n", result);
241	CHK(result == B_OK);
242}
243
244/*
245	BMessenger(const BHandler *handler, const BLooper *looper,
246			   status_t *result)
247	@case 7			handler is not NULL, looper is not NULL, result is not NULL
248					handler does belong to a different looper
249	@results		IsValid() and IsTargetLocal() should return false.
250					Target() should return NULL and NULL for looper.
251					Team() should return -1.
252					result is set to B_MISMATCHED_VALUES.
253 */
254void TBMessengerTester::BMessenger8()
255{
256	// create loopers and handler
257	status_t result = B_OK;
258	BLooper *looper = new BLooper;
259	looper->Run();
260	LooperQuitter quitter(looper);
261	BLooper *looper2 = new BLooper;
262	looper2->Run();
263	LooperQuitter quitter2(looper2);
264	BHandler *handler = new BHandler;
265	HandlerDeleter deleter(handler);
266	CHK(looper->Lock());
267	looper->AddHandler(handler);
268	looper->Unlock();
269	// create the messenger and do the checks
270	BMessenger messenger(handler, looper2, &result);
271	CHK(messenger.IsValid() == false);
272	CHK(messenger.IsTargetLocal() == false);
273	BLooper *resultLooper;
274	CHK(messenger.Target(&resultLooper) == NULL);
275	CHK(resultLooper == NULL);
276	CHK(messenger.Team() == -1);
277//printf("result: %lx\n", result);
278	CHK(result == B_MISMATCHED_VALUES);
279}
280
281/*
282	BMessenger(const BMessenger &from)
283	@case 1			from is uninitialized
284	@results		IsValid() and IsTargetLocal() should return false
285					Target() should return NULL and NULL for looper.
286					Team() should return -1.
287 */
288void TBMessengerTester::BMessenger9()
289{
290	BMessenger from;
291	BMessenger messenger(from);
292	CHK(messenger.IsValid() == false);
293	CHK(messenger.IsTargetLocal() == false);
294	BLooper *looper;
295	CHK(messenger.Target(&looper) == NULL);
296	CHK(looper == NULL);
297	CHK(messenger.Team() == -1);
298}
299
300
301/*
302	BMessenger(const BMessenger &from)
303	@case 2			from is properly initialized to a local target
304	@results		IsValid() and IsTargetLocal() should return true
305					Target() should return the same values as for from.
306					Team() should return this team.
307 */
308void TBMessengerTester::BMessenger10()
309{
310	// create looper and handler
311	status_t result = B_OK;
312	BLooper *looper = new BLooper;
313	looper->Run();
314	LooperQuitter quitter(looper);
315	BHandler *handler = new BHandler;
316	HandlerDeleter deleter(handler);
317	CHK(looper->Lock());
318	looper->AddHandler(handler);
319	looper->Unlock();
320	// create the from messenger
321	BMessenger from(handler, looper, &result);
322	CHK(from.IsValid() == true);
323	CHK(from.IsTargetLocal() == true);
324	BLooper *resultLooper;
325	CHK(from.Target(&resultLooper) == handler);
326	CHK(resultLooper == looper);
327	CHK(from.Team() == get_this_team());
328	CHK(result == B_OK);
329	// create the messenger and do the checks
330	BMessenger messenger(from);
331	CHK(messenger.IsValid() == true);
332	CHK(messenger.IsTargetLocal() == true);
333	resultLooper = NULL;
334	CHK(messenger.Target(&resultLooper) == handler);
335	CHK(resultLooper == looper);
336	CHK(messenger.Team() == get_this_team());
337}
338
339
340/*
341	BMessenger(const char *signature, team_id team, status_t *result)
342	@case 1			signature is NULL, team is -1, result is (not) NULL
343	@results		IsValid() and IsTargetLocal() should return false
344					Target() should return NULL and NULL for looper.
345					Team() should return -1.
346					(result should be set to B_BAD_TYPE.)
347 */
348void TBMessengerTester::BMessengerD1()
349{
350	BApplication app("application/x-vnd.obos-bmessenger-test");
351	// run the remote app
352	AppRunner runner(true);
353	CHK(runner.Run("AppRunTestApp1") == B_OK);
354	// create and check the messengers
355	BMessenger messenger1(NULL, -1, NULL);
356	check_messenger(messenger1, false, false, -1);
357	status_t error;
358	BMessenger messenger2(NULL, -1, &error);
359	check_messenger(messenger2, false, false, -1);
360	CHK(error == B_BAD_TYPE);
361	// quit the remote app
362	runner.WaitFor(true);
363}
364
365/*
366	BMessenger(const char *signature, team_id team, status_t *result)
367	@case 2			signature is not NULL, but identifies no running
368					application, team is -1, result is (not) NULL
369	@results		IsValid() and IsTargetLocal() should return false
370					Target() should return NULL and NULL for looper.
371					Team() should return -1.
372					(result should be set to B_BAD_VALUE.)
373 */
374void TBMessengerTester::BMessengerD2()
375{
376	// create and check the messengers
377	BMessenger messenger1(kRunTestApp1Signature, -1, NULL);
378	check_messenger(messenger1, false, false, -1);
379	status_t error;
380	BMessenger messenger2(kRunTestApp1Signature, -1, &error);
381	check_messenger(messenger2, false, false, -1);
382	CHK(error == B_BAD_VALUE);
383}
384
385/*
386	BMessenger(const char *signature, team_id team, status_t *result)
387	@case 3			signature is NULL, team is > 0, but identifies no running
388					application, result is (not) NULL
389	@results		IsValid() and IsTargetLocal() should return false
390					Target() should return NULL and NULL for looper.
391					Team() should return -1.
392					(result should be set to B_BAD_TEAM_ID.)
393 */
394void TBMessengerTester::BMessengerD3()
395{
396	BApplication app("application/x-vnd.obos-bmessenger-test");
397	// run the remote app
398	AppRunner runner(true);
399	CHK(runner.Run("AppRunTestApp1") == B_OK);
400	team_id team = runner.Team();
401	// quit the remote app
402	runner.WaitFor(true);
403	snooze(10000);
404	// create and check the messengers
405	BMessenger messenger1(NULL, team, NULL);
406	check_messenger(messenger1, false, false, -1);
407	status_t error;
408	BMessenger messenger2(NULL, team, &error);
409	check_messenger(messenger2, false, false, -1);
410	CHK(error == B_BAD_TEAM_ID);
411}
412
413/*
414	BMessenger(const char *signature, team_id team, status_t *result)
415	@case 4			signature is not NULL and identifies a running B_ARGV_ONLY
416					application, team is -1, result is (not) NULL
417	@results		IsValid() and IsTargetLocal() should return false
418					Target() should return NULL and NULL for looper.
419					Team() should return the remote app's team ID.
420					(result should be set to B_BAD_TYPE.)
421 */
422void TBMessengerTester::BMessengerD4()
423{
424	BApplication app("application/x-vnd.obos-bmessenger-test");
425	// run the remote app
426	AppRunner runner(true);
427	CHK(runner.Run("AppRunTestApp1") == B_OK);
428	// create and check the messengers
429	BMessenger messenger1(kRunTestApp1Signature, -1, NULL);
430	check_messenger(messenger1, false, false, runner.Team());
431	status_t error;
432	BMessenger messenger2(kRunTestApp1Signature, -1, &error);
433	check_messenger(messenger2, false, false, runner.Team());
434	CHK(error == B_BAD_TYPE);
435	// quit the remote app
436	runner.WaitFor(true);
437}
438
439/*
440	BMessenger(const char *signature, team_id team, status_t *result)
441	@case 5			signature is NULL,
442					team is > 0 and identifies a running B_ARGV_ONLY
443					application, result is (not) NULL
444	@results		IsValid() and IsTargetLocal() should return false
445					Target() should return NULL and NULL for looper.
446					Team() should return the remote app's team ID.
447					(result should be set to B_BAD_TYPE.)
448 */
449void TBMessengerTester::BMessengerD5()
450{
451	BApplication app("application/x-vnd.obos-bmessenger-test");
452	// run the remote app
453	AppRunner runner(true);
454	CHK(runner.Run("AppRunTestApp1") == B_OK);
455	// create and check the messengers
456	BMessenger messenger1(NULL, runner.Team(), NULL);
457	check_messenger(messenger1, false, false, runner.Team());
458	status_t error;
459	BMessenger messenger2(NULL, runner.Team(), &error);
460	check_messenger(messenger2, false, false, runner.Team());
461	CHK(error == B_BAD_TYPE);
462	// quit the remote app
463	runner.WaitFor(true);
464}
465
466/*
467	BMessenger(const char *signature, team_id team, status_t *result)
468	@case 6			signature is not NULL and identifies a "normal" running
469					application, team is -1, result is (not) NULL
470	@results		IsValid() should return true
471					IsTargetLocal() should return false
472					Target() should return NULL and NULL for looper.
473					Team() should return the team ID of the remote application.
474					(result should be set to B_OK.)
475 */
476void TBMessengerTester::BMessengerD6()
477{
478	BApplication app("application/x-vnd.obos-bmessenger-test");
479	// run the remote apps
480	AppRunner runner1(true);
481	AppRunner runner2(true);
482	CHK(runner1.Run("AppRunTestApp2") == B_OK);
483	CHK(runner2.Run("AppRunTestApp2") == B_OK);
484	// create and check the messengers
485	BMessenger messenger1(kRunTestApp1Signature, -1, NULL);
486	check_messenger(messenger1, true, false, runner1.Team(), NULL, NULL,
487					runner2.Team());
488	status_t error;
489	BMessenger messenger2(kRunTestApp1Signature, -1, &error);
490	check_messenger(messenger2, true, false, runner1.Team(), NULL, NULL,
491					runner2.Team());
492	CHK(error == B_OK);
493	// quit the remote apps
494	runner1.WaitFor(true);
495	runner2.WaitFor(true);
496}
497
498/*
499	BMessenger(const char *signature, team_id team, status_t *result)
500	@case 7			signature is NULL,
501					team is > 0 and identifies a "normal" running application,
502					result is (not) NULL
503	@results		IsValid() should return true
504					IsTargetLocal() should return false
505					Target() should return NULL and NULL for looper.
506					Team() should return the team ID of the remote application (team).
507					(result should be set to B_OK.)
508 */
509void TBMessengerTester::BMessengerD7()
510{
511	BApplication app("application/x-vnd.obos-bmessenger-test");
512	// run the remote apps
513	AppRunner runner1(true);
514	AppRunner runner2(true);
515	CHK(runner1.Run("AppRunTestApp2") == B_OK);
516	CHK(runner2.Run("AppRunTestApp2") == B_OK);
517	// create and check the messengers
518	BMessenger messenger1(NULL, runner1.Team(), NULL);
519	check_messenger(messenger1, true, false, runner1.Team());
520	status_t error;
521	BMessenger messenger2(NULL, runner1.Team(), &error);
522	check_messenger(messenger2, true, false, runner1.Team());
523	CHK(error == B_OK);
524	// quit the remote apps
525	runner1.WaitFor(true);
526	runner2.WaitFor(true);
527	snooze(10000);
528	// check the messengers again
529	check_messenger(messenger1, false, false, runner1.Team());
530	check_messenger(messenger2, false, false, runner1.Team());
531}
532
533/*
534	BMessenger(const char *signature, team_id team, status_t *result)
535	@case 8			signature is not NULL and team is > 0, but both identify
536					different applications, result is (not) NULL
537	@results		IsValid() and IsTargetLocal() should return false
538					Target() should return NULL and NULL for looper.
539					Team() should return -1.
540					(result should be set to B_MISMATCHED_VALUES.)
541 */
542void TBMessengerTester::BMessengerD8()
543{
544	BApplication app("application/x-vnd.obos-bmessenger-test");
545	// run the remote apps
546	AppRunner runner1(true);
547	AppRunner runner2(true);
548	CHK(runner1.Run("BMessengerTestApp1") == B_OK);
549	CHK(runner2.Run("AppRunTestApp2") == B_OK);
550	// create and check the messengers
551	BMessenger messenger1(kRunTestApp1Signature, runner1.Team(), NULL);
552	check_messenger(messenger1, false, false, -1);
553	status_t error;
554	BMessenger messenger2(kRunTestApp1Signature, runner1.Team(), &error);
555	check_messenger(messenger2, false, false, -1);
556	CHK(error == B_MISMATCHED_VALUES);
557	// quit the remote apps
558	runner1.WaitFor(true);
559	runner2.WaitFor(true);
560}
561
562/*
563	BMessenger(const char *signature, team_id team, status_t *result)
564	@case 9			signature is not NULL, team is > 0 and both identify the
565					same application (more than one app with the given
566					signature are running), result is (not) NULL
567	@results		IsValid() should return true
568					IsTargetLocal() should return false
569					Target() should return NULL and NULL for looper.
570					Team() should return the team ID of the remote application (team).
571					(result should be set to B_OK.)
572 */
573void TBMessengerTester::BMessengerD9()
574{
575	BApplication app("application/x-vnd.obos-bmessenger-test");
576	// run the remote apps
577	AppRunner runner1(true);
578	AppRunner runner2(true);
579	CHK(runner1.Run("AppRunTestApp2") == B_OK);
580	CHK(runner2.Run("AppRunTestApp2") == B_OK);
581	// create and check the messengers
582	BMessenger messenger1(kRunTestApp1Signature, runner1.Team(), NULL);
583	check_messenger(messenger1, true, false, runner1.Team());
584	status_t error;
585	BMessenger messenger2(kRunTestApp1Signature, runner1.Team(), &error);
586	check_messenger(messenger2, true, false, runner1.Team());
587	CHK(error == B_OK);
588	BMessenger messenger3(kRunTestApp1Signature, runner2.Team(), NULL);
589	check_messenger(messenger3, true, false, runner2.Team());
590	BMessenger messenger4(kRunTestApp1Signature, runner2.Team(), &error);
591	check_messenger(messenger4, true, false, runner2.Team());
592	CHK(error == B_OK);
593	// quit the remote apps
594	runner1.WaitFor(true);
595	runner2.WaitFor(true);
596}
597
598
599Test* TBMessengerTester::Suite()
600{
601	TestSuite* SuiteOfTests = new TestSuite;
602
603	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessenger1);
604	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessenger2);
605	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessenger3);
606	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessenger4);
607	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessenger5);
608	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessenger6);
609	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessenger7);
610	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessenger8);
611	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessenger9);
612	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessenger10);
613	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessengerD1);
614	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessengerD2);
615	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessengerD3);
616	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessengerD4);
617	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessengerD5);
618	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessengerD6);
619	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessengerD7);
620	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessengerD8);
621	ADD_TEST4(BMessenger, SuiteOfTests, TBMessengerTester, BMessengerD9);
622
623	return SuiteOfTests;
624}
625
626
627
628