xref: /haiku/src/tests/kits/storage/DirectoryTest.cpp (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
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>
9 using 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
20 DirectoryTest::Test*
21 DirectoryTest::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
55 void
56 DirectoryTest::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
71 void
72 DirectoryTest::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
83 void
84 DirectoryTest::CreateUninitializedNodes(TestNodes& testEntries)
85 {
86 	testEntries.clear();
87 	testEntries.add(new BDirectory, "");
88 }
89 
90 // setUp
91 void DirectoryTest::setUp()
92 {
93 	NodeTest::setUp();
94 }
95 
96 // tearDown
97 void DirectoryTest::tearDown()
98 {
99 	NodeTest::tearDown();
100 }
101 
102 // InitTest1
103 void
104 DirectoryTest::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
338 void
339 DirectoryTest::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
558 void
559 DirectoryTest::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
599 void
600 DirectoryTest::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
630 void
631 DirectoryTest::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
802 void
803 DirectoryTest::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
1069 void
1070 DirectoryTest::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
1164 void
1165 DirectoryTest::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
1365 void
1366 DirectoryTest::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
1714 void
1715 DirectoryTest::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
1768 void
1769 DirectoryTest::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