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