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