1// DirectoryTest.cpp
2
3#include <stdio.h>
4#include <string.h>
5#include <unistd.h>
6#include <sys/stat.h>
7
8#include <string>
9using std::string;
10
11#include <Directory.h>
12#include <Entry.h>
13#include <File.h>
14#include <Path.h>
15#include <SymLink.h>
16
17#include "DirectoryTest.h"
18
19// Suite
20DirectoryTest::Test*
21DirectoryTest::Suite()
22{
23	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
24	typedef CppUnit::TestCaller<DirectoryTest> TC;
25
26	NodeTest::AddBaseClassTests<DirectoryTest>("BDirectory::", suite);
27
28	suite->addTest( new TC("BDirectory::Init Test 1",
29						   &DirectoryTest::InitTest1) );
30	suite->addTest( new TC("BDirectory::Init Test 2",
31						   &DirectoryTest::InitTest2) );
32	suite->addTest( new TC("BDirectory::GetEntry Test",
33						   &DirectoryTest::GetEntryTest) );
34	suite->addTest( new TC("BDirectory::IsRoot Test",
35						   &DirectoryTest::IsRootTest) );
36	suite->addTest( new TC("BDirectory::FindEntry Test",
37						   &DirectoryTest::FindEntryTest) );
38	suite->addTest( new TC("BDirectory::Contains Test",
39						   &DirectoryTest::ContainsTest) );
40	suite->addTest( new TC("BDirectory::GetStatFor Test",
41						   &DirectoryTest::GetStatForTest) );
42	suite->addTest( new TC("BDirectory::EntryIteration Test",
43						   &DirectoryTest::EntryIterationTest) );
44	suite->addTest( new TC("BDirectory::Creation Test",
45						   &DirectoryTest::EntryCreationTest) );
46	suite->addTest( new TC("BDirectory::Assignment Test",
47						   &DirectoryTest::AssignmentTest) );
48	suite->addTest( new TC("BDirectory::CreateDirectory Test",
49						   &DirectoryTest::CreateDirectoryTest) );
50
51	return suite;
52}
53
54// CreateRONodes
55void
56DirectoryTest::CreateRONodes(TestNodes& testEntries)
57{
58	testEntries.clear();
59	const char *filename;
60	filename = "/";
61	testEntries.add(new BDirectory(filename), filename);
62	filename = "/boot";
63	testEntries.add(new BDirectory(filename), filename);
64	filename = "/boot/home";
65	testEntries.add(new BDirectory(filename), filename);
66	filename = existingDirname;
67	testEntries.add(new BDirectory(filename), filename);
68}
69
70// CreateRWNodes
71void
72DirectoryTest::CreateRWNodes(TestNodes& testEntries)
73{
74	testEntries.clear();
75	const char *filename;
76	filename = existingDirname;
77	testEntries.add(new BDirectory(filename), filename);
78	filename = existingSubDirname;
79	testEntries.add(new BDirectory(filename), filename);
80}
81
82// CreateUninitializedNodes
83void
84DirectoryTest::CreateUninitializedNodes(TestNodes& testEntries)
85{
86	testEntries.clear();
87	testEntries.add(new BDirectory, "");
88}
89
90// setUp
91void DirectoryTest::setUp()
92{
93	NodeTest::setUp();
94}
95
96// tearDown
97void DirectoryTest::tearDown()
98{
99	NodeTest::tearDown();
100}
101
102// InitTest1
103void
104DirectoryTest::InitTest1()
105{
106	const char *existingFile = existingFilename;
107	const char *existingSuperFile = existingSuperFilename;
108	const char *existingRelFile = existingRelFilename;
109	const char *existing = existingDirname;
110	const char *existingSub = existingSubDirname;
111	const char *existingRelSub = existingRelSubDirname;
112	const char *nonExisting = nonExistingDirname;
113	const char *nonExistingSuper = nonExistingSuperDirname;
114	const char *nonExistingRel = nonExistingRelDirname;
115	// 1. default constructor
116	NextSubTest();
117	{
118		BDirectory dir;
119		CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
120	}
121
122	// 2. BDirectory(const char*)
123	NextSubTest();
124	{
125		BDirectory dir(existing);
126		CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
127	}
128	NextSubTest();
129	{
130		BDirectory dir(nonExisting);
131		CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
132	}
133	NextSubTest();
134	{
135		BDirectory dir((const char *)NULL);
136		CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
137	}
138	NextSubTest();
139	{
140		BDirectory dir("");
141		// BeOS R5 returns B_ENTRY_NOT_FOUND instead of B_BAD_VALUE.
142		CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
143	}
144	NextSubTest();
145	{
146		BDirectory dir(existingFile);
147		// BeOS R5 returns B_BAD_VALUE instead of B_NOT_A_DIRECTORY.
148		CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_NOT_A_DIRECTORY);
149	}
150	NextSubTest();
151	{
152		BDirectory dir(tooLongEntryname);
153		CPPUNIT_ASSERT( dir.InitCheck() == B_NAME_TOO_LONG );
154	}
155	NextSubTest();
156	{
157		BDirectory dir(fileDirname);
158		// BeOS R5 returns B_ENTRY_NOT_FOUND instead of B_NOT_A_DIRECTORY.
159		CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
160	}
161
162	// 3. BDirectory(const BEntry*)
163	NextSubTest();
164	{
165		BEntry entry(existing);
166		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
167		BDirectory dir(&entry);
168		CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
169	}
170	NextSubTest();
171	{
172		BEntry entry(nonExisting);
173		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
174		BDirectory dir(&entry);
175		CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
176	}
177	NextSubTest();
178	{
179		BDirectory dir((BEntry *)NULL);
180		CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
181	}
182	NextSubTest();
183	{
184		BEntry entry;
185		BDirectory dir(&entry);
186		CPPUNIT_ASSERT( equals(dir.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
187	}
188	NextSubTest();
189	{
190		BEntry entry(existingFile);
191		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
192		BDirectory dir(&entry);
193		// BeOS R5 returns B_BAD_VALUE instead of B_NOT_A_DIRECTORY.
194		CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_NOT_A_DIRECTORY);
195	}
196	NextSubTest();
197	{
198		BEntry entry(tooLongEntryname);
199		// BeOS R5 returns E2BIG instead of B_NAME_TOO_LONG
200		CPPUNIT_ASSERT( equals(entry.InitCheck(), E2BIG, B_NAME_TOO_LONG) );
201		BDirectory dir(&entry);
202		CPPUNIT_ASSERT( equals(dir.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
203	}
204
205	// 4. BDirectory(const entry_ref*)
206	NextSubTest();
207	{
208		BEntry entry(existing);
209		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
210		entry_ref ref;
211		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
212		BDirectory dir(&ref);
213		CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
214	}
215	NextSubTest();
216	{
217		BEntry entry(nonExisting);
218		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
219		entry_ref ref;
220		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
221		BDirectory dir(&ref);
222		CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
223	}
224	NextSubTest();
225	{
226		BDirectory dir((entry_ref *)NULL);
227		CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
228	}
229	NextSubTest();
230	{
231		BEntry entry(existingFile);
232		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
233		entry_ref ref;
234		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
235		BDirectory dir(&ref);
236		// BeOS R5 returns B_BAD_VALUE instead of B_NOT_A_DIRECTORY.
237		CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_NOT_A_DIRECTORY);
238	}
239
240	// 5. BDirectory(const node_ref*)
241	NextSubTest();
242	{
243		BNode node(existing);
244		CPPUNIT_ASSERT( node.InitCheck() == B_OK );
245		node_ref nref;
246		CPPUNIT_ASSERT( node.GetNodeRef(&nref) == B_OK );
247		BDirectory dir(&nref);
248		CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
249	}
250	NextSubTest();
251	{
252		BDirectory dir((node_ref *)NULL);
253		CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
254	}
255	NextSubTest();
256	{
257		BNode node(existingFile);
258		CPPUNIT_ASSERT( node.InitCheck() == B_OK );
259		node_ref nref;
260		CPPUNIT_ASSERT( node.GetNodeRef(&nref) == B_OK );
261		BDirectory dir(&nref);
262		// BeOS R5: returns B_BAD_VALUE instead of B_NOT_A_DIRECTORY.
263		CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_NOT_A_DIRECTORY);
264	}
265
266	// 6. BDirectory(const BDirectory*, const char*)
267	NextSubTest();
268	{
269		BDirectory pathDir(existing);
270		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
271		BDirectory dir(&pathDir, existingRelSub);
272		CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
273	}
274	NextSubTest();
275	{
276		BDirectory pathDir(existing);
277		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
278		BDirectory dir(&pathDir, existingSub);
279		CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
280	}
281	NextSubTest();
282	{
283		BDirectory pathDir(nonExistingSuper);
284		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
285		BDirectory dir(&pathDir, nonExistingRel);
286		CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
287	}
288	NextSubTest();
289	{
290		BDirectory dir((BDirectory *)NULL, (const char *)NULL);
291		CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
292	}
293	NextSubTest();
294	{
295		BDirectory dir((BDirectory *)NULL, existingSub);
296		CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
297	}
298	NextSubTest();
299	{
300		BDirectory pathDir(existing);
301		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
302		BDirectory dir(&pathDir, (const char *)NULL);
303		CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
304	}
305	NextSubTest();
306	{
307		BDirectory pathDir(existing);
308		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
309		BDirectory dir(&pathDir, "");
310		CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_ENTRY_NOT_FOUND);
311	}
312	NextSubTest();
313	{
314		BDirectory pathDir(existingSuperFile);
315		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
316		BDirectory dir(&pathDir, existingRelFile);
317		// BeOS R5 returns B_BAD_VALUE instead of B_NOT_A_DIRECTORY.
318		CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_NOT_A_DIRECTORY);
319	}
320	NextSubTest();
321	{
322		BDirectory pathDir(tooLongSuperEntryname);
323		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
324		BDirectory dir(&pathDir, tooLongRelEntryname);
325		CPPUNIT_ASSERT( dir.InitCheck() == B_NAME_TOO_LONG );
326	}
327	NextSubTest();
328	{
329		BDirectory pathDir(fileSuperDirname);
330		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
331		BDirectory dir(&pathDir, fileRelDirname);
332		// BeOS R5 returns B_ENTRY_NOT_FOUND instead of B_NOT_A_DIRECTORY.
333		CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
334	}
335}
336
337// InitTest2
338void
339DirectoryTest::InitTest2()
340{
341	const char *existingFile = existingFilename;
342	const char *existingSuperFile = existingSuperFilename;
343	const char *existingRelFile = existingRelFilename;
344	const char *existing = existingDirname;
345	const char *existingSub = existingSubDirname;
346	const char *existingRelSub = existingRelSubDirname;
347	const char *nonExisting = nonExistingDirname;
348	const char *nonExistingSuper = nonExistingSuperDirname;
349	const char *nonExistingRel = nonExistingRelDirname;
350	BDirectory dir;
351	// 2. SetTo(const char*)
352	NextSubTest();
353	CPPUNIT_ASSERT( dir.SetTo(existing) == B_OK );
354	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
355	dir.Unset();
356	//
357	NextSubTest();
358	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
359	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
360	dir.Unset();
361	//
362	NextSubTest();
363	CPPUNIT_ASSERT( dir.SetTo((const char *)NULL) == B_BAD_VALUE );
364	CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
365	dir.Unset();
366	//
367	NextSubTest();
368	CPPUNIT_ASSERT( dir.SetTo("") == B_ENTRY_NOT_FOUND );
369	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
370	dir.Unset();
371	//
372	NextSubTest();
373	// BeOS R5 returns B_BAD_VALUE instead of B_NOT_A_DIRECTORY.
374	CPPUNIT_ASSERT_EQUAL(dir.SetTo(existingFile), B_NOT_A_DIRECTORY);
375	CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_NOT_A_DIRECTORY);
376	dir.Unset();
377	//
378	NextSubTest();
379	CPPUNIT_ASSERT( dir.SetTo(tooLongEntryname) == B_NAME_TOO_LONG );
380	CPPUNIT_ASSERT( dir.InitCheck() == B_NAME_TOO_LONG );
381	dir.Unset();
382	//
383	NextSubTest();
384	CPPUNIT_ASSERT_EQUAL(dir.SetTo(fileDirname), B_ENTRY_NOT_FOUND);
385	CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_ENTRY_NOT_FOUND);
386	dir.Unset();
387
388	// 3. BDirectory(const BEntry*)
389	NextSubTest();
390	BEntry entry(existing);
391	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
392	CPPUNIT_ASSERT( dir.SetTo(&entry) == B_OK );
393	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
394	dir.Unset();
395	//
396	NextSubTest();
397	entry.SetTo(nonExisting);
398	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
399	CPPUNIT_ASSERT( dir.SetTo(&entry) == B_ENTRY_NOT_FOUND );
400	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
401	dir.Unset();
402	//
403	NextSubTest();
404	CPPUNIT_ASSERT( dir.SetTo((BEntry *)NULL) == B_BAD_VALUE );
405	CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
406	dir.Unset();
407	//
408	NextSubTest();
409	entry.Unset();
410	CPPUNIT_ASSERT( equals(dir.SetTo(&entry), B_BAD_ADDRESS, B_BAD_VALUE) );
411	CPPUNIT_ASSERT( equals(dir.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
412	dir.Unset();
413	//
414	NextSubTest();
415	entry.SetTo(existingFile);
416	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
417	// BeOS R5 returns B_BAD_VALUE instead of B_NOT_A_DIRECTORY.
418	CPPUNIT_ASSERT_EQUAL(dir.SetTo(&entry), B_NOT_A_DIRECTORY);
419	CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_NOT_A_DIRECTORY);
420	dir.Unset();
421	//
422	NextSubTest();
423	entry.SetTo(tooLongEntryname);
424	// BeOS R5 returns E2BIG instead of B_NAME_TOO_LONG
425	CPPUNIT_ASSERT( equals(entry.InitCheck(), E2BIG, B_NAME_TOO_LONG) );
426	CPPUNIT_ASSERT( equals(dir.SetTo(&entry), B_BAD_ADDRESS, B_BAD_VALUE) );
427	CPPUNIT_ASSERT( equals(dir.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
428	dir.Unset();
429
430	// 4. BDirectory(const entry_ref*)
431	NextSubTest();
432	entry.SetTo(existing);
433	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
434	entry_ref ref;
435	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
436	CPPUNIT_ASSERT( dir.SetTo(&ref) == B_OK );
437	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
438	dir.Unset();
439	//
440	NextSubTest();
441	entry.SetTo(nonExisting);
442	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
443	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
444	CPPUNIT_ASSERT( dir.SetTo(&ref) == B_ENTRY_NOT_FOUND );
445	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
446	dir.Unset();
447	//
448	NextSubTest();
449	CPPUNIT_ASSERT( dir.SetTo((entry_ref *)NULL) == B_BAD_VALUE );
450	CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
451	dir.Unset();
452	//
453	NextSubTest();
454	entry.SetTo(existingFile);
455	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
456	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
457	// BeOS R5 returns B_BAD_VALUE instead of B_NOT_A_DIRECTORY.
458	CPPUNIT_ASSERT_EQUAL(dir.SetTo(&ref), B_NOT_A_DIRECTORY);
459	CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_NOT_A_DIRECTORY);
460	dir.Unset();
461
462	// 5. BDirectory(const node_ref*)
463	NextSubTest();
464	BNode node(existing);
465	CPPUNIT_ASSERT( node.InitCheck() == B_OK );
466	node_ref nref;
467	CPPUNIT_ASSERT( node.GetNodeRef(&nref) == B_OK );
468	CPPUNIT_ASSERT( dir.SetTo(&nref) == B_OK );
469	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
470	dir.Unset();
471	//
472	NextSubTest();
473	CPPUNIT_ASSERT( dir.SetTo((node_ref *)NULL) == B_BAD_VALUE );
474	CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
475	dir.Unset();
476	//
477	NextSubTest();
478	CPPUNIT_ASSERT( node.SetTo(existingFile) == B_OK );
479	CPPUNIT_ASSERT( node.GetNodeRef(&nref) == B_OK );
480	// BeOS R5 returns B_BAD_VALUE instead of B_NOT_A_DIRECTORY.
481	CPPUNIT_ASSERT_EQUAL(dir.SetTo(&nref), B_NOT_A_DIRECTORY);
482	CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_NOT_A_DIRECTORY);
483	dir.Unset();
484
485	// 6. BDirectory(const BDirectory*, const char*)
486	NextSubTest();
487	BDirectory pathDir(existing);
488	CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
489	CPPUNIT_ASSERT( dir.SetTo(&pathDir, existingRelSub) == B_OK );
490	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
491	dir.Unset();
492	//
493	NextSubTest();
494	pathDir.SetTo(existing);
495	CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
496	CPPUNIT_ASSERT( dir.SetTo(&pathDir, existingSub) == B_BAD_VALUE );
497	CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
498	dir.Unset();
499	//
500	NextSubTest();
501	pathDir.SetTo(nonExistingSuper);
502	CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
503	CPPUNIT_ASSERT( dir.SetTo(&pathDir, nonExistingRel) == B_ENTRY_NOT_FOUND );
504	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
505	dir.Unset();
506	//
507	NextSubTest();
508	CPPUNIT_ASSERT( dir.SetTo((BDirectory *)NULL, (const char *)NULL) == B_BAD_VALUE );
509	CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
510	dir.Unset();
511	//
512	NextSubTest();
513	CPPUNIT_ASSERT( dir.SetTo((BDirectory *)NULL, existingSub) == B_BAD_VALUE );
514	CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
515	dir.Unset();
516	//
517	NextSubTest();
518	pathDir.SetTo(existing);
519	CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
520	CPPUNIT_ASSERT( dir.SetTo(&pathDir, (const char *)NULL) == B_BAD_VALUE );
521	CPPUNIT_ASSERT( dir.InitCheck() == B_BAD_VALUE );
522	dir.Unset();
523	//
524	NextSubTest();
525	pathDir.SetTo(existing);
526	CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
527	// BeOS R5 initializes dir to pathDir instead of B_ENTRY_NOT_FOUND
528	CPPUNIT_ASSERT_EQUAL(dir.SetTo(&pathDir, ""), B_ENTRY_NOT_FOUND);
529	CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_ENTRY_NOT_FOUND);
530	dir.Unset();
531	//
532	NextSubTest();
533	pathDir.SetTo(existingSuperFile);
534	CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
535	// BeOS R5 returns B_BAD_VALUE instead of B_NOT_A_DIRECTORY.
536	CPPUNIT_ASSERT_EQUAL(dir.SetTo(&pathDir, existingRelFile),
537		B_NOT_A_DIRECTORY);
538	CPPUNIT_ASSERT_EQUAL(dir.InitCheck(), B_NOT_A_DIRECTORY);
539	dir.Unset();
540	//
541	NextSubTest();
542	pathDir.SetTo(tooLongSuperEntryname);
543	CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
544	CPPUNIT_ASSERT( dir.SetTo(&pathDir, tooLongRelEntryname)
545					== B_NAME_TOO_LONG );
546	CPPUNIT_ASSERT( dir.InitCheck() == B_NAME_TOO_LONG );
547	dir.Unset();
548	//
549	NextSubTest();
550	pathDir.SetTo(fileSuperDirname);
551	CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
552	CPPUNIT_ASSERT( dir.SetTo(&pathDir, fileRelDirname) == B_ENTRY_NOT_FOUND );
553	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
554	dir.Unset();
555}
556
557// GetEntryTest
558void
559DirectoryTest::GetEntryTest()
560{
561	const char *existing = existingDirname;
562	const char *nonExisting = nonExistingDirname;
563	//
564	NextSubTest();
565	BDirectory dir;
566	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
567	BEntry entry;
568	CPPUNIT_ASSERT( dir.GetEntry(&entry) == B_NO_INIT );
569	dir.Unset();
570	entry.Unset();
571	//
572	NextSubTest();
573	CPPUNIT_ASSERT( dir.SetTo(existing) == B_OK );
574	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
575	CPPUNIT_ASSERT( dir.GetEntry(&entry) == B_OK );
576	CPPUNIT_ASSERT( entry == BEntry(existing) );
577	dir.Unset();
578	entry.Unset();
579	//
580#if !TEST_R5
581// R5: crashs, when passing a NULL BEntry.
582	NextSubTest();
583	CPPUNIT_ASSERT( dir.SetTo(existing) == B_OK );
584	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
585	CPPUNIT_ASSERT( dir.GetEntry((BEntry *)NULL) == B_BAD_VALUE );
586	dir.Unset();
587	entry.Unset();
588#endif
589	//
590	NextSubTest();
591	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
592	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
593	CPPUNIT_ASSERT( dir.GetEntry(&entry) == B_NO_INIT );
594	dir.Unset();
595	entry.Unset();
596}
597
598// IsRootTest
599void
600DirectoryTest::IsRootTest()
601{
602	//
603	NextSubTest();
604	BDirectory dir;
605	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
606	CPPUNIT_ASSERT( dir.IsRootDirectory() == false );
607	//
608	NextSubTest();
609	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK );
610	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
611	CPPUNIT_ASSERT( dir.IsRootDirectory() == true );
612	//
613	NextSubTest();
614	CPPUNIT_ASSERT(dir.SetTo("/boot/system") == B_OK);
615	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
616	CPPUNIT_ASSERT_EQUAL(dir.IsRootDirectory(), true);
617	//
618	NextSubTest();
619	CPPUNIT_ASSERT( dir.SetTo("/tmp") == B_OK );
620	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
621	CPPUNIT_ASSERT( dir.IsRootDirectory() == false );
622	//
623	NextSubTest();
624	CPPUNIT_ASSERT( dir.SetTo("/") == B_OK );
625	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
626	CPPUNIT_ASSERT( dir.IsRootDirectory() == true );
627}
628
629// FindEntryTest
630void
631DirectoryTest::FindEntryTest()
632{
633	const char *existingFile = existingFilename;
634	const char *existing = existingDirname;
635	const char *existingSub = existingSubDirname;
636	const char *existingRelSub = existingRelSubDirname;
637	const char *nonExisting = nonExistingDirname;
638	const char *nonExistingSuper = nonExistingSuperDirname;
639	const char *nonExistingRel = nonExistingRelDirname;
640	const char *dirLink = dirLinkname;
641	const char *badLink = badLinkname;
642	const char *cyclicLink1 = cyclicLinkname1;
643
644	// These are for verification after finding an entry from a BDirectory.
645	// On BeOS and Haiku, calling BEntry::GetPath() returns the normalized
646	// path, but the paths we are using to initialize the BDirectory are not
647	// normalized. So we use these for comparison.
648	BPath normalizedExistingPath(existing, NULL, true);
649	CPPUNIT_ASSERT_EQUAL(normalizedExistingPath.InitCheck(), B_OK);
650
651	BPath normalizedExistingSubPath(existingSub, NULL, true);
652	CPPUNIT_ASSERT_EQUAL(normalizedExistingSubPath.InitCheck(), B_OK);
653
654	BPath normalizedDirLinkPath(dirLink, NULL, true);
655	CPPUNIT_ASSERT_EQUAL(normalizedDirLinkPath.InitCheck(), B_OK);
656
657	BPath normalizedBadLinkPath(badLink, NULL, true);
658	CPPUNIT_ASSERT_EQUAL(normalizedBadLinkPath.InitCheck(), B_OK);
659
660	BPath normalizedCyclicLink1(cyclicLink1, NULL, true);
661	CPPUNIT_ASSERT_EQUAL(normalizedCyclicLink1.InitCheck(), B_OK);
662
663	// existing absolute path, uninitialized BDirectory
664	NextSubTest();
665	BDirectory dir;
666	BEntry entry;
667	BPath path;
668	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
669	CPPUNIT_ASSERT( dir.FindEntry(existing, &entry) == B_OK );
670	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
671	CPPUNIT_ASSERT( entry.GetPath(&path) == B_OK );
672	CPPUNIT_ASSERT(path != existing);
673	CPPUNIT_ASSERT(path == normalizedExistingPath);
674	dir.Unset();
675	entry.Unset();
676	path.Unset();
677	// existing absolute path, badly initialized BDirectory
678	NextSubTest();
679	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
680	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
681	CPPUNIT_ASSERT( dir.FindEntry(existing, &entry) == B_OK );
682	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
683	CPPUNIT_ASSERT( entry.GetPath(&path) == B_OK );
684	CPPUNIT_ASSERT(path != existing);
685	CPPUNIT_ASSERT(path == normalizedExistingPath);
686	dir.Unset();
687	entry.Unset();
688	path.Unset();
689	// existing path relative to current dir, uninitialized BDirectory
690	NextSubTest();
691	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
692	chdir(existing);
693	CPPUNIT_ASSERT( dir.FindEntry(existingRelSub, &entry) == B_OK );
694	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
695	CPPUNIT_ASSERT( entry.GetPath(&path) == B_OK );
696	CPPUNIT_ASSERT(path != existingSub);
697	CPPUNIT_ASSERT(path == normalizedExistingSubPath);
698	dir.Unset();
699	entry.Unset();
700	path.Unset();
701	chdir("/");
702	// existing path relative to current dir,
703	// initialized BDirectory != current dir
704	NextSubTest();
705	CPPUNIT_ASSERT( dir.SetTo(existingSub) == B_OK );
706	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
707	chdir(existing);
708	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
709	CPPUNIT_ASSERT( dir.FindEntry(existingRelSub, &entry) == B_ENTRY_NOT_FOUND );
710	CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
711	dir.Unset();
712	entry.Unset();
713	path.Unset();
714	chdir("/");
715	// abstract entry
716	NextSubTest();
717	CPPUNIT_ASSERT( dir.SetTo(nonExistingSuper) == B_OK );
718	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
719	chdir(existing);
720	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
721	CPPUNIT_ASSERT( dir.FindEntry(nonExistingRel, &entry) == B_ENTRY_NOT_FOUND );
722	CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
723	dir.Unset();
724	entry.Unset();
725	path.Unset();
726	chdir("/");
727	// bad args
728	NextSubTest();
729	CPPUNIT_ASSERT( dir.SetTo(existing) == B_OK );
730	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
731	CPPUNIT_ASSERT( dir.FindEntry(existingRelSub, NULL) == B_BAD_VALUE );
732	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
733	CPPUNIT_ASSERT( dir.FindEntry(NULL, &entry) == B_BAD_VALUE );
734	CPPUNIT_ASSERT(entry.InitCheck() == B_OK);
735	CPPUNIT_ASSERT( dir.FindEntry(NULL, NULL) == B_BAD_VALUE );
736	dir.Unset();
737	entry.Unset();
738	path.Unset();
739	// don't traverse a valid link
740	NextSubTest();
741	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
742	CPPUNIT_ASSERT( dir.FindEntry(dirLink, &entry) == B_OK );
743	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
744	CPPUNIT_ASSERT( entry.GetPath(&path) == B_OK );
745	CPPUNIT_ASSERT(path != dirLink);
746	CPPUNIT_ASSERT(path == normalizedDirLinkPath);
747	dir.Unset();
748	entry.Unset();
749	path.Unset();
750	// traverse a valid link
751	NextSubTest();
752	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
753	CPPUNIT_ASSERT( dir.FindEntry(dirLink, &entry, true) == B_OK );
754	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
755	CPPUNIT_ASSERT( entry.GetPath(&path) == B_OK );
756	CPPUNIT_ASSERT(path != existing);
757	CPPUNIT_ASSERT(path == normalizedExistingPath);
758	dir.Unset();
759	entry.Unset();
760	path.Unset();
761	// don't traverse an invalid link
762	NextSubTest();
763	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
764	CPPUNIT_ASSERT( dir.FindEntry(badLink, &entry) == B_OK );
765	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
766	CPPUNIT_ASSERT( entry.GetPath(&path) == B_OK );
767	CPPUNIT_ASSERT(path != badLink);
768	CPPUNIT_ASSERT(path == normalizedBadLinkPath);
769	dir.Unset();
770	entry.Unset();
771	path.Unset();
772	// traverse an invalid link
773	NextSubTest();
774	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
775	CPPUNIT_ASSERT( dir.FindEntry(badLink, &entry, true) == B_ENTRY_NOT_FOUND );
776	CPPUNIT_ASSERT( equals(entry.InitCheck(), B_ENTRY_NOT_FOUND, B_NO_INIT) );
777	dir.Unset();
778	entry.Unset();
779	path.Unset();
780	// don't traverse a cyclic link
781	NextSubTest();
782	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
783	CPPUNIT_ASSERT( dir.FindEntry(cyclicLink1, &entry) == B_OK );
784	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
785	CPPUNIT_ASSERT( entry.GetPath(&path) == B_OK );
786	CPPUNIT_ASSERT(path != cyclicLink1);
787	CPPUNIT_ASSERT(path == normalizedCyclicLink1);
788	dir.Unset();
789	entry.Unset();
790	path.Unset();
791	// traverse a cyclic link
792	NextSubTest();
793	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
794	CPPUNIT_ASSERT( dir.FindEntry(cyclicLink1, &entry, true) == B_LINK_LIMIT );
795	CPPUNIT_ASSERT( entry.InitCheck() == B_LINK_LIMIT );
796	dir.Unset();
797	entry.Unset();
798	path.Unset();
799}
800
801// ContainsTest
802void
803DirectoryTest::ContainsTest()
804{
805	const char *existingFile = existingFilename;
806	const char *existingSuperFile = existingSuperFilename;
807	const char *existingRelFile = existingRelFilename;
808	const char *existing = existingDirname;
809	const char *existingSuper = existingSuperDirname;
810	const char *existingSub = existingSubDirname;
811	const char *existingRelSub = existingRelSubDirname;
812	const char *nonExisting = nonExistingDirname;
813	const char *dirLink = dirLinkname;
814	const char *dirSuperLink = dirSuperLinkname;
815	// 1. Contains(const char *, int32)
816	// existing entry, initialized BDirectory
817	NextSubTest();
818	BDirectory dir(existing);
819	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
820	CPPUNIT_ASSERT( dir.Contains(existingSub) == true );
821	dir.Unset();
822	// existing entry, uninitialized BDirectory
823	NextSubTest();
824	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
825// R5 returns true!
826#if TEST_R5
827	CPPUNIT_ASSERT( dir.Contains(existing) == true );
828#else
829	CPPUNIT_ASSERT( dir.Contains(existing) == false );
830#endif
831	dir.Unset();
832	// non-existing entry, uninitialized BDirectory
833	NextSubTest();
834	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
835	CPPUNIT_ASSERT( dir.Contains(nonExisting) == false );
836	dir.Unset();
837	// existing entry, badly initialized BDirectory
838	NextSubTest();
839	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
840	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
841// R5 returns true!
842#if TEST_R5
843	CPPUNIT_ASSERT( dir.Contains(existing) == true );
844#else
845	CPPUNIT_ASSERT( dir.Contains(existing) == false );
846#endif
847	dir.Unset();
848	// non-existing entry, badly initialized BDirectory
849	NextSubTest();
850	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
851	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
852	CPPUNIT_ASSERT( dir.Contains(nonExisting) == false );
853	dir.Unset();
854	// initialized BDirectory, bad args
855	NextSubTest();
856	CPPUNIT_ASSERT( dir.SetTo(existing) == B_OK );
857	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
858	CPPUNIT_ASSERT( dir.Contains((const char*)NULL) == true );
859	dir.Unset();
860	// uninitialized BDirectory, bad args
861	NextSubTest();
862	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
863	CPPUNIT_ASSERT( dir.Contains((const char*)NULL) == false );
864	dir.Unset();
865	// existing entry (second level, absolute path), initialized BDirectory
866	NextSubTest();
867	CPPUNIT_ASSERT( dir.SetTo(existingSuper) == B_OK );
868	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
869	CPPUNIT_ASSERT( dir.Contains(existingSub) == true );
870	dir.Unset();
871	// existing entry (second level, name only), initialized BDirectory
872	NextSubTest();
873	CPPUNIT_ASSERT( dir.SetTo(existingSuper) == B_OK );
874	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
875	CPPUNIT_ASSERT( dir.Contains(existingRelSub) == false );
876	dir.Unset();
877	// initialized BDirectory, self containing
878	NextSubTest();
879	CPPUNIT_ASSERT( dir.SetTo(existing) == B_OK );
880	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
881	CPPUNIT_ASSERT( dir.Contains(existing) == true );
882	dir.Unset();
883	// existing entry (dir), initialized BDirectory, matching node kind
884	NextSubTest();
885	CPPUNIT_ASSERT( dir.SetTo(existingSuper) == B_OK );
886	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
887	CPPUNIT_ASSERT( dir.Contains(existing, B_DIRECTORY_NODE) == true );
888	dir.Unset();
889	// existing entry (dir), initialized BDirectory, mismatching node kind
890	NextSubTest();
891	CPPUNIT_ASSERT( dir.SetTo(existingSuper) == B_OK );
892	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
893	CPPUNIT_ASSERT( dir.Contains(existing, B_FILE_NODE) == false );
894	dir.Unset();
895	// existing entry (file), initialized BDirectory, matching node kind
896	NextSubTest();
897	CPPUNIT_ASSERT( dir.SetTo(existingSuperFile) == B_OK );
898	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
899	CPPUNIT_ASSERT( dir.Contains(existingFile, B_FILE_NODE) == true );
900	dir.Unset();
901	// existing entry (file), initialized BDirectory, mismatching node kind
902	NextSubTest();
903	CPPUNIT_ASSERT( dir.SetTo(existingSuperFile) == B_OK );
904	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
905	CPPUNIT_ASSERT( dir.Contains(existingFile, B_SYMLINK_NODE) == false );
906	dir.Unset();
907	// existing entry (link), initialized BDirectory, matching node kind
908	NextSubTest();
909	CPPUNIT_ASSERT( dir.SetTo(dirSuperLink) == B_OK );
910	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
911	CPPUNIT_ASSERT( dir.Contains(dirLink, B_SYMLINK_NODE) == true );
912	dir.Unset();
913	// existing entry (link), initialized BDirectory, mismatching node kind
914	NextSubTest();
915	CPPUNIT_ASSERT( dir.SetTo(dirSuperLink) == B_OK );
916	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
917	CPPUNIT_ASSERT( dir.Contains(dirLink, B_DIRECTORY_NODE) == false );
918	dir.Unset();
919	// existing entry (relative path), initialized BDirectory,
920	// matching node kind
921	NextSubTest();
922	CPPUNIT_ASSERT( dir.SetTo(existingSuperFile) == B_OK );
923	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
924	CPPUNIT_ASSERT( dir.Contains(existingRelFile, B_FILE_NODE) == true );
925	dir.Unset();
926	// existing entry (relative path), initialized BDirectory,
927	// mismatching node kind
928	NextSubTest();
929	CPPUNIT_ASSERT( dir.SetTo(existingSuperFile) == B_OK );
930	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
931	CPPUNIT_ASSERT( dir.Contains(existingRelFile, B_SYMLINK_NODE) == false );
932	dir.Unset();
933
934	// 2. Contains(const BEntry *, int32)
935	// existing entry, initialized BDirectory
936	NextSubTest();
937	CPPUNIT_ASSERT( dir.SetTo(existing) == B_OK );
938	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
939	BEntry entry(existingSub);
940	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
941	CPPUNIT_ASSERT( dir.Contains(&entry) == true );
942	dir.Unset();
943	// existing entry, uninitialized BDirectory
944	// R5: unlike the other version, this one returns false
945	// Haiku: both versions return false
946	NextSubTest();
947	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
948	CPPUNIT_ASSERT( entry.SetTo(existing) == B_OK );
949	CPPUNIT_ASSERT( dir.Contains(&entry) == false );
950	dir.Unset();
951	entry.Unset();
952	// non-existing entry, uninitialized BDirectory
953	NextSubTest();
954	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
955	CPPUNIT_ASSERT( entry.SetTo(nonExisting) == B_OK);
956	CPPUNIT_ASSERT( dir.Contains(&entry) == false );
957	dir.Unset();
958	entry.Unset();
959	// existing entry, badly initialized BDirectory
960	// R5: unlike the other version, this one returns false
961	// Haiku: both versions return false
962	NextSubTest();
963	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
964	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
965	CPPUNIT_ASSERT( entry.SetTo(existing) == B_OK);
966	CPPUNIT_ASSERT( dir.Contains(&entry) == false );
967	dir.Unset();
968	entry.Unset();
969	// non-existing entry, badly initialized BDirectory
970	NextSubTest();
971	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
972	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
973	CPPUNIT_ASSERT( entry.SetTo(nonExisting) == B_OK);
974	CPPUNIT_ASSERT( dir.Contains(&entry) == false );
975	dir.Unset();
976	entry.Unset();
977	// initialized BDirectory, bad args
978// R5 crashs, when passing a NULL BEntry
979#if !TEST_R5
980	NextSubTest();
981	CPPUNIT_ASSERT( dir.SetTo(existing) == B_OK );
982	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
983	CPPUNIT_ASSERT( dir.Contains((const BEntry*)NULL) == false );
984	dir.Unset();
985#endif
986	// uninitialized BDirectory, bad args
987	NextSubTest();
988	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
989	CPPUNIT_ASSERT( dir.Contains((const BEntry*)NULL) == false );
990	dir.Unset();
991	// existing entry (second level, absolute path), initialized BDirectory
992	NextSubTest();
993	CPPUNIT_ASSERT( dir.SetTo(existingSuper) == B_OK );
994	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
995	CPPUNIT_ASSERT( entry.SetTo(existingSub) == B_OK);
996	CPPUNIT_ASSERT( dir.Contains(&entry) == true );
997	dir.Unset();
998	entry.Unset();
999	// initialized BDirectory, self containing
1000	// R5: behavior is different from Contains(const char*)
1001	// Haiku: both versions return true
1002	NextSubTest();
1003	CPPUNIT_ASSERT( dir.SetTo(existing) == B_OK );
1004	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1005	CPPUNIT_ASSERT( entry.SetTo(existing) == B_OK);
1006	CPPUNIT_ASSERT( equals(dir.Contains(&entry), false, true) );
1007	dir.Unset();
1008	entry.Unset();
1009	// existing entry (dir), initialized BDirectory, matching node kind
1010	NextSubTest();
1011	CPPUNIT_ASSERT( dir.SetTo(existingSuper) == B_OK );
1012	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1013	CPPUNIT_ASSERT( entry.SetTo(existing) == B_OK);
1014	CPPUNIT_ASSERT( dir.Contains(&entry, B_DIRECTORY_NODE) == true );
1015	dir.Unset();
1016	entry.Unset();
1017	// existing entry (dir), initialized BDirectory, mismatching node kind
1018	NextSubTest();
1019	CPPUNIT_ASSERT( dir.SetTo(existingSuper) == B_OK );
1020	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1021	CPPUNIT_ASSERT( entry.SetTo(existing) == B_OK);
1022	CPPUNIT_ASSERT( dir.Contains(&entry, B_FILE_NODE) == false );
1023	dir.Unset();
1024	entry.Unset();
1025	// existing entry (file), initialized BDirectory, matching node kind
1026// R5 bug: returns false
1027#if !TEST_R5
1028	NextSubTest();
1029	CPPUNIT_ASSERT( dir.SetTo(existingSuperFile) == B_OK );
1030	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1031	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK);
1032	CPPUNIT_ASSERT( dir.Contains(&entry, B_FILE_NODE) == true );
1033	dir.Unset();
1034	entry.Unset();
1035#endif
1036	// existing entry (file), initialized BDirectory, mismatching node kind
1037	NextSubTest();
1038	CPPUNIT_ASSERT( dir.SetTo(existingSuperFile) == B_OK );
1039	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1040	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK);
1041	CPPUNIT_ASSERT( dir.Contains(&entry, B_SYMLINK_NODE) == false );
1042	dir.Unset();
1043	entry.Unset();
1044	// existing entry (link), initialized BDirectory, matching node kind
1045// R5 bug: returns false
1046#if !TEST_R5
1047	NextSubTest();
1048	CPPUNIT_ASSERT( dir.SetTo(dirSuperLink) == B_OK );
1049	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1050	CPPUNIT_ASSERT( entry.SetTo(dirLink) == B_OK);
1051	CPPUNIT_ASSERT( dir.Contains(&entry, B_SYMLINK_NODE) == true );
1052	dir.Unset();
1053	entry.Unset();
1054#endif
1055	// existing entry (link), initialized BDirectory, mismatching node kind
1056// R5 bug: returns true
1057#if !TEST_R5
1058	NextSubTest();
1059	CPPUNIT_ASSERT( dir.SetTo(dirSuperLink) == B_OK );
1060	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1061	CPPUNIT_ASSERT( entry.SetTo(dirLink) == B_OK);
1062	CPPUNIT_ASSERT( dir.Contains(&entry, B_DIRECTORY_NODE) == false );
1063	dir.Unset();
1064	entry.Unset();
1065#endif
1066}
1067
1068// GetStatForTest
1069void
1070DirectoryTest::GetStatForTest()
1071{
1072	const char *existing = existingDirname;
1073	const char *existingSuper = existingSuperDirname;
1074	const char *existingRel = existingRelDirname;
1075	const char *nonExisting = nonExistingDirname;
1076	// uninitialized dir, existing entry, absolute path
1077	NextSubTest();
1078	BDirectory dir;
1079	BEntry entry;
1080	struct stat stat1, stat2;
1081	memset(&stat1, 0, sizeof(struct stat));
1082	memset(&stat2, 0, sizeof(struct stat));
1083	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
1084	CPPUNIT_ASSERT( dir.GetStatFor(existing, &stat1) == B_NO_INIT );
1085	dir.Unset();
1086	entry.Unset();
1087	// badly initialized dir, existing entry, absolute path
1088	NextSubTest();
1089	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
1090	CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
1091	memset(&stat1, 0, sizeof(struct stat));
1092	memset(&stat2, 0, sizeof(struct stat));
1093	CPPUNIT_ASSERT( dir.GetStatFor(existing, &stat1) == B_NO_INIT );
1094	dir.Unset();
1095	entry.Unset();
1096	// initialized dir, existing entry, absolute path
1097	NextSubTest();
1098	CPPUNIT_ASSERT( dir.SetTo("/") == B_OK );
1099	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1100	memset(&stat1, 0, sizeof(struct stat));
1101	memset(&stat2, 0, sizeof(struct stat));
1102	CPPUNIT_ASSERT( dir.GetStatFor(existing, &stat1) == B_OK );
1103	CPPUNIT_ASSERT( entry.SetTo(existing) == B_OK );
1104	CPPUNIT_ASSERT( entry.GetStat(&stat2) == B_OK );
1105	CPPUNIT_ASSERT( stat1 == stat2 );
1106	dir.Unset();
1107	entry.Unset();
1108	// initialized dir, existing entry, relative path
1109	NextSubTest();
1110	CPPUNIT_ASSERT( dir.SetTo(existingSuper) == B_OK );
1111	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1112	memset(&stat1, 0, sizeof(struct stat));
1113	memset(&stat2, 0, sizeof(struct stat));
1114	CPPUNIT_ASSERT( dir.GetStatFor(existingRel, &stat1) == B_OK );
1115	CPPUNIT_ASSERT( entry.SetTo(existing) == B_OK );
1116	CPPUNIT_ASSERT( entry.GetStat(&stat2) == B_OK );
1117	CPPUNIT_ASSERT( stat1 == stat2 );
1118	dir.Unset();
1119	entry.Unset();
1120	// initialized dir, non-existing entry, absolute path
1121	NextSubTest();
1122	CPPUNIT_ASSERT( dir.SetTo("/") == B_OK );
1123	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1124	memset(&stat1, 0, sizeof(struct stat));
1125	memset(&stat2, 0, sizeof(struct stat));
1126	CPPUNIT_ASSERT( dir.GetStatFor(nonExisting, &stat1) == B_ENTRY_NOT_FOUND );
1127	dir.Unset();
1128	entry.Unset();
1129	// initialized dir, bad args (NULL path)
1130	// R5 returns B_OK and the stat structure for the directory
1131	NextSubTest();
1132	CPPUNIT_ASSERT( dir.SetTo("/") == B_OK );
1133	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1134	memset(&stat1, 0, sizeof(struct stat));
1135	memset(&stat2, 0, sizeof(struct stat));
1136	CPPUNIT_ASSERT( dir.GetStatFor(NULL, &stat1) == B_OK );
1137	CPPUNIT_ASSERT( entry.SetTo("/") == B_OK );
1138	CPPUNIT_ASSERT( entry.GetStat(&stat2) == B_OK );
1139	CPPUNIT_ASSERT( stat1 == stat2 );
1140	dir.Unset();
1141	entry.Unset();
1142	// initialized dir, bad args (empty path)
1143	// R5 returns B_ENTRY_NOT_FOUND
1144	NextSubTest();
1145	CPPUNIT_ASSERT( dir.SetTo("/") == B_OK );
1146	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1147	CPPUNIT_ASSERT( dir.GetStatFor("", &stat1) == B_ENTRY_NOT_FOUND );
1148	dir.Unset();
1149	entry.Unset();
1150	// initialized dir, bad args
1151	// R5 returns B_BAD_ADDRESS instead of B_BAD_VALUE
1152	NextSubTest();
1153	CPPUNIT_ASSERT( dir.SetTo("/") == B_OK );
1154	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1155	CPPUNIT_ASSERT( equals(dir.GetStatFor(existing, NULL), B_BAD_ADDRESS,
1156						   B_BAD_VALUE) );
1157	CPPUNIT_ASSERT( equals(dir.GetStatFor(NULL, NULL), B_BAD_ADDRESS,
1158						   B_BAD_VALUE) );
1159	dir.Unset();
1160	entry.Unset();
1161}
1162
1163// EntryIterationTest
1164void
1165DirectoryTest::EntryIterationTest()
1166{
1167	const char *existingFile = existingFilename;
1168	const char *nonExisting = nonExistingDirname;
1169	const char *testDir1 = testDirname1;
1170	// create a test directory
1171	execCommand(string("mkdir ") + testDir1);
1172	// 1. empty directory
1173	TestSet testSet;
1174	testSet.add(".");
1175	testSet.add("..");
1176	// GetNextEntry
1177	NextSubTest();
1178	BDirectory dir(testDir1);
1179	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1180	BEntry entry;
1181	CPPUNIT_ASSERT( dir.GetNextEntry(&entry) == B_ENTRY_NOT_FOUND );
1182	CPPUNIT_ASSERT( dir.Rewind() == B_OK );
1183	dir.Unset();
1184	entry.Unset();
1185	// GetNextRef
1186	NextSubTest();
1187	entry_ref ref;
1188	CPPUNIT_ASSERT( dir.SetTo(testDir1) == B_OK );
1189	CPPUNIT_ASSERT( dir.GetNextRef(&ref) == B_ENTRY_NOT_FOUND );
1190	CPPUNIT_ASSERT( dir.Rewind() == B_OK );
1191	dir.Unset();
1192	entry.Unset();
1193	// GetNextDirents
1194	NextSubTest();
1195	size_t bufSize = (sizeof(dirent) + B_FILE_NAME_LENGTH) * 10;
1196	char buffer[bufSize];
1197	dirent *ents = (dirent *)buffer;
1198	CPPUNIT_ASSERT( dir.SetTo(testDir1) == B_OK );
1199	while (dir.GetNextDirents(ents, bufSize, 1) == 1)
1200		CPPUNIT_ASSERT( testSet.test(ents->d_name) == true );
1201	CPPUNIT_ASSERT( testSet.testDone() == true );
1202	CPPUNIT_ASSERT( dir.Rewind() == B_OK );
1203	dir.Unset();
1204	entry.Unset();
1205	testSet.rewind();
1206	// CountEntries
1207	NextSubTest();
1208	CPPUNIT_ASSERT( dir.SetTo(testDir1) == B_OK );
1209	CPPUNIT_ASSERT( dir.CountEntries() == 0 );
1210	dir.Unset();
1211
1212	// 2. non-empty directory
1213	string dirPathName(string(testDir1) + "/");
1214	string entryName("file1");
1215	execCommand(string("touch ") + dirPathName + entryName);
1216	testSet.add(entryName);
1217	entryName = ("file2");
1218	execCommand(string("touch ") + dirPathName + entryName);
1219	testSet.add(entryName);
1220	entryName = ("file3");
1221	execCommand(string("touch ") + dirPathName + entryName);
1222	testSet.add(entryName);
1223	entryName = ("dir1");
1224	execCommand(string("mkdir ") + dirPathName + entryName);
1225	testSet.add(entryName);
1226	entryName = ("dir2");
1227	execCommand(string("mkdir ") + dirPathName + entryName);
1228	testSet.add(entryName);
1229	entryName = ("dir3");
1230	execCommand(string("mkdir ") + dirPathName + entryName);
1231	testSet.add(entryName);
1232	entryName = ("link1");
1233	execCommand(string("ln -s ") + existingFile + " "
1234				+ dirPathName + entryName);
1235	testSet.add(entryName);
1236	entryName = ("link2");
1237	execCommand(string("ln -s ") + existingFile + " "
1238				+ dirPathName + entryName);
1239	testSet.add(entryName);
1240	entryName = ("link3");
1241	execCommand(string("ln -s ") + existingFile + " "
1242				+ dirPathName + entryName);
1243	testSet.add(entryName);
1244	// GetNextEntry
1245	NextSubTest();
1246	testSet.test(".");
1247	testSet.test("..");
1248	CPPUNIT_ASSERT( dir.SetTo(testDir1) == B_OK );
1249	while (dir.GetNextEntry(&entry) == B_OK) {
1250		BPath path;
1251		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1252		CPPUNIT_ASSERT( entry.GetPath(&path) == B_OK );
1253		CPPUNIT_ASSERT( testSet.test(path.Leaf()) == true );
1254	}
1255	CPPUNIT_ASSERT( testSet.testDone() == true );
1256	CPPUNIT_ASSERT( dir.Rewind() == B_OK );
1257	dir.Unset();
1258	entry.Unset();
1259	testSet.rewind();
1260	// GetNextRef
1261	NextSubTest();
1262	testSet.test(".");
1263	testSet.test("..");
1264	CPPUNIT_ASSERT( dir.SetTo(testDir1) == B_OK );
1265	while (dir.GetNextRef(&ref) == B_OK)
1266		CPPUNIT_ASSERT( testSet.test(ref.name) == true );
1267	CPPUNIT_ASSERT( testSet.testDone() == true );
1268	CPPUNIT_ASSERT( dir.Rewind() == B_OK );
1269	dir.Unset();
1270	entry.Unset();
1271	testSet.rewind();
1272	// GetNextDirents
1273	NextSubTest();
1274	CPPUNIT_ASSERT( dir.SetTo(testDir1) == B_OK );
1275	while (dir.GetNextDirents(ents, bufSize, 1) == 1)
1276		CPPUNIT_ASSERT( testSet.test(ents->d_name) == true );
1277	CPPUNIT_ASSERT( testSet.testDone() == true );
1278	CPPUNIT_ASSERT( dir.Rewind() == B_OK );
1279	dir.Unset();
1280	entry.Unset();
1281	testSet.rewind();
1282	// CountEntries
1283	NextSubTest();
1284	CPPUNIT_ASSERT( dir.SetTo(testDir1) == B_OK );
1285	CPPUNIT_ASSERT( dir.CountEntries() == 9 );
1286	CPPUNIT_ASSERT( dir.GetNextRef(&ref) == B_OK );
1287	CPPUNIT_ASSERT( dir.CountEntries() == 9 );
1288	dir.Unset();
1289
1290	// 3. interleaving use of the different methods
1291	NextSubTest();
1292	CPPUNIT_ASSERT( dir.SetTo(testDir1) == B_OK );
1293	while (dir.GetNextDirents(ents, bufSize, 1) == 1) {
1294		CPPUNIT_ASSERT( testSet.test(ents->d_name) == true );
1295		if (dir.GetNextRef(&ref) == B_OK)
1296			CPPUNIT_ASSERT( testSet.test(ref.name) == true );
1297		if (dir.GetNextEntry(&entry) == B_OK) {
1298			BPath path;
1299			CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1300			CPPUNIT_ASSERT( entry.GetPath(&path) == B_OK );
1301			CPPUNIT_ASSERT( testSet.test(path.Leaf()) == true );
1302		}
1303	}
1304	testSet.test(".", false);	// in case they have been skipped
1305	testSet.test("..", false);	//
1306	CPPUNIT_ASSERT( testSet.testDone() == true );
1307	CPPUNIT_ASSERT( dir.Rewind() == B_OK );
1308	dir.Unset();
1309	entry.Unset();
1310	testSet.rewind();
1311
1312	// 4. uninitialized BDirectory
1313	NextSubTest();
1314	dir.Unset();
1315	// R5: unlike the others GetNextRef() returns B_NO_INIT
1316	CPPUNIT_ASSERT( dir.GetNextEntry(&entry) == B_FILE_ERROR );
1317	CPPUNIT_ASSERT( equals(dir.GetNextRef(&ref), B_NO_INIT, B_FILE_ERROR) );
1318	CPPUNIT_ASSERT( dir.Rewind() == B_FILE_ERROR );
1319	CPPUNIT_ASSERT( dir.GetNextDirents(ents, bufSize, 1) == B_FILE_ERROR );
1320	CPPUNIT_ASSERT( dir.CountEntries() == B_FILE_ERROR );
1321	dir.Unset();
1322
1323	// 5. badly initialized BDirectory
1324	NextSubTest();
1325	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
1326	// R5: unlike the others GetNextRef() returns B_NO_INIT
1327	CPPUNIT_ASSERT( dir.GetNextEntry(&entry) == B_FILE_ERROR );
1328	CPPUNIT_ASSERT( equals(dir.GetNextRef(&ref), B_NO_INIT, B_FILE_ERROR) );
1329	CPPUNIT_ASSERT( dir.Rewind() == B_FILE_ERROR );
1330	CPPUNIT_ASSERT( dir.GetNextDirents(ents, bufSize, 1) == B_FILE_ERROR );
1331	CPPUNIT_ASSERT( dir.CountEntries() == B_FILE_ERROR );
1332	dir.Unset();
1333
1334	// 6. bad args
1335// R5 crashs, when passing a NULL BEntry or entry_ref
1336#if !TEST_R5
1337	NextSubTest();
1338	CPPUNIT_ASSERT( dir.SetTo(testDir1) == B_OK );
1339	CPPUNIT_ASSERT( dir.GetNextEntry(NULL) == B_BAD_VALUE );
1340	CPPUNIT_ASSERT( dir.GetNextRef(NULL) == B_BAD_VALUE );
1341	CPPUNIT_ASSERT( equals(dir.GetNextDirents(NULL, bufSize, 1),
1342						   B_BAD_ADDRESS, B_BAD_VALUE) );
1343	dir.Unset();
1344#endif
1345
1346	// 7. link traversation
1347	NextSubTest();
1348	execCommand(string("rm -rf ") + testDir1);
1349	execCommand(string("mkdir ") + testDir1);
1350	entryName = ("link1");
1351	execCommand(string("ln -s ") + existingFile + " "
1352				+ dirPathName + entryName);
1353	CPPUNIT_ASSERT( dir.SetTo(testDir1) == B_OK );
1354	CPPUNIT_ASSERT( dir.GetNextEntry(&entry, true) == B_OK );
1355	BPath path;
1356	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1357	BEntry entry2(existingFile);
1358	CPPUNIT_ASSERT( entry2.InitCheck() == B_OK );
1359	CPPUNIT_ASSERT( entry == entry2 );
1360	dir.Unset();
1361	entry.Unset();
1362}
1363
1364// EntryCreationTest
1365void
1366DirectoryTest::EntryCreationTest()
1367{
1368#ifdef TEST_R5
1369	Outputf("(test currently omitted due to build errors related to BSymLink::SetTo())\n");
1370#else
1371	const char *existingFile = existingFilename;
1372	const char *existing = existingDirname;
1373	const char *testDir1 = testDirname1;
1374	// create a test directory
1375	execCommand(string("mkdir ") + testDir1);
1376	// 1. relative path
1377	BDirectory dir(testDir1);
1378	CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1379	// CreateDirectory
1380	// dir doesn't already exist
1381	NextSubTest();
1382	BDirectory subdir;
1383	string dirPathName(string(testDir1) + "/");
1384	string entryName("subdir1");
1385	CPPUNIT_ASSERT( dir.CreateDirectory(entryName.c_str(), &subdir) == B_OK );
1386	CPPUNIT_ASSERT( subdir.InitCheck() == B_OK );
1387	BEntry entry;
1388	CPPUNIT_ASSERT( subdir.GetEntry(&entry) == B_OK );
1389	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1390	CPPUNIT_ASSERT( entry == BEntry((dirPathName + entryName).c_str()) );
1391	subdir.Unset();
1392	CPPUNIT_ASSERT( subdir.SetTo((dirPathName + entryName).c_str()) == B_OK );
1393	subdir.Unset();
1394	// dir does already exist
1395	NextSubTest();
1396	CPPUNIT_ASSERT( dir.CreateDirectory(entryName.c_str(), &subdir)
1397					== B_FILE_EXISTS );
1398	CPPUNIT_ASSERT( subdir.InitCheck() == B_NO_INIT );
1399	subdir.Unset();
1400	// CreateFile
1401	// file doesn't already exist
1402	NextSubTest();
1403	BFile file;
1404	entryName = "file1";
1405	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), &file, true) == B_OK );
1406	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
1407	file.Unset();
1408	CPPUNIT_ASSERT( file.SetTo((dirPathName + entryName).c_str(),
1409							   B_READ_ONLY) == B_OK );
1410	file.Unset();
1411	// file does already exist, don't fail
1412	NextSubTest();
1413	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), &file, false) == B_OK );
1414	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
1415	file.Unset();
1416	CPPUNIT_ASSERT( file.SetTo((dirPathName + entryName).c_str(),
1417							   B_READ_ONLY) == B_OK );
1418	file.Unset();
1419	// file does already exist, fail
1420	NextSubTest();
1421	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), &file, true)
1422					== B_FILE_EXISTS );
1423	CPPUNIT_ASSERT( file.InitCheck() == B_NO_INIT );
1424	file.Unset();
1425	// CreateSymLink
1426	// link doesn't already exist
1427	NextSubTest();
1428	BSymLink link;
1429	entryName = "link1";
1430	CPPUNIT_ASSERT( dir.CreateSymLink(entryName.c_str(), existingFile, &link)
1431					== B_OK );
1432	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
1433	link.Unset();
1434	CPPUNIT_ASSERT( link.SetTo((dirPathName + entryName).c_str()) == B_OK );
1435	link.Unset();
1436	// link does already exist
1437	NextSubTest();
1438	CPPUNIT_ASSERT( dir.CreateSymLink(entryName.c_str(), existingFile, &link)
1439					== B_FILE_EXISTS );
1440	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
1441	link.Unset();
1442
1443	// 2. absolute path
1444	dir.Unset();
1445	execCommand(string("rm -rf ") + testDir1);
1446	execCommand(string("mkdir ") + testDir1);
1447	CPPUNIT_ASSERT( dir.SetTo(existing) == B_OK );
1448	// CreateDirectory
1449	// dir doesn't already exist
1450	NextSubTest();
1451	entryName = dirPathName + "subdir1";
1452	CPPUNIT_ASSERT( dir.CreateDirectory(entryName.c_str(), &subdir) == B_OK );
1453	CPPUNIT_ASSERT( subdir.InitCheck() == B_OK );
1454	CPPUNIT_ASSERT( subdir.GetEntry(&entry) == B_OK );
1455	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1456	CPPUNIT_ASSERT( entry == BEntry(entryName.c_str()) );
1457	subdir.Unset();
1458	CPPUNIT_ASSERT( subdir.SetTo(entryName.c_str()) == B_OK );
1459	subdir.Unset();
1460	// dir does already exist
1461	NextSubTest();
1462	CPPUNIT_ASSERT( dir.CreateDirectory(entryName.c_str(), &subdir)
1463					== B_FILE_EXISTS );
1464	CPPUNIT_ASSERT( subdir.InitCheck() == B_NO_INIT );
1465	subdir.Unset();
1466	// CreateFile
1467	// file doesn't already exist
1468	NextSubTest();
1469	entryName = dirPathName + "file1";
1470	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), &file, true) == B_OK );
1471	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
1472	file.Unset();
1473	CPPUNIT_ASSERT( file.SetTo(entryName.c_str(), B_READ_ONLY) == B_OK );
1474	file.Unset();
1475	// file does already exist, don't fail
1476	NextSubTest();
1477	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), &file, false) == B_OK );
1478	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
1479	file.Unset();
1480	CPPUNIT_ASSERT( file.SetTo(entryName.c_str(), B_READ_ONLY) == B_OK );
1481	file.Unset();
1482	// file does already exist, fail
1483	NextSubTest();
1484	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), &file, true)
1485					== B_FILE_EXISTS );
1486	CPPUNIT_ASSERT( file.InitCheck() == B_NO_INIT );
1487	file.Unset();
1488	// CreateSymLink
1489	// link doesn't already exist
1490	NextSubTest();
1491	entryName = dirPathName + "link1";
1492	CPPUNIT_ASSERT( dir.CreateSymLink(entryName.c_str(), existingFile, &link)
1493					== B_OK );
1494	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
1495	link.Unset();
1496	CPPUNIT_ASSERT( link.SetTo(entryName.c_str()) == B_OK );
1497	link.Unset();
1498	// link does already exist
1499	NextSubTest();
1500	CPPUNIT_ASSERT( dir.CreateSymLink(entryName.c_str(), existingFile, &link)
1501					== B_FILE_EXISTS );
1502	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
1503	link.Unset();
1504
1505	// 3. uninitialized BDirectory, absolute path
1506	dir.Unset();
1507	execCommand(string("rm -rf ") + testDir1);
1508	execCommand(string("mkdir ") + testDir1);
1509	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
1510	// CreateDirectory
1511	// dir doesn't already exist
1512	NextSubTest();
1513	entryName = dirPathName + "subdir1";
1514	CPPUNIT_ASSERT( dir.CreateDirectory(entryName.c_str(), &subdir) == B_OK );
1515	CPPUNIT_ASSERT( subdir.InitCheck() == B_OK );
1516	CPPUNIT_ASSERT( subdir.GetEntry(&entry) == B_OK );
1517	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1518	CPPUNIT_ASSERT( entry == BEntry(entryName.c_str()) );
1519	subdir.Unset();
1520	CPPUNIT_ASSERT( subdir.SetTo(entryName.c_str()) == B_OK );
1521	subdir.Unset();
1522	// dir does already exist
1523	NextSubTest();
1524	CPPUNIT_ASSERT( dir.CreateDirectory(entryName.c_str(), &subdir)
1525					== B_FILE_EXISTS );
1526	CPPUNIT_ASSERT( subdir.InitCheck() == B_NO_INIT );
1527	subdir.Unset();
1528	// CreateFile
1529	// file doesn't already exist
1530	NextSubTest();
1531	entryName = dirPathName + "file1";
1532	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), &file, true) == B_OK );
1533	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
1534	file.Unset();
1535	CPPUNIT_ASSERT( file.SetTo(entryName.c_str(), B_READ_ONLY) == B_OK );
1536	file.Unset();
1537	// file does already exist, don't fail
1538	NextSubTest();
1539	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), &file, false) == B_OK );
1540	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
1541	file.Unset();
1542	CPPUNIT_ASSERT( file.SetTo(entryName.c_str(), B_READ_ONLY) == B_OK );
1543	file.Unset();
1544	// file does already exist, fail
1545	NextSubTest();
1546	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), &file, true)
1547					== B_FILE_EXISTS );
1548	CPPUNIT_ASSERT( file.InitCheck() == B_NO_INIT );
1549	file.Unset();
1550	// CreateSymLink
1551	// link doesn't already exist
1552	NextSubTest();
1553	entryName = dirPathName + "link1";
1554	CPPUNIT_ASSERT( dir.CreateSymLink(entryName.c_str(), existingFile, &link)
1555					== B_OK );
1556	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
1557	link.Unset();
1558	CPPUNIT_ASSERT( link.SetTo(entryName.c_str()) == B_OK );
1559	link.Unset();
1560	// link does already exist
1561	NextSubTest();
1562	CPPUNIT_ASSERT( dir.CreateSymLink(entryName.c_str(), existingFile, &link)
1563					== B_FILE_EXISTS );
1564	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
1565	link.Unset();
1566
1567	// 4. uninitialized BDirectory, relative path, current directory
1568	dir.Unset();
1569	execCommand(string("rm -rf ") + testDir1);
1570	execCommand(string("mkdir ") + testDir1);
1571	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
1572	chdir(testDir1);
1573	// CreateDirectory
1574	// dir doesn't already exist
1575	NextSubTest();
1576	entryName = "subdir1";
1577	CPPUNIT_ASSERT( dir.CreateDirectory(entryName.c_str(), &subdir) == B_OK );
1578	CPPUNIT_ASSERT( subdir.InitCheck() == B_OK );
1579	CPPUNIT_ASSERT( subdir.GetEntry(&entry) == B_OK );
1580	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1581	CPPUNIT_ASSERT( entry == BEntry((dirPathName + entryName).c_str()) );
1582	subdir.Unset();
1583	CPPUNIT_ASSERT( subdir.SetTo((dirPathName + entryName).c_str()) == B_OK );
1584	subdir.Unset();
1585	// dir does already exist
1586	NextSubTest();
1587	CPPUNIT_ASSERT( dir.CreateDirectory(entryName.c_str(), &subdir)
1588					== B_FILE_EXISTS );
1589	CPPUNIT_ASSERT( subdir.InitCheck() == B_NO_INIT );
1590	subdir.Unset();
1591	// CreateFile
1592	// file doesn't already exist
1593	NextSubTest();
1594	entryName = "file1";
1595	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), &file, true) == B_OK );
1596	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
1597	file.Unset();
1598	CPPUNIT_ASSERT( file.SetTo((dirPathName + entryName).c_str(),
1599							   B_READ_ONLY) == B_OK );
1600	file.Unset();
1601	// file does already exist, don't fail
1602	NextSubTest();
1603	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), &file, false) == B_OK );
1604	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
1605	file.Unset();
1606	CPPUNIT_ASSERT( file.SetTo((dirPathName + entryName).c_str(),
1607							   B_READ_ONLY) == B_OK );
1608	file.Unset();
1609	// file does already exist, fail
1610	NextSubTest();
1611	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), &file, true)
1612					== B_FILE_EXISTS );
1613	CPPUNIT_ASSERT( file.InitCheck() == B_NO_INIT );
1614	file.Unset();
1615	// CreateSymLink
1616	// link doesn't already exist
1617	NextSubTest();
1618	entryName = "link1";
1619	CPPUNIT_ASSERT( dir.CreateSymLink(entryName.c_str(), existingFile, &link)
1620					== B_OK );
1621	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
1622	link.Unset();
1623	CPPUNIT_ASSERT( link.SetTo((dirPathName + entryName).c_str()) == B_OK );
1624	link.Unset();
1625	// link does already exist
1626	NextSubTest();
1627	CPPUNIT_ASSERT( dir.CreateSymLink(entryName.c_str(), existingFile, &link)
1628					== B_FILE_EXISTS );
1629	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
1630	link.Unset();
1631	chdir("/");
1632
1633	// 5. bad args
1634	dir.Unset();
1635	execCommand(string("rm -rf ") + testDir1);
1636	execCommand(string("mkdir ") + testDir1);
1637	CPPUNIT_ASSERT( dir.SetTo(testDir1) == B_OK );
1638	// CreateDirectory
1639	NextSubTest();
1640	entryName = "subdir1";
1641	CPPUNIT_ASSERT( equals(dir.CreateDirectory(NULL, &subdir),
1642						   B_BAD_ADDRESS, B_BAD_VALUE) );
1643	CPPUNIT_ASSERT( subdir.InitCheck() == B_NO_INIT );
1644	subdir.Unset();
1645	// CreateFile
1646	// R5: unlike CreateDirectory/SymLink() CreateFile() returns
1647	//	   B_ENTRY_NOT_FOUND
1648	NextSubTest();
1649	entryName = "file1";
1650	CPPUNIT_ASSERT( equals(dir.CreateFile(NULL, &file), B_ENTRY_NOT_FOUND,
1651						   B_BAD_VALUE) );
1652	CPPUNIT_ASSERT( file.InitCheck() == B_NO_INIT );
1653	file.Unset();
1654	// CreateSymLink
1655	NextSubTest();
1656	entryName = "link1";
1657	CPPUNIT_ASSERT( equals(dir.CreateSymLink(NULL, existingFile, &link),
1658						   B_BAD_ADDRESS, B_BAD_VALUE) );
1659	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
1660	CPPUNIT_ASSERT( equals(dir.CreateSymLink(entryName.c_str(), NULL, &link),
1661						   B_BAD_ADDRESS, B_BAD_VALUE) );
1662	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
1663	link.Unset();
1664
1665	// 6. uninitialized BDirectory, absolute path, no second param
1666	dir.Unset();
1667	execCommand(string("rm -rf ") + testDir1);
1668	execCommand(string("mkdir ") + testDir1);
1669	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
1670	// CreateDirectory
1671	// dir doesn't already exist
1672	NextSubTest();
1673	entryName = dirPathName + "subdir1";
1674	CPPUNIT_ASSERT( dir.CreateDirectory(entryName.c_str(), NULL) == B_OK );
1675	CPPUNIT_ASSERT( subdir.SetTo(entryName.c_str()) == B_OK );
1676	subdir.Unset();
1677	// dir does already exist
1678	NextSubTest();
1679	CPPUNIT_ASSERT( dir.CreateDirectory(entryName.c_str(), NULL)
1680					== B_FILE_EXISTS );
1681	subdir.Unset();
1682	// CreateFile
1683	// file doesn't already exist
1684	NextSubTest();
1685	entryName = dirPathName + "file1";
1686	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), NULL, true) == B_OK );
1687	CPPUNIT_ASSERT( file.SetTo(entryName.c_str(), B_READ_ONLY) == B_OK );
1688	file.Unset();
1689	// file does already exist, don't fail
1690	NextSubTest();
1691	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), NULL, false) == B_OK );
1692	CPPUNIT_ASSERT( file.SetTo(entryName.c_str(), B_READ_ONLY) == B_OK );
1693	file.Unset();
1694	// file does already exist, fail
1695	NextSubTest();
1696	CPPUNIT_ASSERT( dir.CreateFile(entryName.c_str(), NULL, true)
1697					== B_FILE_EXISTS );
1698	// CreateSymLink
1699	// link doesn't already exist
1700	NextSubTest();
1701	entryName = dirPathName + "link1";
1702	CPPUNIT_ASSERT( dir.CreateSymLink(entryName.c_str(), existingFile, NULL)
1703					== B_OK );
1704	CPPUNIT_ASSERT( link.SetTo(entryName.c_str()) == B_OK );
1705	link.Unset();
1706	// link does already exist
1707	NextSubTest();
1708	CPPUNIT_ASSERT( dir.CreateSymLink(entryName.c_str(), existingFile, NULL)
1709					== B_FILE_EXISTS );
1710#endif // ifndef TEST_R5
1711}
1712
1713// AssignmentTest
1714void
1715DirectoryTest::AssignmentTest()
1716{
1717	const char *existing = existingDirname;
1718	// 1. copy constructor
1719	// uninitialized
1720	NextSubTest();
1721	{
1722		BDirectory dir;
1723		CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
1724		BDirectory dir2(dir);
1725		// R5 returns B_BAD_VALUE instead of B_NO_INIT
1726		CPPUNIT_ASSERT( equals(dir2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
1727	}
1728	// existing dir
1729	NextSubTest();
1730	{
1731		BDirectory dir(existing);
1732		CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1733		BDirectory dir2(dir);
1734		CPPUNIT_ASSERT( dir2.InitCheck() == B_OK );
1735	}
1736
1737	// 2. assignment operator
1738	// uninitialized
1739	NextSubTest();
1740	{
1741		BDirectory dir;
1742		BDirectory dir2;
1743		dir2 = dir;
1744		// R5 returns B_BAD_VALUE instead of B_NO_INIT
1745		CPPUNIT_ASSERT( equals(dir2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
1746	}
1747	NextSubTest();
1748	{
1749		BDirectory dir;
1750		BDirectory dir2(existing);
1751		CPPUNIT_ASSERT( dir2.InitCheck() == B_OK );
1752		dir2 = dir;
1753		// R5 returns B_BAD_VALUE instead of B_NO_INIT
1754		CPPUNIT_ASSERT( equals(dir2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
1755	}
1756	// existing dir
1757	NextSubTest();
1758	{
1759		BDirectory dir(existing);
1760		CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
1761		BDirectory dir2;
1762		dir2 = dir;
1763		CPPUNIT_ASSERT( dir2.InitCheck() == B_OK );
1764	}
1765}
1766
1767// CreateDirectoryTest
1768void
1769DirectoryTest::CreateDirectoryTest()
1770{
1771	const char *existingFile = existingFilename;
1772	const char *testDir1 = testDirname1;
1773	const char *dirLink = dirLinkname;
1774	const char *fileLink = fileLinkname;
1775	// 1. absolute path
1776	execCommand(string("mkdir ") + testDir1);
1777	// two levels
1778	NextSubTest();
1779	string dirPathName(string(testDir1) + "/");
1780	string entryName(dirPathName + "subdir1/subdir1.1");
1781	CPPUNIT_ASSERT( create_directory(entryName.c_str(), 0x1ff) == B_OK );
1782	BDirectory subdir;
1783	CPPUNIT_ASSERT( subdir.SetTo(entryName.c_str()) == B_OK );
1784	subdir.Unset();
1785	// one level
1786	NextSubTest();
1787	entryName = dirPathName + "subdir2";
1788	CPPUNIT_ASSERT( create_directory(entryName.c_str(), 0x1ff) == B_OK );
1789	CPPUNIT_ASSERT( subdir.SetTo(entryName.c_str()) == B_OK );
1790	subdir.Unset();
1791	// existing dir
1792	NextSubTest();
1793	entryName = dirPathName;
1794	CPPUNIT_ASSERT( create_directory(entryName.c_str(), 0x1ff) == B_OK );
1795	CPPUNIT_ASSERT( subdir.SetTo(entryName.c_str()) == B_OK );
1796	subdir.Unset();
1797
1798	// 2. relative path
1799	execCommand(string("rm -rf ") + testDir1);
1800	execCommand(string("mkdir ") + testDir1);
1801	chdir(testDir1);
1802	// two levels
1803	NextSubTest();
1804	entryName = "subdir1/subdir1.1";
1805	CPPUNIT_ASSERT( create_directory(entryName.c_str(), 0x1ff) == B_OK );
1806	CPPUNIT_ASSERT( subdir.SetTo(entryName.c_str()) == B_OK );
1807	subdir.Unset();
1808	// one level
1809	NextSubTest();
1810	entryName = "subdir2";
1811	CPPUNIT_ASSERT( create_directory(entryName.c_str(), 0x1ff) == B_OK );
1812	CPPUNIT_ASSERT( subdir.SetTo(entryName.c_str()) == B_OK );
1813	subdir.Unset();
1814	// existing dir
1815	NextSubTest();
1816	entryName = ".";
1817	CPPUNIT_ASSERT( create_directory(entryName.c_str(), 0x1ff) == B_OK );
1818	CPPUNIT_ASSERT( subdir.SetTo(entryName.c_str()) == B_OK );
1819	subdir.Unset();
1820	chdir("/");
1821
1822	// 3. error cases
1823	// existing file/link
1824	NextSubTest();
1825	CPPUNIT_ASSERT( equals(create_directory(existingFile, 0x1ff), B_BAD_VALUE,
1826						   B_NOT_A_DIRECTORY) );
1827	CPPUNIT_ASSERT( equals(create_directory(fileLink, 0x1ff), B_BAD_VALUE,
1828						   B_NOT_A_DIRECTORY) );
1829	CPPUNIT_ASSERT( create_directory(dirLink, 0x1ff) == B_OK );
1830	// bad args
1831	NextSubTest();
1832	CPPUNIT_ASSERT( create_directory(NULL, 0x1ff) == B_BAD_VALUE );
1833}
1834
1835