1//------------------------------------------------------------------------------
2//	LaunchTester.cpp
3//
4//------------------------------------------------------------------------------
5
6// Standard Includes -----------------------------------------------------------
7#include <stdio.h>
8#include <stdlib.h>
9#include <utime.h>
10
11// System Includes -------------------------------------------------------------
12#include <Message.h>
13#include <OS.h>
14#include <AppFileInfo.h>
15#include <Application.h>
16#include <File.h>
17#include <FindDirectory.h>
18#include <Handler.h>
19#include <Looper.h>
20#include <Message.h>
21#include <MessageQueue.h>
22#include <Path.h>
23#include <Roster.h>
24#include <String.h>
25
26// Project Includes ------------------------------------------------------------
27#include <TestShell.h>
28#include <TestUtils.h>
29#include <cppunit/TestAssert.h>
30
31// Local Includes --------------------------------------------------------------
32#include "AppRunner.h"
33#include "LaunchTester.h"
34#include "LaunchTesterHelper.h"
35#include "RosterTestAppDefs.h"
36
37// Local Defines ---------------------------------------------------------------
38
39// Globals ---------------------------------------------------------------------
40
41//------------------------------------------------------------------------------
42
43static const char *testerSignature
44	= "application/x-vnd.obos-roster-launch-test";
45static const char *uninstalledType
46	= "application/x-vnd.obos-roster-launch-uninstalled";
47static const char *appType1	= "application/x-vnd.obos-roster-launch-app1";
48static const char *appType2	= "application/x-vnd.obos-roster-launch-app2";
49static const char *fileType1 = "application/x-vnd.obos-roster-launch-file1";
50static const char *fileType2 = "application/x-vnd.obos-roster-launch-file2";
51static const char *textTestType = "text/x-vnd.obos-roster-launch";
52
53static const char *testDir		= "/tmp/testdir";
54static const char *appFile1		= "/tmp/testdir/app1";
55static const char *appFile2		= "/tmp/testdir/app2";
56static const char *testFile1	= "/tmp/testdir/testFile1";
57static const char *testLink1	= "/tmp/testdir/testLink1";
58static const char *trashAppName	= "roster-launch-app";
59
60// dump_messenger
61/*static
62void
63dump_messenger(BMessenger messenger)
64{
65	struct fake_messenger {
66		port_id	fPort;
67		int32	fHandlerToken;
68		team_id	fTeam;
69		int32	extra0;
70		int32	extra1;
71		bool	fPreferredTarget;
72		bool	extra2;
73		bool	extra3;
74		bool	extra4;
75	} &fake = *(fake_messenger*)&messenger;
76	printf("BMessenger: fPort:            %ld\n"
77		   "            fHandlerToken:    %ld\n"
78		   "            fTeam:            %ld\n"
79		   "            fPreferredTarget: %d\n",
80		   fake.fPort, fake.fHandlerToken, fake.fTeam, fake.fPreferredTarget);
81}*/
82
83
84// get_trash_app_file
85static
86const char*
87get_trash_app_file()
88{
89	static char trashAppFile[B_PATH_NAME_LENGTH];
90	static bool initialized = false;
91	if (!initialized) {
92		BPath path;
93		CHK(find_directory(B_TRASH_DIRECTORY, &path) == B_OK);
94		CHK(path.Append(trashAppName) == B_OK);
95		strcpy(trashAppFile, path.Path());
96		initialized = true;
97	}
98	return trashAppFile;
99}
100
101// install_type
102static
103void
104install_type(const char *type, const char *preferredApp = NULL,
105			 const char *snifferRule = NULL)
106{
107	BMimeType mimeType(type);
108	if (!mimeType.IsInstalled())
109		CHK(mimeType.Install() == B_OK);
110	if (preferredApp)
111		CHK(mimeType.SetPreferredApp(preferredApp) == B_OK);
112	if (snifferRule)
113		CHK(mimeType.SetSnifferRule(snifferRule) == B_OK);
114}
115
116// ref_for_path
117static
118entry_ref
119ref_for_path(const char *filename, bool traverse = true)
120{
121	entry_ref ref;
122	BEntry entry;
123	CHK(entry.SetTo(filename, traverse) == B_OK);
124	CHK(entry.GetRef(&ref) == B_OK);
125	return ref;
126}
127
128// ref_for_team
129static
130entry_ref
131ref_for_team(team_id team)
132{
133	BRoster roster;
134	app_info info;
135	CHK(roster.GetRunningAppInfo(team, &info) == B_OK);
136	return info.ref;
137}
138
139// create_app
140static
141void
142create_app(const char *filename, const char *signature,
143		   bool install = false, bool makeExecutable = true,
144		   uint32 appFlags = B_SINGLE_LAUNCH)
145{
146	BString testApp;
147	CHK(find_test_app("RosterLaunchTestApp1", &testApp) == B_OK);
148	system((string("cp ") + testApp.String() + " " + filename).c_str());
149	if (makeExecutable)
150		system((string("chmod a+x ") + filename).c_str());
151	BFile file;
152	CHK(file.SetTo(filename, B_READ_WRITE) == B_OK);
153	BAppFileInfo appFileInfo;
154	CHK(appFileInfo.SetTo(&file) == B_OK);
155	if (signature)
156		CHK(appFileInfo.SetSignature(signature) == B_OK);
157	CHK(appFileInfo.SetAppFlags(appFlags) == B_OK);
158	if (install && signature)
159		CHK(BMimeType(signature).Install() == B_OK);
160	// We write the signature into a separate attribute, just in case we
161	// decide to also test files without BEOS:APP_SIG attribute.
162	BString signatureString(signature);
163	file.WriteAttrString("signature", &signatureString);
164}
165
166// create_file
167static
168entry_ref
169create_file(const char *filename, const char *type,
170			const char *preferredApp = NULL, const char *appHintPath = NULL,
171			const char *contents = NULL)
172{
173	if (contents)
174		system((string("echo -n \"") + contents + "\" > " + filename).c_str());
175	else
176		system((string("touch ") + filename).c_str());
177	if (type || preferredApp || appHintPath) {
178		BFile file;
179		CHK(file.SetTo(filename, B_READ_WRITE) == B_OK);
180		BNodeInfo nodeInfo;
181		CHK(nodeInfo.SetTo(&file) == B_OK);
182		if (type)
183			CHK(nodeInfo.SetType(type) == B_OK);
184		if (preferredApp)
185			CHK(nodeInfo.SetPreferredApp(preferredApp) == B_OK);
186		if (appHintPath) {
187			entry_ref appHint(ref_for_path(appHintPath));
188			CHK(nodeInfo.SetAppHint(&appHint) == B_OK);
189		}
190	}
191	return ref_for_path(filename);
192}
193
194// check_app_type
195static
196void
197check_app_type(const char *signature, const char *filename)
198{
199	BMimeType type(signature);
200	CHK(type.IsInstalled() == true);
201	if (filename) {
202		entry_ref appHint;
203		CHK(type.GetAppHint(&appHint) == B_OK);
204		CHK(ref_for_path(filename) == appHint);
205	}
206}
207
208// set_file_time
209static
210void
211set_file_time(const char *filename, time_t time)
212{
213	utimbuf buffer;
214	buffer.actime = time;
215	buffer.modtime = time;
216	CHK(utime(filename, &buffer) == 0);
217}
218
219// set_version
220static
221void
222set_version(const char *filename, uint32 version)
223{
224	version_info versionInfo = { 1, 1, 1, 1, version, "short1", "long1" };
225	BFile file;
226	CHK(file.SetTo(filename, B_READ_WRITE) == B_OK);
227	BAppFileInfo appFileInfo;
228	CHK(appFileInfo.SetTo(&file) == B_OK);
229	CHK(appFileInfo.SetVersionInfo(&versionInfo, B_APP_VERSION_KIND) == B_OK);
230}
231
232// set_type_app_hint
233static
234void
235set_type_app_hint(const char *signature, const char *filename)
236{
237	BMimeType type(signature);
238	if (!type.IsInstalled());
239		CHK(type.Install() == B_OK);
240	entry_ref fileRef(ref_for_path(filename));
241	CHK(type.SetAppHint(&fileRef) == B_OK);
242}
243
244// setUp
245void
246LaunchTester::setUp()
247{
248	fApplication = new RosterLaunchApp(testerSignature);
249	system((string("mkdir ") + testDir).c_str());
250}
251
252// tearDown
253void
254LaunchTester::tearDown()
255{
256	BMimeType(uninstalledType).Delete();
257	BMimeType(appType1).Delete();
258	BMimeType(appType2).Delete();
259	BMimeType(fileType1).Delete();
260	BMimeType(fileType2).Delete();
261	BMimeType(textTestType).Delete();
262	delete fApplication;
263	system((string("rm -rf ") + testDir).c_str());
264	system((string("rm -f ") + get_trash_app_file()).c_str());
265}
266
267/*
268	@case 1			uninstalled type mimeType
269	@results		Should return B_LAUNCH_FAILED_APP_NOT_FOUND.
270*/
271static
272void
273CommonLaunchTest1(LaunchCaller &caller)
274{
275	LaunchContext context;
276	BRoster roster;
277	team_id team;
278	CHK(context(caller, uninstalledType, &team) == B_LAUNCH_FAILED_APP_NOT_FOUND);
279}
280
281/*
282	@case 2			installed type mimeType, no preferred app
283	@results		Should return B_LAUNCH_FAILED_NO_PREFERRED_APP.
284*/
285static
286void
287CommonLaunchTest2(LaunchCaller &caller)
288{
289	LaunchContext context;
290	BRoster roster;
291	install_type(fileType1);
292	team_id team;
293	CHK(context(caller, fileType1, &team) == B_LAUNCH_FAILED_NO_PREFERRED_APP);
294}
295
296/*
297	@case 3			installed type mimeType, preferred app, app type not
298					installed, app has no signature
299	@results		Should return B_LAUNCH_FAILED_APP_NOT_FOUND.
300*/
301static
302void
303CommonLaunchTest3(LaunchCaller &caller)
304{
305	LaunchContext context;
306	BRoster roster;
307	install_type(fileType1, appType1);
308	team_id team;
309	CHK(context(caller, fileType1, &team) == B_LAUNCH_FAILED_APP_NOT_FOUND);
310}
311
312/*
313	@case 4			installed type mimeType, preferred app, app type not
314					installed, app has signature
315	@results		Should return B_OK and set team to the ID of the team
316					running the application's executable. Should install the
317					app type and set the app hint on it.
318*/
319static
320void
321CommonLaunchTest4(LaunchCaller &caller)
322{
323	LaunchContext context;
324	BRoster roster;
325	create_app(appFile1, appType1);
326	install_type(fileType1, appType1);
327	team_id team;
328	CHK(context(caller, fileType1, &team) == B_OK);
329	entry_ref ref = ref_for_team(team);
330	CHK(ref_for_path(appFile1) == ref);
331	check_app_type(appType1, appFile1);
332	context.Terminate();
333	int32 cookie = 0;
334	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
335	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
336	CHK(context.CheckMessageMessages(caller, team, cookie));
337	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
338	if (caller.SupportsRefs() && !caller.SupportsArgv())
339		CHK(context.CheckRefsMessage(caller, team, cookie));
340	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
341	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
342	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
343}
344
345/*
346	@case 5			installed type mimeType, preferred app, app type installed,
347					app has signature
348	@results		Should return B_OK and set team to the ID of the team
349					running the application's executable. Should set the app
350					hint on the app type.
351*/
352static
353void
354CommonLaunchTest5(LaunchCaller &caller)
355{
356	LaunchContext context;
357	BRoster roster;
358	create_app(appFile1, appType1, true);
359	install_type(fileType1, appType1);
360	team_id team;
361	CHK(context(caller, fileType1, &team) == B_OK);
362	entry_ref ref = ref_for_team(team);
363	CHK(ref_for_path(appFile1) == ref);
364	check_app_type(appType1, appFile1);
365	context.Terminate();
366	int32 cookie = 0;
367	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
368	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
369	CHK(context.CheckMessageMessages(caller, team, cookie));
370	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
371	if (caller.SupportsRefs() && !caller.SupportsArgv())
372		CHK(context.CheckRefsMessage(caller, team, cookie));
373	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
374	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
375	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
376}
377
378/*
379	@case 6			installed type mimeType, preferred app, app type installed,
380					app has signature, app has no execute permission
381	@results		Should return B_OK and set team to the ID of the team
382					running the application's executable. Should set the app
383					hint on the app type.
384*/
385static
386void
387CommonLaunchTest6(LaunchCaller &caller)
388{
389	LaunchContext context;
390	BRoster roster;
391	create_app(appFile1, appType1, true, false);
392	install_type(fileType1, appType1);
393	team_id team;
394	CHK(context(caller, fileType1, &team) == B_OK);
395	entry_ref ref = ref_for_team(team);
396	CHK(ref_for_path(appFile1) == ref);
397	check_app_type(appType1, appFile1);
398	context.Terminate();
399	int32 cookie = 0;
400	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
401	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
402	CHK(context.CheckMessageMessages(caller, team, cookie));
403	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
404	if (caller.SupportsRefs() && !caller.SupportsArgv())
405		CHK(context.CheckRefsMessage(caller, team, cookie));
406	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
407	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
408	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
409}
410
411/*
412	@case 7			installed type mimeType, preferred app, app type installed,
413					two apps have the signature
414	@results		Should return B_OK and set team to the ID of the team
415					running the application executable with the most recent
416					modification time. Should set the app hint on the app type.
417*/
418static
419void
420CommonLaunchTest7(LaunchCaller &caller)
421{
422	LaunchContext context;
423	BRoster roster;
424	create_app(appFile1, appType1);
425	create_app(appFile2, appType1, true);
426	set_file_time(appFile2, time(NULL) + 1);
427	install_type(fileType1, appType1);
428	team_id team;
429	CHK(context(caller, fileType1, &team) == B_OK);
430	entry_ref ref = ref_for_team(team);
431	CHK(ref_for_path(appFile2) == ref);
432	check_app_type(appType1, appFile2);
433	context.Terminate();
434	int32 cookie = 0;
435	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
436	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
437	CHK(context.CheckMessageMessages(caller, team, cookie));
438	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
439	if (caller.SupportsRefs() && !caller.SupportsArgv())
440		CHK(context.CheckRefsMessage(caller, team, cookie));
441	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
442	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
443	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
444}
445
446/*
447	@case 8			installed type mimeType, preferred app, app type installed,
448					two apps have the signature, one has a version info, the
449					other one is newer
450	@results		Should return B_OK and set team to the ID of the team
451					running the application executable with version info.
452					Should set the app hint on the app type.
453*/
454static
455void
456CommonLaunchTest8(LaunchCaller &caller)
457{
458	LaunchContext context;
459	BRoster roster;
460	create_app(appFile1, appType1);
461	set_version(appFile1, 1);
462	create_app(appFile2, appType1, true);
463	set_file_time(appFile2, time(NULL) + 1);
464	install_type(fileType1, appType1);
465	team_id team;
466	CHK(context(caller, fileType1, &team) == B_OK);
467	entry_ref ref = ref_for_team(team);
468	CHK(ref_for_path(appFile1) == ref);
469	check_app_type(appType1, appFile1);
470	context.Terminate();
471	int32 cookie = 0;
472	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
473	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
474	CHK(context.CheckMessageMessages(caller, team, cookie));
475	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
476	if (caller.SupportsRefs() && !caller.SupportsArgv())
477		CHK(context.CheckRefsMessage(caller, team, cookie));
478	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
479	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
480	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
481}
482
483/*
484	@case 9			installed type mimeType, preferred app, app type installed,
485					two apps have the signature, both apps have a version info
486	@results		Should return B_OK and set team to the ID of the team
487					running the application executable with the greater
488					version. Should set the app hint on the app type.
489*/
490static
491void
492CommonLaunchTest9(LaunchCaller &caller)
493{
494	LaunchContext context;
495	BRoster roster;
496	create_app(appFile1, appType1);
497	set_version(appFile1, 2);
498	create_app(appFile2, appType1, true);
499	set_version(appFile1, 1);
500	set_file_time(appFile2, time(NULL) + 1);
501	install_type(fileType1, appType1);
502	team_id team;
503	CHK(context(caller, fileType1, &team) == B_OK);
504	entry_ref ref = ref_for_team(team);
505	CHK(ref_for_path(appFile1) == ref);
506	check_app_type(appType1, appFile1);
507	context.Terminate();
508	int32 cookie = 0;
509	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
510	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
511	CHK(context.CheckMessageMessages(caller, team, cookie));
512	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
513	if (caller.SupportsRefs() && !caller.SupportsArgv())
514		CHK(context.CheckRefsMessage(caller, team, cookie));
515	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
516	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
517	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
518}
519
520/*
521	@case 10		installed type mimeType, preferred app, app type installed,
522					preferred app type has an app hint that points to an app
523					with a different signature
524	@results		Should return B_OK and set team to the ID of the team
525					running the application's executable. Should remove the
526					incorrect app hint on the app type. (Haiku: Should set the
527					correct app hint. Don't even return the wrong app?)
528*/
529static
530void
531CommonLaunchTest10(LaunchCaller &caller)
532{
533	LaunchContext context;
534	BRoster roster;
535	create_app(appFile1, appType2);
536	set_type_app_hint(appType1, appFile1);
537	entry_ref appHint;
538	CHK(BMimeType(appType1).GetAppHint(&appHint) == B_OK);
539	install_type(fileType1, appType1);
540	team_id team;
541	CHK(context(caller, fileType1, &team) == B_OK);
542	entry_ref ref = ref_for_team(team);
543	CHK(ref_for_path(appFile1) == ref);
544	CHK(BMimeType(appType1).GetAppHint(&appHint) == B_ENTRY_NOT_FOUND);
545// Haiku: We set the app hint for app type 2. There's no reason not to do it.
546#ifdef TEST_R5
547	CHK(BMimeType(appType2).IsInstalled() == false);
548#else
549	check_app_type(appType2, appFile1);
550#endif
551	context.Terminate();
552	int32 cookie = 0;
553	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
554	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
555	CHK(context.CheckMessageMessages(caller, team, cookie));
556	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
557	if (caller.SupportsRefs() && !caller.SupportsArgv())
558		CHK(context.CheckRefsMessage(caller, team, cookie));
559	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
560	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
561	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
562}
563
564/*
565	@case 11		installed type mimeType, preferred app, app type installed,
566					preferred app type has an app hint pointing to void,
567					a differently named app with this signature exists
568	@results		Should return B_OK and set team to the ID of the team
569					running the application's executable. Should update the
570					app hint on the app type.
571*/
572static
573void
574CommonLaunchTest11(LaunchCaller &caller)
575{
576	LaunchContext context;
577	BRoster roster;
578	create_app(appFile1, appType1);
579	set_type_app_hint(appType1, appFile2);
580	install_type(fileType1, appType1);
581	team_id team;
582	CHK(context(caller, fileType1, &team) == B_OK);
583	entry_ref ref = ref_for_team(team);
584	CHK(ref_for_path(appFile1) == ref);
585	check_app_type(appType1, appFile1);
586	context.Terminate();
587	int32 cookie = 0;
588	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
589	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
590	CHK(context.CheckMessageMessages(caller, team, cookie));
591	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
592	if (caller.SupportsRefs() && !caller.SupportsArgv())
593		CHK(context.CheckRefsMessage(caller, team, cookie));
594	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
595	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
596	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
597}
598
599/*
600	@case 12		mimeType is app signature, not installed
601	@results		Should return B_OK and set team to the ID of the team
602					running the application executable. Should set the app
603					hint on the app type.
604*/
605static
606void
607CommonLaunchTest12(LaunchCaller &caller)
608{
609	LaunchContext context;
610	BRoster roster;
611	create_app(appFile1, appType1);
612	team_id team;
613	CHK(context(caller, appType1, &team) == B_OK);
614	entry_ref ref = ref_for_team(team);
615	CHK(ref_for_path(appFile1) == ref);
616	check_app_type(appType1, appFile1);
617	context.Terminate();
618	int32 cookie = 0;
619	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
620	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
621	CHK(context.CheckMessageMessages(caller, team, cookie));
622	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
623	if (caller.SupportsRefs() && !caller.SupportsArgv())
624		CHK(context.CheckRefsMessage(caller, team, cookie));
625	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
626	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
627	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
628}
629
630/*
631	@case 13		mimeType is installed, but has no preferred application,
632					super type has preferred application
633	@results		Should return B_OK and set team to the ID of the team
634					running the application executable associated with the
635					preferred app of the supertype. Should set the app hint
636					on the app type.
637*/
638static
639void
640CommonLaunchTest13(LaunchCaller &caller)
641{
642	LaunchContext context;
643	BRoster roster;
644	// make sure, the original preferred app for the "text" supertype is
645	// re-installed
646	struct TextTypeSaver {
647		TextTypeSaver()
648		{
649			BMimeType textType("text");
650			hasPreferredApp
651				= (textType.GetPreferredApp(preferredApp) == B_OK);
652		}
653
654		~TextTypeSaver()
655		{
656			BMimeType textType("text");
657			textType.SetPreferredApp(hasPreferredApp ? preferredApp : NULL);
658		}
659
660		bool	hasPreferredApp;
661		char	preferredApp[B_MIME_TYPE_LENGTH];
662	} _saver;
663
664	create_app(appFile1, appType1);
665	CHK(BMimeType("text").SetPreferredApp(appType1) == B_OK);
666	install_type(textTestType);
667	team_id team;
668	CHK(context(caller, textTestType, &team) == B_OK);
669	entry_ref ref = ref_for_team(team);
670	CHK(ref_for_path(appFile1) == ref);
671	check_app_type(appType1, appFile1);
672	context.Terminate();
673	int32 cookie = 0;
674	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
675	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
676	CHK(context.CheckMessageMessages(caller, team, cookie));
677	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
678	if (caller.SupportsRefs() && !caller.SupportsArgv())
679		CHK(context.CheckRefsMessage(caller, team, cookie));
680	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
681	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
682	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
683}
684
685/*
686	@case 14		installed type mimeType, preferred app, app type not
687					installed, app has signature, app is trash
688	@results		Should return B_LAUNCH_FAILED_APP_IN_TRASH.
689*/
690static
691void
692CommonLaunchTest14(LaunchCaller &caller)
693{
694	LaunchContext context;
695	BRoster roster;
696	create_app(get_trash_app_file(), appType1);
697	install_type(fileType1, appType1);
698	team_id team;
699	CHK(context(caller, fileType1, &team) == B_LAUNCH_FAILED_APP_IN_TRASH);
700}
701
702/*
703	@case 15		installed type mimeType, preferred app, app type not
704					installed, app has signature, team is NULL
705	@results		Should return B_OK and set team to the ID of the team
706					running the application's executable. Should install the
707					app type and set the app hint on it.
708*/
709static
710void
711CommonLaunchTest15(LaunchCaller &caller)
712{
713	LaunchContext context;
714	BRoster roster;
715	create_app(appFile1, appType1);
716	install_type(fileType1, appType1);
717	CHK(context(caller, fileType1, NULL) == B_OK);
718	context.WaitForMessage(uint32(MSG_STARTED), true);
719	team_id team = context.TeamAt(0);
720	CHK(team >= 0);
721	entry_ref ref = ref_for_team(team);
722	CHK(ref_for_path(appFile1) == ref);
723	check_app_type(appType1, appFile1);
724	context.Terminate();
725	int32 cookie = 0;
726	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
727	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
728	CHK(context.CheckMessageMessages(caller, team, cookie));
729	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
730	if (caller.SupportsRefs() && !caller.SupportsArgv())
731		CHK(context.CheckRefsMessage(caller, team, cookie));
732	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
733	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
734	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
735}
736
737/*
738	@case 16		launch the app two times: B_MULTIPLE_LAUNCH | B_ARGV_ONLY
739	@results		first app:	ArgvReceived(), ReadyToRun(), QuitRequested()
740					second app:	ArgvReceived(), ReadyToRun(), QuitRequested()
741*/
742static
743void
744CommonLaunchTest16(LaunchCaller &caller)
745{
746	LaunchCaller &caller2 = caller.Clone();
747	LaunchContext context;
748	BRoster roster;
749	create_app(appFile1, appType1, false, true,
750			   B_MULTIPLE_LAUNCH | B_ARGV_ONLY);
751	install_type(fileType1, appType1);
752	// launch app 1
753	team_id team1;
754	CHK(context(caller, fileType1, &team1) == B_OK);
755	entry_ref ref1 = ref_for_team(team1);
756	CHK(ref_for_path(appFile1) == ref1);
757	check_app_type(appType1, appFile1);
758	context.WaitForMessage(team1, MSG_STARTED);
759	// launch app 2
760	team_id team2;
761	CHK(context(caller2, fileType1, &team2) == B_OK);
762	entry_ref ref2 = ref_for_team(team2);
763	CHK(ref_for_path(appFile1) == ref2);
764	check_app_type(appType1, appFile1);
765	// checks 1
766	context.Terminate();
767	int32 cookie = 0;
768	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_STARTED));
769	CHK(context.CheckMainArgsMessage(caller, team1, cookie, &ref1));
770//	CHK(context.CheckMessageMessages(caller, team1, cookie));
771	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
772//	if (caller.SupportsRefs() && !caller.SupportsArgv())
773//		CHK(context.CheckRefsMessage(caller, team1, cookie));
774	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_READY_TO_RUN));
775	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_QUIT_REQUESTED));
776	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_TERMINATED));
777	// checks 2
778	cookie = 0;
779	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_STARTED));
780	CHK(context.CheckMainArgsMessage(caller2, team2, cookie, &ref2));
781//	CHK(context.CheckMessageMessages(caller2, team2, cookie));
782	CHK(context.CheckArgvMessage(caller2, team2, cookie, &ref2));
783//	if (caller.SupportsRefs() && !caller.SupportsArgv())
784//		CHK(context.CheckRefsMessage(caller2, team2, cookie));
785	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_READY_TO_RUN));
786	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_QUIT_REQUESTED));
787	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_TERMINATED));
788}
789
790/*
791	@case 17		launch the app two times: B_MULTIPLE_LAUNCH | B_ARGV_ONLY
792	@results		first app:	{Message,Argv,Refs}Received()*, ReadyToRun(),
793								QuitRequested()
794					second app:	{Message,Argv,Refs}Received()*, ReadyToRun(),
795								QuitRequested()
796*/
797static
798void
799CommonLaunchTest17(LaunchCaller &caller)
800{
801	LaunchCaller &caller2 = caller.Clone();
802	LaunchContext context;
803	BRoster roster;
804	create_app(appFile1, appType1, false, true,
805			   B_MULTIPLE_LAUNCH);
806	install_type(fileType1, appType1);
807	// launch app 1
808	team_id team1;
809	CHK(context(caller, fileType1, &team1) == B_OK);
810	entry_ref ref1 = ref_for_team(team1);
811	CHK(ref_for_path(appFile1) == ref1);
812	check_app_type(appType1, appFile1);
813	context.WaitForMessage(team1, MSG_STARTED);
814	// launch app 2
815	team_id team2;
816	CHK(context(caller2, fileType1, &team2) == B_OK);
817	entry_ref ref2 = ref_for_team(team2);
818	CHK(ref_for_path(appFile1) == ref2);
819	check_app_type(appType1, appFile1);
820	// checks 1
821	context.Terminate();
822	int32 cookie = 0;
823	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_STARTED));
824	CHK(context.CheckMainArgsMessage(caller, team1, cookie, &ref1));
825	CHK(context.CheckMessageMessages(caller, team1, cookie));
826	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
827	if (caller.SupportsRefs() && !caller.SupportsArgv())
828		CHK(context.CheckRefsMessage(caller, team1, cookie));
829	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_READY_TO_RUN));
830	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_QUIT_REQUESTED));
831	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_TERMINATED));
832	// checks 2
833	cookie = 0;
834	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_STARTED));
835	CHK(context.CheckMainArgsMessage(caller2, team2, cookie, &ref2));
836	CHK(context.CheckMessageMessages(caller2, team2, cookie));
837	CHK(context.CheckArgvMessage(caller2, team2, cookie, &ref2));
838	if (caller.SupportsRefs() && !caller.SupportsArgv())
839		CHK(context.CheckRefsMessage(caller2, team2, cookie));
840	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_READY_TO_RUN));
841	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_QUIT_REQUESTED));
842	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_TERMINATED));
843}
844
845/*
846	@case 18		launch the app two times: B_SINGLE_LAUNCH | B_ARGV_ONLY
847	@results		first app:	ArgvReceived(), ReadyToRun(), QuitRequested()
848								(No second ArgvReceived()!)
849					second app:	Launch() fails with B_ALREADY_RUNNING
850*/
851static
852void
853CommonLaunchTest18(LaunchCaller &caller)
854{
855	LaunchCaller &caller2 = caller.Clone();
856	LaunchContext context;
857	BRoster roster;
858	create_app(appFile1, appType1, false, true,
859			   B_SINGLE_LAUNCH | B_ARGV_ONLY);
860	install_type(fileType1, appType1);
861	// launch app 1
862	team_id team1;
863	CHK(context(caller, fileType1, &team1) == B_OK);
864	entry_ref ref1 = ref_for_team(team1);
865	CHK(ref_for_path(appFile1) == ref1);
866	check_app_type(appType1, appFile1);
867	context.WaitForMessage(team1, MSG_STARTED);
868	// launch app 2
869	team_id team2;
870	CHK(context(caller2, fileType1, &team2) == B_ALREADY_RUNNING);
871	// checks 1
872	context.Terminate();
873	int32 cookie = 0;
874	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_STARTED));
875	CHK(context.CheckMainArgsMessage(caller, team1, cookie, &ref1));
876//	CHK(context.CheckMessageMessages(caller, team1, cookie));
877	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
878//	if (caller.SupportsRefs() && !caller.SupportsArgv())
879//		CHK(context.CheckRefsMessage(caller, team1, cookie));
880	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_READY_TO_RUN));
881	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_QUIT_REQUESTED));
882	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_TERMINATED));
883}
884
885/*
886	@case 19		launch the app two times: B_SINGLE_LAUNCH
887	@results		first app:	{Message,Argv,Refs}Received()*, ReadyToRun(),
888								{Message,Argv,Refs}Received()*, QuitRequested()
889					second app:	Launch() fails with B_ALREADY_RUNNING
890*/
891static
892void
893CommonLaunchTest19(LaunchCaller &caller)
894{
895	LaunchCaller &caller2 = caller.Clone();
896	LaunchContext context;
897	BRoster roster;
898	create_app(appFile1, appType1, false, true,
899			   B_SINGLE_LAUNCH);
900	install_type(fileType1, appType1);
901	// launch app 1
902	team_id team1;
903	CHK(context(caller, fileType1, &team1) == B_OK);
904	entry_ref ref1 = ref_for_team(team1);
905	CHK(ref_for_path(appFile1) == ref1);
906	check_app_type(appType1, appFile1);
907	context.WaitForMessage(team1, MSG_STARTED);
908	// launch app 2
909	team_id team2;
910	CHK(context(caller2, fileType1, &team2) == B_ALREADY_RUNNING);
911	// checks 1
912	context.Terminate();
913	int32 cookie = 0;
914	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_STARTED));
915	CHK(context.CheckMainArgsMessage(caller, team1, cookie, &ref1));
916	CHK(context.CheckMessageMessages(caller, team1, cookie));
917	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
918	if (caller.SupportsRefs() && !caller.SupportsArgv())
919		CHK(context.CheckRefsMessage(caller, team1, cookie));
920	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_READY_TO_RUN));
921	CHK(context.CheckMessageMessages(caller, team1, cookie));
922	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
923	if (caller.SupportsRefs() && !caller.SupportsArgv())
924		CHK(context.CheckRefsMessage(caller, team1, cookie));
925	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_QUIT_REQUESTED));
926	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_TERMINATED));
927}
928
929/*
930	@case 20		launch two apps with the same signature:
931					B_SINGLE_LAUNCH | B_ARGV_ONLY
932	@results		first app:	ArgvReceived(), ReadyToRun(), QuitRequested()
933					second app:	ArgvReceived(), ReadyToRun(), QuitRequested()
934*/
935static
936void
937CommonLaunchTest20(LaunchCaller &caller)
938{
939	LaunchCaller &caller2 = caller.Clone();
940	LaunchContext context;
941	BRoster roster;
942	// launch app 1
943	create_app(appFile1, appType1, false, true,
944			   B_SINGLE_LAUNCH | B_ARGV_ONLY);
945	install_type(fileType1, appType1);
946	team_id team1;
947	CHK(context(caller, fileType1, &team1) == B_OK);
948	entry_ref ref1 = ref_for_team(team1);
949	CHK(ref_for_path(appFile1) == ref1);
950	check_app_type(appType1, appFile1);
951	context.WaitForMessage(team1, MSG_STARTED);
952	// launch app 2 (greater modification time)
953	CHK(BMimeType(appType1).Delete() == B_OK);
954	create_app(appFile2, appType1, false, true,
955			   B_SINGLE_LAUNCH | B_ARGV_ONLY);
956	set_file_time(appFile2, time(NULL) + 1);
957	team_id team2;
958	CHK(context(caller2, fileType1, &team2) == B_OK);
959	entry_ref ref2 = ref_for_team(team2);
960	CHK(ref_for_path(appFile2) == ref2);
961	check_app_type(appType1, appFile2);
962	// checks 1
963	context.Terminate();
964	int32 cookie = 0;
965	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_STARTED));
966	CHK(context.CheckMainArgsMessage(caller, team1, cookie, &ref1));
967//	CHK(context.CheckMessageMessages(caller, team1, cookie));
968	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
969//	if (caller.SupportsRefs() && !caller.SupportsArgv())
970//		CHK(context.CheckRefsMessage(caller, team1, cookie));
971	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_READY_TO_RUN));
972	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_QUIT_REQUESTED));
973	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_TERMINATED));
974	// checks 2
975	cookie = 0;
976	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_STARTED));
977	CHK(context.CheckMainArgsMessage(caller2, team2, cookie, &ref2));
978//	CHK(context.CheckMessageMessages(caller2, team2, cookie));
979	CHK(context.CheckArgvMessage(caller2, team2, cookie, &ref2));
980//	if (caller.SupportsRefs() && !caller.SupportsArgv())
981//		CHK(context.CheckRefsMessage(caller2, team2, cookie));
982	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_READY_TO_RUN));
983	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_QUIT_REQUESTED));
984	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_TERMINATED));
985}
986
987/*
988	@case 21		launch two apps with the same signature: B_SINGLE_LAUNCH
989	@results		first app:	{Message,Argv,Refs}Received()*, ReadyToRun(),
990								QuitRequested()
991					second app:	{Message,Argv,Refs}Received()*, ReadyToRun(),
992								QuitRequested()
993*/
994static
995void
996CommonLaunchTest21(LaunchCaller &caller)
997{
998	LaunchCaller &caller2 = caller.Clone();
999	LaunchContext context;
1000	BRoster roster;
1001	// launch app 1
1002	create_app(appFile1, appType1, false, true,
1003			   B_SINGLE_LAUNCH);
1004	install_type(fileType1, appType1);
1005	team_id team1;
1006	CHK(context(caller, fileType1, &team1) == B_OK);
1007	entry_ref ref1 = ref_for_team(team1);
1008	CHK(ref_for_path(appFile1) == ref1);
1009	check_app_type(appType1, appFile1);
1010	context.WaitForMessage(team1, MSG_STARTED);
1011	// launch app 2 (greater modification time)
1012	CHK(BMimeType(appType1).Delete() == B_OK);
1013	create_app(appFile2, appType1, false, true,
1014			   B_SINGLE_LAUNCH);
1015	set_file_time(appFile2, time(NULL) + 1);
1016	team_id team2;
1017	CHK(context(caller2, fileType1, &team2) == B_OK);
1018	entry_ref ref2 = ref_for_team(team2);
1019	CHK(ref_for_path(appFile2) == ref2);
1020	check_app_type(appType1, appFile2);
1021	// checks 1
1022	context.Terminate();
1023	int32 cookie = 0;
1024	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_STARTED));
1025	CHK(context.CheckMainArgsMessage(caller, team1, cookie, &ref1));
1026	CHK(context.CheckMessageMessages(caller, team1, cookie));
1027	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
1028	if (caller.SupportsRefs() && !caller.SupportsArgv())
1029		CHK(context.CheckRefsMessage(caller, team1, cookie));
1030	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_READY_TO_RUN));
1031	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_QUIT_REQUESTED));
1032	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_TERMINATED));
1033	// checks 2
1034	cookie = 0;
1035	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_STARTED));
1036	CHK(context.CheckMainArgsMessage(caller2, team2, cookie, &ref2));
1037	CHK(context.CheckMessageMessages(caller2, team2, cookie));
1038	CHK(context.CheckArgvMessage(caller2, team2, cookie, &ref2));
1039	if (caller.SupportsRefs() && !caller.SupportsArgv())
1040		CHK(context.CheckRefsMessage(caller2, team2, cookie));
1041	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_READY_TO_RUN));
1042	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_QUIT_REQUESTED));
1043	CHK(context.CheckNextMessage(caller2, team2, cookie, MSG_TERMINATED));
1044}
1045
1046/*
1047	@case 22		launch the app two times: B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY
1048	@results		first app:	ArgvReceived(), ReadyToRun(), QuitRequested()
1049								(No second ArgvReceived()!)
1050					second app:	Launch() fails with B_ALREADY_RUNNING
1051*/
1052static
1053void
1054CommonLaunchTest22(LaunchCaller &caller)
1055{
1056	LaunchCaller &caller2 = caller.Clone();
1057	LaunchContext context;
1058	BRoster roster;
1059	create_app(appFile1, appType1, false, true,
1060			   B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY);
1061	install_type(fileType1, appType1);
1062	// launch app 1
1063	team_id team1;
1064	CHK(context(caller, fileType1, &team1) == B_OK);
1065	entry_ref ref1 = ref_for_team(team1);
1066	CHK(ref_for_path(appFile1) == ref1);
1067	check_app_type(appType1, appFile1);
1068	context.WaitForMessage(team1, MSG_STARTED);
1069	// launch app 2
1070	team_id team2;
1071	CHK(context(caller2, fileType1, &team2) == B_ALREADY_RUNNING);
1072	// checks 1
1073	context.Terminate();
1074	int32 cookie = 0;
1075	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_STARTED));
1076	CHK(context.CheckMainArgsMessage(caller, team1, cookie, &ref1));
1077//	CHK(context.CheckMessageMessages(caller, team1, cookie));
1078	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
1079//	if (caller.SupportsRefs() && !caller.SupportsArgv())
1080//		CHK(context.CheckRefsMessage(caller, team1, cookie));
1081	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_READY_TO_RUN));
1082	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_QUIT_REQUESTED));
1083	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_TERMINATED));
1084}
1085
1086/*
1087	@case 23		launch the app two times: B_EXCLUSIVE_LAUNCH
1088	@results		first app:	{Message,Argv,Refs}Received()*, ReadyToRun(),
1089								{Message,Argv,Refs}Received()*, QuitRequested()
1090					second app:	Launch() fails with B_ALREADY_RUNNING
1091*/
1092static
1093void
1094CommonLaunchTest23(LaunchCaller &caller)
1095{
1096	LaunchCaller &caller2 = caller.Clone();
1097	LaunchContext context;
1098	BRoster roster;
1099	create_app(appFile1, appType1, false, true,
1100			   B_EXCLUSIVE_LAUNCH);
1101	install_type(fileType1, appType1);
1102	// launch app 1
1103	team_id team1;
1104	CHK(context(caller, fileType1, &team1) == B_OK);
1105	entry_ref ref1 = ref_for_team(team1);
1106	CHK(ref_for_path(appFile1) == ref1);
1107	check_app_type(appType1, appFile1);
1108	context.WaitForMessage(team1, MSG_STARTED);
1109	// launch app 2
1110	team_id team2;
1111	CHK(context(caller2, fileType1, &team2) == B_ALREADY_RUNNING);
1112	// checks 1
1113	context.Terminate();
1114	int32 cookie = 0;
1115	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_STARTED));
1116	CHK(context.CheckMainArgsMessage(caller, team1, cookie, &ref1));
1117	CHK(context.CheckMessageMessages(caller, team1, cookie));
1118	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
1119	if (caller.SupportsRefs() && !caller.SupportsArgv())
1120		CHK(context.CheckRefsMessage(caller, team1, cookie));
1121	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_READY_TO_RUN));
1122	CHK(context.CheckMessageMessages(caller, team1, cookie));
1123	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
1124	if (caller.SupportsRefs() && !caller.SupportsArgv())
1125		CHK(context.CheckRefsMessage(caller, team1, cookie));
1126	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_QUIT_REQUESTED));
1127	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_TERMINATED));
1128}
1129
1130/*
1131	@case 24		launch two apps with the same signature:
1132					B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY
1133	@results		first app:	ArgvReceived(), ReadyToRun(), QuitRequested()
1134								(No second ArgvReceived()!)
1135					second app:	Launch() fails with B_ALREADY_RUNNING
1136*/
1137static
1138void
1139CommonLaunchTest24(LaunchCaller &caller)
1140{
1141	LaunchCaller &caller2 = caller.Clone();
1142	LaunchContext context;
1143	BRoster roster;
1144	// launch app 1
1145	create_app(appFile1, appType1, false, true,
1146			   B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY);
1147	install_type(fileType1, appType1);
1148	team_id team1;
1149	CHK(context(caller, fileType1, &team1) == B_OK);
1150	entry_ref ref1 = ref_for_team(team1);
1151	CHK(ref_for_path(appFile1) == ref1);
1152	check_app_type(appType1, appFile1);
1153	context.WaitForMessage(team1, MSG_STARTED);
1154	// launch app 2 (greater modification time)
1155	CHK(BMimeType(appType1).Delete() == B_OK);
1156	create_app(appFile2, appType1, false, true,
1157			   B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY);
1158	set_file_time(appFile2, time(NULL) + 1);
1159	team_id team2;
1160	CHK(context(caller2, fileType1, &team2) == B_ALREADY_RUNNING);
1161	// checks 1
1162	context.Terminate();
1163	int32 cookie = 0;
1164	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_STARTED));
1165	CHK(context.CheckMainArgsMessage(caller, team1, cookie, &ref1));
1166//	CHK(context.CheckMessageMessages(caller, team1, cookie));
1167	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
1168//	if (caller.SupportsRefs() && !caller.SupportsArgv())
1169//		CHK(context.CheckRefsMessage(caller, team1, cookie));
1170	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_READY_TO_RUN));
1171	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_QUIT_REQUESTED));
1172	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_TERMINATED));
1173}
1174
1175/*
1176	@case 25		launch two apps with the same signature:
1177					B_EXCLUSIVE_LAUNCH
1178	@results		first app:	{Message,Argv,Refs}Received()*, ReadyToRun(),
1179								{Message,Argv,Refs}Received()*, QuitRequested()
1180					second app:	Launch() fails with B_ALREADY_RUNNING
1181*/
1182static
1183void
1184CommonLaunchTest25(LaunchCaller &caller)
1185{
1186	LaunchCaller &caller2 = caller.Clone();
1187	LaunchContext context;
1188	BRoster roster;
1189	// launch app 1
1190	create_app(appFile1, appType1, false, true,
1191			   B_EXCLUSIVE_LAUNCH);
1192	install_type(fileType1, appType1);
1193	team_id team1;
1194	CHK(context(caller, fileType1, &team1) == B_OK);
1195	entry_ref ref1 = ref_for_team(team1);
1196	CHK(ref_for_path(appFile1) == ref1);
1197	check_app_type(appType1, appFile1);
1198	context.WaitForMessage(team1, MSG_STARTED);
1199	// launch app 2 (greater modification time)
1200	CHK(BMimeType(appType1).Delete() == B_OK);
1201	create_app(appFile2, appType1, false, true,
1202			   B_EXCLUSIVE_LAUNCH);
1203	set_file_time(appFile2, time(NULL) + 1);
1204	team_id team2;
1205	CHK(context(caller2, fileType1, &team2) == B_ALREADY_RUNNING);
1206	entry_ref ref2 = ref_for_path(appFile2);
1207	// checks 1
1208	context.Terminate();
1209	int32 cookie = 0;
1210	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_STARTED));
1211	CHK(context.CheckMainArgsMessage(caller, team1, cookie, &ref1));
1212	CHK(context.CheckMessageMessages(caller, team1, cookie));
1213	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
1214	if (caller.SupportsRefs() && !caller.SupportsArgv())
1215		CHK(context.CheckRefsMessage(caller, team1, cookie));
1216	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_READY_TO_RUN));
1217	CHK(context.CheckMessageMessages(caller, team1, cookie));
1218	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref2));
1219	if (caller.SupportsRefs() && !caller.SupportsArgv())
1220		CHK(context.CheckRefsMessage(caller, team1, cookie));
1221	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_QUIT_REQUESTED));
1222	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_TERMINATED));
1223}
1224
1225/*
1226	@case 26		launch two apps with the same signature:
1227					first: B_EXCLUSIVE_LAUNCH,
1228					second: B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY =>
1229	@results		first app:	{Message,Argv,Refs}Received()*, ReadyToRun(),
1230								QuitRequested()
1231					second app:	Launch() fails with B_ALREADY_RUNNING
1232*/
1233static
1234void
1235CommonLaunchTest26(LaunchCaller &caller)
1236{
1237	LaunchCaller &caller2 = caller.Clone();
1238	LaunchContext context;
1239	BRoster roster;
1240	// launch app 1
1241	create_app(appFile1, appType1, false, true,
1242			   B_EXCLUSIVE_LAUNCH);
1243	install_type(fileType1, appType1);
1244	team_id team1;
1245	CHK(context(caller, fileType1, &team1) == B_OK);
1246	entry_ref ref1 = ref_for_team(team1);
1247	CHK(ref_for_path(appFile1) == ref1);
1248	check_app_type(appType1, appFile1);
1249	context.WaitForMessage(team1, MSG_STARTED);
1250	// launch app 2 (greater modification time)
1251	CHK(BMimeType(appType1).Delete() == B_OK);
1252	create_app(appFile2, appType1, false, true,
1253			   B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY);
1254	set_file_time(appFile2, time(NULL) + 1);
1255	team_id team2;
1256	CHK(context(caller2, fileType1, &team2) == B_ALREADY_RUNNING);
1257	entry_ref ref2 = ref_for_path(appFile2);
1258	// checks 1
1259	context.Terminate();
1260	int32 cookie = 0;
1261	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_STARTED));
1262	CHK(context.CheckMainArgsMessage(caller, team1, cookie, &ref1));
1263	CHK(context.CheckMessageMessages(caller, team1, cookie));
1264	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
1265	if (caller.SupportsRefs() && !caller.SupportsArgv())
1266		CHK(context.CheckRefsMessage(caller, team1, cookie));
1267	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_READY_TO_RUN));
1268	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_QUIT_REQUESTED));
1269	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_TERMINATED));
1270}
1271
1272/*
1273	@case 27		launch two apps with the same signature:
1274					first: B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
1275					second: B_EXCLUSIVE_LAUNCH
1276	@results		first app:	ArgvReceived(), ReadyToRun(), QuitRequested()
1277								(No second ArgvReceived()!)
1278					second app:	Launch() fails with B_ALREADY_RUNNING
1279*/
1280static
1281void
1282CommonLaunchTest27(LaunchCaller &caller)
1283{
1284	LaunchCaller &caller2 = caller.Clone();
1285	LaunchContext context;
1286	BRoster roster;
1287	// launch app 1
1288	create_app(appFile1, appType1, false, true,
1289			   B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY);
1290	install_type(fileType1, appType1);
1291	team_id team1;
1292	CHK(context(caller, fileType1, &team1) == B_OK);
1293	entry_ref ref1 = ref_for_team(team1);
1294	CHK(ref_for_path(appFile1) == ref1);
1295	check_app_type(appType1, appFile1);
1296	context.WaitForMessage(team1, MSG_STARTED);
1297	// launch app 2 (greater modification time)
1298	CHK(BMimeType(appType1).Delete() == B_OK);
1299	create_app(appFile2, appType1, false, true,
1300			   B_EXCLUSIVE_LAUNCH);
1301	set_file_time(appFile2, time(NULL) + 1);
1302	team_id team2;
1303	CHK(context(caller2, fileType1, &team2) == B_ALREADY_RUNNING);
1304	// checks 1
1305	context.Terminate();
1306	int32 cookie = 0;
1307	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_STARTED));
1308	CHK(context.CheckMainArgsMessage(caller, team1, cookie, &ref1));
1309//	CHK(context.CheckMessageMessages(caller, team1, cookie));
1310	CHK(context.CheckArgvMessage(caller, team1, cookie, &ref1));
1311//	if (caller.SupportsRefs() && !caller.SupportsArgv())
1312//		CHK(context.CheckRefsMessage(caller, team1, cookie));
1313	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_READY_TO_RUN));
1314	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_QUIT_REQUESTED));
1315	CHK(context.CheckNextMessage(caller, team1, cookie, MSG_TERMINATED));
1316}
1317
1318/*
1319	@case 28		installed type mimeType, preferred app, app type installed,
1320					preferred app type has an app hint pointing to void,
1321					no app with this signature exists
1322	@results		Should return B_LAUNCH_FAILED_APP_NOT_FOUND and unset the
1323					app type's app hint.
1324*/
1325static
1326void
1327CommonLaunchTest28(LaunchCaller &caller)
1328{
1329	LaunchContext context;
1330	BRoster roster;
1331	set_type_app_hint(appType1, appFile1);
1332	install_type(fileType1, appType1);
1333	team_id team;
1334	CHK(context(caller, fileType1, &team) == B_LAUNCH_FAILED_APP_NOT_FOUND);
1335	entry_ref appHint;
1336	CHK(BMimeType(appType1).GetAppHint(&appHint) == B_ENTRY_NOT_FOUND);
1337}
1338
1339/*
1340	@case 29		installed type mimeType, preferred app, app type installed,
1341					preferred app type has an app hint pointing to a cyclic
1342					link, no app with this signature exists
1343	@results		Should return
1344					Haiku: B_LAUNCH_FAILED_APP_NOT_FOUND and unset the app
1345					type's app hint.
1346					R5: B_ENTRY_NOT_FOUND or B_LAUNCH_FAILED_NO_RESOLVE_LINK.
1347*/
1348static
1349void
1350CommonLaunchTest29(LaunchCaller &caller)
1351{
1352	LaunchContext context;
1353	BRoster roster;
1354	set_type_app_hint(appType1, appFile1);
1355	install_type(fileType1, appType1);
1356	system((string("ln -s ") + appFile1 + " " + appFile1).c_str());
1357	team_id team;
1358	entry_ref appHint;
1359#if TEST_R5
1360	if (caller.SupportsRefs()) {
1361		CHK(context(caller, fileType1, &team)
1362			== B_LAUNCH_FAILED_NO_RESOLVE_LINK);
1363	} else
1364		CHK(context(caller, fileType1, &team) == B_ENTRY_NOT_FOUND);
1365	CHK(BMimeType(appType1).GetAppHint(&appHint) == B_OK);
1366	CHK(appHint == ref_for_path(appFile1, false));
1367#else
1368	CHK(context(caller, fileType1, &team) == B_LAUNCH_FAILED_APP_NOT_FOUND);
1369	CHK(BMimeType(appType1).GetAppHint(&appHint) == B_ENTRY_NOT_FOUND);
1370#endif
1371}
1372
1373/*
1374	@case 30		installed type mimeType, preferred app, app type installed,
1375					preferred app type has an app hint that points to an app
1376					without a signature, app will pass a different signature
1377					to the BApplication constructor
1378	@results		Should return B_OK and set team to the ID of the team
1379					running the application's executable. Should remove the
1380					incorrect app hint on the app type.
1381					BRoster::GetRunningAppInfo() should return an app_info
1382					with the signature passed to the BApplication constructor.
1383*/
1384static
1385void
1386CommonLaunchTest30(LaunchCaller &caller)
1387{
1388	LaunchContext context;
1389	BRoster roster;
1390	create_app(appFile1, NULL);
1391	set_type_app_hint(appType1, appFile1);
1392	entry_ref appHint;
1393	CHK(BMimeType(appType1).GetAppHint(&appHint) == B_OK);
1394	install_type(fileType1, appType1);
1395	team_id team;
1396	CHK(context(caller, fileType1, &team) == B_OK);
1397	entry_ref ref = ref_for_team(team);
1398	CHK(ref_for_path(appFile1) == ref);
1399// Haiku: We unset the app hint for the app type. R5 leaves it untouched.
1400#ifdef TEST_R5
1401	check_app_type(appType1, appFile1);
1402#else
1403	CHK(BMimeType(appType1).GetAppHint(&appHint) == B_ENTRY_NOT_FOUND);
1404#endif
1405	context.WaitForMessage(team, MSG_STARTED, true);
1406	app_info appInfo;
1407	CHK(roster.GetRunningAppInfo(team, &appInfo) == B_OK);
1408// R5 keeps appType1, Haiku updates the signature
1409#ifdef TEST_R5
1410	CHK(!strcmp(appInfo.signature, appType1));
1411#else
1412	CHK(!strcmp(appInfo.signature, kDefaultTestAppSignature));
1413#endif
1414	context.Terminate();
1415	int32 cookie = 0;
1416	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
1417	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
1418	CHK(context.CheckMessageMessages(caller, team, cookie));
1419	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
1420	if (caller.SupportsRefs() && !caller.SupportsArgv())
1421		CHK(context.CheckRefsMessage(caller, team, cookie));
1422	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
1423	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
1424	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
1425}
1426
1427typedef void commonTestFunction(LaunchCaller &caller);
1428static commonTestFunction *commonTestFunctions[] = {
1429	CommonLaunchTest1, CommonLaunchTest2, CommonLaunchTest3,
1430	CommonLaunchTest4, CommonLaunchTest5, CommonLaunchTest6,
1431	CommonLaunchTest7, CommonLaunchTest8, CommonLaunchTest9,
1432	CommonLaunchTest10, CommonLaunchTest11, CommonLaunchTest12,
1433	CommonLaunchTest13, CommonLaunchTest14, CommonLaunchTest15,
1434	CommonLaunchTest16, CommonLaunchTest17, CommonLaunchTest18,
1435	CommonLaunchTest19, CommonLaunchTest20, CommonLaunchTest21,
1436	CommonLaunchTest22, CommonLaunchTest23, CommonLaunchTest24,
1437	CommonLaunchTest25, CommonLaunchTest26, CommonLaunchTest27,
1438	CommonLaunchTest28, CommonLaunchTest29, CommonLaunchTest30
1439};
1440static int32 commonTestFunctionCount
1441	= sizeof(commonTestFunctions) / sizeof(commonTestFunction*);
1442
1443/*
1444	status_t Launch(const char *mimeType, BMessage *initialMsgs,
1445					team_id *appTeam) const
1446	@case 1			mimeType is NULL
1447	@results		Should return B_BAD_VALUE.
1448*/
1449void LaunchTester::LaunchTestA1()
1450{
1451	BRoster roster;
1452	BMessage message;
1453	CHK(roster.Launch((const char*)NULL, &message, NULL) == B_BAD_VALUE);
1454}
1455
1456/*
1457	status_t Launch(const char *mimeType, BMessage *initialMsgs,
1458					team_id *appTeam) const
1459	@case 2			mimeType is invalid
1460	@results		Should return B_BAD_VALUE.
1461*/
1462void LaunchTester::LaunchTestA2()
1463{
1464	BRoster roster;
1465	BMessage message;
1466	CHK(roster.Launch("invalid/mine/type", &message, NULL) == B_BAD_VALUE);
1467}
1468
1469// LaunchTypeCaller1
1470class LaunchTypeCaller1 : public LaunchCaller {
1471public:
1472	virtual status_t operator()(const char *type, BList *messages, int32 argc,
1473								const char **argv, team_id *team)
1474	{
1475		BMessage *message = (messages ? (BMessage*)messages->ItemAt(0L)
1476									  : NULL);
1477		BRoster roster;
1478		return roster.Launch(type, message, team);
1479	}
1480
1481	virtual LaunchCaller *CloneInternal()
1482	{
1483		return new LaunchTypeCaller1;
1484	}
1485};
1486
1487/*
1488	status_t Launch(const char *mimeType, BMessage *initialMsgs,
1489					team_id *appTeam) const
1490	@case 3			common cases 1-14
1491*/
1492void LaunchTester::LaunchTestA3()
1493{
1494	LaunchTypeCaller1 caller;
1495	for (int32 i = 0; i < commonTestFunctionCount; i++) {
1496		NextSubTest();
1497		(*commonTestFunctions[i])(caller);
1498		tearDown();
1499		setUp();
1500	}
1501}
1502
1503/*
1504	status_t Launch(const char *mimeType, BMessage *initialMsgs,
1505					team_id *appTeam) const
1506	@case 4			installed type mimeType, preferred app, app type not
1507					installed, app has signature, NULL initialMsg
1508	@results		Should return B_OK and set team to the ID of the team
1509					running the application's executable. Should install the
1510					app type and set the app hint on it.
1511*/
1512void LaunchTester::LaunchTestA4()
1513{
1514	LaunchTypeCaller1 caller;
1515	LaunchContext context;
1516	BRoster roster;
1517	create_app(appFile1, appType1);
1518	install_type(fileType1, appType1);
1519	team_id team;
1520	CHK(context(caller, fileType1, NULL, LaunchContext::kStandardArgc,
1521				LaunchContext::kStandardArgv, &team) == B_OK);
1522	entry_ref ref = ref_for_team(team);
1523	CHK(ref_for_path(appFile1) == ref);
1524	check_app_type(appType1, appFile1);
1525	context.Terminate();
1526	int32 cookie = 0;
1527	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
1528	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
1529//	CHK(context.CheckMessageMessages(caller, team, cookie));
1530//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
1531//	CHK(context.CheckRefsMessage(caller, team, cookie));
1532	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
1533	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
1534	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
1535}
1536
1537/*
1538	status_t Launch(const char *mimeType, BList *messageList,
1539					team_id *appTeam) const
1540	@case 1			mimeType is NULL
1541	@results		Should return B_BAD_VALUE.
1542*/
1543void LaunchTester::LaunchTestB1()
1544{
1545	BRoster roster;
1546	BList list;
1547	CHK(roster.Launch((const char*)NULL, &list, NULL) == B_BAD_VALUE);
1548}
1549
1550/*
1551	status_t Launch(const char *mimeType, BMessage *initialMsgs,
1552					team_id *appTeam) const
1553	@case 2			mimeType is invalid
1554	@results		Should return B_BAD_VALUE.
1555*/
1556void LaunchTester::LaunchTestB2()
1557{
1558	BRoster roster;
1559	BList list;
1560	CHK(roster.Launch("invalid/mine/type", &list, NULL) == B_BAD_VALUE);
1561}
1562
1563// LaunchTypeCaller2
1564class LaunchTypeCaller2 : public LaunchCaller {
1565public:
1566	virtual status_t operator()(const char *type, BList *messages, int32 argc,
1567								const char **argv, team_id *team)
1568	{
1569		BRoster roster;
1570		return roster.Launch(type, messages, team);
1571	}
1572	virtual int32 SupportsMessages() const { return 1000; }
1573
1574	virtual LaunchCaller *CloneInternal()
1575	{
1576		return new LaunchTypeCaller2;
1577	}
1578};
1579
1580/*
1581	status_t Launch(const char *mimeType, BList *messageList,
1582					team_id *appTeam) const
1583	@case 3			common cases 1-14
1584*/
1585void LaunchTester::LaunchTestB3()
1586{
1587	LaunchTypeCaller2 caller;
1588	for (int32 i = 0; i < commonTestFunctionCount; i++) {
1589		NextSubTest();
1590		(*commonTestFunctions[i])(caller);
1591		tearDown();
1592		setUp();
1593	}
1594}
1595
1596/*
1597	status_t Launch(const char *mimeType, BList *messageList,
1598					team_id *appTeam) const
1599	@case 4			installed type mimeType, preferred app, app type not
1600					installed, app has signature, NULL messageList
1601	@results		Should return B_OK and set team to the ID of the team
1602					running the application's executable. Should install the
1603					app type and set the app hint on it.
1604*/
1605void LaunchTester::LaunchTestB4()
1606{
1607	LaunchTypeCaller2 caller;
1608	LaunchContext context;
1609	BRoster roster;
1610	create_app(appFile1, appType1);
1611	install_type(fileType1, appType1);
1612	team_id team;
1613	CHK(context(caller, fileType1, NULL, LaunchContext::kStandardArgc,
1614				LaunchContext::kStandardArgv, &team) == B_OK);
1615	entry_ref ref = ref_for_team(team);
1616	CHK(ref_for_path(appFile1) == ref);
1617	check_app_type(appType1, appFile1);
1618	context.Terminate();
1619	int32 cookie = 0;
1620	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
1621	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
1622//	CHK(context.CheckMessageMessages(caller, team, cookie));
1623//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
1624//	CHK(context.CheckRefsMessage(caller, team, cookie));
1625	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
1626	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
1627	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
1628}
1629
1630/*
1631	status_t Launch(const char *mimeType, BList *messageList,
1632					team_id *appTeam) const
1633	@case 5			installed type mimeType, preferred app, app type not
1634					installed, app has signature, empty messageList
1635	@results		Should return B_OK and set team to the ID of the team
1636					running the application's executable. Should install the
1637					app type and set the app hint on it.
1638*/
1639void LaunchTester::LaunchTestB5()
1640{
1641	LaunchTypeCaller2 caller;
1642	LaunchContext context;
1643	BRoster roster;
1644	create_app(appFile1, appType1);
1645	install_type(fileType1, appType1);
1646	team_id team;
1647	BList list;
1648	CHK(context(caller, fileType1, &list, LaunchContext::kStandardArgc,
1649				LaunchContext::kStandardArgv, &team) == B_OK);
1650	entry_ref ref = ref_for_team(team);
1651	CHK(ref_for_path(appFile1) == ref);
1652	check_app_type(appType1, appFile1);
1653	context.Terminate();
1654	int32 cookie = 0;
1655	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
1656	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
1657//	CHK(context.CheckMessageMessages(caller, team, cookie));
1658//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
1659//	CHK(context.CheckRefsMessage(caller, team, cookie));
1660	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
1661	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
1662	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
1663}
1664
1665/*
1666	status_t Launch(const char *mimeType, int argc, char **args,
1667					team_id *appTeam) const
1668	@case 1			mimeType is NULL or argc > 0 and args is NULL
1669	@results		Should return B_BAD_VALUE.
1670*/
1671void LaunchTester::LaunchTestC1()
1672{
1673	BRoster roster;
1674	char *argv[] = { "Hey!" };
1675	CHK(roster.Launch((const char*)NULL, 1, argv, NULL) == B_BAD_VALUE);
1676	CHK(roster.Launch((const char*)NULL, 1, (char**)NULL, NULL)
1677		== B_BAD_VALUE);
1678}
1679
1680/*
1681	status_t Launch(const char *mimeType, int argc, char **args,
1682					team_id *appTeam) const
1683	@case 2			mimeType is invalid
1684	@results		Should return B_BAD_VALUE.
1685*/
1686void LaunchTester::LaunchTestC2()
1687{
1688	BRoster roster;
1689	BList list;
1690	char *argv[] = { "Hey!" };
1691	CHK(roster.Launch("invalid/mine/type", 1, argv, NULL) == B_BAD_VALUE);
1692}
1693
1694// LaunchTypeCaller3
1695class LaunchTypeCaller3 : public LaunchCaller {
1696public:
1697	virtual status_t operator()(const char *type, BList *messages, int32 argc,
1698								const char **argv, team_id *team)
1699	{
1700		BRoster roster;
1701		return roster.Launch(type, argc, const_cast<char**>(argv), team);
1702	}
1703	virtual int32 SupportsMessages() const { return 0; }
1704
1705	virtual LaunchCaller *CloneInternal()
1706	{
1707		return new LaunchTypeCaller3;
1708	}
1709};
1710
1711/*
1712	status_t Launch(const char *mimeType, int argc, char **args,
1713					team_id *appTeam) const
1714	@case 3			common cases 1-14
1715*/
1716void LaunchTester::LaunchTestC3()
1717{
1718	LaunchTypeCaller3 caller;
1719	for (int32 i = 0; i < commonTestFunctionCount; i++) {
1720		NextSubTest();
1721		(*commonTestFunctions[i])(caller);
1722		tearDown();
1723		setUp();
1724	}
1725}
1726
1727/*
1728	status_t Launch(const char *mimeType, int argc, char **args,
1729					team_id *appTeam) const
1730	@case 4			installed type mimeType, preferred app, app type not
1731					installed, app has signature, NULL args, argc is 0
1732	@results		Should return B_OK and set team to the ID of the team
1733					running the application's executable. Should install the
1734					app type and set the app hint on it.
1735*/
1736void LaunchTester::LaunchTestC4()
1737{
1738	LaunchTypeCaller3 caller;
1739	LaunchContext context;
1740	BRoster roster;
1741	create_app(appFile1, appType1);
1742	install_type(fileType1, appType1);
1743	team_id team;
1744	CHK(context(caller, fileType1, NULL, 0, (const char**)NULL, &team) == B_OK);
1745	entry_ref ref = ref_for_team(team);
1746	CHK(ref_for_path(appFile1) == ref);
1747	check_app_type(appType1, appFile1);
1748	context.Terminate();
1749	int32 cookie = 0;
1750	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
1751	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref, 0, NULL));
1752//	CHK(context.CheckMessageMessages(caller, team, cookie));
1753//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
1754//	CHK(context.CheckRefsMessage(caller, team, cookie));
1755	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
1756	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
1757	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
1758}
1759
1760// SimpleFileCaller1
1761class SimpleFileCaller1 : public LaunchCaller {
1762public:
1763	SimpleFileCaller1() : fRef() {}
1764	SimpleFileCaller1(const entry_ref &ref) : fRef(ref) {}
1765	virtual ~SimpleFileCaller1() {}
1766	virtual status_t operator()(const char *type, BList *messages, int32 argc,
1767								const char **argv, team_id *team)
1768	{
1769		BRoster roster;
1770		BMessage *message = (messages ? (BMessage*)messages->ItemAt(0L)
1771									  : NULL);
1772		return roster.Launch(&fRef, message, team);
1773	}
1774	virtual bool SupportsRefs() const { return true; }
1775	virtual const entry_ref *Ref() const { return &fRef; }
1776
1777	virtual LaunchCaller *CloneInternal()
1778	{
1779		return new SimpleFileCaller1;
1780	}
1781
1782protected:
1783	entry_ref fRef;
1784};
1785
1786// FileWithTypeCaller1
1787class FileWithTypeCaller1 : public SimpleFileCaller1 {
1788public:
1789	virtual status_t operator()(const char *type, BList *messages, int32 argc,
1790								const char **argv, team_id *team)
1791	{
1792		BRoster roster;
1793		BMessage *message = (messages ? (BMessage*)messages->ItemAt(0L)
1794									  : NULL);
1795		fRef = create_file(testFile1, type);
1796		return roster.Launch(&fRef, message, team);
1797	}
1798
1799	virtual LaunchCaller *CloneInternal()
1800	{
1801		return new FileWithTypeCaller1;
1802	}
1803};
1804
1805// SniffFileTypeCaller1
1806class SniffFileTypeCaller1 : public SimpleFileCaller1 {
1807public:
1808	virtual status_t operator()(const char *type, BList *messages, int32 argc,
1809								const char **argv, team_id *team)
1810	{
1811		BRoster roster;
1812		BMessage *message = (messages ? (BMessage*)messages->ItemAt(0L)
1813									  : NULL);
1814		fRef = create_file(testFile1, type, NULL, NULL, "UnIQe pAtTeRn");
1815		install_type(fileType1, NULL, "1.0 [0] ('UnIQe pAtTeRn')");
1816		return roster.Launch(&fRef, message, team);
1817	}
1818
1819	virtual LaunchCaller *CloneInternal()
1820	{
1821		return new SniffFileTypeCaller1;
1822	}
1823};
1824
1825/*
1826	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
1827					team_id *app_team) const
1828	@case 1			ref is NULL
1829	@results		Should return B_BAD_VALUE.
1830*/
1831void LaunchTester::LaunchTestD1()
1832{
1833	BRoster roster;
1834	BMessage message;
1835	CHK(roster.Launch((const entry_ref*)NULL, &message, NULL) == B_BAD_VALUE);
1836}
1837
1838/*
1839	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
1840					team_id *app_team) const
1841	@case 2			ref doesn't refer to an existing entry
1842	@results		Should return B_ENTRY_NOT_FOUND.
1843*/
1844void LaunchTester::LaunchTestD2()
1845{
1846	BRoster roster;
1847	BMessage message;
1848	entry_ref fileRef(ref_for_path(testFile1));
1849	CHK(roster.Launch(&fileRef, &message, NULL) == B_ENTRY_NOT_FOUND);
1850}
1851
1852/*
1853	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
1854					team_id *app_team) const
1855	@case 3			ref is valid, file has type and preferred app, app type is
1856					not installed, app exists and has signature
1857	@results		Should return B_OK and set team to the ID of the team
1858					running the file's (not the file type's) preferred
1859					application's executable.
1860					Should install the app type and set the app hint on it.
1861*/
1862void LaunchTester::LaunchTestD3()
1863{
1864	BRoster roster;
1865	create_app(appFile1, appType1);
1866	create_app(appFile2, appType2);
1867	install_type(fileType1, appType1);
1868	entry_ref fileRef(create_file(testFile1, fileType1, appType2));
1869	SimpleFileCaller1 caller(fileRef);
1870	LaunchContext context;
1871	team_id team;
1872	CHK(context(caller, fileType1, context.StandardMessages(),
1873				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
1874				&team) == B_OK);
1875	entry_ref ref = ref_for_team(team);
1876	CHK(ref_for_path(appFile2) == ref);
1877	check_app_type(appType2, appFile2);
1878
1879	context.Terminate();
1880	int32 cookie = 0;
1881	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
1882	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
1883	CHK(context.CheckMessageMessages(caller, team, cookie));
1884//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
1885	CHK(context.CheckRefsMessage(caller, team, cookie));
1886	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
1887	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
1888	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
1889}
1890
1891/*
1892	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
1893					team_id *app_team) const
1894	@case 4			ref is valid, file has no type, but preferred app,
1895					app type is not installed, app exists and has signature
1896	@results		Should return B_OK and set team to the ID of the team
1897					running the application's executable. Should install the
1898					app type and set the app hint on it.
1899*/
1900void LaunchTester::LaunchTestD4()
1901{
1902	BRoster roster;
1903	create_app(appFile1, appType1);
1904	entry_ref fileRef(create_file(testFile1, NULL, appType1));
1905	SimpleFileCaller1 caller(fileRef);
1906	LaunchContext context;
1907	team_id team;
1908	CHK(context(caller, fileType1, context.StandardMessages(),
1909				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
1910				&team) == B_OK);
1911	entry_ref ref = ref_for_team(team);
1912	CHK(ref_for_path(appFile1) == ref);
1913	check_app_type(appType1, appFile1);
1914
1915	context.Terminate();
1916	int32 cookie = 0;
1917	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
1918	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
1919	CHK(context.CheckMessageMessages(caller, team, cookie));
1920//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
1921	CHK(context.CheckRefsMessage(caller, team, cookie));
1922	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
1923	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
1924	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
1925}
1926
1927/*
1928	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
1929					team_id *app_team) const
1930	@case 5			ref is valid, file has type and app hint, the type's
1931					preferred app type is not installed, app exists and has
1932					signature
1933	@results		Should return B_OK and set team to the ID of the team
1934					running the file type's preferred application's executable.
1935					Should install the app type and set the app hint on it.
1936*/
1937void LaunchTester::LaunchTestD5()
1938{
1939	BRoster roster;
1940	create_app(appFile1, appType1);
1941	create_app(appFile2, appType2);
1942	install_type(fileType1, appType1);
1943	entry_ref fileRef(create_file(testFile1, fileType1, NULL, appFile2));
1944	SimpleFileCaller1 caller(fileRef);
1945	LaunchContext context;
1946	team_id team;
1947	CHK(context(caller, fileType1, context.StandardMessages(),
1948				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
1949				&team) == B_OK);
1950	entry_ref ref = ref_for_team(team);
1951	CHK(ref_for_path(appFile1) == ref);
1952	check_app_type(appType1, appFile1);
1953
1954	context.Terminate();
1955	int32 cookie = 0;
1956	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
1957	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
1958	CHK(context.CheckMessageMessages(caller, team, cookie));
1959//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
1960	CHK(context.CheckRefsMessage(caller, team, cookie));
1961	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
1962	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
1963	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
1964}
1965
1966/*
1967	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
1968					team_id *app_team) const
1969	@case 6			ref is valid, file has type, the type's preferred app
1970					type is not installed, app exists and has signature, file
1971					has executable permission, but is not executable
1972	@results		Should return B_LAUNCH_FAILED_EXECUTABLE.
1973					Should not set the app hint on the app or file type.
1974*/
1975void LaunchTester::LaunchTestD6()
1976{
1977	BRoster roster;
1978	create_app(appFile1, appType1);
1979	install_type(fileType1, appType1);
1980	entry_ref fileRef(create_file(testFile1, fileType1));
1981	system((string("chmod a+x ") + testFile1).c_str());
1982	BMessage message;
1983	team_id team;
1984	CHK(roster.Launch(&fileRef, &message, &team)
1985		== B_LAUNCH_FAILED_EXECUTABLE);
1986	CHK(BMimeType(appType1).IsInstalled() == false);
1987	CHK(BMimeType(fileType1).GetAppHint(&fileRef) == B_ENTRY_NOT_FOUND);
1988}
1989
1990/*
1991	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
1992					team_id *app_team) const
1993	@case 7			ref is valid and refers to a link to a file, file has type,
1994					the type's preferred app type is not installed,
1995					app exists and has signature
1996	@results		Should return B_OK and set team to the ID of the team
1997					running the file type's preferred application's executable.
1998					Should install the app type and set the app hint on it.
1999*/
2000void LaunchTester::LaunchTestD7()
2001{
2002	BRoster roster;
2003	create_app(appFile1, appType1);
2004	install_type(fileType1, appType1);
2005	create_file(testFile1, fileType1);
2006	system((string("ln -s ") + testFile1 + " " + testLink1).c_str());
2007	entry_ref fileRef(ref_for_path(testFile1, false));
2008	entry_ref linkRef(ref_for_path(testLink1, false));
2009	SimpleFileCaller1 caller(linkRef);
2010	LaunchContext context;
2011	team_id team;
2012	CHK(context(caller, fileType1, context.StandardMessages(),
2013				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
2014				&team) == B_OK);
2015	entry_ref ref = ref_for_team(team);
2016	CHK(ref_for_path(appFile1) == ref);
2017	check_app_type(appType1, appFile1);
2018
2019	context.Terminate();
2020	int32 cookie = 0;
2021	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2022	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2023	CHK(context.CheckMessageMessages(caller, team, cookie));
2024//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2025	CHK(context.CheckRefsMessage(caller, team, cookie, &fileRef));
2026	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2027	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2028	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2029}
2030
2031/*
2032	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
2033					team_id *app_team) const
2034	@case 8			ref is valid, file has no type, sniffing results in a type,
2035					type is set on file,
2036					Launch(const char*, entry_ref*) cases 4-16
2037					(== common cases 2-14)
2038*/
2039void LaunchTester::LaunchTestD8()
2040{
2041	FileWithTypeCaller1 caller;
2042	for (int32 i = 0; i < commonTestFunctionCount; i++) {
2043		NextSubTest();
2044		(*commonTestFunctions[i])(caller);
2045		tearDown();
2046		setUp();
2047	}
2048}
2049
2050/*
2051	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
2052					team_id *app_team) const
2053	@case 9			ref is valid, file has no type, sniffing results in a type,
2054					type is set on file,
2055					Launch(const char*, entry_ref*) cases 3-16
2056					(== common cases 1-14)
2057*/
2058void LaunchTester::LaunchTestD9()
2059{
2060	SniffFileTypeCaller1 caller;
2061	for (int32 i = 1; i < commonTestFunctionCount; i++) {
2062		NextSubTest();
2063		(*commonTestFunctions[i])(caller);
2064		tearDown();
2065		setUp();
2066	}
2067}
2068
2069/*
2070	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
2071					team_id *app_team) const
2072	@case 10		ref is valid, file has no type, but preferred app, app
2073					type is not installed, app exists and has signature,
2074					NULL initialMessage
2075	@results		Should return B_OK and set team to the ID of the team
2076					running the application's executable. Should install the
2077					app type and set the app hint on it.
2078*/
2079void LaunchTester::LaunchTestD10()
2080{
2081	BRoster roster;
2082	create_app(appFile1, appType1);
2083	entry_ref fileRef(create_file(testFile1, NULL, appType1));
2084	SimpleFileCaller1 caller(fileRef);
2085	LaunchContext context;
2086	team_id team;
2087	CHK(context(caller, fileType1, NULL, LaunchContext::kStandardArgc,
2088				LaunchContext::kStandardArgv, &team) == B_OK);
2089	entry_ref ref = ref_for_team(team);
2090	CHK(ref_for_path(appFile1) == ref);
2091	check_app_type(appType1, appFile1);
2092
2093	context.Terminate();
2094	int32 cookie = 0;
2095	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2096	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2097//	CHK(context.CheckMessageMessages(caller, team, cookie));
2098//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2099	CHK(context.CheckRefsMessage(caller, team, cookie));
2100	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2101	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2102	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2103}
2104
2105/*
2106	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
2107					team_id *app_team) const
2108	@case 11		ref is valid and refers to a cyclic link
2109	@results		Should return B_LAUNCH_FAILED_NO_RESOLVE_LINK.
2110*/
2111void LaunchTester::LaunchTestD11()
2112{
2113	BRoster roster;
2114	system((string("ln -s ") + testLink1 + " " + testLink1).c_str());
2115	entry_ref linkRef(ref_for_path(testLink1, false));
2116	BMessage message;
2117	team_id team;
2118	CHK(roster.Launch(&linkRef, &message, &team)
2119		== B_LAUNCH_FAILED_NO_RESOLVE_LINK);
2120}
2121
2122/*
2123	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
2124					team_id *app_team) const
2125	@case 12		ref is valid and refers to a link to void
2126	@results		Should return B_LAUNCH_FAILED_NO_RESOLVE_LINK.
2127*/
2128void LaunchTester::LaunchTestD12()
2129{
2130	BRoster roster;
2131	system((string("ln -s ") + testFile1 + " " + testLink1).c_str());
2132	entry_ref linkRef(ref_for_path(testLink1, false));
2133	BMessage message;
2134	team_id team;
2135	CHK(roster.Launch(&linkRef, &message, &team)
2136		== B_LAUNCH_FAILED_NO_RESOLVE_LINK);
2137}
2138
2139/*
2140	status_t Launch(const entry_ref *ref, const BMessage *initialMessage,
2141					team_id *app_team) const
2142	@case 13		ref is valid and refers to an executable without signature
2143	@results		Should return B_OK and set team to the ID of the team
2144					running the application's executable.
2145*/
2146void LaunchTester::LaunchTestD13()
2147{
2148	BRoster roster;
2149	create_app(appFile1, NULL);
2150	entry_ref fileRef(ref_for_path(appFile1));
2151	SimpleFileCaller1 caller(fileRef);
2152	LaunchContext context;
2153	team_id team;
2154	CHK(context(caller, appType1, context.StandardMessages(),
2155				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
2156				&team) == B_OK);
2157	entry_ref ref = ref_for_team(team);
2158	CHK(ref_for_path(appFile1) == ref);
2159	context.WaitForMessage(team, MSG_STARTED, true);
2160	app_info appInfo;
2161	CHK(roster.GetRunningAppInfo(team, &appInfo) == B_OK);
2162	CHK(!strcmp(appInfo.signature, kDefaultTestAppSignature));
2163
2164	context.Terminate();
2165	int32 cookie = 0;
2166	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2167//	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2168	CHK(context.CheckArgsMessage(caller, team, cookie, &ref, NULL,
2169								 0, NULL, MSG_MAIN_ARGS));
2170	CHK(context.CheckMessageMessages(caller, team, cookie));
2171//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2172//	CHK(context.CheckArgsMessage(caller, team, cookie, &ref, NULL,
2173//								 LaunchContext::kStandardArgc,
2174//								 LaunchContext::kStandardArgv,
2175//								 MSG_ARGV_RECEIVED));
2176	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2177	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2178	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2179}
2180
2181// SimpleFileCaller2
2182class SimpleFileCaller2 : public LaunchCaller {
2183public:
2184	SimpleFileCaller2() : fRef() {}
2185	SimpleFileCaller2(const entry_ref &ref) : fRef(ref) {}
2186	virtual ~SimpleFileCaller2() {}
2187	virtual status_t operator()(const char *type, BList *messages, int32 argc,
2188								const char **argv, team_id *team)
2189	{
2190		BRoster roster;
2191		return roster.Launch(&fRef, messages, team);
2192	}
2193	virtual int32 SupportsMessages() const { return 1000; }
2194	virtual bool SupportsRefs() const { return true; }
2195	virtual const entry_ref *Ref() const { return &fRef; }
2196
2197	virtual LaunchCaller *CloneInternal()
2198	{
2199		return new SimpleFileCaller2;
2200	}
2201
2202protected:
2203	entry_ref fRef;
2204};
2205
2206// FileWithTypeCaller2
2207class FileWithTypeCaller2 : public SimpleFileCaller2 {
2208public:
2209	virtual status_t operator()(const char *type, BList *messages, int32 argc,
2210								const char **argv, team_id *team)
2211	{
2212		BRoster roster;
2213		fRef = create_file(testFile1, type);
2214		return roster.Launch(&fRef, messages, team);
2215	}
2216
2217	virtual LaunchCaller *CloneInternal()
2218	{
2219		return new FileWithTypeCaller2;
2220	}
2221};
2222
2223// SniffFileTypeCaller2
2224class SniffFileTypeCaller2 : public SimpleFileCaller2 {
2225public:
2226	virtual status_t operator()(const char *type, BList *messages, int32 argc,
2227								const char **argv, team_id *team)
2228	{
2229		BRoster roster;
2230		fRef = create_file(testFile1, type, NULL, NULL, "UnIQe pAtTeRn");
2231		install_type(fileType1, NULL, "1.0 [0] ('UnIQe pAtTeRn')");
2232		return roster.Launch(&fRef, messages, team);
2233	}
2234
2235	virtual LaunchCaller *CloneInternal()
2236	{
2237		return new SniffFileTypeCaller2;
2238	}
2239};
2240
2241/*
2242	status_t Launch(const entry_ref *ref, const BList *messageList,
2243					team_id *appTeam) const
2244	@case 1			ref is NULL
2245	@results		Should return B_BAD_VALUE.
2246*/
2247void LaunchTester::LaunchTestE1()
2248{
2249	BRoster roster;
2250	BList list;
2251	CHK(roster.Launch((const entry_ref*)NULL, &list, NULL) == B_BAD_VALUE);
2252}
2253
2254/*
2255	status_t Launch(const entry_ref *ref, const BList *messageList,
2256					team_id *appTeam) const
2257	@case 2			ref doesn't refer to an existing entry
2258	@results		Should return B_ENTRY_NOT_FOUND.
2259*/
2260void LaunchTester::LaunchTestE2()
2261{
2262	BRoster roster;
2263	BMessage message;
2264	entry_ref fileRef(ref_for_path(testFile1));
2265	BList list;
2266	CHK(roster.Launch(&fileRef, &list, NULL) == B_ENTRY_NOT_FOUND);
2267}
2268
2269/*
2270	status_t Launch(const entry_ref *ref, const BList *messageList,
2271					team_id *appTeam) const
2272	@case 3			ref is valid, file has type and preferred app, app type is
2273					not installed, app exists and has signature
2274	@results		Should return B_OK and set team to the ID of the team
2275					running the file's (not the file type's) preferred
2276					application's executable.
2277					Should install the app type and set the app hint on it.
2278*/
2279void LaunchTester::LaunchTestE3()
2280{
2281	BRoster roster;
2282	create_app(appFile1, appType1);
2283	create_app(appFile2, appType2);
2284	install_type(fileType1, appType1);
2285	entry_ref fileRef(create_file(testFile1, fileType1, appType2));
2286	SimpleFileCaller2 caller(fileRef);
2287	LaunchContext context;
2288	team_id team;
2289	CHK(context(caller, fileType1, context.StandardMessages(),
2290				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
2291				&team) == B_OK);
2292	entry_ref ref = ref_for_team(team);
2293	CHK(ref_for_path(appFile2) == ref);
2294	check_app_type(appType2, appFile2);
2295
2296	context.Terminate();
2297	int32 cookie = 0;
2298	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2299	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2300	CHK(context.CheckMessageMessages(caller, team, cookie));
2301//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2302	CHK(context.CheckRefsMessage(caller, team, cookie));
2303	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2304	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2305	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2306}
2307
2308/*
2309	status_t Launch(const entry_ref *ref, const BList *messageList,
2310					team_id *appTeam) const
2311	@case 4			ref is valid, file has no type, but preferred app,
2312					app type is not installed, app exists and has signature
2313	@results		Should return B_OK and set team to the ID of the team
2314					running the application's executable. Should install the
2315					app type and set the app hint on it.
2316*/
2317void LaunchTester::LaunchTestE4()
2318{
2319	BRoster roster;
2320	create_app(appFile1, appType1);
2321	entry_ref fileRef(create_file(testFile1, NULL, appType1));
2322	SimpleFileCaller2 caller(fileRef);
2323	LaunchContext context;
2324	team_id team;
2325	CHK(context(caller, fileType1, context.StandardMessages(),
2326				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
2327				&team) == B_OK);
2328	entry_ref ref = ref_for_team(team);
2329	CHK(ref_for_path(appFile1) == ref);
2330	check_app_type(appType1, appFile1);
2331
2332	context.Terminate();
2333	int32 cookie = 0;
2334	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2335	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2336	CHK(context.CheckMessageMessages(caller, team, cookie));
2337//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2338	CHK(context.CheckRefsMessage(caller, team, cookie));
2339	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2340	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2341	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2342}
2343
2344/*
2345	status_t Launch(const entry_ref *ref, const BList *messageList,
2346					team_id *appTeam) const
2347	@case 5			ref is valid, file has type and app hint, the type's
2348					preferred app type is not installed, app exists and has
2349					signature
2350	@results		Should return B_OK and set team to the ID of the team
2351					running the file type's preferred application's executable.
2352					Should install the app type and set the app hint on it.
2353*/
2354void LaunchTester::LaunchTestE5()
2355{
2356	BRoster roster;
2357	create_app(appFile1, appType1);
2358	create_app(appFile2, appType2);
2359	install_type(fileType1, appType1);
2360	entry_ref fileRef(create_file(testFile1, fileType1, NULL, appFile2));
2361	SimpleFileCaller2 caller(fileRef);
2362	LaunchContext context;
2363	team_id team;
2364	CHK(context(caller, fileType1, context.StandardMessages(),
2365				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
2366				&team) == B_OK);
2367	entry_ref ref = ref_for_team(team);
2368	CHK(ref_for_path(appFile1) == ref);
2369	check_app_type(appType1, appFile1);
2370
2371	context.Terminate();
2372	int32 cookie = 0;
2373	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2374	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2375	CHK(context.CheckMessageMessages(caller, team, cookie));
2376//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2377	CHK(context.CheckRefsMessage(caller, team, cookie));
2378	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2379	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2380	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2381}
2382
2383/*
2384	status_t Launch(const entry_ref *ref, const BList *messageList,
2385					team_id *appTeam) const
2386	@case 6			ref is valid, file has type, the type's preferred app
2387					type is not installed, app exists and has signature, file
2388					has executable permission, but is not executable
2389	@results		Should return B_LAUNCH_FAILED_EXECUTABLE.
2390					Should not set the app hint on the app or file type.
2391*/
2392void LaunchTester::LaunchTestE6()
2393{
2394	BRoster roster;
2395	create_app(appFile1, appType1);
2396	install_type(fileType1, appType1);
2397	entry_ref fileRef(create_file(testFile1, fileType1));
2398	system((string("chmod a+x ") + testFile1).c_str());
2399	BList list;
2400	team_id team;
2401	CHK(roster.Launch(&fileRef, &list, &team) == B_LAUNCH_FAILED_EXECUTABLE);
2402	CHK(BMimeType(appType1).IsInstalled() == false);
2403	CHK(BMimeType(fileType1).GetAppHint(&fileRef) == B_ENTRY_NOT_FOUND);
2404}
2405
2406/*
2407	status_t Launch(const entry_ref *ref, const BList *messageList,
2408					team_id *appTeam) const
2409	@case 7			ref is valid and refers to a link to a file, file has type,
2410					the type's preferred app type is not installed,
2411					app exists and has signature
2412	@results		Should return B_OK and set team to the ID of the team
2413					running the file type's preferred application's executable.
2414					Should install the app type and set the app hint on it.
2415*/
2416void LaunchTester::LaunchTestE7()
2417{
2418	BRoster roster;
2419	create_app(appFile1, appType1);
2420	install_type(fileType1, appType1);
2421	create_file(testFile1, fileType1);
2422	system((string("ln -s ") + testFile1 + " " + testLink1).c_str());
2423	entry_ref fileRef(ref_for_path(testFile1, false));
2424	entry_ref linkRef(ref_for_path(testLink1, false));
2425	SimpleFileCaller2 caller(linkRef);
2426	LaunchContext context;
2427	team_id team;
2428	CHK(context(caller, fileType1, context.StandardMessages(),
2429				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
2430				&team) == B_OK);
2431	entry_ref ref = ref_for_team(team);
2432	CHK(ref_for_path(appFile1) == ref);
2433	check_app_type(appType1, appFile1);
2434
2435	context.Terminate();
2436	int32 cookie = 0;
2437	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2438	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2439	CHK(context.CheckMessageMessages(caller, team, cookie));
2440//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2441	CHK(context.CheckRefsMessage(caller, team, cookie, &fileRef));
2442	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2443	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2444	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2445}
2446
2447/*
2448	status_t Launch(const entry_ref *ref, const BList *messageList,
2449					team_id *appTeam) const
2450	@case 8			ref is valid, file has no type, sniffing results in a type,
2451					type is set on file,
2452					Launch(const char*, entry_ref*) cases 4-16
2453					(== common cases 2-14)
2454*/
2455void LaunchTester::LaunchTestE8()
2456{
2457	FileWithTypeCaller2 caller;
2458	for (int32 i = 0; i < commonTestFunctionCount; i++) {
2459		NextSubTest();
2460		(*commonTestFunctions[i])(caller);
2461		tearDown();
2462		setUp();
2463	}
2464}
2465
2466/*
2467	status_t Launch(const entry_ref *ref, const BList *messageList,
2468					team_id *appTeam) const
2469	@case 9			ref is valid, file has no type, sniffing results in a type,
2470					type is set on file,
2471					Launch(const char*, entry_ref*) cases 3-16
2472					(== common cases 1-14)
2473*/
2474void LaunchTester::LaunchTestE9()
2475{
2476	SniffFileTypeCaller2 caller;
2477	for (int32 i = 1; i < commonTestFunctionCount; i++) {
2478		NextSubTest();
2479		(*commonTestFunctions[i])(caller);
2480		tearDown();
2481		setUp();
2482	}
2483}
2484
2485/*
2486	status_t Launch(const entry_ref *ref, const BList *messageList,
2487					team_id *appTeam) const
2488	@case 10		ref is valid, file has no type, but preferred app, app
2489					type is not installed, app exists and has signature,
2490					NULL messageList
2491	@results		Should return B_OK and set team to the ID of the team
2492					running the application's executable. Should install the
2493					app type and set the app hint on it.
2494*/
2495void LaunchTester::LaunchTestE10()
2496{
2497	BRoster roster;
2498	create_app(appFile1, appType1);
2499	entry_ref fileRef(create_file(testFile1, NULL, appType1));
2500	SimpleFileCaller2 caller(fileRef);
2501	LaunchContext context;
2502	team_id team;
2503	CHK(context(caller, fileType1, NULL, LaunchContext::kStandardArgc,
2504				LaunchContext::kStandardArgv, &team) == B_OK);
2505	entry_ref ref = ref_for_team(team);
2506	CHK(ref_for_path(appFile1) == ref);
2507	check_app_type(appType1, appFile1);
2508
2509	context.Terminate();
2510	int32 cookie = 0;
2511	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2512	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2513//	CHK(context.CheckMessageMessages(caller, team, cookie));
2514//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2515	CHK(context.CheckRefsMessage(caller, team, cookie));
2516	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2517	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2518	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2519}
2520
2521/*
2522	status_t Launch(const entry_ref *ref, const BList *messageList,
2523					team_id *appTeam) const
2524	@case 11		ref is valid, file has no type, but preferred app, app
2525					type is not installed, app exists and has signature,
2526					empty messageList
2527	@results		Should return B_OK and set team to the ID of the team
2528					running the application's executable. Should install the
2529					app type and set the app hint on it.
2530*/
2531void LaunchTester::LaunchTestE11()
2532{
2533	BRoster roster;
2534	create_app(appFile1, appType1);
2535	entry_ref fileRef(create_file(testFile1, NULL, appType1));
2536	SimpleFileCaller2 caller(fileRef);
2537	LaunchContext context;
2538	team_id team;
2539	BList list;
2540	CHK(context(caller, fileType1, &list, LaunchContext::kStandardArgc,
2541				LaunchContext::kStandardArgv, &team) == B_OK);
2542	entry_ref ref = ref_for_team(team);
2543	CHK(ref_for_path(appFile1) == ref);
2544	check_app_type(appType1, appFile1);
2545
2546	context.Terminate();
2547	int32 cookie = 0;
2548	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2549	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2550//	CHK(context.CheckMessageMessages(caller, team, cookie));
2551//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2552	CHK(context.CheckRefsMessage(caller, team, cookie));
2553	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2554	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2555	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2556}
2557
2558/*
2559	status_t Launch(const entry_ref *ref, const BList *messageList,
2560					team_id *appTeam) const
2561	@case 12		ref is valid and refers to a cyclic link
2562	@results		Should return B_LAUNCH_FAILED_NO_RESOLVE_LINK.
2563*/
2564void LaunchTester::LaunchTestE12()
2565{
2566	BRoster roster;
2567	system((string("ln -s ") + testLink1 + " " + testLink1).c_str());
2568	entry_ref linkRef(ref_for_path(testLink1, false));
2569	BMessage message;
2570	team_id team;
2571	BList list;
2572	CHK(roster.Launch(&linkRef, &list, &team)
2573		== B_LAUNCH_FAILED_NO_RESOLVE_LINK);
2574}
2575
2576/*
2577	status_t Launch(const entry_ref *ref, const BList *messageList,
2578					team_id *appTeam) const
2579	@case 13		ref is valid and refers to a link to void
2580	@results		Should return B_LAUNCH_FAILED_NO_RESOLVE_LINK.
2581*/
2582void LaunchTester::LaunchTestE13()
2583{
2584	BRoster roster;
2585	system((string("ln -s ") + testFile1 + " " + testLink1).c_str());
2586	entry_ref linkRef(ref_for_path(testLink1, false));
2587	BMessage message;
2588	team_id team;
2589	BList list;
2590	CHK(roster.Launch(&linkRef, &list, &team)
2591		== B_LAUNCH_FAILED_NO_RESOLVE_LINK);
2592}
2593
2594/*
2595	status_t Launch(const entry_ref *ref, const BList *messageList,
2596					team_id *appTeam) const
2597	@case 14		ref is valid and refers to an executable without signature
2598	@results		Should return B_OK and set team to the ID of the team
2599					running the application's executable.
2600*/
2601void LaunchTester::LaunchTestE14()
2602{
2603	BRoster roster;
2604	create_app(appFile1, NULL);
2605	entry_ref fileRef(ref_for_path(appFile1));
2606	SimpleFileCaller2 caller(fileRef);
2607	LaunchContext context;
2608	team_id team;
2609	CHK(context(caller, appType1, context.StandardMessages(),
2610				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
2611				&team) == B_OK);
2612	entry_ref ref = ref_for_team(team);
2613	CHK(ref_for_path(appFile1) == ref);
2614	context.WaitForMessage(team, MSG_STARTED, true);
2615	app_info appInfo;
2616	CHK(roster.GetRunningAppInfo(team, &appInfo) == B_OK);
2617	CHK(!strcmp(appInfo.signature, kDefaultTestAppSignature));
2618
2619	context.Terminate();
2620	int32 cookie = 0;
2621	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2622//	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2623	CHK(context.CheckArgsMessage(caller, team, cookie, &ref, NULL,
2624								 0, NULL, MSG_MAIN_ARGS));
2625	CHK(context.CheckMessageMessages(caller, team, cookie));
2626//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2627//	CHK(context.CheckArgsMessage(caller, team, cookie, &ref, NULL,
2628//								 LaunchContext::kStandardArgc,
2629//								 LaunchContext::kStandardArgv,
2630//								 MSG_ARGV_RECEIVED));
2631	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2632	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2633	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2634}
2635
2636// SimpleFileCaller3
2637class SimpleFileCaller3 : public LaunchCaller {
2638public:
2639	SimpleFileCaller3() : fRef() {}
2640	SimpleFileCaller3(const entry_ref &ref) : fRef(ref) {}
2641	virtual ~SimpleFileCaller3() {}
2642	virtual status_t operator()(const char *type, BList *messages, int32 argc,
2643								const char **argv, team_id *team)
2644	{
2645		BRoster roster;
2646		return roster.Launch(&fRef, argc, argv, team);
2647	}
2648	virtual int32 SupportsMessages() const { return 0; }
2649	virtual bool SupportsRefs() const { return true; }
2650	virtual const entry_ref *Ref() const { return &fRef; }
2651
2652	virtual LaunchCaller *CloneInternal()
2653	{
2654		return new SimpleFileCaller3;
2655	}
2656
2657protected:
2658	entry_ref fRef;
2659};
2660
2661// FileWithTypeCaller3
2662class FileWithTypeCaller3 : public SimpleFileCaller3 {
2663public:
2664	virtual status_t operator()(const char *type, BList *messages, int32 argc,
2665								const char **argv, team_id *team)
2666	{
2667		BRoster roster;
2668		fRef = create_file(testFile1, type);
2669		return roster.Launch(&fRef, argc, argv, team);
2670	}
2671
2672	virtual LaunchCaller *CloneInternal()
2673	{
2674		return new FileWithTypeCaller3;
2675	}
2676};
2677
2678// SniffFileTypeCaller3
2679class SniffFileTypeCaller3 : public SimpleFileCaller3 {
2680public:
2681	virtual status_t operator()(const char *type, BList *messages, int32 argc,
2682								const char **argv, team_id *team)
2683	{
2684		BRoster roster;
2685		fRef = create_file(testFile1, type, NULL, NULL, "UnIQe pAtTeRn");
2686		install_type(fileType1, NULL, "1.0 [0] ('UnIQe pAtTeRn')");
2687		return roster.Launch(&fRef, argc, argv, team);
2688	}
2689
2690	virtual LaunchCaller *CloneInternal()
2691	{
2692		return new SniffFileTypeCaller3;
2693	}
2694};
2695
2696/*
2697	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
2698					team_id *appTeam) const
2699	@case 1			ref is NULL
2700	@results		Should return B_BAD_VALUE.
2701*/
2702void LaunchTester::LaunchTestF1()
2703{
2704	BRoster roster;
2705	char *argv[] = { "Hey!" };
2706	CHK(roster.Launch((const entry_ref*)NULL, 1, argv, NULL) == B_BAD_VALUE);
2707}
2708
2709/*
2710	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
2711					team_id *appTeam) const
2712	@case 2			ref doesn't refer to an existing entry
2713	@results		Should return B_ENTRY_NOT_FOUND.
2714*/
2715void LaunchTester::LaunchTestF2()
2716{
2717	BRoster roster;
2718	BMessage message;
2719	entry_ref fileRef(ref_for_path(testFile1));
2720	char *argv[] = { "Hey!" };
2721	CHK(roster.Launch(&fileRef, 1, argv, NULL) == B_ENTRY_NOT_FOUND);
2722}
2723
2724/*
2725	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
2726					team_id *appTeam) const
2727	@case 3			ref is valid, file has type and preferred app, app type is
2728					not installed, app exists and has signature
2729	@results		Should return B_OK and set team to the ID of the team
2730					running the file's (not the file type's) preferred
2731					application's executable.
2732					Should install the app type and set the app hint on it.
2733*/
2734void LaunchTester::LaunchTestF3()
2735{
2736	BRoster roster;
2737	create_app(appFile1, appType1);
2738	create_app(appFile2, appType2);
2739	install_type(fileType1, appType1);
2740	entry_ref fileRef(create_file(testFile1, fileType1, appType2));
2741	SimpleFileCaller3 caller(fileRef);
2742	LaunchContext context;
2743	team_id team;
2744	CHK(context(caller, fileType1, context.StandardMessages(),
2745				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
2746				&team) == B_OK);
2747	entry_ref ref = ref_for_team(team);
2748	CHK(ref_for_path(appFile2) == ref);
2749	check_app_type(appType2, appFile2);
2750
2751	context.Terminate();
2752	int32 cookie = 0;
2753	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2754	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2755//	CHK(context.CheckMessageMessages(caller, team, cookie));
2756	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2757//	CHK(context.CheckRefsMessage(caller, team, cookie));
2758	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2759	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2760	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2761}
2762
2763/*
2764	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
2765					team_id *appTeam) const
2766	@case 4			ref is valid, file has no type, but preferred app,
2767					app type is not installed, app exists and has signature
2768	@results		Should return B_OK and set team to the ID of the team
2769					running the application's executable. Should install the
2770					app type and set the app hint on it.
2771*/
2772void LaunchTester::LaunchTestF4()
2773{
2774	BRoster roster;
2775	create_app(appFile1, appType1);
2776	entry_ref fileRef(create_file(testFile1, NULL, appType1));
2777	SimpleFileCaller3 caller(fileRef);
2778	LaunchContext context;
2779	team_id team;
2780	CHK(context(caller, fileType1, context.StandardMessages(),
2781				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
2782				&team) == B_OK);
2783	entry_ref ref = ref_for_team(team);
2784	CHK(ref_for_path(appFile1) == ref);
2785	check_app_type(appType1, appFile1);
2786
2787	context.Terminate();
2788	int32 cookie = 0;
2789	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2790	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2791//	CHK(context.CheckMessageMessages(caller, team, cookie));
2792	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2793//	CHK(context.CheckRefsMessage(caller, team, cookie));
2794	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2795	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2796	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2797}
2798
2799/*
2800	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
2801					team_id *appTeam) const
2802	@case 5			ref is valid, file has type and app hint, the type's
2803					preferred app type is not installed, app exists and has
2804					signature
2805	@results		Should return B_OK and set team to the ID of the team
2806					running the file type's preferred application's executable.
2807					Should install the app type and set the app hint on it.
2808*/
2809void LaunchTester::LaunchTestF5()
2810{
2811	BRoster roster;
2812	create_app(appFile1, appType1);
2813	create_app(appFile2, appType2);
2814	install_type(fileType1, appType1);
2815	entry_ref fileRef(create_file(testFile1, fileType1, NULL, appFile2));
2816	SimpleFileCaller3 caller(fileRef);
2817	LaunchContext context;
2818	team_id team;
2819	CHK(context(caller, fileType1, context.StandardMessages(),
2820				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
2821				&team) == B_OK);
2822	entry_ref ref = ref_for_team(team);
2823	CHK(ref_for_path(appFile1) == ref);
2824	check_app_type(appType1, appFile1);
2825
2826	context.Terminate();
2827	int32 cookie = 0;
2828	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2829	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2830//	CHK(context.CheckMessageMessages(caller, team, cookie));
2831	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2832//	CHK(context.CheckRefsMessage(caller, team, cookie));
2833	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2834	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2835	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2836}
2837
2838/*
2839	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
2840					team_id *appTeam) const
2841	@case 6			ref is valid, file has type, the type's preferred app
2842					type is not installed, app exists and has signature, file
2843					has executable permission, but is not executable
2844	@results		Should return B_LAUNCH_FAILED_EXECUTABLE.
2845					Should not set the app hint on the app or file type.
2846*/
2847void LaunchTester::LaunchTestF6()
2848{
2849	BRoster roster;
2850	create_app(appFile1, appType1);
2851	install_type(fileType1, appType1);
2852	entry_ref fileRef(create_file(testFile1, fileType1));
2853	system((string("chmod a+x ") + testFile1).c_str());
2854	team_id team;
2855	char *argv[] = { "Hey!" };
2856	CHK(roster.Launch(&fileRef, 1, argv, &team) == B_LAUNCH_FAILED_EXECUTABLE);
2857	CHK(BMimeType(appType1).IsInstalled() == false);
2858	CHK(BMimeType(fileType1).GetAppHint(&fileRef) == B_ENTRY_NOT_FOUND);
2859}
2860
2861/*
2862	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
2863					team_id *appTeam) const
2864	@case 7			ref is valid and refers to a link to a file, file has type,
2865					the type's preferred app type is not installed,
2866					app exists and has signature
2867	@results		Should return B_OK and set team to the ID of the team
2868					running the file type's preferred application's executable.
2869					Should install the app type and set the app hint on it.
2870*/
2871void LaunchTester::LaunchTestF7()
2872{
2873	BRoster roster;
2874	create_app(appFile1, appType1);
2875	install_type(fileType1, appType1);
2876	create_file(testFile1, fileType1);
2877	system((string("ln -s ") + testFile1 + " " + testLink1).c_str());
2878	entry_ref fileRef(ref_for_path(testFile1, false));
2879	entry_ref linkRef(ref_for_path(testLink1, false));
2880	SimpleFileCaller3 caller(linkRef);
2881	LaunchContext context;
2882	team_id team;
2883	CHK(context(caller, fileType1, context.StandardMessages(),
2884				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
2885				&team) == B_OK);
2886	entry_ref ref = ref_for_team(team);
2887	CHK(ref_for_path(appFile1) == ref);
2888	check_app_type(appType1, appFile1);
2889
2890	context.Terminate();
2891	int32 cookie = 0;
2892	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2893//	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
2894	CHK(context.CheckArgsMessage(caller, team, cookie, &ref, &fileRef,
2895								 LaunchContext::kStandardArgc,
2896								 LaunchContext::kStandardArgv, MSG_MAIN_ARGS));
2897//	CHK(context.CheckMessageMessages(caller, team, cookie));
2898//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2899	CHK(context.CheckArgsMessage(caller, team, cookie, &ref, &fileRef,
2900								 LaunchContext::kStandardArgc,
2901								 LaunchContext::kStandardArgv,
2902								 MSG_ARGV_RECEIVED));
2903//	CHK(context.CheckRefsMessage(caller, team, cookie));
2904	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2905	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2906	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2907}
2908
2909/*
2910	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
2911					team_id *appTeam) const
2912	@case 8			ref is valid, file has no type, sniffing results in a type,
2913					type is set on file,
2914					Launch(const char*, entry_ref*) cases 4-16
2915					(== common cases 2-14)
2916*/
2917void LaunchTester::LaunchTestF8()
2918{
2919	FileWithTypeCaller3 caller;
2920	for (int32 i = 0; i < commonTestFunctionCount; i++) {
2921		NextSubTest();
2922		(*commonTestFunctions[i])(caller);
2923		tearDown();
2924		setUp();
2925	}
2926}
2927
2928/*
2929	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
2930					team_id *appTeam) const
2931	@case 9			ref is valid, file has no type, sniffing results in a type,
2932					type is set on file,
2933					Launch(const char*, entry_ref*) cases 3-16
2934					(== common cases 1-14)
2935*/
2936void LaunchTester::LaunchTestF9()
2937{
2938	SniffFileTypeCaller3 caller;
2939	for (int32 i = 1; i < commonTestFunctionCount; i++) {
2940		NextSubTest();
2941		(*commonTestFunctions[i])(caller);
2942		tearDown();
2943		setUp();
2944	}
2945}
2946
2947/*
2948	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
2949					team_id *appTeam) const
2950	@case 10		ref is valid, file has no type, but preferred app, app
2951					type is not installed, app exists and has signature,
2952					NULL args, argc is 0
2953	@results		Should return B_OK and set team to the ID of the team
2954					running the application's executable. Should install the
2955					app type and set the app hint on it. argv are ignored.
2956*/
2957void LaunchTester::LaunchTestF10()
2958{
2959	BRoster roster;
2960	create_app(appFile1, appType1);
2961	entry_ref fileRef(create_file(testFile1, NULL, appType1));
2962	SimpleFileCaller3 caller(fileRef);
2963	LaunchContext context;
2964	team_id team;
2965	CHK(context(caller, fileType1, NULL, 0, NULL, &team) == B_OK);
2966	entry_ref ref = ref_for_team(team);
2967	CHK(ref_for_path(appFile1) == ref);
2968	check_app_type(appType1, appFile1);
2969
2970	context.Terminate();
2971	int32 cookie = 0;
2972	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
2973	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref, 0, NULL));
2974//	CHK(context.CheckMessageMessages(caller, team, cookie));
2975//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
2976	CHK(context.CheckRefsMessage(caller, team, cookie));
2977	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
2978	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
2979	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
2980}
2981
2982/*
2983	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
2984					team_id *appTeam) const
2985	@case 11		ref is valid, file has no type, but preferred app, app
2986					type is not installed, app exists and has signature,
2987					NULL args, argc > 0
2988	@results		Should return B_OK and set team to the ID of the team
2989					running the application's executable. Should install the
2990					app type and set the app hint on it. argv are ignored.
2991*/
2992void LaunchTester::LaunchTestF11()
2993{
2994	BRoster roster;
2995	create_app(appFile1, appType1);
2996	entry_ref fileRef(create_file(testFile1, NULL, appType1));
2997	SimpleFileCaller3 caller(fileRef);
2998	LaunchContext context;
2999	team_id team;
3000	CHK(context(caller, fileType1, NULL, 1, NULL, &team) == B_OK);
3001	entry_ref ref = ref_for_team(team);
3002	CHK(ref_for_path(appFile1) == ref);
3003	check_app_type(appType1, appFile1);
3004
3005	context.Terminate();
3006	int32 cookie = 0;
3007	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
3008	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref, 0, NULL));
3009//	CHK(context.CheckMessageMessages(caller, team, cookie));
3010//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
3011	CHK(context.CheckRefsMessage(caller, team, cookie));
3012	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
3013	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
3014	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
3015}
3016
3017/*
3018	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
3019					team_id *appTeam) const
3020	@case 12		ref is valid and refers to a cyclic link
3021	@results		Should return B_LAUNCH_FAILED_NO_RESOLVE_LINK.
3022*/
3023void LaunchTester::LaunchTestF12()
3024{
3025	BRoster roster;
3026	system((string("ln -s ") + testLink1 + " " + testLink1).c_str());
3027	entry_ref linkRef(ref_for_path(testLink1, false));
3028	BMessage message;
3029	team_id team;
3030	CHK(roster.Launch(&linkRef, LaunchContext::kStandardArgc,
3031					  LaunchContext::kStandardArgv, &team)
3032		== B_LAUNCH_FAILED_NO_RESOLVE_LINK);
3033}
3034
3035/*
3036	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
3037					team_id *appTeam) const
3038	@case 13		ref is valid and refers to a link to void
3039	@results		Should return B_LAUNCH_FAILED_NO_RESOLVE_LINK.
3040*/
3041void LaunchTester::LaunchTestF13()
3042{
3043	BRoster roster;
3044	system((string("ln -s ") + testFile1 + " " + testLink1).c_str());
3045	entry_ref linkRef(ref_for_path(testLink1, false));
3046	BMessage message;
3047	team_id team;
3048	CHK(roster.Launch(&linkRef, LaunchContext::kStandardArgc,
3049					  LaunchContext::kStandardArgv, &team)
3050		== B_LAUNCH_FAILED_NO_RESOLVE_LINK);
3051}
3052
3053/*
3054	status_t Launch(const entry_ref *ref, int argc, const char * const *args,
3055					team_id *appTeam) const
3056	@case 14		ref is valid and refers to an executable without signature
3057	@results		Should return B_OK and set team to the ID of the team
3058					running the application's executable.
3059*/
3060void LaunchTester::LaunchTestF14()
3061{
3062	BRoster roster;
3063	create_app(appFile1, NULL);
3064	entry_ref fileRef(ref_for_path(appFile1));
3065	SimpleFileCaller3 caller(fileRef);
3066	LaunchContext context;
3067	team_id team;
3068	CHK(context(caller, appType1, context.StandardMessages(),
3069				LaunchContext::kStandardArgc, LaunchContext::kStandardArgv,
3070				&team) == B_OK);
3071	entry_ref ref = ref_for_team(team);
3072	CHK(ref_for_path(appFile1) == ref);
3073	context.WaitForMessage(team, MSG_STARTED, true);
3074	app_info appInfo;
3075	CHK(roster.GetRunningAppInfo(team, &appInfo) == B_OK);
3076	CHK(!strcmp(appInfo.signature, kDefaultTestAppSignature));
3077
3078	context.Terminate();
3079	int32 cookie = 0;
3080	CHK(context.CheckNextMessage(caller, team, cookie, MSG_STARTED));
3081//	CHK(context.CheckMainArgsMessage(caller, team, cookie, &ref));
3082	CHK(context.CheckArgsMessage(caller, team, cookie, &ref, NULL,
3083								 LaunchContext::kStandardArgc,
3084								 LaunchContext::kStandardArgv,
3085								 MSG_MAIN_ARGS));
3086//	CHK(context.CheckMessageMessages(caller, team, cookie));
3087//	CHK(context.CheckArgvMessage(caller, team, cookie, &ref));
3088	CHK(context.CheckArgsMessage(caller, team, cookie, &ref, NULL,
3089								 LaunchContext::kStandardArgc,
3090								 LaunchContext::kStandardArgv,
3091								 MSG_ARGV_RECEIVED));
3092	CHK(context.CheckNextMessage(caller, team, cookie, MSG_READY_TO_RUN));
3093	CHK(context.CheckNextMessage(caller, team, cookie, MSG_QUIT_REQUESTED));
3094	CHK(context.CheckNextMessage(caller, team, cookie, MSG_TERMINATED));
3095}
3096
3097
3098Test* LaunchTester::Suite()
3099{
3100	TestSuite* SuiteOfTests = new TestSuite;
3101
3102	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestA1);
3103	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestA2);
3104	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestA3);
3105	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestA4);
3106
3107	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestB1);
3108	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestB2);
3109	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestB3);
3110	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestB4);
3111	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestB5);
3112
3113	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestC1);
3114	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestC2);
3115	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestC3);
3116	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestC4);
3117
3118	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD1);
3119	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD2);
3120	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD3);
3121	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD4);
3122	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD5);
3123	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD6);
3124	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD7);
3125	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD8);
3126	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD9);
3127	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD10);
3128	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD11);
3129	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD12);
3130	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestD13);
3131
3132	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE1);
3133	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE2);
3134	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE3);
3135	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE4);
3136	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE5);
3137	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE6);
3138	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE7);
3139	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE8);
3140	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE9);
3141	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE10);
3142	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE11);
3143	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE12);
3144	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE13);
3145	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestE14);
3146
3147	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF1);
3148	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF2);
3149	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF3);
3150	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF4);
3151	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF5);
3152	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF6);
3153	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF7);
3154	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF8);
3155	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF9);
3156	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF10);
3157	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF11);
3158	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF12);
3159	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF13);
3160	ADD_TEST4(BRoster, SuiteOfTests, LaunchTester, LaunchTestF14);
3161
3162	return SuiteOfTests;
3163}
3164
3165