1 // EntryTest.cpp
2
3 #include <errno.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <unistd.h>
7
8 #include <list>
9 using std::list;
10 #include <map>
11 using std::map;
12 #include <set>
13 using std::set;
14
15 #include <cppunit/TestCaller.h>
16 #include <cppunit/TestSuite.h>
17
18 #include <Entry.h>
19 #include <Directory.h>
20 #include <Path.h>
21
22 #include "EntryTest.h"
23
24 enum test_entry_kind {
25 DIR_ENTRY,
26 FILE_ENTRY,
27 LINK_ENTRY,
28 ABSTRACT_ENTRY,
29 BAD_ENTRY,
30 };
31
32 struct TestEntry {
33 TestEntry();
34
35 void init(TestEntry &super, string name, test_entry_kind kind,
36 bool relative = false);
37 void initDir(TestEntry &super, string name);
38 void initFile(TestEntry &super, string name);
39 void initRLink(TestEntry &super, string name, TestEntry &target);
40 void initALink(TestEntry &super, string name, TestEntry &target);
41 void initPath(const char *pathName = NULL);
42 void completeInit();
isConcreteTestEntry43 bool isConcrete() const { return !(isAbstract() || isBad()); }
isAbstractTestEntry44 bool isAbstract() const { return kind == ABSTRACT_ENTRY; }
isBadTestEntry45 bool isBad() const { return kind == BAD_ENTRY; }
46 const entry_ref &get_ref();
47
48 TestEntry * super;
49 string name;
50 test_entry_kind kind;
51 string path;
52 TestEntry * target;
53 string link;
54 entry_ref ref;
55 bool relative;
56 // C strings
57 const char * cname;
58 const char * cpath;
59 const char * clink;
60 };
61
62 static list<TestEntry*> allTestEntries;
63
64 static TestEntry badTestEntry;
65 static TestEntry testDir;
66 static TestEntry dir1;
67 static TestEntry dir2;
68 static TestEntry file1;
69 static TestEntry file2;
70 static TestEntry file3;
71 static TestEntry file4;
72 static TestEntry subDir1;
73 static TestEntry abstractEntry1;
74 static TestEntry badEntry1;
75 static TestEntry absDirLink1;
76 static TestEntry absDirLink2;
77 static TestEntry absDirLink3;
78 static TestEntry absDirLink4;
79 static TestEntry relDirLink1;
80 static TestEntry relDirLink2;
81 static TestEntry relDirLink3;
82 static TestEntry relDirLink4;
83 static TestEntry absFileLink1;
84 static TestEntry absFileLink2;
85 static TestEntry absFileLink3;
86 static TestEntry absFileLink4;
87 static TestEntry relFileLink1;
88 static TestEntry relFileLink2;
89 static TestEntry relFileLink3;
90 static TestEntry relFileLink4;
91 static TestEntry absCyclicLink1;
92 static TestEntry absCyclicLink2;
93 static TestEntry relCyclicLink1;
94 static TestEntry relCyclicLink2;
95 static TestEntry absBadLink1;
96 static TestEntry absBadLink2;
97 static TestEntry absBadLink3;
98 static TestEntry absBadLink4;
99 static TestEntry relBadLink1;
100 static TestEntry relBadLink2;
101 static TestEntry relBadLink3;
102 static TestEntry relBadLink4;
103 static TestEntry absVeryBadLink1;
104 static TestEntry absVeryBadLink2;
105 static TestEntry absVeryBadLink3;
106 static TestEntry absVeryBadLink4;
107 static TestEntry relVeryBadLink1;
108 static TestEntry relVeryBadLink2;
109 static TestEntry relVeryBadLink3;
110 static TestEntry relVeryBadLink4;
111 static TestEntry tooLongEntry1;
112 static TestEntry tooLongDir1;
113 static TestEntry tooLongDir2;
114 static TestEntry tooLongDir3;
115 static TestEntry tooLongDir4;
116 static TestEntry tooLongDir5;
117 static TestEntry tooLongDir6;
118 static TestEntry tooLongDir7;
119 static TestEntry tooLongDir8;
120 static TestEntry tooLongDir9;
121 static TestEntry tooLongDir10;
122 static TestEntry tooLongDir11;
123 static TestEntry tooLongDir12;
124 static TestEntry tooLongDir13;
125 static TestEntry tooLongDir14;
126 static TestEntry tooLongDir15;
127 static TestEntry tooLongDir16;
128
129 static string setUpCommandLine;
130 static string tearDownCommandLine;
131
132 // forward declarations
133 static TestEntry *resolve_link(TestEntry *entry);
134 static string get_shortest_relative_path(TestEntry *dir, TestEntry *entry);
135
136 static const status_t kErrors[] = {
137 B_BAD_ADDRESS,
138 B_BAD_VALUE,
139 B_CROSS_DEVICE_LINK,
140 B_DEVICE_FULL,
141 B_DIRECTORY_NOT_EMPTY,
142 B_ENTRY_NOT_FOUND,
143 B_ERROR,
144 B_FILE_ERROR,
145 B_FILE_EXISTS,
146 B_IS_A_DIRECTORY,
147 B_LINK_LIMIT,
148 B_NAME_TOO_LONG,
149 B_NO_MORE_FDS,
150 B_NOT_A_DIRECTORY,
151 B_OK,
152 B_PARTITION_TOO_SMALL,
153 B_READ_ONLY_DEVICE,
154 B_UNSUPPORTED,
155 E2BIG
156 };
157 static const int32 kErrorCount = sizeof(kErrors) / sizeof(status_t);
158
159 // get_error_index
160 static
161 int32
get_error_index(status_t error)162 get_error_index(status_t error)
163 {
164 int32 result = -1;
165 for (int32 i = 0; result == -1 && i < kErrorCount; i++) {
166 if (kErrors[i] == error)
167 result = i;
168 }
169 if (result == -1)
170 printf("WARNING: error %lx is not in the list of errors\n", error);
171 return result;
172 }
173
174 // fuzzy_error
175 static
176 status_t
fuzzy_error(status_t error1,status_t error2)177 fuzzy_error(status_t error1, status_t error2)
178 {
179 status_t result = error1;
180 // encode the two errors in one value
181 int32 index1 = get_error_index(error1);
182 int32 index2 = get_error_index(error2);
183 if (index1 >= 0 && index2 >= 0)
184 result = index1 * kErrorCount + index2 + 1;
185 return result;
186 }
187
188 // fuzzy_equals
189 static
190 bool
fuzzy_equals(status_t error,status_t fuzzyError)191 fuzzy_equals(status_t error, status_t fuzzyError)
192 {
193 bool result = false;
194 if (fuzzyError <= 0)
195 result = (error == fuzzyError);
196 else {
197 // decode the error
198 int32 index1 = (fuzzyError - 1) / kErrorCount;
199 int32 index2 = (fuzzyError - 1) % kErrorCount;
200 if (index1 >= kErrorCount)
201 printf("WARNING: bad fuzzy error: %lx\n", fuzzyError);
202 else {
203 status_t error1 = kErrors[index1];
204 status_t error2 = kErrors[index2];
205 result = (error == error1 || error == error2);
206 }
207 }
208 return result;
209 }
210
211
212 // Suite
213 CppUnit::Test*
Suite()214 EntryTest::Suite()
215 {
216 CppUnit::TestSuite *suite = new CppUnit::TestSuite();
217 typedef CppUnit::TestCaller<EntryTest> TC;
218
219 StatableTest::AddBaseClassTests<EntryTest>("BEntry::", suite);
220
221 suite->addTest( new TC("BEntry::Init Test1", &EntryTest::InitTest1) );
222 suite->addTest( new TC("BEntry::Init Test2", &EntryTest::InitTest2) );
223 suite->addTest( new TC("BEntry::Special cases for Exists(), GetPath(),...",
224 &EntryTest::SpecialGetCasesTest) );
225 suite->addTest( new TC("BEntry::Rename Test", &EntryTest::RenameTest) );
226 suite->addTest( new TC("BEntry::MoveTo Test", &EntryTest::MoveToTest) );
227 suite->addTest( new TC("BEntry::Remove Test", &EntryTest::RemoveTest) );
228 suite->addTest( new TC("BEntry::Comparison Test",
229 &EntryTest::ComparisonTest) );
230 suite->addTest( new TC("BEntry::Assignment Test",
231 &EntryTest::AssignmentTest) );
232 suite->addTest( new TC("BEntry::C Functions Test",
233 &EntryTest::CFunctionsTest) );
234 // suite->addTest( new TC("BEntry::Miscellaneous Test", &EntryTest::MiscTest) );
235
236 return suite;
237 }
238
239 // CreateROStatables
240 void
CreateROStatables(TestStatables & testEntries)241 EntryTest::CreateROStatables(TestStatables& testEntries)
242 {
243 CreateRWStatables(testEntries);
244 }
245
246 // CreateRWStatables
247 void
CreateRWStatables(TestStatables & testStatables)248 EntryTest::CreateRWStatables(TestStatables& testStatables)
249 {
250 TestEntry *testEntries[] = {
251 &dir1, &dir2, &file1, &subDir1,
252 &absDirLink1, &absDirLink2, &absDirLink3, &absDirLink4,
253 &relDirLink1, &relDirLink2, &relDirLink3, &relDirLink4,
254 &absFileLink1, &absFileLink2, &absFileLink3, &absFileLink4,
255 &relFileLink1, &relFileLink2, &relFileLink3, &relFileLink4,
256 &absBadLink1, &absBadLink2, &absBadLink3, &absBadLink4,
257 &relBadLink1, &relBadLink2, &relBadLink3, &relBadLink4,
258 &absVeryBadLink1, &absVeryBadLink2, &absVeryBadLink3, &absVeryBadLink4,
259 &relVeryBadLink1, &relVeryBadLink2, &relVeryBadLink3, &relVeryBadLink4
260 };
261 int32 testEntryCount = sizeof(testEntries) / sizeof(TestEntry*);
262 for (int32 i = 0; i < testEntryCount; i++) {
263 TestEntry *testEntry = testEntries[i];
264 const char *filename = testEntry->cpath;
265 testStatables.add(new BEntry(filename), filename);
266 }
267 }
268
269 // CreateUninitializedStatables
270 void
CreateUninitializedStatables(TestStatables & testEntries)271 EntryTest::CreateUninitializedStatables(TestStatables& testEntries)
272 {
273 testEntries.add(new BEntry, "");
274 }
275
276 // setUp
277 void
setUp()278 EntryTest::setUp()
279 {
280 StatableTest::setUp();
281 execCommand(setUpCommandLine);
282 }
283
284 // tearDown
285 void
tearDown()286 EntryTest::tearDown()
287 {
288 StatableTest::tearDown();
289 execCommand(tearDownCommandLine);
290 }
291
292 // examine_entry
293 static
294 void
examine_entry(BEntry & entry,TestEntry * testEntry,bool traverse)295 examine_entry(BEntry &entry, TestEntry *testEntry, bool traverse)
296 {
297 if (traverse)
298 testEntry = resolve_link(testEntry);
299 // Exists()
300 CPPUNIT_ASSERT( entry.Exists() == testEntry->isConcrete() );
301 // GetPath()
302 BPath path;
303 CPPUNIT_ASSERT( entry.GetPath(&path) == B_OK );
304 CPPUNIT_ASSERT( path == testEntry->cpath );
305 // GetName()
306 char name[B_FILE_NAME_LENGTH + 1];
307 CPPUNIT_ASSERT( entry.GetName(name) == B_OK );
308 CPPUNIT_ASSERT( testEntry->name == name );
309 // GetParent(BEntry *)
310 BEntry parentEntry;
311 CPPUNIT_ASSERT( entry.GetParent(&parentEntry) == B_OK );
312 CPPUNIT_ASSERT( parentEntry.InitCheck() == B_OK );
313 CPPUNIT_ASSERT( parentEntry.GetPath(&path) == B_OK );
314 CPPUNIT_ASSERT( path == testEntry->super->cpath );
315 parentEntry.Unset();
316 path.Unset();
317 // GetParent(BDirectory *)
318 BDirectory parentDir;
319 CPPUNIT_ASSERT( entry.GetParent(&parentDir) == B_OK );
320 CPPUNIT_ASSERT( parentDir.GetEntry(&parentEntry) == B_OK );
321 CPPUNIT_ASSERT( parentEntry.InitCheck() == B_OK );
322 CPPUNIT_ASSERT( parentEntry.GetPath(&path) == B_OK );
323 CPPUNIT_ASSERT( path == testEntry->super->cpath );
324 // GetRef()
325 entry_ref ref;
326 CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
327 // We can't get a ref of an entry with a too long path name yet.
328 if (testEntry->path.length() < B_PATH_NAME_LENGTH)
329 CPPUNIT_ASSERT( ref == testEntry->get_ref() );
330 }
331
332 // InitTest1Paths
333 void
InitTest1Paths(TestEntry & _testEntry,status_t error,bool traverse)334 EntryTest::InitTest1Paths(TestEntry &_testEntry, status_t error, bool traverse)
335 {
336 TestEntry *testEntry = &_testEntry;
337 // absolute path
338 NextSubTest();
339 {
340 //printf("%s\n", testEntry->cpath);
341 BEntry entry(testEntry->cpath, traverse);
342 status_t result = entry.InitCheck();
343 if (!fuzzy_equals(result, error))
344 printf("error: %lx (%lx)\n", result, error);
345 CPPUNIT_ASSERT( fuzzy_equals(result, error) );
346 if (result == B_OK)
347 examine_entry(entry, testEntry, traverse);
348 }
349 // relative path
350 NextSubTest();
351 {
352 //printf("%s\n", testEntry->cpath);
353 if (chdir(testEntry->super->cpath) == 0) {
354 BEntry entry(testEntry->cname, traverse);
355 status_t result = entry.InitCheck();
356 if (!fuzzy_equals(result, error))
357 printf("error: %lx (%lx)\n", result, error);
358 CPPUNIT_ASSERT( fuzzy_equals(result, error) );
359 if (error == B_OK)
360 examine_entry(entry, testEntry, traverse);
361 RestoreCWD();
362 }
363 }
364 }
365
366 // InitTest1Refs
367 void
InitTest1Refs(TestEntry & _testEntry,status_t error,bool traverse)368 EntryTest::InitTest1Refs(TestEntry &_testEntry, status_t error, bool traverse)
369 {
370 TestEntry *testEntry = &_testEntry;
371 // absolute path
372 NextSubTest();
373 {
374 //printf("%s\n", testEntry->cpath);
375 BEntry entry(&testEntry->get_ref(), traverse);
376 status_t result = entry.InitCheck();
377 if (!fuzzy_equals(result, error))
378 printf("error: %lx (%lx)\n", result, error);
379 CPPUNIT_ASSERT( fuzzy_equals(result, error) );
380 if (error == B_OK)
381 examine_entry(entry, testEntry, traverse);
382 }
383 }
384
385 // InitTest1DirPaths
386 void
InitTest1DirPaths(TestEntry & _testEntry,status_t error,bool traverse)387 EntryTest::InitTest1DirPaths(TestEntry &_testEntry, status_t error,
388 bool traverse)
389 {
390 TestEntry *testEntry = &_testEntry;
391 // absolute path
392 NextSubTest();
393 {
394 if (!testEntry->isBad()
395 && testEntry->path.length() < B_PATH_NAME_LENGTH) {
396 //printf("%s\n", testEntry->cpath);
397 BDirectory dir("/boot/home/Desktop");
398 CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
399 BEntry entry(&dir, testEntry->cpath, traverse);
400 status_t result = entry.InitCheck();
401 if (!fuzzy_equals(result, error))
402 printf("error: %lx (%lx)\n", result, error);
403 CPPUNIT_ASSERT( fuzzy_equals(result, error) );
404 if (error == B_OK)
405 examine_entry(entry, testEntry, traverse);
406 }
407 }
408 // relative path (one level)
409 NextSubTest();
410 {
411 if (!testEntry->isBad()
412 && testEntry->super->path.length() < B_PATH_NAME_LENGTH) {
413 //printf("%s + %s\n", testEntry->super->cpath, testEntry->cname);
414 BDirectory dir(testEntry->super->cpath);
415 CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
416 BEntry entry(&dir, testEntry->cname, traverse);
417 status_t result = entry.InitCheck();
418 if (!fuzzy_equals(result, error))
419 printf("error: %lx (%lx)\n", result, error);
420 CPPUNIT_ASSERT( fuzzy_equals(result, error) );
421 if (error == B_OK)
422 examine_entry(entry, testEntry, traverse);
423 }
424 }
425 // relative path (two levels)
426 NextSubTest();
427 {
428 if (!testEntry->super->isBad() && !testEntry->super->super->isBad()) {
429 string entryName = testEntry->super->name + "/" + testEntry->name;
430 //printf("%s + %s\n", testEntry->super->super->cpath, entryName.c_str());
431 BDirectory dir(testEntry->super->super->cpath);
432 CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
433 BEntry entry(&dir, entryName.c_str(), traverse);
434 status_t result = entry.InitCheck();
435 if (!fuzzy_equals(result, error))
436 printf("error: %lx (%lx)\n", result, error);
437 CPPUNIT_ASSERT( fuzzy_equals(result, error) );
438 if (error == B_OK)
439 examine_entry(entry, testEntry, traverse);
440 }
441 }
442 }
443
444 // InitTest1
445 void
InitTest1()446 EntryTest::InitTest1()
447 {
448 // 1. default constructor
449 NextSubTest();
450 {
451 BEntry entry;
452 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
453 }
454
455 // 2. BEntry(const char *, bool)
456 // don't traverse
457 InitTest1Paths(dir1, B_OK);
458 InitTest1Paths(dir2, B_OK);
459 InitTest1Paths(file1, B_OK);
460 InitTest1Paths(subDir1, B_OK);
461 InitTest1Paths(abstractEntry1, B_OK);
462 InitTest1Paths(badEntry1, B_ENTRY_NOT_FOUND);
463 InitTest1Paths(absDirLink1, B_OK);
464 InitTest1Paths(absDirLink2, B_OK);
465 InitTest1Paths(absDirLink3, B_OK);
466 InitTest1Paths(absDirLink4, B_OK);
467 InitTest1Paths(relDirLink1, B_OK);
468 InitTest1Paths(relDirLink2, B_OK);
469 InitTest1Paths(relDirLink3, B_OK);
470 InitTest1Paths(relDirLink4, B_OK);
471 InitTest1Paths(absFileLink1, B_OK);
472 InitTest1Paths(absFileLink2, B_OK);
473 InitTest1Paths(absFileLink3, B_OK);
474 InitTest1Paths(absFileLink4, B_OK);
475 InitTest1Paths(relFileLink1, B_OK);
476 InitTest1Paths(relFileLink2, B_OK);
477 InitTest1Paths(relFileLink3, B_OK);
478 InitTest1Paths(relFileLink4, B_OK);
479 InitTest1Paths(absCyclicLink1, B_OK);
480 InitTest1Paths(relCyclicLink1, B_OK);
481 InitTest1Paths(absBadLink1, B_OK);
482 InitTest1Paths(absBadLink2, B_OK);
483 InitTest1Paths(absBadLink3, B_OK);
484 InitTest1Paths(absBadLink4, B_OK);
485 InitTest1Paths(relBadLink1, B_OK);
486 InitTest1Paths(relBadLink2, B_OK);
487 InitTest1Paths(relBadLink3, B_OK);
488 InitTest1Paths(relBadLink4, B_OK);
489 InitTest1Paths(absVeryBadLink1, B_OK);
490 InitTest1Paths(absVeryBadLink2, B_OK);
491 InitTest1Paths(absVeryBadLink3, B_OK);
492 InitTest1Paths(absVeryBadLink4, B_OK);
493 InitTest1Paths(relVeryBadLink1, B_OK);
494 InitTest1Paths(relVeryBadLink2, B_OK);
495 InitTest1Paths(relVeryBadLink3, B_OK);
496 InitTest1Paths(relVeryBadLink4, B_OK);
497 // R5: returns E2BIG instead of B_NAME_TOO_LONG
498 InitTest1Paths(tooLongEntry1, fuzzy_error(E2BIG, B_NAME_TOO_LONG));
499 // R5: returns B_ERROR instead of B_NAME_TOO_LONG
500 InitTest1Paths(tooLongDir16, fuzzy_error(B_ERROR, B_NAME_TOO_LONG));
501 // traverse
502 InitTest1Paths(dir1, B_OK, true);
503 InitTest1Paths(dir2, B_OK, true);
504 InitTest1Paths(file1, B_OK, true);
505 InitTest1Paths(subDir1, B_OK, true);
506 InitTest1Paths(abstractEntry1, B_OK, true);
507 InitTest1Paths(badEntry1, B_ENTRY_NOT_FOUND, true);
508 InitTest1Paths(absDirLink1, B_OK, true);
509 InitTest1Paths(absDirLink2, B_OK, true);
510 InitTest1Paths(absDirLink3, B_OK, true);
511 InitTest1Paths(absDirLink4, B_OK, true);
512 InitTest1Paths(relDirLink1, B_OK, true);
513 InitTest1Paths(relDirLink2, B_OK, true);
514 InitTest1Paths(relDirLink3, B_OK, true);
515 InitTest1Paths(relDirLink4, B_OK, true);
516 InitTest1Paths(absFileLink1, B_OK, true);
517 InitTest1Paths(absFileLink2, B_OK, true);
518 InitTest1Paths(absFileLink3, B_OK, true);
519 InitTest1Paths(absFileLink4, B_OK, true);
520 InitTest1Paths(relFileLink1, B_OK, true);
521 InitTest1Paths(relFileLink2, B_OK, true);
522 InitTest1Paths(relFileLink3, B_OK, true);
523 InitTest1Paths(relFileLink4, B_OK, true);
524 InitTest1Paths(absCyclicLink1, B_LINK_LIMIT, true);
525 InitTest1Paths(relCyclicLink1, B_LINK_LIMIT, true);
526 InitTest1Paths(absBadLink1, B_ENTRY_NOT_FOUND, true);
527 InitTest1Paths(absBadLink2, B_ENTRY_NOT_FOUND, true);
528 InitTest1Paths(absBadLink3, B_ENTRY_NOT_FOUND, true);
529 InitTest1Paths(absBadLink4, B_ENTRY_NOT_FOUND, true);
530 InitTest1Paths(relBadLink1, B_ENTRY_NOT_FOUND, true);
531 InitTest1Paths(relBadLink2, B_ENTRY_NOT_FOUND, true);
532 InitTest1Paths(relBadLink3, B_ENTRY_NOT_FOUND, true);
533 InitTest1Paths(relBadLink4, B_ENTRY_NOT_FOUND, true);
534 InitTest1Paths(absVeryBadLink1, B_ENTRY_NOT_FOUND, true);
535 InitTest1Paths(absVeryBadLink2, B_ENTRY_NOT_FOUND, true);
536 InitTest1Paths(absVeryBadLink3, B_ENTRY_NOT_FOUND, true);
537 InitTest1Paths(absVeryBadLink4, B_ENTRY_NOT_FOUND, true);
538 InitTest1Paths(relVeryBadLink1, B_ENTRY_NOT_FOUND, true);
539 InitTest1Paths(relVeryBadLink2, B_ENTRY_NOT_FOUND, true);
540 InitTest1Paths(relVeryBadLink3, B_ENTRY_NOT_FOUND, true);
541 InitTest1Paths(relVeryBadLink4, B_ENTRY_NOT_FOUND, true);
542 // R5: returns E2BIG instead of B_NAME_TOO_LONG
543 InitTest1Paths(tooLongEntry1, fuzzy_error(E2BIG, B_NAME_TOO_LONG), true);
544 // R5: returns B_ERROR instead of B_NAME_TOO_LONG
545 InitTest1Paths(tooLongDir16, fuzzy_error(B_ERROR, B_NAME_TOO_LONG), true);
546
547 // special cases (root dir)
548 NextSubTest();
549 {
550 BEntry entry("/");
551 CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
552 }
553 // special cases (fs root dir)
554 NextSubTest();
555 {
556 BEntry entry("/boot");
557 CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
558 }
559 // bad args
560 NextSubTest();
561 {
562 BEntry entry((const char*)NULL);
563 CPPUNIT_ASSERT( entry.InitCheck() == B_BAD_VALUE );
564 }
565
566 // 3. BEntry(const entry_ref *, bool)
567 // don't traverse
568 InitTest1Refs(dir1, B_OK);
569 InitTest1Refs(dir2, B_OK);
570 InitTest1Refs(file1, B_OK);
571 InitTest1Refs(subDir1, B_OK);
572 InitTest1Refs(abstractEntry1, B_OK);
573 InitTest1Refs(absDirLink1, B_OK);
574 InitTest1Refs(absDirLink2, B_OK);
575 InitTest1Refs(absDirLink3, B_OK);
576 InitTest1Refs(absDirLink4, B_OK);
577 InitTest1Refs(relDirLink1, B_OK);
578 InitTest1Refs(relDirLink2, B_OK);
579 InitTest1Refs(relDirLink3, B_OK);
580 InitTest1Refs(relDirLink4, B_OK);
581 InitTest1Refs(absFileLink1, B_OK);
582 InitTest1Refs(absFileLink2, B_OK);
583 InitTest1Refs(absFileLink3, B_OK);
584 InitTest1Refs(absFileLink4, B_OK);
585 InitTest1Refs(relFileLink1, B_OK);
586 InitTest1Refs(relFileLink2, B_OK);
587 InitTest1Refs(relFileLink3, B_OK);
588 InitTest1Refs(relFileLink4, B_OK);
589 InitTest1Refs(absCyclicLink1, B_OK);
590 InitTest1Refs(relCyclicLink1, B_OK);
591 InitTest1Refs(absBadLink1, B_OK);
592 InitTest1Refs(absBadLink2, B_OK);
593 InitTest1Refs(absBadLink3, B_OK);
594 InitTest1Refs(absBadLink4, B_OK);
595 InitTest1Refs(relBadLink1, B_OK);
596 InitTest1Refs(relBadLink2, B_OK);
597 InitTest1Refs(relBadLink3, B_OK);
598 InitTest1Refs(relBadLink4, B_OK);
599 InitTest1Refs(absVeryBadLink1, B_OK);
600 InitTest1Refs(absVeryBadLink2, B_OK);
601 InitTest1Refs(absVeryBadLink3, B_OK);
602 InitTest1Refs(absVeryBadLink4, B_OK);
603 InitTest1Refs(relVeryBadLink1, B_OK);
604 InitTest1Refs(relVeryBadLink2, B_OK);
605 InitTest1Refs(relVeryBadLink3, B_OK);
606 InitTest1Refs(relVeryBadLink4, B_OK);
607 // traverse
608 InitTest1Refs(dir1, B_OK, true);
609 InitTest1Refs(dir2, B_OK, true);
610 InitTest1Refs(file1, B_OK, true);
611 InitTest1Refs(subDir1, B_OK, true);
612 InitTest1Refs(abstractEntry1, B_OK, true);
613 InitTest1Refs(absDirLink1, B_OK, true);
614 InitTest1Refs(absDirLink2, B_OK, true);
615 InitTest1Refs(absDirLink3, B_OK, true);
616 InitTest1Refs(absDirLink4, B_OK, true);
617 InitTest1Refs(relDirLink1, B_OK, true);
618 InitTest1Refs(relDirLink2, B_OK, true);
619 InitTest1Refs(relDirLink3, B_OK, true);
620 InitTest1Refs(relDirLink4, B_OK, true);
621 InitTest1Refs(absFileLink1, B_OK, true);
622 InitTest1Refs(absFileLink2, B_OK, true);
623 InitTest1Refs(absFileLink3, B_OK, true);
624 InitTest1Refs(absFileLink4, B_OK, true);
625 InitTest1Refs(relFileLink1, B_OK, true);
626 InitTest1Refs(relFileLink2, B_OK, true);
627 InitTest1Refs(relFileLink3, B_OK, true);
628 InitTest1Refs(relFileLink4, B_OK, true);
629 InitTest1Refs(absCyclicLink1, B_LINK_LIMIT, true);
630 InitTest1Refs(relCyclicLink1, B_LINK_LIMIT, true);
631 InitTest1Refs(absBadLink1, B_ENTRY_NOT_FOUND, true);
632 InitTest1Refs(absBadLink2, B_ENTRY_NOT_FOUND, true);
633 InitTest1Refs(absBadLink3, B_ENTRY_NOT_FOUND, true);
634 InitTest1Refs(absBadLink4, B_ENTRY_NOT_FOUND, true);
635 InitTest1Refs(relBadLink1, B_ENTRY_NOT_FOUND, true);
636 InitTest1Refs(relBadLink2, B_ENTRY_NOT_FOUND, true);
637 InitTest1Refs(relBadLink3, B_ENTRY_NOT_FOUND, true);
638 InitTest1Refs(relBadLink4, B_ENTRY_NOT_FOUND, true);
639 InitTest1Refs(absVeryBadLink1, B_ENTRY_NOT_FOUND, true);
640 InitTest1Refs(absVeryBadLink2, B_ENTRY_NOT_FOUND, true);
641 InitTest1Refs(absVeryBadLink3, B_ENTRY_NOT_FOUND, true);
642 InitTest1Refs(absVeryBadLink4, B_ENTRY_NOT_FOUND, true);
643 InitTest1Refs(relVeryBadLink1, B_ENTRY_NOT_FOUND, true);
644 InitTest1Refs(relVeryBadLink2, B_ENTRY_NOT_FOUND, true);
645 InitTest1Refs(relVeryBadLink3, B_ENTRY_NOT_FOUND, true);
646 InitTest1Refs(relVeryBadLink4, B_ENTRY_NOT_FOUND, true);
647 // bad args
648 NextSubTest();
649 {
650 BEntry entry((const entry_ref*)NULL);
651 CPPUNIT_ASSERT( entry.InitCheck() == B_BAD_VALUE );
652 }
653
654 // 4. BEntry(const BDirectory *, const char *, bool)
655 // don't traverse
656 InitTest1DirPaths(dir1, B_OK);
657 InitTest1DirPaths(dir2, B_OK);
658 InitTest1DirPaths(file1, B_OK);
659 InitTest1DirPaths(subDir1, B_OK);
660 InitTest1DirPaths(abstractEntry1, B_OK);
661 InitTest1DirPaths(badEntry1, B_ENTRY_NOT_FOUND);
662 InitTest1DirPaths(absDirLink1, B_OK);
663 InitTest1DirPaths(absDirLink2, B_OK);
664 InitTest1DirPaths(absDirLink3, B_OK);
665 InitTest1DirPaths(absDirLink4, B_OK);
666 InitTest1DirPaths(relDirLink1, B_OK);
667 InitTest1DirPaths(relDirLink2, B_OK);
668 InitTest1DirPaths(relDirLink3, B_OK);
669 InitTest1DirPaths(relDirLink4, B_OK);
670 InitTest1DirPaths(absFileLink1, B_OK);
671 InitTest1DirPaths(absFileLink2, B_OK);
672 InitTest1DirPaths(absFileLink3, B_OK);
673 InitTest1DirPaths(absFileLink4, B_OK);
674 InitTest1DirPaths(relFileLink1, B_OK);
675 InitTest1DirPaths(relFileLink2, B_OK);
676 InitTest1DirPaths(relFileLink3, B_OK);
677 InitTest1DirPaths(relFileLink4, B_OK);
678 InitTest1DirPaths(absCyclicLink1, B_OK);
679 InitTest1DirPaths(relCyclicLink1, B_OK);
680 InitTest1DirPaths(absBadLink1, B_OK);
681 InitTest1DirPaths(absBadLink2, B_OK);
682 InitTest1DirPaths(absBadLink3, B_OK);
683 InitTest1DirPaths(absBadLink4, B_OK);
684 InitTest1DirPaths(relBadLink1, B_OK);
685 InitTest1DirPaths(relBadLink2, B_OK);
686 InitTest1DirPaths(relBadLink3, B_OK);
687 InitTest1DirPaths(relBadLink4, B_OK);
688 InitTest1DirPaths(absVeryBadLink1, B_OK);
689 InitTest1DirPaths(absVeryBadLink2, B_OK);
690 InitTest1DirPaths(absVeryBadLink3, B_OK);
691 InitTest1DirPaths(absVeryBadLink4, B_OK);
692 InitTest1DirPaths(relVeryBadLink1, B_OK);
693 InitTest1DirPaths(relVeryBadLink2, B_OK);
694 InitTest1DirPaths(relVeryBadLink3, B_OK);
695 InitTest1DirPaths(relVeryBadLink4, B_OK);
696 // R5: returns E2BIG instead of B_NAME_TOO_LONG
697 InitTest1DirPaths(tooLongEntry1, fuzzy_error(E2BIG, B_NAME_TOO_LONG));
698 // Haiku: Fails, because the implementation concatenates the dir and leaf
699 // name.
700 #if !TEST_OBOS /* !!!POSIX ONLY!!! */
701 InitTest1DirPaths(tooLongDir16, B_OK, true);
702 #endif
703 // traverse
704 InitTest1DirPaths(dir1, B_OK, true);
705 InitTest1DirPaths(dir2, B_OK, true);
706 InitTest1DirPaths(file1, B_OK, true);
707 InitTest1DirPaths(subDir1, B_OK, true);
708 InitTest1DirPaths(abstractEntry1, B_OK, true);
709 InitTest1DirPaths(badEntry1, B_ENTRY_NOT_FOUND, true);
710 InitTest1DirPaths(absDirLink1, B_OK, true);
711 InitTest1DirPaths(absDirLink2, B_OK, true);
712 InitTest1DirPaths(absDirLink3, B_OK, true);
713 InitTest1DirPaths(absDirLink4, B_OK, true);
714 InitTest1DirPaths(relDirLink1, B_OK, true);
715 InitTest1DirPaths(relDirLink2, B_OK, true);
716 InitTest1DirPaths(relDirLink3, B_OK, true);
717 InitTest1DirPaths(relDirLink4, B_OK, true);
718 InitTest1DirPaths(absFileLink1, B_OK, true);
719 InitTest1DirPaths(absFileLink2, B_OK, true);
720 InitTest1DirPaths(absFileLink3, B_OK, true);
721 InitTest1DirPaths(absFileLink4, B_OK, true);
722 InitTest1DirPaths(relFileLink1, B_OK, true);
723 InitTest1DirPaths(relFileLink2, B_OK, true);
724 InitTest1DirPaths(relFileLink3, B_OK, true);
725 InitTest1DirPaths(relFileLink4, B_OK, true);
726 InitTest1DirPaths(absCyclicLink1, B_LINK_LIMIT, true);
727 InitTest1DirPaths(relCyclicLink1, B_LINK_LIMIT, true);
728 InitTest1DirPaths(absBadLink1, B_ENTRY_NOT_FOUND, true);
729 InitTest1DirPaths(absBadLink2, B_ENTRY_NOT_FOUND, true);
730 InitTest1DirPaths(absBadLink3, B_ENTRY_NOT_FOUND, true);
731 InitTest1DirPaths(absBadLink4, B_ENTRY_NOT_FOUND, true);
732 InitTest1DirPaths(relBadLink1, B_ENTRY_NOT_FOUND, true);
733 InitTest1DirPaths(relBadLink2, B_ENTRY_NOT_FOUND, true);
734 InitTest1DirPaths(relBadLink3, B_ENTRY_NOT_FOUND, true);
735 InitTest1DirPaths(relBadLink4, B_ENTRY_NOT_FOUND, true);
736 InitTest1DirPaths(absVeryBadLink1, B_ENTRY_NOT_FOUND, true);
737 InitTest1DirPaths(absVeryBadLink2, B_ENTRY_NOT_FOUND, true);
738 InitTest1DirPaths(absVeryBadLink3, B_ENTRY_NOT_FOUND, true);
739 InitTest1DirPaths(absVeryBadLink4, B_ENTRY_NOT_FOUND, true);
740 InitTest1DirPaths(relVeryBadLink1, B_ENTRY_NOT_FOUND, true);
741 InitTest1DirPaths(relVeryBadLink2, B_ENTRY_NOT_FOUND, true);
742 InitTest1DirPaths(relVeryBadLink3, B_ENTRY_NOT_FOUND, true);
743 InitTest1DirPaths(relVeryBadLink4, B_ENTRY_NOT_FOUND, true);
744 // R5: returns E2BIG instead of B_NAME_TOO_LONG
745 InitTest1DirPaths(tooLongEntry1, fuzzy_error(E2BIG, B_NAME_TOO_LONG), true);
746 // Haiku: Fails, because the implementation concatenates the dir and leaf
747 // name.
748 #if !TEST_OBOS /* !!!POSIX ONLY!!! */
749 InitTest1DirPaths(tooLongDir16, B_OK, true);
750 #endif
751
752 // special cases (root dir)
753 NextSubTest();
754 {
755 BDirectory dir("/");
756 BEntry entry(&dir, ".");
757 CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
758 }
759 // special cases (fs root dir)
760 NextSubTest();
761 {
762 BDirectory dir("/");
763 BEntry entry(&dir, "boot");
764 CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
765 }
766 // NULL path
767 NextSubTest();
768 {
769 BDirectory dir("/");
770 BEntry entry(&dir, (const char*)NULL);
771 CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
772 }
773 // bad args (NULL dir)
774 // R5: crashs
775 #if !TEST_R5
776 NextSubTest();
777 {
778 chdir("/");
779 BEntry entry((const BDirectory*)NULL, "tmp");
780 CPPUNIT_ASSERT( entry.InitCheck() == B_BAD_VALUE );
781 RestoreCWD();
782 }
783 #endif
784 // strange args (badly initialized dir, absolute path)
785 NextSubTest();
786 {
787 BDirectory dir(badEntry1.cpath);
788 CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
789 BEntry entry(&dir, "/tmp");
790 CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
791 }
792 // bad args (NULL dir and path)
793 // R5: crashs
794 #if !TEST_R5
795 NextSubTest();
796 {
797 BEntry entry((const BDirectory*)NULL, (const char*)NULL);
798 CPPUNIT_ASSERT( entry.InitCheck() == B_BAD_VALUE );
799 }
800 #endif
801 // bad args(NULL dir, absolute path)
802 // R5: crashs
803 #if !TEST_R5
804 NextSubTest();
805 {
806 BEntry entry((const BDirectory*)NULL, "/tmp");
807 CPPUNIT_ASSERT( entry.InitCheck() == B_BAD_VALUE );
808 }
809 #endif
810 }
811
812 // InitTest2Paths
813 void
InitTest2Paths(TestEntry & _testEntry,status_t error,bool traverse)814 EntryTest::InitTest2Paths(TestEntry &_testEntry, status_t error, bool traverse)
815 {
816 TestEntry *testEntry = &_testEntry;
817 BEntry entry;
818 // absolute path
819 NextSubTest();
820 {
821 //printf("%s\n", testEntry->cpath);
822 status_t result = entry.SetTo(testEntry->cpath, traverse);
823 if (!fuzzy_equals(result, error))
824 printf("error: %lx (%lx)\n", result, error);
825 CPPUNIT_ASSERT( fuzzy_equals(result, error) );
826 CPPUNIT_ASSERT( fuzzy_equals(entry.InitCheck(), error) );
827 if (result == B_OK)
828 examine_entry(entry, testEntry, traverse);
829 }
830 // relative path
831 NextSubTest();
832 {
833 //printf("%s\n", testEntry->cpath);
834 if (chdir(testEntry->super->cpath) == 0) {
835 status_t result = entry.SetTo(testEntry->cname, traverse);
836 if (!fuzzy_equals(result, error))
837 printf("error: %lx (%lx)\n", result, error);
838 CPPUNIT_ASSERT( fuzzy_equals(result, error) );
839 CPPUNIT_ASSERT( fuzzy_equals(entry.InitCheck(), error) );
840 if (result == B_OK)
841 examine_entry(entry, testEntry, traverse);
842 RestoreCWD();
843 }
844 }
845 }
846
847 // InitTest2Refs
848 void
InitTest2Refs(TestEntry & _testEntry,status_t error,bool traverse)849 EntryTest::InitTest2Refs(TestEntry &_testEntry, status_t error, bool traverse)
850 {
851 TestEntry *testEntry = &_testEntry;
852 BEntry entry;
853 // absolute path
854 NextSubTest();
855 {
856 //printf("%s\n", testEntry->cpath);
857 status_t result = entry.SetTo(&testEntry->get_ref(), traverse);
858 if (!fuzzy_equals(result, error))
859 printf("error: %lx (%lx)\n", result, error);
860 CPPUNIT_ASSERT( fuzzy_equals(result, error) );
861 CPPUNIT_ASSERT( fuzzy_equals(entry.InitCheck(), error) );
862 if (result == B_OK)
863 examine_entry(entry, testEntry, traverse);
864 }
865 }
866
867 // InitTest2DirPaths
868 void
InitTest2DirPaths(TestEntry & _testEntry,status_t error,bool traverse)869 EntryTest::InitTest2DirPaths(TestEntry &_testEntry, status_t error,
870 bool traverse)
871 {
872 TestEntry *testEntry = &_testEntry;
873 BEntry entry;
874 // absolute path
875 NextSubTest();
876 {
877 if (!testEntry->isBad()
878 && testEntry->path.length() < B_PATH_NAME_LENGTH) {
879 //printf("%s\n", testEntry->cpath);
880 BDirectory dir("/boot/home/Desktop");
881 CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
882 status_t result = entry.SetTo(&dir, testEntry->cpath, traverse);
883 if (!fuzzy_equals(result, error))
884 printf("error: %lx (%lx)\n", result, error);
885 CPPUNIT_ASSERT( fuzzy_equals(result, error) );
886 CPPUNIT_ASSERT( fuzzy_equals(entry.InitCheck(), error) );
887 if (result == B_OK)
888 examine_entry(entry, testEntry, traverse);
889 }
890 }
891 // relative path (one level)
892 NextSubTest();
893 {
894 if (!testEntry->isBad()
895 && testEntry->super->path.length() < B_PATH_NAME_LENGTH) {
896 //printf("%s + %s\n", testEntry->super->cpath, testEntry->cname);
897 BDirectory dir(testEntry->super->cpath);
898 CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
899 status_t result = entry.SetTo(&dir, testEntry->cname, traverse);
900 if (!fuzzy_equals(result, error))
901 printf("error: %lx (%lx)\n", result, error);
902 CPPUNIT_ASSERT( fuzzy_equals(result, error) );
903 CPPUNIT_ASSERT( fuzzy_equals(entry.InitCheck(), error) );
904 if (result == B_OK)
905 examine_entry(entry, testEntry, traverse);
906 }
907 }
908 // relative path (two levels)
909 NextSubTest();
910 {
911 if (!testEntry->super->isBad() && !testEntry->super->super->isBad()) {
912 string entryName = testEntry->super->name + "/" + testEntry->name;
913 //printf("%s + %s\n", testEntry->super->super->cpath, entryName.c_str());
914 BDirectory dir(testEntry->super->super->cpath);
915 CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
916 status_t result = entry.SetTo(&dir, entryName.c_str(), traverse);
917 if (!fuzzy_equals(result, error))
918 printf("error: %lx (%lx)\n", result, error);
919 CPPUNIT_ASSERT( fuzzy_equals(result, error) );
920 CPPUNIT_ASSERT( fuzzy_equals(entry.InitCheck(), error) );
921 if (result == B_OK)
922 examine_entry(entry, testEntry, traverse);
923 }
924 }
925 }
926
927 // InitTest2
928 void
InitTest2()929 EntryTest::InitTest2()
930 {
931 BEntry entry;
932 // 2. SetTo(const char *, bool)
933 // don't traverse
934 InitTest2Paths(dir1, B_OK);
935 InitTest2Paths(dir2, B_OK);
936 InitTest2Paths(file1, B_OK);
937 InitTest2Paths(subDir1, B_OK);
938 InitTest2Paths(abstractEntry1, B_OK);
939 InitTest2Paths(badEntry1, B_ENTRY_NOT_FOUND);
940 InitTest2Paths(absDirLink1, B_OK);
941 InitTest2Paths(absDirLink2, B_OK);
942 InitTest2Paths(absDirLink3, B_OK);
943 InitTest2Paths(absDirLink4, B_OK);
944 InitTest2Paths(relDirLink1, B_OK);
945 InitTest2Paths(relDirLink2, B_OK);
946 InitTest2Paths(relDirLink3, B_OK);
947 InitTest2Paths(relDirLink4, B_OK);
948 InitTest2Paths(absFileLink1, B_OK);
949 InitTest2Paths(absFileLink2, B_OK);
950 InitTest2Paths(absFileLink3, B_OK);
951 InitTest2Paths(absFileLink4, B_OK);
952 InitTest2Paths(relFileLink1, B_OK);
953 InitTest2Paths(relFileLink2, B_OK);
954 InitTest2Paths(relFileLink3, B_OK);
955 InitTest2Paths(relFileLink4, B_OK);
956 InitTest2Paths(absCyclicLink1, B_OK);
957 InitTest2Paths(relCyclicLink1, B_OK);
958 InitTest2Paths(absBadLink1, B_OK);
959 InitTest2Paths(absBadLink2, B_OK);
960 InitTest2Paths(absBadLink3, B_OK);
961 InitTest2Paths(absBadLink4, B_OK);
962 InitTest2Paths(relBadLink1, B_OK);
963 InitTest2Paths(relBadLink2, B_OK);
964 InitTest2Paths(relBadLink3, B_OK);
965 InitTest2Paths(relBadLink4, B_OK);
966 InitTest2Paths(absVeryBadLink1, B_OK);
967 InitTest2Paths(absVeryBadLink2, B_OK);
968 InitTest2Paths(absVeryBadLink3, B_OK);
969 InitTest2Paths(absVeryBadLink4, B_OK);
970 InitTest2Paths(relVeryBadLink1, B_OK);
971 InitTest2Paths(relVeryBadLink2, B_OK);
972 InitTest2Paths(relVeryBadLink3, B_OK);
973 InitTest2Paths(relVeryBadLink4, B_OK);
974 // R5: returns E2BIG instead of B_NAME_TOO_LONG
975 InitTest2Paths(tooLongEntry1, fuzzy_error(E2BIG, B_NAME_TOO_LONG));
976 // R5: returns B_ERROR instead of B_NAME_TOO_LONG
977 InitTest2Paths(tooLongDir16, fuzzy_error(B_ERROR, B_NAME_TOO_LONG));
978 // traverse
979 InitTest2Paths(dir1, B_OK, true);
980 InitTest2Paths(dir2, B_OK, true);
981 InitTest2Paths(file1, B_OK, true);
982 InitTest2Paths(subDir1, B_OK, true);
983 InitTest2Paths(abstractEntry1, B_OK, true);
984 InitTest2Paths(badEntry1, B_ENTRY_NOT_FOUND, true);
985 InitTest2Paths(absDirLink1, B_OK, true);
986 InitTest2Paths(absDirLink2, B_OK, true);
987 InitTest2Paths(absDirLink3, B_OK, true);
988 InitTest2Paths(absDirLink4, B_OK, true);
989 InitTest2Paths(relDirLink1, B_OK, true);
990 InitTest2Paths(relDirLink2, B_OK, true);
991 InitTest2Paths(relDirLink3, B_OK, true);
992 InitTest2Paths(relDirLink4, B_OK, true);
993 InitTest2Paths(absFileLink1, B_OK, true);
994 InitTest2Paths(absFileLink2, B_OK, true);
995 InitTest2Paths(absFileLink3, B_OK, true);
996 InitTest2Paths(absFileLink4, B_OK, true);
997 InitTest2Paths(relFileLink1, B_OK, true);
998 InitTest2Paths(relFileLink2, B_OK, true);
999 InitTest2Paths(relFileLink3, B_OK, true);
1000 InitTest2Paths(relFileLink4, B_OK, true);
1001 InitTest2Paths(absCyclicLink1, B_LINK_LIMIT, true);
1002 InitTest2Paths(relCyclicLink1, B_LINK_LIMIT, true);
1003 InitTest2Paths(absBadLink1, B_ENTRY_NOT_FOUND, true);
1004 InitTest2Paths(absBadLink2, B_ENTRY_NOT_FOUND, true);
1005 InitTest2Paths(absBadLink3, B_ENTRY_NOT_FOUND, true);
1006 InitTest2Paths(absBadLink4, B_ENTRY_NOT_FOUND, true);
1007 InitTest2Paths(relBadLink1, B_ENTRY_NOT_FOUND, true);
1008 InitTest2Paths(relBadLink2, B_ENTRY_NOT_FOUND, true);
1009 InitTest2Paths(relBadLink3, B_ENTRY_NOT_FOUND, true);
1010 InitTest2Paths(relBadLink4, B_ENTRY_NOT_FOUND, true);
1011 InitTest2Paths(absVeryBadLink1, B_ENTRY_NOT_FOUND, true);
1012 InitTest2Paths(absVeryBadLink2, B_ENTRY_NOT_FOUND, true);
1013 InitTest2Paths(absVeryBadLink3, B_ENTRY_NOT_FOUND, true);
1014 InitTest2Paths(absVeryBadLink4, B_ENTRY_NOT_FOUND, true);
1015 InitTest2Paths(relVeryBadLink1, B_ENTRY_NOT_FOUND, true);
1016 InitTest2Paths(relVeryBadLink2, B_ENTRY_NOT_FOUND, true);
1017 InitTest2Paths(relVeryBadLink3, B_ENTRY_NOT_FOUND, true);
1018 InitTest2Paths(relVeryBadLink4, B_ENTRY_NOT_FOUND, true);
1019 // R5: returns E2BIG instead of B_NAME_TOO_LONG
1020 InitTest2Paths(tooLongEntry1, fuzzy_error(E2BIG, B_NAME_TOO_LONG), true);
1021 // R5: returns B_ERROR instead of B_NAME_TOO_LONG
1022 InitTest2Paths(tooLongDir16, fuzzy_error(B_ERROR, B_NAME_TOO_LONG), true);
1023 // special cases (root dir)
1024 NextSubTest();
1025 CPPUNIT_ASSERT( entry.SetTo("/") == B_OK );
1026 CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1027 entry.Unset();
1028 // special cases (fs root dir)
1029 NextSubTest();
1030 CPPUNIT_ASSERT( entry.SetTo("/boot") == B_OK );
1031 CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1032 entry.Unset();
1033 // bad args
1034 NextSubTest();
1035 CPPUNIT_ASSERT( entry.SetTo((const char*)NULL) == B_BAD_VALUE );
1036 CPPUNIT_ASSERT( entry.InitCheck() == B_BAD_VALUE );
1037 entry.Unset();
1038
1039 // 3. BEntry(const entry_ref *, bool)
1040 // don't traverse
1041 InitTest2Refs(dir1, B_OK);
1042 InitTest2Refs(dir2, B_OK);
1043 InitTest2Refs(file1, B_OK);
1044 InitTest2Refs(subDir1, B_OK);
1045 InitTest2Refs(abstractEntry1, B_OK);
1046 InitTest2Refs(absDirLink1, B_OK);
1047 InitTest2Refs(absDirLink2, B_OK);
1048 InitTest2Refs(absDirLink3, B_OK);
1049 InitTest2Refs(absDirLink4, B_OK);
1050 InitTest2Refs(relDirLink1, B_OK);
1051 InitTest2Refs(relDirLink2, B_OK);
1052 InitTest2Refs(relDirLink3, B_OK);
1053 InitTest2Refs(relDirLink4, B_OK);
1054 InitTest2Refs(absFileLink1, B_OK);
1055 InitTest2Refs(absFileLink2, B_OK);
1056 InitTest2Refs(absFileLink3, B_OK);
1057 InitTest2Refs(absFileLink4, B_OK);
1058 InitTest2Refs(relFileLink1, B_OK);
1059 InitTest2Refs(relFileLink2, B_OK);
1060 InitTest2Refs(relFileLink3, B_OK);
1061 InitTest2Refs(relFileLink4, B_OK);
1062 InitTest2Refs(absCyclicLink1, B_OK);
1063 InitTest2Refs(relCyclicLink1, B_OK);
1064 InitTest2Refs(absBadLink1, B_OK);
1065 InitTest2Refs(absBadLink2, B_OK);
1066 InitTest2Refs(absBadLink3, B_OK);
1067 InitTest2Refs(absBadLink4, B_OK);
1068 InitTest2Refs(relBadLink1, B_OK);
1069 InitTest2Refs(relBadLink2, B_OK);
1070 InitTest2Refs(relBadLink3, B_OK);
1071 InitTest2Refs(relBadLink4, B_OK);
1072 InitTest2Refs(absVeryBadLink1, B_OK);
1073 InitTest2Refs(absVeryBadLink2, B_OK);
1074 InitTest2Refs(absVeryBadLink3, B_OK);
1075 InitTest2Refs(absVeryBadLink4, B_OK);
1076 InitTest2Refs(relVeryBadLink1, B_OK);
1077 InitTest2Refs(relVeryBadLink2, B_OK);
1078 InitTest2Refs(relVeryBadLink3, B_OK);
1079 InitTest2Refs(relVeryBadLink4, B_OK);
1080 // traverse
1081 InitTest2Refs(dir1, B_OK, true);
1082 InitTest2Refs(dir2, B_OK, true);
1083 InitTest2Refs(file1, B_OK, true);
1084 InitTest2Refs(subDir1, B_OK, true);
1085 InitTest2Refs(abstractEntry1, B_OK, true);
1086 InitTest2Refs(absDirLink1, B_OK, true);
1087 InitTest2Refs(absDirLink2, B_OK, true);
1088 InitTest2Refs(absDirLink3, B_OK, true);
1089 InitTest2Refs(absDirLink4, B_OK, true);
1090 InitTest2Refs(relDirLink1, B_OK, true);
1091 InitTest2Refs(relDirLink2, B_OK, true);
1092 InitTest2Refs(relDirLink3, B_OK, true);
1093 InitTest2Refs(relDirLink4, B_OK, true);
1094 InitTest2Refs(absFileLink1, B_OK, true);
1095 InitTest2Refs(absFileLink2, B_OK, true);
1096 InitTest2Refs(absFileLink3, B_OK, true);
1097 InitTest2Refs(absFileLink4, B_OK, true);
1098 InitTest2Refs(relFileLink1, B_OK, true);
1099 InitTest2Refs(relFileLink2, B_OK, true);
1100 InitTest2Refs(relFileLink3, B_OK, true);
1101 InitTest2Refs(relFileLink4, B_OK, true);
1102 InitTest2Refs(absCyclicLink1, B_LINK_LIMIT, true);
1103 InitTest2Refs(relCyclicLink1, B_LINK_LIMIT, true);
1104 InitTest2Refs(absBadLink1, B_ENTRY_NOT_FOUND, true);
1105 InitTest2Refs(absBadLink2, B_ENTRY_NOT_FOUND, true);
1106 InitTest2Refs(absBadLink3, B_ENTRY_NOT_FOUND, true);
1107 InitTest2Refs(absBadLink4, B_ENTRY_NOT_FOUND, true);
1108 InitTest2Refs(relBadLink1, B_ENTRY_NOT_FOUND, true);
1109 InitTest2Refs(relBadLink2, B_ENTRY_NOT_FOUND, true);
1110 InitTest2Refs(relBadLink3, B_ENTRY_NOT_FOUND, true);
1111 InitTest2Refs(relBadLink4, B_ENTRY_NOT_FOUND, true);
1112 InitTest2Refs(absVeryBadLink1, B_ENTRY_NOT_FOUND, true);
1113 InitTest2Refs(absVeryBadLink2, B_ENTRY_NOT_FOUND, true);
1114 InitTest2Refs(absVeryBadLink3, B_ENTRY_NOT_FOUND, true);
1115 InitTest2Refs(absVeryBadLink4, B_ENTRY_NOT_FOUND, true);
1116 InitTest2Refs(relVeryBadLink1, B_ENTRY_NOT_FOUND, true);
1117 InitTest2Refs(relVeryBadLink2, B_ENTRY_NOT_FOUND, true);
1118 InitTest2Refs(relVeryBadLink3, B_ENTRY_NOT_FOUND, true);
1119 InitTest2Refs(relVeryBadLink4, B_ENTRY_NOT_FOUND, true);
1120 // bad args
1121 NextSubTest();
1122 CPPUNIT_ASSERT( entry.SetTo((const entry_ref*)NULL) == B_BAD_VALUE );
1123 CPPUNIT_ASSERT( entry.InitCheck() == B_BAD_VALUE );
1124 entry.Unset();
1125
1126 // 4. BEntry(const BDirectory *, const char *, bool)
1127 // don't traverse
1128 InitTest2DirPaths(dir1, B_OK);
1129 InitTest2DirPaths(dir2, B_OK);
1130 InitTest2DirPaths(file1, B_OK);
1131 InitTest2DirPaths(subDir1, B_OK);
1132 InitTest2DirPaths(abstractEntry1, B_OK);
1133 InitTest2DirPaths(badEntry1, B_ENTRY_NOT_FOUND);
1134 InitTest2DirPaths(absDirLink1, B_OK);
1135 InitTest2DirPaths(absDirLink2, B_OK);
1136 InitTest2DirPaths(absDirLink3, B_OK);
1137 InitTest2DirPaths(absDirLink4, B_OK);
1138 InitTest2DirPaths(relDirLink1, B_OK);
1139 InitTest2DirPaths(relDirLink2, B_OK);
1140 InitTest2DirPaths(relDirLink3, B_OK);
1141 InitTest2DirPaths(relDirLink4, B_OK);
1142 InitTest2DirPaths(absFileLink1, B_OK);
1143 InitTest2DirPaths(absFileLink2, B_OK);
1144 InitTest2DirPaths(absFileLink3, B_OK);
1145 InitTest2DirPaths(absFileLink4, B_OK);
1146 InitTest2DirPaths(relFileLink1, B_OK);
1147 InitTest2DirPaths(relFileLink2, B_OK);
1148 InitTest2DirPaths(relFileLink3, B_OK);
1149 InitTest2DirPaths(relFileLink4, B_OK);
1150 InitTest2DirPaths(absCyclicLink1, B_OK);
1151 InitTest2DirPaths(relCyclicLink1, B_OK);
1152 InitTest2DirPaths(absBadLink1, B_OK);
1153 InitTest2DirPaths(absBadLink2, B_OK);
1154 InitTest2DirPaths(absBadLink3, B_OK);
1155 InitTest2DirPaths(absBadLink4, B_OK);
1156 InitTest2DirPaths(relBadLink1, B_OK);
1157 InitTest2DirPaths(relBadLink2, B_OK);
1158 InitTest2DirPaths(relBadLink3, B_OK);
1159 InitTest2DirPaths(relBadLink4, B_OK);
1160 InitTest2DirPaths(absVeryBadLink1, B_OK);
1161 InitTest2DirPaths(absVeryBadLink2, B_OK);
1162 InitTest2DirPaths(absVeryBadLink3, B_OK);
1163 InitTest2DirPaths(absVeryBadLink4, B_OK);
1164 InitTest2DirPaths(relVeryBadLink1, B_OK);
1165 InitTest2DirPaths(relVeryBadLink2, B_OK);
1166 InitTest2DirPaths(relVeryBadLink3, B_OK);
1167 InitTest2DirPaths(relVeryBadLink4, B_OK);
1168 // R5: returns E2BIG instead of B_NAME_TOO_LONG
1169 InitTest2DirPaths(tooLongEntry1, fuzzy_error(E2BIG, B_NAME_TOO_LONG));
1170 // Haiku: Fails, because the implementation concatenates the dir and leaf
1171 // name.
1172 #if !TEST_OBOS /* !!!POSIX ONLY!!! */
1173 InitTest2DirPaths(tooLongDir16, B_OK, true);
1174 #endif
1175 // traverse
1176 InitTest2DirPaths(dir1, B_OK, true);
1177 InitTest2DirPaths(dir2, B_OK, true);
1178 InitTest2DirPaths(file1, B_OK, true);
1179 InitTest2DirPaths(subDir1, B_OK, true);
1180 InitTest2DirPaths(abstractEntry1, B_OK, true);
1181 InitTest2DirPaths(badEntry1, B_ENTRY_NOT_FOUND, true);
1182 InitTest2DirPaths(absDirLink1, B_OK, true);
1183 InitTest2DirPaths(absDirLink2, B_OK, true);
1184 InitTest2DirPaths(absDirLink3, B_OK, true);
1185 InitTest2DirPaths(absDirLink4, B_OK, true);
1186 InitTest2DirPaths(relDirLink1, B_OK, true);
1187 InitTest2DirPaths(relDirLink2, B_OK, true);
1188 InitTest2DirPaths(relDirLink3, B_OK, true);
1189 InitTest2DirPaths(relDirLink4, B_OK, true);
1190 InitTest2DirPaths(absFileLink1, B_OK, true);
1191 InitTest2DirPaths(absFileLink2, B_OK, true);
1192 InitTest2DirPaths(absFileLink3, B_OK, true);
1193 InitTest2DirPaths(absFileLink4, B_OK, true);
1194 InitTest2DirPaths(relFileLink1, B_OK, true);
1195 InitTest2DirPaths(relFileLink2, B_OK, true);
1196 InitTest2DirPaths(relFileLink3, B_OK, true);
1197 InitTest2DirPaths(relFileLink4, B_OK, true);
1198 InitTest2DirPaths(absCyclicLink1, B_LINK_LIMIT, true);
1199 InitTest2DirPaths(relCyclicLink1, B_LINK_LIMIT, true);
1200 InitTest2DirPaths(absBadLink1, B_ENTRY_NOT_FOUND, true);
1201 InitTest2DirPaths(absBadLink2, B_ENTRY_NOT_FOUND, true);
1202 InitTest2DirPaths(absBadLink3, B_ENTRY_NOT_FOUND, true);
1203 InitTest2DirPaths(absBadLink4, B_ENTRY_NOT_FOUND, true);
1204 InitTest2DirPaths(relBadLink1, B_ENTRY_NOT_FOUND, true);
1205 InitTest2DirPaths(relBadLink2, B_ENTRY_NOT_FOUND, true);
1206 InitTest2DirPaths(relBadLink3, B_ENTRY_NOT_FOUND, true);
1207 InitTest2DirPaths(relBadLink4, B_ENTRY_NOT_FOUND, true);
1208 InitTest2DirPaths(absVeryBadLink1, B_ENTRY_NOT_FOUND, true);
1209 InitTest2DirPaths(absVeryBadLink2, B_ENTRY_NOT_FOUND, true);
1210 InitTest2DirPaths(absVeryBadLink3, B_ENTRY_NOT_FOUND, true);
1211 InitTest2DirPaths(absVeryBadLink4, B_ENTRY_NOT_FOUND, true);
1212 InitTest2DirPaths(relVeryBadLink1, B_ENTRY_NOT_FOUND, true);
1213 InitTest2DirPaths(relVeryBadLink2, B_ENTRY_NOT_FOUND, true);
1214 InitTest2DirPaths(relVeryBadLink3, B_ENTRY_NOT_FOUND, true);
1215 InitTest2DirPaths(relVeryBadLink4, B_ENTRY_NOT_FOUND, true);
1216 // R5: returns E2BIG instead of B_NAME_TOO_LONG
1217 InitTest2DirPaths(tooLongEntry1, fuzzy_error(E2BIG, B_NAME_TOO_LONG), true);
1218 // Haiku: Fails, because the implementation concatenates the dir and leaf
1219 // name.
1220 #if !TEST_OBOS /* !!!POSIX ONLY!!! */
1221 InitTest2DirPaths(tooLongDir16, B_OK, true);
1222 #endif
1223 // special cases (root dir)
1224 NextSubTest();
1225 {
1226 BDirectory dir("/");
1227 CPPUNIT_ASSERT( entry.SetTo(&dir, ".") == B_OK );
1228 CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1229 entry.Unset();
1230 }
1231 // special cases (fs root dir)
1232 NextSubTest();
1233 {
1234 BDirectory dir("/");
1235 CPPUNIT_ASSERT( entry.SetTo(&dir, "boot") == B_OK );
1236 CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1237 entry.Unset();
1238 }
1239 // NULL path
1240 NextSubTest();
1241 {
1242 BDirectory dir("/");
1243 CPPUNIT_ASSERT( entry.SetTo(&dir, (const char*)NULL) == B_OK );
1244 CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1245 entry.Unset();
1246 }
1247 // bad args (NULL dir)
1248 // R5: crashs
1249 #if !TEST_R5
1250 NextSubTest();
1251 {
1252 chdir("/");
1253 CPPUNIT_ASSERT( entry.SetTo((const BDirectory*)NULL, "tmp")
1254 == B_BAD_VALUE );
1255 CPPUNIT_ASSERT( entry.InitCheck() == B_BAD_VALUE );
1256 RestoreCWD();
1257 entry.Unset();
1258 }
1259 #endif
1260 // strange args (badly initialized dir, absolute path)
1261 NextSubTest();
1262 {
1263 BDirectory dir(badEntry1.cpath);
1264 CPPUNIT_ASSERT( dir.InitCheck() == B_ENTRY_NOT_FOUND );
1265 CPPUNIT_ASSERT( entry.SetTo(&dir, "/tmp") == B_OK );
1266 CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
1267 }
1268 // bad args (NULL dir and path)
1269 // R5: crashs
1270 #if !TEST_R5
1271 NextSubTest();
1272 {
1273 CPPUNIT_ASSERT( entry.SetTo((const BDirectory*)NULL, (const char*)NULL)
1274 == B_BAD_VALUE );
1275 CPPUNIT_ASSERT( entry.InitCheck() == B_BAD_VALUE );
1276 entry.Unset();
1277 }
1278 #endif
1279 // bad args(NULL dir, absolute path)
1280 // R5: crashs
1281 #if !TEST_R5
1282 NextSubTest();
1283 {
1284 CPPUNIT_ASSERT( entry.SetTo((const BDirectory*)NULL, "/tmp")
1285 == B_BAD_VALUE );
1286 CPPUNIT_ASSERT( entry.InitCheck() == B_BAD_VALUE );
1287 entry.Unset();
1288 }
1289 #endif
1290 }
1291
1292 // SpecialGetCasesTest
1293 //
1294 // Tests special (mostly error) cases for Exists(), GetPath(), GetName(),
1295 // GetParent() and GetRef(). The other cases have already been tested in
1296 // InitTest1/2().
1297 void
SpecialGetCasesTest()1298 EntryTest::SpecialGetCasesTest()
1299 {
1300 BEntry entry;
1301 // 1. Exists()
1302 // uninitialized
1303 NextSubTest();
1304 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
1305 CPPUNIT_ASSERT( entry.Exists() == false );
1306 entry.Unset();
1307 // badly initialized
1308 NextSubTest();
1309 CPPUNIT_ASSERT( entry.SetTo(badEntry1.cpath) == B_ENTRY_NOT_FOUND );
1310 CPPUNIT_ASSERT( entry.Exists() == false );
1311 entry.Unset();
1312 // root
1313 NextSubTest();
1314 CPPUNIT_ASSERT( entry.SetTo("/") == B_OK );
1315 CPPUNIT_ASSERT( entry.Exists() == true );
1316 entry.Unset();
1317
1318 // 2. GetPath()
1319 BPath path;
1320 // uninitialized
1321 NextSubTest();
1322 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
1323 CPPUNIT_ASSERT( entry.GetPath(&path) == B_NO_INIT );
1324 entry.Unset();
1325 // badly initialized
1326 NextSubTest();
1327 CPPUNIT_ASSERT( entry.SetTo(badEntry1.cpath) == B_ENTRY_NOT_FOUND );
1328 CPPUNIT_ASSERT( entry.GetPath(&path) == B_NO_INIT );
1329 entry.Unset();
1330 // too long pathname
1331 // Haiku: Fails, because the implementation concatenates the dir and leaf
1332 // name.
1333 #if !TEST_OBOS /* !!!POSIX ONLY!!! */
1334 NextSubTest();
1335 BDirectory dir(tooLongDir16.super->super->cpath);
1336 string entryName = tooLongDir16.super->name + "/" + tooLongDir16.name;
1337 CPPUNIT_ASSERT( entry.SetTo(&dir, entryName.c_str()) == B_OK );
1338 CPPUNIT_ASSERT( entry.GetPath(&path) == B_OK );
1339 CPPUNIT_ASSERT( path == tooLongDir16.cpath );
1340 entry.Unset();
1341 #endif
1342
1343 // 3. GetName()
1344 char name[B_FILE_NAME_LENGTH + 1];
1345 // uninitialized
1346 NextSubTest();
1347 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
1348 CPPUNIT_ASSERT( entry.GetName(name) == B_NO_INIT );
1349 entry.Unset();
1350 // badly initialized
1351 NextSubTest();
1352 CPPUNIT_ASSERT( entry.SetTo(badEntry1.cpath) == B_ENTRY_NOT_FOUND );
1353 CPPUNIT_ASSERT( entry.GetName(name) == B_NO_INIT );
1354 entry.Unset();
1355
1356 // 4. GetParent(BEntry *)
1357 BEntry parentEntry;
1358 // uninitialized
1359 NextSubTest();
1360 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
1361 CPPUNIT_ASSERT( entry.GetParent(&parentEntry) == B_NO_INIT );
1362 entry.Unset();
1363 // badly initialized
1364 NextSubTest();
1365 CPPUNIT_ASSERT( entry.SetTo(badEntry1.cpath) == B_ENTRY_NOT_FOUND );
1366 CPPUNIT_ASSERT( entry.GetParent(&parentEntry) == B_NO_INIT );
1367 entry.Unset();
1368 // parent of root dir
1369 NextSubTest();
1370 CPPUNIT_ASSERT( entry.SetTo("/") == B_OK );
1371 CPPUNIT_ASSERT( entry.GetParent(&parentEntry) == B_ENTRY_NOT_FOUND );
1372 entry.Unset();
1373
1374 // 5. GetParent(BDirectory *)
1375 BDirectory parentDir;
1376 // uninitialized
1377 NextSubTest();
1378 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
1379 CPPUNIT_ASSERT( entry.GetParent(&parentDir) == B_NO_INIT );
1380 entry.Unset();
1381 // badly initialized
1382 NextSubTest();
1383 CPPUNIT_ASSERT( entry.SetTo(badEntry1.cpath) == B_ENTRY_NOT_FOUND );
1384 CPPUNIT_ASSERT( entry.GetParent(&parentDir) == B_NO_INIT );
1385 entry.Unset();
1386 // parent of root dir
1387 NextSubTest();
1388 CPPUNIT_ASSERT( entry.SetTo("/") == B_OK );
1389 CPPUNIT_ASSERT( entry.GetParent(&parentDir) == B_ENTRY_NOT_FOUND );
1390 entry.Unset();
1391
1392 // 6. GetRef()
1393 entry_ref ref, ref2;
1394 // uninitialized
1395 NextSubTest();
1396 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
1397 CPPUNIT_ASSERT( entry.GetRef(&ref) == B_NO_INIT );
1398 entry.Unset();
1399 // badly initialized
1400 NextSubTest();
1401 CPPUNIT_ASSERT( entry.SetTo(badEntry1.cpath) == B_ENTRY_NOT_FOUND );
1402 CPPUNIT_ASSERT( entry.GetRef(&ref) == B_NO_INIT );
1403 entry.Unset();
1404 // ref for root dir
1405 NextSubTest();
1406 CPPUNIT_ASSERT( entry.SetTo("/") == B_OK );
1407 CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
1408 entry.Unset();
1409 }
1410
1411 // RenameTestEntry
1412 void
RenameTestEntry(TestEntry * testEntry,TestEntry * newTestEntry,string newName,bool existing,bool clobber,status_t error,uint32 kind)1413 EntryTest::RenameTestEntry(TestEntry *testEntry, TestEntry *newTestEntry,
1414 string newName, bool existing, bool clobber,
1415 status_t error, uint32 kind)
1416 {
1417 NextSubTest();
1418 BEntry entry;
1419 BDirectory dir;
1420 // get all the names
1421 string pathname = testEntry->path;
1422 string dirname = testEntry->super->path;
1423 string newPathname = newTestEntry->path;
1424 //printf("path: `%s', dir: `%s', new name: `%s'\n", pathname.c_str(),
1425 //dirname.c_str(), newPathname.c_str());
1426 // create the entries
1427 switch (kind) {
1428 case B_FILE_NODE:
1429 CreateFile(pathname.c_str());
1430 break;
1431 case B_DIRECTORY_NODE:
1432 CreateDir(pathname.c_str());
1433 break;
1434 case B_SYMLINK_NODE:
1435 CreateLink(pathname.c_str(), file1.cpath);
1436 break;
1437 }
1438 if (existing)
1439 CreateFile(newPathname.c_str());
1440 // rename the file
1441 CPPUNIT_ASSERT( entry.SetTo(pathname.c_str()) == B_OK );
1442 CPPUNIT_ASSERT( dir.SetTo(dirname.c_str()) == B_OK );
1443 status_t result = entry.Rename(newName.c_str(), clobber);
1444 if (result != error) {
1445 printf("`%s'.Rename(`%s', %d): ", pathname.c_str(), newName.c_str(), clobber);
1446 printf("error: %lx (%lx)\n", result, error);
1447 }
1448 CPPUNIT_ASSERT( result == error );
1449 // check and cleanup
1450 if (error == B_OK) {
1451 switch (kind) {
1452 case B_FILE_NODE:
1453 CPPUNIT_ASSERT( !PingFile(pathname.c_str()) );
1454 CPPUNIT_ASSERT( PingFile(newPathname.c_str()) );
1455 break;
1456 case B_DIRECTORY_NODE:
1457 CPPUNIT_ASSERT( !PingDir(pathname.c_str()) );
1458 CPPUNIT_ASSERT( PingDir(newPathname.c_str()) );
1459 break;
1460 case B_SYMLINK_NODE:
1461 CPPUNIT_ASSERT( !PingLink(pathname.c_str()) );
1462 CPPUNIT_ASSERT( PingLink(newPathname.c_str(), file1.cpath) );
1463 break;
1464 }
1465 RemoveFile(newPathname.c_str());
1466 } else {
1467 switch (kind) {
1468 case B_FILE_NODE:
1469 CPPUNIT_ASSERT( PingFile(pathname.c_str()) );
1470 break;
1471 case B_DIRECTORY_NODE:
1472 CPPUNIT_ASSERT( PingDir(pathname.c_str()) );
1473 break;
1474 case B_SYMLINK_NODE:
1475 CPPUNIT_ASSERT( PingLink(pathname.c_str(), file1.cpath) );
1476 break;
1477 }
1478 if (existing) {
1479 CPPUNIT_ASSERT( PingFile(newPathname.c_str()) );
1480 RemoveFile(newPathname.c_str());
1481 }
1482 RemoveFile(pathname.c_str());
1483 }
1484 }
1485
1486 // RenameTestEntry
1487 void
RenameTestEntry(TestEntry * testEntry,TestEntry * newTestEntry,bool existing,bool clobber,status_t error,uint32 kind)1488 EntryTest::RenameTestEntry(TestEntry *testEntry, TestEntry *newTestEntry,
1489 bool existing, bool clobber, status_t error,
1490 uint32 kind)
1491 {
1492 // relative path
1493 string relPath = get_shortest_relative_path(testEntry->super,
1494 newTestEntry);
1495 if (relPath.length() > 0) {
1496 RenameTestEntry(testEntry, newTestEntry, relPath, existing,
1497 clobber, error, B_FILE_NODE);
1498 }
1499 // absolute path
1500 RenameTestEntry(testEntry, newTestEntry, newTestEntry->path, existing,
1501 clobber, error, B_FILE_NODE);
1502 }
1503
1504 // RenameTestFile
1505 void
RenameTestFile(TestEntry * testEntry,TestEntry * newTestEntry,bool existing,bool clobber,status_t error)1506 EntryTest::RenameTestFile(TestEntry *testEntry, TestEntry *newTestEntry,
1507 bool existing, bool clobber, status_t error)
1508 {
1509 RenameTestEntry(testEntry, newTestEntry, existing, clobber, error,
1510 B_FILE_NODE);
1511 }
1512
1513 // RenameTestDir
1514 void
RenameTestDir(TestEntry * testEntry,TestEntry * newTestEntry,bool existing,bool clobber,status_t error)1515 EntryTest::RenameTestDir(TestEntry *testEntry, TestEntry *newTestEntry,
1516 bool existing, bool clobber, status_t error)
1517 {
1518 RenameTestEntry(testEntry, newTestEntry, existing, clobber, error,
1519 B_DIRECTORY_NODE);
1520 }
1521
1522 // RenameTestLink
1523 void
RenameTestLink(TestEntry * testEntry,TestEntry * newTestEntry,bool existing,bool clobber,status_t error)1524 EntryTest::RenameTestLink(TestEntry *testEntry, TestEntry *newTestEntry,
1525 bool existing, bool clobber, status_t error)
1526 {
1527 RenameTestEntry(testEntry, newTestEntry, existing, clobber, error,
1528 B_SYMLINK_NODE);
1529 }
1530
1531 // RenameTest
1532 void
RenameTest()1533 EntryTest::RenameTest()
1534 {
1535 BDirectory dir;
1536 BEntry entry;
1537 // file
1538 // same dir
1539 RenameTestFile(&file2, &file2, false, false, B_FILE_EXISTS);
1540 RenameTestFile(&file2, &file2, false, true, B_NOT_ALLOWED);
1541 RenameTestFile(&file2, &file4, false, false, B_OK);
1542 // different dir
1543 RenameTestFile(&file2, &file3, false, false, B_OK);
1544 // different dir, existing file, clobber
1545 RenameTestFile(&file2, &file3, true, true, B_OK);
1546 // different dir, existing file, no clobber
1547 RenameTestFile(&file2, &file3, true, false, B_FILE_EXISTS);
1548 // dir
1549 // same dir
1550 RenameTestDir(&file2, &file2, false, false, B_FILE_EXISTS);
1551 RenameTestDir(&file2, &file2, false, true, B_NOT_ALLOWED);
1552 RenameTestDir(&file2, &file4, false, false, B_OK);
1553 // different dir
1554 RenameTestDir(&file2, &file3, false, false, B_OK);
1555 // different dir, existing file, clobber
1556 RenameTestDir(&file2, &file3, true, true, B_OK);
1557 // different dir, existing file, no clobber
1558 RenameTestDir(&file2, &file3, true, false, B_FILE_EXISTS);
1559 // link
1560 // same dir
1561 RenameTestLink(&file2, &file2, false, false, B_FILE_EXISTS);
1562 RenameTestLink(&file2, &file2, false, true, B_NOT_ALLOWED);
1563 RenameTestLink(&file2, &file4, false, false, B_OK);
1564 // different dir
1565 RenameTestLink(&file2, &file3, false, false, B_OK);
1566 // different dir, existing file, clobber
1567 RenameTestLink(&file2, &file3, true, true, B_OK);
1568 // different dir, existing file, no clobber
1569 RenameTestLink(&file2, &file3, true, false, B_FILE_EXISTS);
1570
1571 // try to clobber a non-empty directory
1572 NextSubTest();
1573 CreateFile(file3.cpath);
1574 CPPUNIT_ASSERT( entry.SetTo(file3.cpath) == B_OK );
1575 CPPUNIT_ASSERT( entry.Rename(dir1.cpath, true) == B_DIRECTORY_NOT_EMPTY );
1576 CPPUNIT_ASSERT( PingDir(dir1.cpath) );
1577 CPPUNIT_ASSERT( PingFile(file3.cpath, &entry) );
1578 RemoveFile(file3.cpath);
1579 entry.Unset();
1580 dir.Unset();
1581 // clobber an empty directory
1582 NextSubTest();
1583 CreateFile(file3.cpath);
1584 CPPUNIT_ASSERT( entry.SetTo(file3.cpath) == B_OK );
1585 CPPUNIT_ASSERT( entry.Rename(subDir1.cpath, true) == B_OK );
1586 CPPUNIT_ASSERT( PingFile(subDir1.cpath, &entry) );
1587 CPPUNIT_ASSERT( !PingFile(file3.cpath) );
1588 RemoveFile(subDir1.cpath);
1589 entry.Unset();
1590 dir.Unset();
1591 // abstract entry
1592 NextSubTest();
1593 CPPUNIT_ASSERT( entry.SetTo(file2.cpath) == B_OK );
1594 CPPUNIT_ASSERT( entry.Rename(file4.cname) == B_ENTRY_NOT_FOUND );
1595 entry.Unset();
1596 dir.Unset();
1597 // uninitialized entry
1598 NextSubTest();
1599 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
1600 CPPUNIT_ASSERT( entry.Rename(file4.cpath) == B_NO_INIT );
1601 entry.Unset();
1602 dir.Unset();
1603 // badly initialized entry
1604 NextSubTest();
1605 CPPUNIT_ASSERT( entry.SetTo(badEntry1.cpath) == B_ENTRY_NOT_FOUND );
1606 CPPUNIT_ASSERT( entry.Rename(file4.cpath) == B_NO_INIT );
1607 entry.Unset();
1608 dir.Unset();
1609 // Verify attempts to rename root
1610 NextSubTest();
1611 BEntry root("/");
1612 CPPUNIT_ASSERT( root.Rename("/", false) == B_FILE_EXISTS );
1613 CPPUNIT_ASSERT( root.Rename("/", true) == B_NOT_ALLOWED );
1614 // Verify abstract entries
1615 NextSubTest();
1616 BEntry abstract(abstractEntry1.cpath);
1617 CPPUNIT_ASSERT( abstract.InitCheck() == B_OK );
1618 CPPUNIT_ASSERT( !abstract.Exists() );
1619 CPPUNIT_ASSERT( abstract.Rename("/boot/DoesntMatter") == B_ENTRY_NOT_FOUND );
1620 CPPUNIT_ASSERT( abstract.Rename("/boot/DontMatter", true) == B_ENTRY_NOT_FOUND );
1621 CPPUNIT_ASSERT( abstract.Rename("/DoesntMatter") == B_CROSS_DEVICE_LINK );
1622 CPPUNIT_ASSERT( abstract.Rename("/DontMatter", true) == B_CROSS_DEVICE_LINK );
1623 // bad args
1624 NextSubTest();
1625 CPPUNIT_ASSERT( entry.SetTo(file1.cpath) == B_OK );
1626 CPPUNIT_ASSERT( equals(entry.Rename(NULL, false), B_FILE_EXISTS,
1627 B_BAD_VALUE) );
1628 CPPUNIT_ASSERT( equals(entry.Rename(NULL, true), B_NOT_ALLOWED,
1629 B_BAD_VALUE) );
1630 }
1631
1632 // MoveToTestEntry
1633 void
MoveToTestEntry(TestEntry * testEntry,TestEntry * testDir,string newName,bool existing,bool clobber,status_t error,uint32 kind)1634 EntryTest::MoveToTestEntry(TestEntry *testEntry, TestEntry *testDir,
1635 string newName, bool existing, bool clobber,
1636 status_t error, uint32 kind)
1637 {
1638 NextSubTest();
1639 BEntry entry;
1640 BDirectory dir;
1641 // get all the names
1642 string pathname = testEntry->path;
1643 string dirname = testDir->path;
1644 string newPathname = dirname + "/";
1645 if (newName.length() == 0)
1646 newPathname += testEntry->name;
1647 else {
1648 // check, if the new path is absolute
1649 if (newName.find("/") == 0)
1650 newPathname = newName;
1651 else
1652 newPathname += newName;
1653 }
1654 //printf("path: `%s', dir: `%s', new name: `%s'\n", pathname.c_str(),
1655 //dirname.c_str(), newPathname.c_str());
1656 // create the entries
1657 switch (kind) {
1658 case B_FILE_NODE:
1659 CreateFile(pathname.c_str());
1660 break;
1661 case B_DIRECTORY_NODE:
1662 CreateDir(pathname.c_str());
1663 break;
1664 case B_SYMLINK_NODE:
1665 CreateLink(pathname.c_str(), file1.cpath);
1666 break;
1667 }
1668 if (existing)
1669 CreateFile(newPathname.c_str());
1670 // move the file
1671 CPPUNIT_ASSERT( entry.SetTo(pathname.c_str()) == B_OK );
1672 CPPUNIT_ASSERT( dir.SetTo(dirname.c_str()) == B_OK );
1673 if (newName.length() == 0) {
1674 status_t result = entry.MoveTo(&dir, NULL, clobber);
1675 if (result != error) {
1676 printf("`%s'.MoveTo(`%s', NULL, %d): ", pathname.c_str(), dirname.c_str(), clobber);
1677 printf("error: %lx (%lx)\n", result, error);
1678 }
1679 CPPUNIT_ASSERT( result == error );
1680 } else {
1681 status_t result = entry.MoveTo(&dir, newName.c_str(), clobber);
1682 if (result != error) {
1683 printf("`%s'.MoveTo(`%s', `%s', %d): ", pathname.c_str(), newName.c_str(), dirname.c_str(), clobber);
1684 printf("error: %lx (%lx)\n", result, error);
1685 }
1686 CPPUNIT_ASSERT( result == error );
1687 }
1688 // check and cleanup
1689 if (error == B_OK) {
1690 switch (kind) {
1691 case B_FILE_NODE:
1692 CPPUNIT_ASSERT( !PingFile(pathname.c_str()) );
1693 CPPUNIT_ASSERT( PingFile(newPathname.c_str()) );
1694 break;
1695 case B_DIRECTORY_NODE:
1696 CPPUNIT_ASSERT( !PingDir(pathname.c_str()) );
1697 CPPUNIT_ASSERT( PingDir(newPathname.c_str()) );
1698 break;
1699 case B_SYMLINK_NODE:
1700 CPPUNIT_ASSERT( !PingLink(pathname.c_str()) );
1701 CPPUNIT_ASSERT( PingLink(newPathname.c_str(), file1.cpath) );
1702 break;
1703 }
1704 RemoveFile(newPathname.c_str());
1705 } else {
1706 switch (kind) {
1707 case B_FILE_NODE:
1708 CPPUNIT_ASSERT( PingFile(pathname.c_str()) );
1709 break;
1710 case B_DIRECTORY_NODE:
1711 CPPUNIT_ASSERT( PingDir(pathname.c_str()) );
1712 break;
1713 case B_SYMLINK_NODE:
1714 CPPUNIT_ASSERT( PingLink(pathname.c_str(), file1.cpath) );
1715 break;
1716 }
1717 if (existing) {
1718 CPPUNIT_ASSERT( PingFile(newPathname.c_str()) );
1719 RemoveFile(newPathname.c_str());
1720 }
1721 RemoveFile(pathname.c_str());
1722 }
1723 }
1724
1725 // MoveToTestEntry
1726 void
MoveToTestEntry(TestEntry * testEntry,TestEntry * testDir,TestEntry * newTestEntry,bool existing,bool clobber,status_t error,uint32 kind)1727 EntryTest::MoveToTestEntry(TestEntry *testEntry, TestEntry *testDir,
1728 TestEntry *newTestEntry, bool existing,
1729 bool clobber, status_t error, uint32 kind)
1730 {
1731 if (newTestEntry) {
1732 // Here is the right place to play a little bit with the dir and path
1733 // arguments. At this time we only pass the leaf name and the
1734 // absolute path name.
1735 MoveToTestEntry(testEntry, testDir, newTestEntry->name, existing,
1736 clobber, error, B_FILE_NODE);
1737 MoveToTestEntry(testEntry, &subDir1, newTestEntry->path, existing,
1738 clobber, error, B_FILE_NODE);
1739 } else {
1740 MoveToTestEntry(testEntry, testDir, "", existing, clobber, error,
1741 B_FILE_NODE);
1742 }
1743 }
1744
1745 // MoveToTestFile
1746 void
MoveToTestFile(TestEntry * testEntry,TestEntry * testDir,TestEntry * newTestEntry,bool existing,bool clobber,status_t error)1747 EntryTest::MoveToTestFile(TestEntry *testEntry, TestEntry *testDir,
1748 TestEntry *newTestEntry, bool existing, bool clobber,
1749 status_t error)
1750 {
1751 MoveToTestEntry(testEntry, testDir, newTestEntry, existing, clobber, error,
1752 B_FILE_NODE);
1753 }
1754
1755 // MoveToTestDir
1756 void
MoveToTestDir(TestEntry * testEntry,TestEntry * testDir,TestEntry * newTestEntry,bool existing,bool clobber,status_t error)1757 EntryTest::MoveToTestDir(TestEntry *testEntry, TestEntry *testDir,
1758 TestEntry *newTestEntry, bool existing, bool clobber,
1759 status_t error)
1760 {
1761 MoveToTestEntry(testEntry, testDir, newTestEntry, existing, clobber, error,
1762 B_DIRECTORY_NODE);
1763 }
1764
1765 // MoveToTestLink
1766 void
MoveToTestLink(TestEntry * testEntry,TestEntry * testDir,TestEntry * newTestEntry,bool existing,bool clobber,status_t error)1767 EntryTest::MoveToTestLink(TestEntry *testEntry, TestEntry *testDir,
1768 TestEntry *newTestEntry, bool existing, bool clobber,
1769 status_t error)
1770 {
1771 MoveToTestEntry(testEntry, testDir, newTestEntry, existing, clobber, error,
1772 B_SYMLINK_NODE);
1773 }
1774
1775 // MoveToTest
1776 void
MoveToTest()1777 EntryTest::MoveToTest()
1778 {
1779 BDirectory dir;
1780 BEntry entry;
1781 // 1. NULL path
1782 // file
1783 // same dir
1784 MoveToTestFile(&file2, file2.super, NULL, false, false, B_FILE_EXISTS);
1785 MoveToTestFile(&file2, file2.super, NULL, false, true, B_NOT_ALLOWED);
1786 // different dir
1787 MoveToTestFile(&file2, &dir2, NULL, false, false, B_OK);
1788 // different dir, existing file, clobber
1789 MoveToTestFile(&file2, &dir2, NULL, true, true, B_OK);
1790 // different dir, existing file, no clobber
1791 MoveToTestFile(&file2, &dir2, NULL, true, false, B_FILE_EXISTS);
1792 // dir
1793 // same dir
1794 MoveToTestDir(&file2, file2.super, NULL, false, false, B_FILE_EXISTS);
1795 MoveToTestDir(&file2, file2.super, NULL, false, true, B_NOT_ALLOWED);
1796 // different dir
1797 MoveToTestDir(&file2, &dir2, NULL, false, false, B_OK);
1798 // different dir, existing file, clobber
1799 MoveToTestDir(&file2, &dir2, NULL, true, true, B_OK);
1800 // different dir, existing file, no clobber
1801 MoveToTestDir(&file2, &dir2, NULL, true, false, B_FILE_EXISTS);
1802 // link
1803 // same dir
1804 MoveToTestLink(&file2, file2.super, NULL, false, false, B_FILE_EXISTS);
1805 MoveToTestLink(&file2, file2.super, NULL, false, true, B_NOT_ALLOWED);
1806 // different dir
1807 MoveToTestLink(&file2, &dir2, NULL, false, false, B_OK);
1808 // different dir, existing file, clobber
1809 MoveToTestLink(&file2, &dir2, NULL, true, true, B_OK);
1810 // different dir, existing file, no clobber
1811 MoveToTestLink(&file2, &dir2, NULL, true, false, B_FILE_EXISTS);
1812
1813 // 2. non NULL path
1814 // file
1815 // same dir
1816 MoveToTestFile(&file2, file2.super, &file2, false, false,
1817 B_FILE_EXISTS);
1818 MoveToTestFile(&file2, file2.super, &file2, false, true,
1819 B_NOT_ALLOWED);
1820 MoveToTestFile(&file2, file2.super, &file3, false, false, B_OK);
1821 // different dir
1822 MoveToTestFile(&file2, &dir2, &file3, false, false, B_OK);
1823 // different dir, existing file, clobber
1824 MoveToTestFile(&file2, &dir2, &file3, true, true, B_OK);
1825 // different dir, existing file, no clobber
1826 MoveToTestFile(&file2, &dir2, &file3, true, false, B_FILE_EXISTS);
1827 // dir
1828 // same dir
1829 MoveToTestDir(&file2, file2.super, &file2, false, false,
1830 B_FILE_EXISTS);
1831 MoveToTestDir(&file2, file2.super, &file2, false, true,
1832 B_NOT_ALLOWED);
1833 MoveToTestDir(&file2, file2.super, &file3, false, false, B_OK);
1834 // different dir
1835 MoveToTestDir(&file2, &dir2, &file3, false, false, B_OK);
1836 // different dir, existing file, clobber
1837 MoveToTestDir(&file2, &dir2, &file3, true, true, B_OK);
1838 // different dir, existing file, no clobber
1839 MoveToTestDir(&file2, &dir2, &file3, true, false, B_FILE_EXISTS);
1840 // link
1841 // same dir
1842 MoveToTestLink(&file2, file2.super, &file2, false, false,
1843 B_FILE_EXISTS);
1844 MoveToTestLink(&file2, file2.super, &file2, false, true,
1845 B_NOT_ALLOWED);
1846 MoveToTestLink(&file2, file2.super, &file3, false, false, B_OK);
1847 // different dir
1848 MoveToTestLink(&file2, &dir2, &file3, false, false, B_OK);
1849 // different dir, existing file, clobber
1850 MoveToTestLink(&file2, &dir2, &file3, true, true, B_OK);
1851 // different dir, existing file, no clobber
1852 MoveToTestLink(&file2, &dir2, &file3, true, false, B_FILE_EXISTS);
1853
1854 // try to clobber a non-empty directory
1855 CreateFile(file3.cpath);
1856 CPPUNIT_ASSERT( entry.SetTo(file3.cpath) == B_OK );
1857 CPPUNIT_ASSERT( dir.SetTo(dir1.super->cpath) == B_OK );
1858 CPPUNIT_ASSERT( entry.MoveTo(&dir, dir1.cname, true)
1859 == B_DIRECTORY_NOT_EMPTY );
1860 CPPUNIT_ASSERT( PingDir(dir1.cpath) );
1861 CPPUNIT_ASSERT( PingFile(file3.cpath, &entry) );
1862 RemoveFile(file3.cpath);
1863 entry.Unset();
1864 dir.Unset();
1865 // clobber an empty directory
1866 CreateFile(file3.cpath);
1867 CPPUNIT_ASSERT( entry.SetTo(file3.cpath) == B_OK );
1868 CPPUNIT_ASSERT( dir.SetTo(subDir1.super->cpath) == B_OK );
1869 CPPUNIT_ASSERT( entry.MoveTo(&dir, subDir1.cname, true) == B_OK );
1870 CPPUNIT_ASSERT( PingFile(subDir1.cpath, &entry) );
1871 CPPUNIT_ASSERT( !PingFile(file3.cpath) );
1872 RemoveFile(subDir1.cpath);
1873 entry.Unset();
1874 dir.Unset();
1875 // abstract entry
1876 CPPUNIT_ASSERT( entry.SetTo(file2.cpath) == B_OK );
1877 CPPUNIT_ASSERT( dir.SetTo(dir2.cpath) == B_OK );
1878 CPPUNIT_ASSERT( entry.MoveTo(&dir) == B_ENTRY_NOT_FOUND );
1879 entry.Unset();
1880 dir.Unset();
1881 // uninitialized entry
1882 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
1883 CPPUNIT_ASSERT( dir.SetTo(dir2.cpath) == B_OK );
1884 CPPUNIT_ASSERT( entry.MoveTo(&dir) == B_NO_INIT );
1885 entry.Unset();
1886 dir.Unset();
1887 // badly initialized entry
1888 CPPUNIT_ASSERT( entry.SetTo(badEntry1.cpath) == B_ENTRY_NOT_FOUND );
1889 CPPUNIT_ASSERT( dir.SetTo(dir2.cpath) == B_OK );
1890 CPPUNIT_ASSERT( entry.MoveTo(&dir) == B_NO_INIT );
1891 entry.Unset();
1892 dir.Unset();
1893 // bad args (NULL dir)
1894 // R5: crashs
1895 #if !TEST_R5
1896 CreateFile(file2.cpath);
1897 CPPUNIT_ASSERT( entry.SetTo(file2.cpath) == B_OK );
1898 CPPUNIT_ASSERT( entry.MoveTo(NULL, file3.cpath) == B_BAD_VALUE );
1899 RemoveFile(file3.cpath);
1900 entry.Unset();
1901 dir.Unset();
1902 #endif
1903 // uninitialized dir, absolute path
1904 CreateFile(file2.cpath);
1905 CPPUNIT_ASSERT( entry.SetTo(file2.cpath) == B_OK );
1906 CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT );
1907 CPPUNIT_ASSERT( entry.MoveTo(&dir, file3.cpath) == B_BAD_VALUE );
1908 RemoveFile(file3.cpath);
1909 entry.Unset();
1910 dir.Unset();
1911 }
1912
1913 // RemoveTest
1914 void
RemoveTest()1915 EntryTest::RemoveTest()
1916 {
1917 BEntry entry;
1918 // file
1919 NextSubTest();
1920 CPPUNIT_ASSERT( entry.SetTo(file1.cpath) == B_OK );
1921 CPPUNIT_ASSERT( entry.Remove() == B_OK );
1922 CPPUNIT_ASSERT( !PingFile(file1.cpath) );
1923 entry.Unset();
1924 // symlink
1925 NextSubTest();
1926 CPPUNIT_ASSERT( entry.SetTo(absFileLink1.cpath) == B_OK );
1927 CPPUNIT_ASSERT( entry.Remove() == B_OK );
1928 CPPUNIT_ASSERT( !PingLink(absFileLink1.cpath) );
1929 entry.Unset();
1930 // empty dir
1931 NextSubTest();
1932 CPPUNIT_ASSERT( entry.SetTo(subDir1.cpath) == B_OK );
1933 CPPUNIT_ASSERT( entry.Remove() == B_OK );
1934 CPPUNIT_ASSERT( !PingDir(subDir1.cpath) );
1935 entry.Unset();
1936 // non-empty dir
1937 NextSubTest();
1938 CPPUNIT_ASSERT( entry.SetTo(dir1.cpath) == B_OK );
1939 CPPUNIT_ASSERT( entry.Remove() == B_DIRECTORY_NOT_EMPTY );
1940 CPPUNIT_ASSERT( PingDir(dir1.cpath) );
1941 entry.Unset();
1942 // abstract entry
1943 NextSubTest();
1944 CPPUNIT_ASSERT( entry.SetTo(abstractEntry1.cpath) == B_OK );
1945 CPPUNIT_ASSERT( entry.Remove() == B_ENTRY_NOT_FOUND );
1946 entry.Unset();
1947 // uninitialized
1948 NextSubTest();
1949 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
1950 CPPUNIT_ASSERT( entry.Remove() == B_NO_INIT );
1951 entry.Unset();
1952 // badly initialized
1953 NextSubTest();
1954 CPPUNIT_ASSERT( entry.SetTo(badEntry1.cpath) == B_ENTRY_NOT_FOUND );
1955 CPPUNIT_ASSERT( entry.Remove() == B_NO_INIT );
1956 entry.Unset();
1957 }
1958
1959 // compareEntries
1960 static
1961 void
compareEntries(const BEntry & entry,const BEntry & entry2,const TestEntry * testEntry,const TestEntry * testEntry2,bool traversed,bool traversed2)1962 compareEntries(const BEntry &entry, const BEntry &entry2,
1963 const TestEntry *testEntry, const TestEntry *testEntry2,
1964 bool traversed, bool traversed2)
1965 {
1966 if (!testEntry->isBad() && !testEntry2->isBad()
1967 && (!traversed && testEntry->isConcrete())
1968 && (!traversed2 && testEntry2->isConcrete())) {
1969 //printf("compare: `%s', `%s'\n", testEntry->cpath, testEntry2->cpath);
1970 //printf("InitCheck(): %x, %x\n", entry.InitCheck(), entry2.InitCheck());
1971 CPPUNIT_ASSERT( (entry == entry2) == (testEntry == testEntry2) );
1972 CPPUNIT_ASSERT( (entry == entry2) == (testEntry2 == testEntry) );
1973 CPPUNIT_ASSERT( (entry != entry2) == (testEntry != testEntry2) );
1974 CPPUNIT_ASSERT( (entry != entry2) == (testEntry2 != testEntry) );
1975 }
1976 }
1977
1978 // ComparisonTest
1979 void
ComparisonTest()1980 EntryTest::ComparisonTest()
1981 {
1982 // uninitialized
1983 NextSubTest();
1984 {
1985 BEntry entry;
1986 BEntry entry2;
1987 CPPUNIT_ASSERT( entry == entry2 );
1988 CPPUNIT_ASSERT( entry2 == entry );
1989 CPPUNIT_ASSERT( !(entry != entry2) );
1990 CPPUNIT_ASSERT( !(entry2 != entry) );
1991 }
1992 // initialized + uninitialized
1993 NextSubTest();
1994 {
1995 BEntry entry(file1.cpath);
1996 BEntry entry2;
1997 CPPUNIT_ASSERT( !(entry == entry2) );
1998 CPPUNIT_ASSERT( !(entry2 == entry) );
1999 CPPUNIT_ASSERT( entry != entry2 );
2000 CPPUNIT_ASSERT( entry2 != entry );
2001 }
2002 {
2003 BEntry entry;
2004 BEntry entry2(file1.cpath);
2005 CPPUNIT_ASSERT( !(entry == entry2) );
2006 CPPUNIT_ASSERT( !(entry2 == entry) );
2007 CPPUNIT_ASSERT( entry != entry2 );
2008 CPPUNIT_ASSERT( entry2 != entry );
2009 }
2010 // initialized
2011 TestEntry *testEntries[] = {
2012 &dir1, &dir2, &file1, &subDir1, &abstractEntry1, &badEntry1,
2013 &absDirLink1, &absDirLink2, &absDirLink3, &absDirLink4,
2014 &relDirLink1, &relDirLink2, &relDirLink3, &relDirLink4,
2015 &absFileLink1, &absFileLink2, &absFileLink3, &absFileLink4,
2016 &relFileLink1, &relFileLink2, &relFileLink3, &relFileLink4,
2017 &absBadLink1, &absBadLink2, &absBadLink3, &absBadLink4,
2018 &relBadLink1, &relBadLink2, &relBadLink3, &relBadLink4,
2019 &absVeryBadLink1, &absVeryBadLink2, &absVeryBadLink3, &absVeryBadLink4,
2020 &relVeryBadLink1, &relVeryBadLink2, &relVeryBadLink3, &relVeryBadLink4
2021 };
2022 int32 testEntryCount = sizeof(testEntries) / sizeof(TestEntry*);
2023 for (int32 i = 0; i < testEntryCount; i++) {
2024 NextSubTest();
2025 TestEntry *testEntry = testEntries[i];
2026 TestEntry *traversedTestEntry = resolve_link(testEntry);
2027 BEntry entry(testEntry->cpath);
2028 BEntry traversedEntry(testEntry->cpath, true);
2029 for (int32 k = 0; k < testEntryCount; k++) {
2030 TestEntry *testEntry2 = testEntries[k];
2031 TestEntry *traversedTestEntry2 = resolve_link(testEntry2);
2032 BEntry entry2(testEntry2->cpath);
2033 BEntry traversedEntry2(testEntry2->cpath, true);
2034 compareEntries(entry, entry2, testEntry, testEntry2, false, false);
2035 compareEntries(traversedEntry, entry2,
2036 traversedTestEntry, testEntry2, true, false);
2037 compareEntries(entry, traversedEntry2,
2038 testEntry, traversedTestEntry2, false, true);
2039 compareEntries(traversedEntry, traversedEntry2,
2040 traversedTestEntry, traversedTestEntry2,
2041 true, true);
2042 }
2043 }
2044 }
2045
2046 // AssignmentTest
2047 void
AssignmentTest()2048 EntryTest::AssignmentTest()
2049 {
2050 // 1. copy constructor
2051 // uninitialized
2052 NextSubTest();
2053 {
2054 BEntry entry;
2055 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
2056 BEntry entry2(entry);
2057 // R5: returns B_BAD_VALUE instead of B_NO_INIT
2058 CPPUNIT_ASSERT( equals(entry2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
2059 CPPUNIT_ASSERT( entry == entry2 );
2060 }
2061 // initialized
2062 TestEntry *testEntries[] = {
2063 &dir1, &dir2, &file1, &subDir1, &abstractEntry1, &badEntry1,
2064 &absDirLink1, &absDirLink2, &absDirLink3, &absDirLink4,
2065 &relDirLink1, &relDirLink2, &relDirLink3, &relDirLink4,
2066 &absFileLink1, &absFileLink2, &absFileLink3, &absFileLink4,
2067 &relFileLink1, &relFileLink2, &relFileLink3, &relFileLink4,
2068 &absBadLink1, &absBadLink2, &absBadLink3, &absBadLink4,
2069 &relBadLink1, &relBadLink2, &relBadLink3, &relBadLink4,
2070 &absVeryBadLink1, &absVeryBadLink2, &absVeryBadLink3, &absVeryBadLink4,
2071 &relVeryBadLink1, &relVeryBadLink2, &relVeryBadLink3, &relVeryBadLink4
2072 };
2073 int32 testEntryCount = sizeof(testEntries) / sizeof(TestEntry*);
2074 for (int32 i = 0; i < testEntryCount; i++) {
2075 NextSubTest();
2076 TestEntry *testEntry = testEntries[i];
2077 BEntry entry(testEntry->cpath);
2078 BEntry entry2(entry);
2079 CPPUNIT_ASSERT( entry == entry2 );
2080 CPPUNIT_ASSERT( entry2 == entry );
2081 CPPUNIT_ASSERT( !(entry != entry2) );
2082 CPPUNIT_ASSERT( !(entry2 != entry) );
2083 }
2084
2085 // 2. assignment operator
2086 // uninitialized
2087 NextSubTest();
2088 {
2089 BEntry entry;
2090 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
2091 BEntry entry2;
2092 entry2 = entry;
2093 // R5: returns B_BAD_VALUE instead of B_NO_INIT
2094 CPPUNIT_ASSERT( equals(entry2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
2095 CPPUNIT_ASSERT( entry == entry2 );
2096 }
2097 NextSubTest();
2098 {
2099 BEntry entry;
2100 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
2101 BEntry entry2(file1.cpath);
2102 entry2 = entry;
2103 // R5: returns B_BAD_VALUE instead of B_NO_INIT
2104 CPPUNIT_ASSERT( equals(entry2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
2105 CPPUNIT_ASSERT( entry == entry2 );
2106 }
2107 // initialized
2108 for (int32 i = 0; i < testEntryCount; i++) {
2109 NextSubTest();
2110 TestEntry *testEntry = testEntries[i];
2111 BEntry entry(testEntry->cpath);
2112 BEntry entry2;
2113 BEntry entry3(file1.cpath);
2114 entry2 = entry;
2115 entry3 = entry;
2116 CPPUNIT_ASSERT( entry == entry2 );
2117 CPPUNIT_ASSERT( entry2 == entry );
2118 CPPUNIT_ASSERT( !(entry != entry2) );
2119 CPPUNIT_ASSERT( !(entry2 != entry) );
2120 CPPUNIT_ASSERT( entry == entry3 );
2121 CPPUNIT_ASSERT( entry3 == entry );
2122 CPPUNIT_ASSERT( !(entry != entry3) );
2123 CPPUNIT_ASSERT( !(entry3 != entry) );
2124 }
2125 }
2126
2127 // get_entry_ref_for_entry
2128 static
2129 status_t
get_entry_ref_for_entry(const char * dir,const char * leaf,entry_ref * ref)2130 get_entry_ref_for_entry(const char *dir, const char *leaf, entry_ref *ref)
2131 {
2132 status_t error = (dir && leaf ? B_OK : B_BAD_VALUE);
2133 struct stat dirStat;
2134 if (lstat(dir, &dirStat) == 0) {
2135 ref->device = dirStat.st_dev;
2136 ref->directory = dirStat.st_ino;
2137 ref->set_name(leaf);
2138 } else
2139 error = errno;
2140 return error;
2141 }
2142
2143 // entry_ref >
2144 bool
operator >(const entry_ref & a,const entry_ref & b)2145 operator>(const entry_ref & a, const entry_ref & b)
2146 {
2147 return (a.device > b.device
2148 || (a.device == b.device
2149 && (a.directory > b.directory
2150 || (a.directory == b.directory
2151 && (a.name != NULL && b.name == NULL
2152 || (a.name != NULL && b.name != NULL
2153 && strcmp(a.name, b.name) > 0))))));
2154 }
2155
2156 // CFunctionsTest
2157 void
CFunctionsTest()2158 EntryTest::CFunctionsTest()
2159 {
2160 // get_ref_for_path(), <
2161 TestEntry *testEntries[] = {
2162 &dir1, &dir2, &file1, &subDir1, &abstractEntry1, &badEntry1,
2163 &absDirLink1, &absDirLink2, &absDirLink3, &absDirLink4,
2164 &relDirLink1, &relDirLink2, &relDirLink3, &relDirLink4,
2165 &absFileLink1, &absFileLink2, &absFileLink3, &absFileLink4,
2166 &relFileLink1, &relFileLink2, &relFileLink3, &relFileLink4,
2167 &absBadLink1, &absBadLink2, &absBadLink3, &absBadLink4,
2168 &relBadLink1, &relBadLink2, &relBadLink3, &relBadLink4,
2169 &absVeryBadLink1, &absVeryBadLink2, &absVeryBadLink3, &absVeryBadLink4,
2170 &relVeryBadLink1, &relVeryBadLink2, &relVeryBadLink3, &relVeryBadLink4
2171 };
2172 int32 testEntryCount = sizeof(testEntries) / sizeof(TestEntry*);
2173 for (int32 i = 0; i < testEntryCount; i++) {
2174 NextSubTest();
2175 TestEntry *testEntry = testEntries[i];
2176 const char *path = testEntry->cpath;
2177 entry_ref ref;
2178 if (testEntry->isBad())
2179 CPPUNIT_ASSERT( get_ref_for_path(path, &ref) == B_ENTRY_NOT_FOUND );
2180 else {
2181 CPPUNIT_ASSERT( get_ref_for_path(path, &ref) == B_OK );
2182 const entry_ref &testEntryRef = testEntry->get_ref();
2183 CPPUNIT_ASSERT( testEntryRef.device == ref.device );
2184 CPPUNIT_ASSERT( testEntryRef.directory == ref.directory );
2185 CPPUNIT_ASSERT( strcmp(testEntryRef.name, ref.name) == 0 );
2186 CPPUNIT_ASSERT( testEntryRef == ref );
2187 CPPUNIT_ASSERT( !(testEntryRef != ref) );
2188 CPPUNIT_ASSERT( ref == testEntryRef );
2189 CPPUNIT_ASSERT( !(ref != testEntryRef) );
2190 for (int32 k = 0; k < testEntryCount; k++) {
2191 TestEntry *testEntry2 = testEntries[k];
2192 const char *path2 = testEntry2->cpath;
2193 entry_ref ref2;
2194 if (!testEntry2->isBad()) {
2195 CPPUNIT_ASSERT( get_ref_for_path(path2, &ref2) == B_OK );
2196 int cmp = 0;
2197 if (ref > ref2)
2198 cmp = 1;
2199 else if (ref2 > ref)
2200 cmp = -1;
2201 CPPUNIT_ASSERT( (ref == ref2) == (cmp == 0) );
2202 CPPUNIT_ASSERT( (ref2 == ref) == (cmp == 0) );
2203 CPPUNIT_ASSERT( (ref != ref2) == (cmp != 0) );
2204 CPPUNIT_ASSERT( (ref2 != ref) == (cmp != 0) );
2205 CPPUNIT_ASSERT( (ref < ref2) == (cmp < 0) );
2206 CPPUNIT_ASSERT( (ref2 < ref) == (cmp > 0) );
2207 }
2208 }
2209 }
2210 }
2211 // root dir
2212 NextSubTest();
2213 entry_ref ref, ref2;
2214 CPPUNIT_ASSERT( get_ref_for_path("/", &ref) == B_OK );
2215 CPPUNIT_ASSERT( get_entry_ref_for_entry("/", ".", &ref2) == B_OK );
2216 CPPUNIT_ASSERT( ref.device == ref2.device );
2217 CPPUNIT_ASSERT( ref.directory == ref2.directory );
2218 CPPUNIT_ASSERT( strcmp(ref.name, ref2.name) == 0 );
2219 CPPUNIT_ASSERT( ref == ref2 );
2220 // fs root dir
2221 NextSubTest();
2222 CPPUNIT_ASSERT( get_ref_for_path("/boot", &ref) == B_OK );
2223 CPPUNIT_ASSERT( get_entry_ref_for_entry("/", "boot", &ref2) == B_OK );
2224 CPPUNIT_ASSERT( ref.device == ref2.device );
2225 CPPUNIT_ASSERT( ref.directory == ref2.directory );
2226 CPPUNIT_ASSERT( strcmp(ref.name, ref2.name) == 0 );
2227 CPPUNIT_ASSERT( ref == ref2 );
2228 // uninitialized
2229 NextSubTest();
2230 ref = entry_ref();
2231 ref2 = entry_ref();
2232 CPPUNIT_ASSERT( ref == ref2 );
2233 CPPUNIT_ASSERT( !(ref != ref2) );
2234 CPPUNIT_ASSERT( !(ref < ref2) );
2235 CPPUNIT_ASSERT( !(ref2 < ref) );
2236 CPPUNIT_ASSERT( get_entry_ref_for_entry("/", ".", &ref2) == B_OK );
2237 CPPUNIT_ASSERT( !(ref == ref2) );
2238 CPPUNIT_ASSERT( ref != ref2 );
2239 CPPUNIT_ASSERT( ref < ref2 );
2240 CPPUNIT_ASSERT( !(ref2 < ref) );
2241 }
2242
2243
2244 // isHarmlessPathname
2245 bool
isHarmlessPathname(const char * path)2246 isHarmlessPathname(const char *path)
2247 {
2248 bool result = false;
2249 if (path) {
2250 const char *harmlessDir = "/tmp/";
2251 result = (string(path).find(harmlessDir) == 0);
2252 }
2253 if (!result)
2254 printf("WARNING: `%s' is not a harmless pathname.\n", path);
2255 return result;
2256 }
2257
2258 // CreateLink
2259 void
CreateLink(const char * link,const char * target)2260 EntryTest::CreateLink(const char *link, const char *target)
2261 {
2262 if (link && target && isHarmlessPathname(link)) {
2263 execCommand(string("rm -rf ") + link
2264 + " ; ln -s " + target + " " + link);
2265 }
2266 }
2267
2268 // CreateFile
2269 void
CreateFile(const char * file)2270 EntryTest::CreateFile(const char *file)
2271 {
2272 if (file && isHarmlessPathname(file))
2273 execCommand(string("rm -rf ") + file + " ; touch " + file);
2274 }
2275
2276 // CreateDir
2277 void
CreateDir(const char * dir)2278 EntryTest::CreateDir(const char *dir)
2279 {
2280 if (dir && isHarmlessPathname(dir))
2281 execCommand(string("rm -rf ") + dir + " ; mkdir " + dir);
2282 }
2283
2284 // RemoveFile
2285 void
RemoveFile(const char * file)2286 EntryTest::RemoveFile(const char *file)
2287 {
2288 if (file && isHarmlessPathname(file))
2289 execCommand(string("rm -rf ") + file);
2290 }
2291
2292 // PingFile
2293 bool
PingFile(const char * path,BEntry * entry)2294 EntryTest::PingFile(const char *path, BEntry *entry)
2295 {
2296 bool result = false;
2297 // check existence and type
2298 struct stat st;
2299 if (lstat(path, &st) == 0)
2300 result = (S_ISREG(st.st_mode));
2301 // check entry
2302 if (result && entry) {
2303 BPath entryPath;
2304 result = (entry->GetPath(&entryPath) == B_OK && entryPath == path);
2305 }
2306 return result;
2307 }
2308
2309 // PingDir
2310 bool
PingDir(const char * path,BEntry * entry)2311 EntryTest::PingDir(const char *path, BEntry *entry)
2312 {
2313 bool result = false;
2314 // check existence and type
2315 struct stat st;
2316 if (lstat(path, &st) == 0)
2317 result = (S_ISDIR(st.st_mode));
2318 // check entry
2319 if (result && entry) {
2320 BPath entryPath;
2321 result = (entry->GetPath(&entryPath) == B_OK && entryPath == path);
2322 }
2323 return result;
2324 }
2325
2326 // PingLink
2327 bool
PingLink(const char * path,const char * target,BEntry * entry)2328 EntryTest::PingLink(const char *path, const char *target, BEntry *entry)
2329 {
2330 bool result = false;
2331 // check existence and type
2332 struct stat st;
2333 if (lstat(path, &st) == 0)
2334 result = (S_ISLNK(st.st_mode));
2335 // check target
2336 if (result && target) {
2337 char linkTarget[B_PATH_NAME_LENGTH + 1];
2338 ssize_t size = readlink(path, linkTarget, B_PATH_NAME_LENGTH);
2339 result = (size >= 0);
2340 if (result) {
2341 linkTarget[size] = 0;
2342 result = (string(linkTarget) == target);
2343 }
2344 }
2345 // check entry
2346 if (result && entry) {
2347 BPath entryPath;
2348 result = (entry->GetPath(&entryPath) == B_OK && entryPath == path);
2349 }
2350 return result;
2351 }
2352
2353 // MiscTest
2354 void
MiscTest()2355 EntryTest::MiscTest()
2356 {
2357 BNode node(file1.cpath);
2358 BEntry entry(file1.cpath);
2359
2360 CPPUNIT_ASSERT(node.Lock() == B_OK);
2361 CPPUNIT_ASSERT( entry.Exists() );
2362 }
2363
2364
2365
2366 // directory name for too long path name (70 characters)
2367 static const char *tooLongDirname =
2368 "1234567890123456789012345678901234567890123456789012345678901234567890";
2369
2370 // too long entry name (257 characters)
2371 static const char *tooLongEntryname =
2372 "1234567890123456789012345678901234567890123456789012345678901234567890"
2373 "1234567890123456789012345678901234567890123456789012345678901234567890"
2374 "1234567890123456789012345678901234567890123456789012345678901234567890"
2375 "12345678901234567890123456789012345678901234567";
2376
2377
2378 static void
init_entry_test()2379 init_entry_test()
2380 {
2381 // root dir for testing
2382 testDir.initDir(badTestEntry, "testDir");
2383 testDir.initPath((string("/tmp/") + testDir.name).c_str());
2384 allTestEntries.pop_back();
2385 // other entries
2386 dir1.initDir(testDir, "dir1");
2387 dir2.initDir(testDir, "dir2");
2388 file1.initFile(dir1, "file1");
2389 file2.init(dir1, "file2", ABSTRACT_ENTRY);
2390 file3.init(dir2, "file3", ABSTRACT_ENTRY);
2391 file4.init(dir1, "file4", ABSTRACT_ENTRY);
2392 subDir1.initDir(dir1, "subDir1");
2393 abstractEntry1.init(dir1, "abstractEntry1", ABSTRACT_ENTRY);
2394 badEntry1.init(abstractEntry1, "badEntry1", BAD_ENTRY);
2395 absDirLink1.initALink(dir1, "absDirLink1", subDir1);
2396 absDirLink2.initALink(dir1, "absDirLink2", absDirLink1);
2397 absDirLink3.initALink(dir2, "absDirLink3", absDirLink2);
2398 absDirLink4.initALink(testDir, "absDirLink4", absDirLink3);
2399 relDirLink1.initRLink(dir1, "relDirLink1", subDir1);
2400 relDirLink2.initRLink(dir1, "relDirLink2", relDirLink1);
2401 relDirLink3.initRLink(dir2, "relDirLink3", relDirLink2);
2402 relDirLink4.initRLink(testDir, "relDirLink4", relDirLink3);
2403 absFileLink1.initALink(dir1, "absFileLink1", file1);
2404 absFileLink2.initALink(dir1, "absFileLink2", absFileLink1);
2405 absFileLink3.initALink(dir2, "absFileLink3", absFileLink2);
2406 absFileLink4.initALink(testDir, "absFileLink4", absFileLink3);
2407 relFileLink1.initRLink(dir1, "relFileLink1", file1);
2408 relFileLink2.initRLink(dir1, "relFileLink2", relFileLink1);
2409 relFileLink3.initRLink(dir2, "relFileLink3", relFileLink2);
2410 relFileLink4.initRLink(testDir, "relFileLink4", relFileLink3);
2411 absCyclicLink1.initALink(dir1, "absCyclicLink1", absCyclicLink2);
2412 absCyclicLink2.initALink(dir1, "absCyclicLink2", absCyclicLink1);
2413 relCyclicLink1.initRLink(dir1, "relCyclicLink1", relCyclicLink2);
2414 relCyclicLink2.initRLink(dir1, "relCyclicLink2", relCyclicLink1);
2415 absBadLink1.initALink(dir1, "absBadLink1", abstractEntry1);
2416 absBadLink2.initALink(dir1, "absBadLink2", absBadLink1);
2417 absBadLink3.initALink(dir2, "absBadLink3", absBadLink2);
2418 absBadLink4.initALink(testDir, "absBadLink4", absBadLink3);
2419 relBadLink1.initRLink(dir1, "relBadLink1", abstractEntry1);
2420 relBadLink2.initRLink(dir1, "relBadLink2", relBadLink1);
2421 relBadLink3.initRLink(dir2, "relBadLink3", relBadLink2);
2422 relBadLink4.initRLink(testDir, "relBadLink4", relBadLink3);
2423 absVeryBadLink1.initALink(dir1, "absVeryBadLink1", badEntry1);
2424 absVeryBadLink2.initALink(dir1, "absVeryBadLink2", absVeryBadLink1);
2425 absVeryBadLink3.initALink(dir2, "absVeryBadLink3", absVeryBadLink2);
2426 absVeryBadLink4.initALink(testDir, "absVeryBadLink4", absVeryBadLink3);
2427 relVeryBadLink1.initRLink(dir1, "relVeryBadLink1", badEntry1);
2428 relVeryBadLink2.initRLink(dir1, "relVeryBadLink2", relVeryBadLink1);
2429 relVeryBadLink3.initRLink(dir2, "relVeryBadLink3", relVeryBadLink2);
2430 relVeryBadLink4.initRLink(testDir, "relVeryBadLink4", relVeryBadLink3);
2431 tooLongEntry1.init(testDir, tooLongEntryname, ABSTRACT_ENTRY);
2432 tooLongDir1.initDir(testDir, tooLongDirname);
2433 tooLongDir2.initDir(tooLongDir1, tooLongDirname);
2434 tooLongDir3.initDir(tooLongDir2, tooLongDirname);
2435 tooLongDir4.initDir(tooLongDir3, tooLongDirname);
2436 tooLongDir5.initDir(tooLongDir4, tooLongDirname);
2437 tooLongDir6.initDir(tooLongDir5, tooLongDirname);
2438 tooLongDir7.initDir(tooLongDir6, tooLongDirname);
2439 tooLongDir8.initDir(tooLongDir7, tooLongDirname);
2440 tooLongDir9.initDir(tooLongDir8, tooLongDirname);
2441 tooLongDir10.initDir(tooLongDir9, tooLongDirname);
2442 tooLongDir11.initDir(tooLongDir10, tooLongDirname);
2443 tooLongDir12.initDir(tooLongDir11, tooLongDirname);
2444 tooLongDir13.initDir(tooLongDir12, tooLongDirname);
2445 tooLongDir14.initDir(tooLongDir13, tooLongDirname);
2446 tooLongDir15.initDir(tooLongDir14, tooLongDirname);
2447 tooLongDir16.initDir(tooLongDir15, tooLongDirname);
2448
2449 // init paths
2450 for (list<TestEntry*>::iterator it = allTestEntries.begin();
2451 it != allTestEntries.end(); it++) {
2452 (*it)->initPath();
2453 }
2454 // complete initialization
2455 testDir.completeInit();
2456 for (list<TestEntry*>::iterator it = allTestEntries.begin();
2457 it != allTestEntries.end(); it++) {
2458 (*it)->completeInit();
2459 }
2460 // create the set up command line
2461 setUpCommandLine = string("mkdir ") + testDir.path;
2462 for (list<TestEntry*>::iterator it = allTestEntries.begin();
2463 it != allTestEntries.end(); it++) {
2464 TestEntry *entry = *it;
2465 string command;
2466 switch (entry->kind) {
2467 case ABSTRACT_ENTRY:
2468 break;
2469 case DIR_ENTRY:
2470 {
2471 if (entry->path.length() < B_PATH_NAME_LENGTH) {
2472 command = string("mkdir ") + entry->path;
2473 } else {
2474 command = string("( ")
2475 + "cd " + entry->super->super->path + " ; "
2476 + " mkdir " + entry->super->name + "/" + entry->name
2477 + " )";
2478 }
2479 break;
2480 }
2481 case FILE_ENTRY:
2482 {
2483 command = string("touch ") + entry->path;
2484 break;
2485 }
2486 case LINK_ENTRY:
2487 {
2488 command = string("ln -s ") + entry->link + " " + entry->path;
2489 break;
2490 }
2491 default:
2492 break;
2493 }
2494 if (command.length() > 0) {
2495 if (setUpCommandLine.length() == 0)
2496 setUpCommandLine = command;
2497 else
2498 setUpCommandLine += string(" ; ") + command;
2499 }
2500 }
2501 // create the tear down command line
2502 tearDownCommandLine = string("rm -rf ") + testDir.path;
2503 }
2504
2505 struct InitEntryTest {
InitEntryTestInitEntryTest2506 InitEntryTest()
2507 {
2508 init_entry_test();
2509 }
2510 } _InitEntryTest;
2511
2512
2513 // TestEntry
2514
2515 // constructor
TestEntry()2516 TestEntry::TestEntry()
2517 : super(&badTestEntry),
2518 name("badTestEntry"),
2519 kind(BAD_ENTRY),
2520 path("/tmp/badTestEntry"),
2521 target(&badTestEntry),
2522 link(),
2523 ref(),
2524 relative(true),
2525 cname(""),
2526 cpath(""),
2527 clink("")
2528 {
2529 }
2530
2531 // init
2532 void
init(TestEntry & super,string name,test_entry_kind kind,bool relative)2533 TestEntry::init(TestEntry &super, string name, test_entry_kind kind,
2534 bool relative)
2535 {
2536 this->super = &super;
2537 this->name = name;
2538 this->kind = kind;
2539 this->relative = relative;
2540 allTestEntries.push_back(this);
2541 }
2542
2543 // initDir
2544 void
initDir(TestEntry & super,string name)2545 TestEntry::initDir(TestEntry &super, string name)
2546 {
2547 init(super, name, DIR_ENTRY);
2548 }
2549
2550 // initFile
2551 void
initFile(TestEntry & super,string name)2552 TestEntry::initFile(TestEntry &super, string name)
2553 {
2554 init(super, name, FILE_ENTRY);
2555 }
2556
2557 // initRLink
2558 void
initRLink(TestEntry & super,string name,TestEntry & target)2559 TestEntry::initRLink(TestEntry &super, string name, TestEntry &target)
2560 {
2561 init(super, name, LINK_ENTRY, true);
2562 this->target = ⌖
2563 }
2564
2565 // initALink
2566 void
initALink(TestEntry & super,string name,TestEntry & target)2567 TestEntry::initALink(TestEntry &super, string name, TestEntry &target)
2568 {
2569 init(super, name, LINK_ENTRY, false);
2570 this->target = ⌖
2571 }
2572
2573 // initPath
2574 void
initPath(const char * pathName)2575 TestEntry::initPath(const char *pathName)
2576 {
2577 if (pathName)
2578 path = pathName;
2579 else
2580 path = super->path + "/" + name;
2581 }
2582
2583 // completeInit
2584 void
completeInit()2585 TestEntry::completeInit()
2586 {
2587 // init link
2588 if (kind == LINK_ENTRY) {
2589 if (relative)
2590 link = get_shortest_relative_path(super, target);
2591 else
2592 link = target->path;
2593 }
2594 // init the C strings
2595 cname = name.c_str();
2596 cpath = path.c_str();
2597 clink = link.c_str();
2598 }
2599
2600 // get_ref
2601 const entry_ref &
get_ref()2602 TestEntry::get_ref()
2603 {
2604 if (isConcrete() || isAbstract())
2605 get_entry_ref_for_entry(super->cpath, cname, &ref);
2606 return ref;
2607 }
2608
2609 // get_shortest_relative_path
2610 static
2611 string
get_shortest_relative_path(TestEntry * dir,TestEntry * entry)2612 get_shortest_relative_path(TestEntry *dir, TestEntry *entry)
2613 {
2614 string relPath;
2615 // put all super directories (including dir itself) of the dir in a set
2616 map<TestEntry*, int> superDirs;
2617 int dirSuperLevel = 0;
2618 for (TestEntry *superDir = dir;
2619 superDir != &badTestEntry;
2620 superDir = superDir->super, dirSuperLevel++) {
2621 superDirs[superDir] = dirSuperLevel;
2622 }
2623 // find the first super dir that dir and entry have in common
2624 TestEntry *commonSuperDir = &badTestEntry;
2625 int targetSuperLevel = 0;
2626 for (TestEntry *superDir = entry;
2627 commonSuperDir == &badTestEntry
2628 && superDir != &badTestEntry;
2629 superDir = superDir->super, targetSuperLevel++) {
2630 if (superDirs.find(superDir) != superDirs.end())
2631 commonSuperDir = superDir;
2632 }
2633 // construct the relative path
2634 if (commonSuperDir != &badTestEntry) {
2635 dirSuperLevel = superDirs[commonSuperDir];
2636 if (dirSuperLevel == 0 && targetSuperLevel == 0) {
2637 // entry == dir
2638 relPath == ".";
2639 } else {
2640 // levels down
2641 for (TestEntry *superDir = entry;
2642 superDir != commonSuperDir;
2643 superDir = superDir->super) {
2644 if (relPath.length() == 0)
2645 relPath = superDir->name;
2646 else
2647 relPath = superDir->name + "/" + relPath;
2648 }
2649 // levels up
2650 for (int i = dirSuperLevel; i > 0; i--) {
2651 if (relPath.length() == 0)
2652 relPath = "..";
2653 else
2654 relPath = string("../") + relPath;
2655 }
2656 }
2657 }
2658 return relPath;
2659 }
2660
2661 // resolve_link
2662 static
2663 TestEntry *
resolve_link(TestEntry * entry)2664 resolve_link(TestEntry *entry)
2665 {
2666 set<TestEntry*> followedLinks;
2667 while (entry != &badTestEntry && entry->kind == LINK_ENTRY) {
2668 if (followedLinks.find(entry) == followedLinks.end()) {
2669 followedLinks.insert(entry);
2670 entry = entry->target;
2671 } else
2672 entry = &badTestEntry; // cyclic link
2673 }
2674 return entry;
2675 }
2676
2677
2678
2679
2680