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