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