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