1 // NodeTest.cpp 2 3 #include <cppunit/TestCase.h> 4 #include <cppunit/TestCaller.h> 5 #include <cppunit/TestSuite.h> 6 #include <TestUtils.h> 7 8 #include <errno.h> 9 #include <fs_attr.h> // For struct attr_info 10 #include <stdio.h> 11 #include <unistd.h> 12 #include <sys/stat.h> // For struct stat 13 14 #include <Directory.h> 15 #include <Entry.h> 16 #include <Node.h> 17 #include <StorageDefs.h> 18 #include <String.h> 19 #include <TypeConstants.h> 20 21 #include "NodeTest.h" 22 23 24 // == for attr_info 25 static 26 inline 27 bool 28 operator==(const attr_info &info1, const attr_info &info2) 29 { 30 return (info1.type == info2.type && info1.size == info2.size); 31 } 32 33 // Suite 34 CppUnit::Test* 35 NodeTest::Suite() { 36 CppUnit::TestSuite *suite = new CppUnit::TestSuite(); 37 38 StatableTest::AddBaseClassTests<NodeTest>("BNode::", suite); 39 40 suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Init Test1", &NodeTest::InitTest1) ); 41 suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Init Test2", &NodeTest::InitTest2) ); 42 suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Attribute Directory Test", &NodeTest::AttrDirTest) ); 43 suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Attribute Read/Write/Remove Test", &NodeTest::AttrTest) ); 44 suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Attribute Rename Test" 45 #if TEST_R5 46 " (NOTE: test not actually performed with R5 libraries)" 47 #endif 48 , &NodeTest::AttrRenameTest) ); 49 suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Attribute Info Test", &NodeTest::AttrInfoTest) ); 50 // TODO: AttrBString deadlocks entire OS (UnitTester at 100% CPU, 51 // windows don't respond to actions, won't open, OS won't even shut down) 52 //suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Attribute BString Test", &NodeTest::AttrBStringTest) ); 53 suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Sync Test", &NodeTest::SyncTest) ); 54 suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Dup Test", &NodeTest::DupTest) ); 55 suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Equality Test", &NodeTest::EqualityTest) ); 56 suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Assignment Test", &NodeTest::AssignmentTest) ); 57 suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Lock Test" 58 , &NodeTest::LockTest) ); 59 60 return suite; 61 } 62 63 // ConvertTestNodesToStatables 64 static 65 void 66 ConvertTestStatablesToNodes(TestNodes& testNodes, TestStatables& testStatables) 67 { 68 BNode *node; 69 string entryName; 70 for (testNodes.rewind(); testNodes.getNext(node, entryName); ) 71 testStatables.add(node, entryName); 72 testNodes.clear(); // avoid deletion 73 } 74 75 // CreateROStatables 76 void 77 NodeTest::CreateROStatables(TestStatables& testEntries) 78 { 79 TestNodes testNodes; 80 CreateRONodes(testNodes); 81 ConvertTestStatablesToNodes(testNodes, testEntries); 82 } 83 84 // CreateRWStatables 85 void 86 NodeTest::CreateRWStatables(TestStatables& testEntries) 87 { 88 TestNodes testNodes; 89 CreateRWNodes(testNodes); 90 ConvertTestStatablesToNodes(testNodes, testEntries); 91 } 92 93 // CreateUninitializedStatables 94 void 95 NodeTest::CreateUninitializedStatables(TestStatables& testEntries) 96 { 97 TestNodes testNodes; 98 CreateUninitializedNodes(testNodes); 99 ConvertTestStatablesToNodes(testNodes, testEntries); 100 } 101 102 // CreateRONodes 103 void 104 NodeTest::CreateRONodes(TestNodes& testEntries) 105 { 106 const char *filename; 107 filename = "/tmp"; 108 testEntries.add(new BNode(filename), filename); 109 filename = "/"; 110 testEntries.add(new BNode(filename), filename); 111 filename = "/boot"; 112 testEntries.add(new BNode(filename), filename); 113 filename = "/boot/home"; 114 testEntries.add(new BNode(filename), filename); 115 filename = "/boot/home/Desktop"; 116 testEntries.add(new BNode(filename), filename); 117 filename = existingFilename; 118 testEntries.add(new BNode(filename), filename); 119 filename = dirLinkname; 120 testEntries.add(new BNode(filename), filename); 121 filename = fileLinkname; 122 testEntries.add(new BNode(filename), filename); 123 } 124 125 // CreateRWNodes 126 void 127 NodeTest::CreateRWNodes(TestNodes& testEntries) 128 { 129 const char *filename; 130 filename = existingFilename; 131 testEntries.add(new BNode(filename), filename); 132 filename = existingDirname; 133 testEntries.add(new BNode(filename), filename); 134 filename = existingSubDirname; 135 testEntries.add(new BNode(filename), filename); 136 filename = dirLinkname; 137 testEntries.add(new BNode(filename), filename); 138 filename = fileLinkname; 139 testEntries.add(new BNode(filename), filename); 140 filename = relDirLinkname; 141 testEntries.add(new BNode(filename), filename); 142 filename = relFileLinkname; 143 testEntries.add(new BNode(filename), filename); 144 filename = cyclicLinkname1; 145 testEntries.add(new BNode(filename), filename); 146 } 147 148 // CreateUninitializedNodes 149 void 150 NodeTest::CreateUninitializedNodes(TestNodes& testEntries) 151 { 152 testEntries.add(new BNode, ""); 153 } 154 155 // setUp 156 void 157 NodeTest::setUp() 158 { 159 StatableTest::setUp(); 160 execCommand( 161 string("touch ") + existingFilename 162 + "; mkdir " + existingDirname 163 + "; mkdir " + existingSubDirname 164 + "; ln -s " + existingDirname + " " + dirLinkname 165 + "; ln -s " + existingFilename + " " + fileLinkname 166 + "; ln -s " + existingRelDirname + " " + relDirLinkname 167 + "; ln -s " + existingRelFilename + " " + relFileLinkname 168 + "; ln -s " + nonExistingDirname + " " + badLinkname 169 + "; ln -s " + cyclicLinkname1 + " " + cyclicLinkname2 170 + "; ln -s " + cyclicLinkname2 + " " + cyclicLinkname1 171 ); 172 } 173 174 // tearDown 175 void 176 NodeTest::tearDown() 177 { 178 StatableTest::tearDown(); 179 // cleanup 180 string cmdLine("rm -rf "); 181 for (int32 i = 0; i < allFilenameCount; i++) 182 cmdLine += string(" ") + allFilenames[i]; 183 if (allFilenameCount > 0) 184 execCommand(cmdLine); 185 } 186 187 // InitTest1 188 void 189 NodeTest::InitTest1() 190 { 191 const char *dirLink = dirLinkname; 192 const char *dirSuperLink = dirSuperLinkname; 193 const char *dirRelLink = dirRelLinkname; 194 const char *fileLink = fileLinkname; 195 const char *existingDir = existingDirname; 196 const char *existingSuperDir = existingSuperDirname; 197 const char *existingRelDir = existingRelDirname; 198 const char *existingFile = existingFilename; 199 const char *existingSuperFile = existingSuperFilename; 200 const char *existingRelFile = existingRelFilename; 201 const char *nonExisting = nonExistingDirname; 202 const char *nonExistingSuper = nonExistingSuperDirname; 203 const char *nonExistingRel = nonExistingRelDirname; 204 // 1. default constructor 205 NextSubTest(); 206 { 207 BNode node; 208 CPPUNIT_ASSERT( node.InitCheck() == B_NO_INIT ); 209 } 210 211 // 2. BNode(const char*) 212 NextSubTest(); 213 { 214 BNode node(fileLink); 215 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 216 } 217 NextSubTest(); 218 { 219 BNode node(nonExisting); 220 CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND ); 221 } 222 NextSubTest(); 223 { 224 BNode node((const char *)NULL); 225 CPPUNIT_ASSERT( equals(node.InitCheck(), B_BAD_VALUE, B_NO_INIT) ); 226 } 227 NextSubTest(); 228 { 229 BNode node(""); 230 CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND ); 231 } 232 NextSubTest(); 233 { 234 BNode node(existingFile); 235 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 236 } 237 NextSubTest(); 238 { 239 BNode node(existingDir); 240 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 241 } 242 NextSubTest(); 243 { 244 BNode node(tooLongEntryname); 245 CPPUNIT_ASSERT( node.InitCheck() == B_NAME_TOO_LONG ); 246 } 247 248 // 3. BNode(const BEntry*) 249 NextSubTest(); 250 { 251 BEntry entry(dirLink); 252 CPPUNIT_ASSERT( entry.InitCheck() == B_OK ); 253 BNode node(&entry); 254 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 255 } 256 NextSubTest(); 257 { 258 BEntry entry(nonExisting); 259 CPPUNIT_ASSERT( entry.InitCheck() == B_OK ); 260 BNode node(&entry); 261 CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND ); 262 } 263 NextSubTest(); 264 { 265 BNode node((BEntry *)NULL); 266 CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE ); 267 } 268 NextSubTest(); 269 { 270 BEntry entry; 271 BNode node(&entry); 272 CPPUNIT_ASSERT( equals(node.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) ); 273 } 274 NextSubTest(); 275 { 276 BEntry entry(existingFile); 277 CPPUNIT_ASSERT( entry.InitCheck() == B_OK ); 278 BNode node(&entry); 279 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 280 281 } 282 NextSubTest(); 283 { 284 BEntry entry(existingDir); 285 CPPUNIT_ASSERT( entry.InitCheck() == B_OK ); 286 BNode node(&entry); 287 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 288 289 } 290 NextSubTest(); 291 { 292 BEntry entry(tooLongEntryname); 293 // R5 returns E2BIG instead of B_NAME_TOO_LONG 294 CPPUNIT_ASSERT( equals(entry.InitCheck(), E2BIG, B_NAME_TOO_LONG) ); 295 BNode node(&entry); 296 CPPUNIT_ASSERT( equals(node.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) ); 297 } 298 299 // 4. BNode(const entry_ref*) 300 NextSubTest(); 301 { 302 BEntry entry(dirLink); 303 CPPUNIT_ASSERT( entry.InitCheck() == B_OK ); 304 entry_ref ref; 305 CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK ); 306 BNode node(&ref); 307 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 308 } 309 NextSubTest(); 310 { 311 BEntry entry(nonExisting); 312 CPPUNIT_ASSERT( entry.InitCheck() == B_OK ); 313 entry_ref ref; 314 CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK ); 315 BNode node(&ref); 316 CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND ); 317 } 318 NextSubTest(); 319 { 320 BNode node((entry_ref *)NULL); 321 CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE ); 322 } 323 NextSubTest(); 324 { 325 BEntry entry(existingFile); 326 CPPUNIT_ASSERT( entry.InitCheck() == B_OK ); 327 entry_ref ref; 328 CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK ); 329 BNode node(&ref); 330 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 331 } 332 NextSubTest(); 333 { 334 BEntry entry(existingDir); 335 CPPUNIT_ASSERT( entry.InitCheck() == B_OK ); 336 entry_ref ref; 337 CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK ); 338 BNode node(&ref); 339 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 340 } 341 342 // 5. BNode(const BDirectory*, const char*) 343 NextSubTest(); 344 { 345 BDirectory pathDir(dirSuperLink); 346 CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK ); 347 BNode node(&pathDir, dirRelLink); 348 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 349 } 350 NextSubTest(); 351 { 352 BDirectory pathDir(dirSuperLink); 353 CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK ); 354 BNode node(&pathDir, dirLink); 355 CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE ); 356 } 357 NextSubTest(); 358 { 359 BDirectory pathDir(nonExistingSuper); 360 CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK ); 361 BNode node(&pathDir, nonExistingRel); 362 CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND ); 363 } 364 NextSubTest(); 365 { 366 BNode node((BDirectory *)NULL, (const char *)NULL); 367 CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE ); 368 } 369 NextSubTest(); 370 { 371 BNode node((BDirectory *)NULL, dirLink); 372 CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE ); 373 } 374 NextSubTest(); 375 { 376 BDirectory pathDir(dirSuperLink); 377 CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK ); 378 BNode node(&pathDir, (const char *)NULL); 379 CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE ); 380 } 381 NextSubTest(); 382 { 383 BDirectory pathDir(dirSuperLink); 384 CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK ); 385 BNode node(&pathDir, ""); 386 CPPUNIT_ASSERT(node.InitCheck() == B_ENTRY_NOT_FOUND); 387 } 388 NextSubTest(); 389 { 390 BDirectory pathDir(existingSuperFile); 391 CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK ); 392 BNode node(&pathDir, existingRelFile); 393 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 394 } 395 NextSubTest(); 396 { 397 BDirectory pathDir(existingSuperDir); 398 CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK ); 399 BNode node(&pathDir, existingRelDir); 400 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 401 } 402 NextSubTest(); 403 { 404 BDirectory pathDir(tooLongSuperEntryname); 405 CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK ); 406 BNode node(&pathDir, tooLongRelEntryname); 407 CPPUNIT_ASSERT( node.InitCheck() == B_NAME_TOO_LONG ); 408 } 409 NextSubTest(); 410 { 411 BDirectory pathDir(fileSuperDirname); 412 CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK ); 413 BNode node(&pathDir, fileRelDirname); 414 CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND ); 415 } 416 } 417 418 // InitTest2 419 void 420 NodeTest::InitTest2() 421 { 422 const char *dirLink = dirLinkname; 423 const char *dirSuperLink = dirSuperLinkname; 424 const char *dirRelLink = dirRelLinkname; 425 const char *fileLink = fileLinkname; 426 const char *existingDir = existingDirname; 427 const char *existingSuperDir = existingSuperDirname; 428 const char *existingRelDir = existingRelDirname; 429 const char *existingFile = existingFilename; 430 const char *existingSuperFile = existingSuperFilename; 431 const char *existingRelFile = existingRelFilename; 432 const char *nonExisting = nonExistingDirname; 433 const char *nonExistingSuper = nonExistingSuperDirname; 434 const char *nonExistingRel = nonExistingRelDirname; 435 BNode node; 436 // 2. BNode(const char*) 437 NextSubTest(); 438 CPPUNIT_ASSERT( node.SetTo(fileLink) == B_OK ); 439 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 440 // 441 NextSubTest(); 442 CPPUNIT_ASSERT( node.SetTo(nonExisting) == B_ENTRY_NOT_FOUND ); 443 CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND ); 444 // 445 NextSubTest(); 446 CPPUNIT_ASSERT( equals(node.SetTo((const char *)NULL), B_BAD_VALUE, 447 B_NO_INIT) ); 448 CPPUNIT_ASSERT( equals(node.InitCheck(), B_BAD_VALUE, B_NO_INIT) ); 449 // 450 NextSubTest(); 451 CPPUNIT_ASSERT( node.SetTo("") == B_ENTRY_NOT_FOUND ); 452 CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND ); 453 // 454 NextSubTest(); 455 CPPUNIT_ASSERT( node.SetTo(existingFile) == B_OK ); 456 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 457 // 458 NextSubTest(); 459 CPPUNIT_ASSERT( node.SetTo(existingDir) == B_OK ); 460 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 461 // 462 NextSubTest(); 463 CPPUNIT_ASSERT( node.SetTo(tooLongEntryname) == B_NAME_TOO_LONG ); 464 CPPUNIT_ASSERT( node.InitCheck() == B_NAME_TOO_LONG ); 465 466 // 3. BNode(const BEntry*) 467 NextSubTest(); 468 BEntry entry(dirLink); 469 CPPUNIT_ASSERT( entry.InitCheck() == B_OK ); 470 CPPUNIT_ASSERT( node.SetTo(&entry) == B_OK ); 471 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 472 // 473 NextSubTest(); 474 CPPUNIT_ASSERT( entry.SetTo(nonExisting) == B_OK ); 475 CPPUNIT_ASSERT( node.SetTo(&entry) == B_ENTRY_NOT_FOUND ); 476 CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND ); 477 // 478 NextSubTest(); 479 CPPUNIT_ASSERT( node.SetTo((BEntry *)NULL) == B_BAD_VALUE ); 480 CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE ); 481 // 482 NextSubTest(); 483 entry.Unset(); 484 CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT ); 485 CPPUNIT_ASSERT( equals(node.SetTo(&entry), B_BAD_ADDRESS, B_BAD_VALUE) ); 486 CPPUNIT_ASSERT( equals(node.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) ); 487 // 488 NextSubTest(); 489 CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK ); 490 CPPUNIT_ASSERT( node.SetTo(&entry) == B_OK ); 491 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 492 // 493 NextSubTest(); 494 CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK ); 495 CPPUNIT_ASSERT( node.SetTo(&entry) == B_OK ); 496 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 497 // 498 NextSubTest(); 499 // R5 returns E2BIG instead of B_NAME_TOO_LONG 500 CPPUNIT_ASSERT( equals(entry.SetTo(tooLongEntryname), E2BIG, B_NAME_TOO_LONG) ); 501 CPPUNIT_ASSERT( equals(node.SetTo(&entry), B_BAD_ADDRESS, B_BAD_VALUE) ); 502 CPPUNIT_ASSERT( equals(node.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) ); 503 504 // 4. BNode(const entry_ref*) 505 NextSubTest(); 506 CPPUNIT_ASSERT( entry.SetTo(dirLink) == B_OK ); 507 entry_ref ref; 508 CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK ); 509 CPPUNIT_ASSERT( node.SetTo(&ref) == B_OK ); 510 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 511 // 512 NextSubTest(); 513 CPPUNIT_ASSERT( entry.SetTo(nonExisting) == B_OK ); 514 CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK ); 515 CPPUNIT_ASSERT( node.SetTo(&ref) == B_ENTRY_NOT_FOUND ); 516 CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND ); 517 // 518 NextSubTest(); 519 CPPUNIT_ASSERT( node.SetTo((entry_ref *)NULL) == B_BAD_VALUE ); 520 CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE ); 521 // 522 NextSubTest(); 523 CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK ); 524 CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK ); 525 CPPUNIT_ASSERT( node.SetTo(&ref) == B_OK ); 526 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 527 // 528 NextSubTest(); 529 CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK ); 530 CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK ); 531 CPPUNIT_ASSERT( node.SetTo(&ref) == B_OK ); 532 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 533 534 // 5. BNode(const BDirectory*, const char*) 535 NextSubTest(); 536 BDirectory pathDir(dirSuperLink); 537 CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK ); 538 CPPUNIT_ASSERT( node.SetTo(&pathDir, dirRelLink) == B_OK ); 539 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 540 // 541 NextSubTest(); 542 CPPUNIT_ASSERT( pathDir.SetTo(dirSuperLink) == B_OK ); 543 CPPUNIT_ASSERT( node.SetTo(&pathDir, dirLink) == B_BAD_VALUE ); 544 CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE ); 545 // 546 NextSubTest(); 547 CPPUNIT_ASSERT( pathDir.SetTo(nonExistingSuper) == B_OK ); 548 CPPUNIT_ASSERT( node.SetTo(&pathDir, nonExistingRel) == B_ENTRY_NOT_FOUND ); 549 CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND ); 550 // 551 NextSubTest(); 552 CPPUNIT_ASSERT( node.SetTo((BDirectory *)NULL, (const char *)NULL) 553 == B_BAD_VALUE ); 554 CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE ); 555 // 556 NextSubTest(); 557 CPPUNIT_ASSERT( node.SetTo((BDirectory *)NULL, dirLink) == B_BAD_VALUE ); 558 CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE ); 559 // 560 NextSubTest(); 561 CPPUNIT_ASSERT( pathDir.SetTo(dirSuperLink) == B_OK ); 562 CPPUNIT_ASSERT( node.SetTo(&pathDir, (const char *)NULL) == B_BAD_VALUE ); 563 CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE ); 564 // 565 NextSubTest(); 566 CPPUNIT_ASSERT( pathDir.SetTo(dirSuperLink) == B_OK ); 567 CPPUNIT_ASSERT(node.SetTo(&pathDir, "") == B_ENTRY_NOT_FOUND); 568 CPPUNIT_ASSERT(node.InitCheck() == B_ENTRY_NOT_FOUND); 569 // 570 NextSubTest(); 571 CPPUNIT_ASSERT( pathDir.SetTo(existingSuperFile) == B_OK ); 572 CPPUNIT_ASSERT( node.SetTo(&pathDir, existingRelFile) == B_OK ); 573 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 574 // 575 NextSubTest(); 576 CPPUNIT_ASSERT( pathDir.SetTo(existingSuperDir) == B_OK ); 577 CPPUNIT_ASSERT( node.SetTo(&pathDir, existingRelDir) == B_OK ); 578 CPPUNIT_ASSERT( node.InitCheck() == B_OK ); 579 // 580 NextSubTest(); 581 CPPUNIT_ASSERT( pathDir.SetTo(tooLongSuperEntryname) == B_OK ); 582 CPPUNIT_ASSERT( node.SetTo(&pathDir, tooLongRelEntryname) == B_NAME_TOO_LONG ); 583 CPPUNIT_ASSERT( node.InitCheck() == B_NAME_TOO_LONG ); 584 // 585 NextSubTest(); 586 CPPUNIT_ASSERT( pathDir.SetTo(fileSuperDirname) == B_OK ); 587 CPPUNIT_ASSERT( node.SetTo(&pathDir, fileRelDirname) == B_ENTRY_NOT_FOUND ); 588 CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND ); 589 } 590 591 // WriteAttributes 592 static 593 void 594 WriteAttributes(BNode &node, const char **attrNames, const char **attrValues, 595 int32 attrCount) 596 { 597 for (int32 i = 0; i < attrCount; i++) { 598 const char *attrName = attrNames[i]; 599 const char *attrValue = attrValues[i]; 600 int32 valueSize = strlen(attrValue) + 1; 601 CPPUNIT_ASSERT( node.WriteAttr(attrName, B_STRING_TYPE, 0, attrValue, 602 valueSize) == valueSize ); 603 } 604 } 605 606 // AttrDirTest 607 void 608 NodeTest::AttrDirTest(BNode &node) 609 { 610 // node should not have any attributes at the beginning 611 char nameBuffer[B_ATTR_NAME_LENGTH]; 612 CPPUNIT_ASSERT( node.GetNextAttrName(nameBuffer) == B_ENTRY_NOT_FOUND ); 613 // add some 614 const char *attrNames[] = { 615 "attr1", "attr2", "attr3", "attr4", "attr5" 616 }; 617 const char *attrValues[] = { 618 "value1", "value2", "value3", "value4", "value5" 619 }; 620 int32 attrCount = sizeof(attrNames) / sizeof(const char *); 621 WriteAttributes(node, attrNames, attrValues, attrCount); 622 TestSet testSet; 623 for (int32 i = 0; i < attrCount; i++) 624 testSet.add(attrNames[i]); 625 // get all attribute names 626 // R5: We have to rewind, we wouldn't get any attribute otherwise. 627 CPPUNIT_ASSERT( node.RewindAttrs() == B_OK ); 628 while (node.GetNextAttrName(nameBuffer) == B_OK) 629 CPPUNIT_ASSERT( testSet.test(nameBuffer) == true ); 630 CPPUNIT_ASSERT( testSet.testDone() == true ); 631 CPPUNIT_ASSERT( node.GetNextAttrName(nameBuffer) == B_ENTRY_NOT_FOUND ); 632 // rewind, get one attribute, rewind again and iterate through the whole 633 // list again 634 CPPUNIT_ASSERT( node.RewindAttrs() == B_OK ); 635 testSet.rewind(); 636 CPPUNIT_ASSERT( node.GetNextAttrName(nameBuffer) == B_OK ); 637 CPPUNIT_ASSERT( testSet.test(nameBuffer) == true ); 638 CPPUNIT_ASSERT( node.RewindAttrs() == B_OK ); 639 testSet.rewind(); 640 while (node.GetNextAttrName(nameBuffer) == B_OK) 641 CPPUNIT_ASSERT( testSet.test(nameBuffer) == true ); 642 CPPUNIT_ASSERT( testSet.testDone() == true ); 643 CPPUNIT_ASSERT( node.GetNextAttrName(nameBuffer) == B_ENTRY_NOT_FOUND ); 644 // bad args 645 CPPUNIT_ASSERT( node.RewindAttrs() == B_OK ); 646 testSet.rewind(); 647 // R5: crashs, if passing a NULL buffer 648 #if !TEST_R5 649 CPPUNIT_ASSERT( node.GetNextAttrName(NULL) == B_BAD_VALUE ); 650 #endif 651 } 652 653 // AttrDirTest 654 void 655 NodeTest::AttrDirTest() 656 { 657 // uninitialized objects 658 NextSubTest(); 659 TestNodes testEntries; 660 CreateUninitializedNodes(testEntries); 661 BNode *node; 662 string nodeName; 663 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 664 char nameBuffer[B_ATTR_NAME_LENGTH]; 665 CPPUNIT_ASSERT( node->RewindAttrs() != B_OK ); 666 CPPUNIT_ASSERT( node->GetNextAttrName(nameBuffer) != B_OK ); 667 } 668 testEntries.delete_all(); 669 // existing entries 670 NextSubTest(); 671 CreateRWNodes(testEntries); 672 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 673 AttrDirTest(*node); 674 } 675 testEntries.delete_all(); 676 } 677 678 // AttrTest 679 void 680 NodeTest::AttrTest(BNode &node) 681 { 682 // add some attributes 683 const char *attrNames[] = { 684 "attr1", "attr2", "attr3", "attr4", "attr5" 685 }; 686 const char *attrValues[] = { 687 "value1", "value2", "value3", "value4", "value5" 688 }; 689 const char *newAttrValues[] = { 690 "fd", "kkgkjsdhfgkjhsd", "lihuhuh", "", "alkfgnakdfjgn" 691 }; 692 int32 attrCount = sizeof(attrNames) / sizeof(const char *); 693 WriteAttributes(node, attrNames, attrValues, attrCount); 694 char buffer[1024]; 695 // read and check them 696 for (int32 i = 0; i < attrCount; i++) { 697 const char *attrName = attrNames[i]; 698 const char *attrValue = attrValues[i]; 699 int32 valueSize = strlen(attrValue) + 1; 700 CPPUNIT_ASSERT( node.ReadAttr(attrName, B_STRING_TYPE, 0, buffer, 701 sizeof(buffer)) == valueSize ); 702 CPPUNIT_ASSERT( strcmp(buffer, attrValue) == 0 ); 703 } 704 // write a new value for each attribute 705 WriteAttributes(node, attrNames, newAttrValues, attrCount); 706 // read and check them 707 for (int32 i = 0; i < attrCount; i++) { 708 const char *attrName = attrNames[i]; 709 const char *attrValue = newAttrValues[i]; 710 int32 valueSize = strlen(attrValue) + 1; 711 CPPUNIT_ASSERT( node.ReadAttr(attrName, B_STRING_TYPE, 0, buffer, 712 sizeof(buffer)) == valueSize ); 713 CPPUNIT_ASSERT( strcmp(buffer, attrValue) == 0 ); 714 } 715 // bad args 716 CPPUNIT_ASSERT( equals(node.ReadAttr(NULL, B_STRING_TYPE, 0, buffer, 717 sizeof(buffer)), 718 B_BAD_ADDRESS, B_BAD_VALUE) ); 719 CPPUNIT_ASSERT( equals(node.ReadAttr(attrNames[0], B_STRING_TYPE, 0, NULL, 720 sizeof(buffer)), 721 B_BAD_ADDRESS, B_BAD_VALUE) ); 722 CPPUNIT_ASSERT( equals(node.ReadAttr(NULL, B_STRING_TYPE, 0, NULL, 723 sizeof(buffer)), 724 B_BAD_ADDRESS, B_BAD_VALUE) ); 725 CPPUNIT_ASSERT( equals(node.WriteAttr(NULL, B_STRING_TYPE, 0, buffer, 726 sizeof(buffer)), 727 B_BAD_ADDRESS, B_BAD_VALUE) ); 728 CPPUNIT_ASSERT( equals(node.WriteAttr(attrNames[0], B_STRING_TYPE, 0, NULL, 729 sizeof(buffer)), 730 B_BAD_ADDRESS, B_BAD_VALUE) ); 731 CPPUNIT_ASSERT( equals(node.WriteAttr(NULL, B_STRING_TYPE, 0, NULL, 732 sizeof(buffer)), 733 B_BAD_ADDRESS, B_BAD_VALUE) ); 734 CPPUNIT_ASSERT( equals(node.RemoveAttr(NULL), B_BAD_ADDRESS, B_BAD_VALUE) ); 735 // too long attribute name 736 // R5: Read/RemoveAttr() do not return B_NAME_TOO_LONG, but B_ENTRY_NOT_FOUND 737 // R5: WriteAttr() does not return B_NAME_TOO_LONG, but B_BAD_VALUE 738 // R5: Haiku has a max attribute size of 256, while R5's was 255, exclusive 739 // of the null terminator. See changeset 4069e1f30. 740 char tooLongAttrName[B_ATTR_NAME_LENGTH + 3]; 741 memset(tooLongAttrName, 'a', B_ATTR_NAME_LENGTH + 1); 742 tooLongAttrName[B_ATTR_NAME_LENGTH + 2] = '\0'; 743 CPPUNIT_ASSERT_EQUAL( 744 node.WriteAttr(tooLongAttrName, B_STRING_TYPE, 0, buffer, 745 sizeof(buffer)), 746 B_NAME_TOO_LONG); 747 CPPUNIT_ASSERT_EQUAL( 748 node.ReadAttr(tooLongAttrName, B_STRING_TYPE, 0, buffer, 749 sizeof(buffer)), 750 B_NAME_TOO_LONG); 751 CPPUNIT_ASSERT_EQUAL(node.RemoveAttr(tooLongAttrName), B_NAME_TOO_LONG); 752 753 // remove the attributes and try to read them 754 for (int32 i = 0; i < attrCount; i++) { 755 const char *attrName = attrNames[i]; 756 CPPUNIT_ASSERT( node.RemoveAttr(attrName) == B_OK ); 757 CPPUNIT_ASSERT( node.ReadAttr(attrName, B_STRING_TYPE, 0, buffer, 758 sizeof(buffer)) == B_ENTRY_NOT_FOUND ); 759 } 760 // try to remove a non-existing attribute 761 CPPUNIT_ASSERT( node.RemoveAttr("non existing attribute") 762 == B_ENTRY_NOT_FOUND ); 763 } 764 765 // AttrTest 766 void 767 NodeTest::AttrTest() 768 { 769 // uninitialized objects 770 NextSubTest(); 771 TestNodes testEntries; 772 CreateUninitializedNodes(testEntries); 773 BNode *node; 774 string nodeName; 775 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 776 char buffer[1024]; 777 CPPUNIT_ASSERT( node->ReadAttr("attr1", B_STRING_TYPE, 0, buffer, 778 sizeof(buffer)) == B_FILE_ERROR ); 779 CPPUNIT_ASSERT( node->WriteAttr("attr1", B_STRING_TYPE, 0, buffer, 780 sizeof(buffer)) == B_FILE_ERROR ); 781 CPPUNIT_ASSERT( node->RemoveAttr("attr1") == B_FILE_ERROR ); 782 } 783 testEntries.delete_all(); 784 // existing entries 785 NextSubTest(); 786 CreateRWNodes(testEntries); 787 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 788 AttrTest(*node); 789 } 790 testEntries.delete_all(); 791 } 792 793 // AttrRenameTest 794 void 795 NodeTest::AttrRenameTest(BNode &node) 796 { 797 const char attr1[] = "StorageKit::SomeAttribute"; 798 const char attr2[] = "StorageKit::AnotherAttribute"; 799 800 CPPUNIT_ASSERT( node.SetTo("./") == B_OK ); 801 802 // Test the case of the first attribute not existing 803 node.RemoveAttr(attr1); 804 805 #if 1 806 // The actual tests in the else block below are disabled because as of 807 // right now, BFS doesn't support attribute rename. bfs_rename_attr() 808 // always reutrns B_NOT_SUPPORTED, which means BNode::RenameAttr() will 809 // also always return that result. 810 // 811 // So until that is implemented, we'll just test for B_NOT_SUPPORTED here. 812 // Once that functionality is implemented, this test will pass and someone 813 // can remove this section. 814 CPPUNIT_ASSERT_EQUAL(node.RenameAttr(attr1, attr2), B_NOT_SUPPORTED); 815 #else 816 const char str[] = "This is my testing string and it rules your world."; 817 const int strLen = strlen(str) + 1; 818 const int dataLen = 1024; 819 char data[dataLen]; 820 821 CPPUNIT_ASSERT( node.RenameAttr(attr1, attr2) == B_BAD_VALUE ); 822 823 // Write an attribute, read it to verify it, rename it, read the 824 // new attribute, read the old (which fails), and then remove the new. 825 CPPUNIT_ASSERT( node.WriteAttr(attr1, B_STRING_TYPE, 0, str, strLen) == strLen ); 826 CPPUNIT_ASSERT( node.ReadAttr(attr1, B_STRING_TYPE, 0, data, dataLen) == strLen ); 827 CPPUNIT_ASSERT( strcmp(data, str) == 0 ); 828 CPPUNIT_ASSERT( node.RenameAttr(attr1, attr2) == B_OK ); // <<< This fails with R5::BNode 829 CPPUNIT_ASSERT( node.ReadAttr(attr1, B_STRING_TYPE, 0, data, dataLen) == B_ENTRY_NOT_FOUND ); 830 CPPUNIT_ASSERT( node.ReadAttr(attr2, B_STRING_TYPE, 0, data, dataLen) == strLen ); 831 CPPUNIT_ASSERT( strcmp(data, str) == 0 ); 832 CPPUNIT_ASSERT( node.RemoveAttr(attr2) == B_OK ); 833 834 // bad args 835 CPPUNIT_ASSERT( equals(node.RenameAttr(attr1, NULL), B_BAD_ADDRESS, 836 B_BAD_VALUE) ); 837 CPPUNIT_ASSERT( equals(node.RenameAttr(NULL, attr2), B_BAD_ADDRESS, 838 B_BAD_VALUE) ); 839 CPPUNIT_ASSERT( equals(node.RenameAttr(NULL, NULL), B_BAD_ADDRESS, 840 B_BAD_VALUE) ); 841 // too long attribute name 842 // R5: RenameAttr() returns B_BAD_VALUE instead of B_NAME_TOO_LONG 843 char tooLongAttrName[B_ATTR_NAME_LENGTH + 2]; 844 memset(tooLongAttrName, 'a', B_ATTR_NAME_LENGTH); 845 tooLongAttrName[B_ATTR_NAME_LENGTH + 1] = '\0'; 846 CPPUNIT_ASSERT( node.RenameAttr(attr1, tooLongAttrName) 847 == B_BAD_VALUE ); 848 CPPUNIT_ASSERT( node.RenameAttr(tooLongAttrName, attr1) 849 == B_BAD_VALUE ); 850 #endif 851 } 852 853 854 // AttrRenameTest 855 void 856 NodeTest::AttrRenameTest() 857 { 858 // uninitialized objects 859 NextSubTest(); 860 TestNodes testEntries; 861 CreateUninitializedNodes(testEntries); 862 BNode *node; 863 string nodeName; 864 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 865 CPPUNIT_ASSERT( node->RenameAttr("attr1", "attr2") == B_FILE_ERROR ); 866 } 867 testEntries.delete_all(); 868 // existing entries 869 NextSubTest(); 870 CreateRWNodes(testEntries); 871 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 872 AttrRenameTest(*node); 873 } 874 testEntries.delete_all(); 875 } 876 877 // AttrInfoTest 878 void 879 NodeTest::AttrInfoTest(BNode &node) 880 { 881 // add some attributes 882 const char *attrNames[] = { 883 "attr1", "attr2", "attr3", "attr4", "attr5" 884 }; 885 const int32 attrCount = sizeof(attrNames) / sizeof(const char*); 886 const char attrValue1[] = "This is the greatest string ever."; 887 int32 attrValue2 = 17; 888 uint64 attrValue3 = 42; 889 double attrValue4 = 435.5; 890 struct flat_entry_ref { dev_t device; ino_t directory; char name[256]; } 891 attrValue5 = { 9, 16, "Hello world!" }; 892 const void *attrValues[] = { 893 attrValue1, &attrValue2, &attrValue3, &attrValue4, &attrValue5 894 }; 895 attr_info attrInfos[] = { 896 { B_STRING_TYPE, sizeof(attrValue1) }, 897 { B_INT32_TYPE, sizeof(attrValue2) }, 898 { B_UINT64_TYPE, sizeof(attrValue3) }, 899 { B_DOUBLE_TYPE, sizeof(attrValue4) }, 900 { B_REF_TYPE, sizeof(attrValue5) } 901 }; 902 for (int32 i = 0; i < attrCount; i++) { 903 const char *attrName = attrNames[i]; 904 const void *attrValue = attrValues[i]; 905 int32 valueSize = attrInfos[i].size; 906 uint32 attrType = attrInfos[i].type; 907 CPPUNIT_ASSERT( node.WriteAttr(attrName, attrType, 0, attrValue, 908 valueSize) == valueSize ); 909 } 910 // get the attribute infos 911 for (int32 i = 0; i < attrCount; i++) { 912 const char *attrName = attrNames[i]; 913 attr_info info; 914 CPPUNIT_ASSERT( node.GetAttrInfo(attrName, &info) == B_OK ); 915 CPPUNIT_ASSERT( info == attrInfos[i] ); 916 } 917 // try get an info for a non-existing attribute 918 attr_info info; 919 CPPUNIT_ASSERT( node.GetAttrInfo("non-existing attribute", &info) 920 == B_ENTRY_NOT_FOUND ); 921 // bad values 922 CPPUNIT_ASSERT( equals(node.GetAttrInfo(NULL, &info), B_BAD_ADDRESS, 923 B_BAD_VALUE) ); 924 CPPUNIT_ASSERT( equals(node.GetAttrInfo(attrNames[0], NULL), B_BAD_ADDRESS, 925 B_BAD_VALUE) ); 926 CPPUNIT_ASSERT( equals(node.GetAttrInfo(NULL, NULL), B_BAD_ADDRESS, 927 B_BAD_VALUE) ); 928 // too long attribute name 929 // R5: GetAttrInfo() does not return B_NAME_TOO_LONG 930 char tooLongAttrName[B_ATTR_NAME_LENGTH + 2]; 931 memset(tooLongAttrName, 'a', B_ATTR_NAME_LENGTH); 932 tooLongAttrName[B_ATTR_NAME_LENGTH + 1] = '\0'; 933 CPPUNIT_ASSERT( node.GetAttrInfo(tooLongAttrName, &info) 934 == B_ENTRY_NOT_FOUND ); 935 } 936 937 // AttrInfoTest 938 void 939 NodeTest::AttrInfoTest() 940 { 941 // uninitialized objects 942 NextSubTest(); 943 TestNodes testEntries; 944 CreateUninitializedNodes(testEntries); 945 BNode *node; 946 string nodeName; 947 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 948 attr_info info; 949 CPPUNIT_ASSERT( node->GetAttrInfo("attr1", &info) == B_FILE_ERROR ); 950 } 951 testEntries.delete_all(); 952 // existing entries 953 NextSubTest(); 954 CreateRWNodes(testEntries); 955 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 956 AttrInfoTest(*node); 957 } 958 testEntries.delete_all(); 959 } 960 961 // AttrBStringTest 962 void 963 NodeTest::AttrBStringTest(BNode &node) 964 { 965 // add some attributes 966 const char *attrNames[] = { 967 "attr1", "attr2", "attr3", "attr4", "attr5" 968 }; 969 const char *attrValues[] = { 970 "value1", "value2", "value3", "value4", "value5" 971 }; 972 const char *newAttrValues[] = { 973 "fd", "kkgkjsdhfgkjhsd", "lihuhuh", "", "alkfgnakdfjgn" 974 }; 975 int32 attrCount = sizeof(attrNames) / sizeof(const char *); 976 for (int32 i = 0; i < attrCount; i++) { 977 const char *attrName = attrNames[i]; 978 BString attrValue(attrValues[i]); 979 CPPUNIT_ASSERT( node.WriteAttrString(attrName, &attrValue) == B_OK ); 980 } 981 // read and check them 982 for (int32 i = 0; i < attrCount; i++) { 983 const char *attrName = attrNames[i]; 984 const char *attrValue = attrValues[i]; 985 BString readValue; 986 CPPUNIT_ASSERT( node.ReadAttrString(attrName, &readValue) == B_OK ); 987 CPPUNIT_ASSERT( readValue == attrValue ); 988 } 989 // write a new value for each attribute 990 for (int32 i = 0; i < attrCount; i++) { 991 const char *attrName = attrNames[i]; 992 BString attrValue(newAttrValues[i]); 993 CPPUNIT_ASSERT( node.WriteAttrString(attrName, &attrValue) == B_OK ); 994 } 995 // read and check them 996 for (int32 i = 0; i < attrCount; i++) { 997 const char *attrName = attrNames[i]; 998 const char *attrValue = newAttrValues[i]; 999 BString readValue; 1000 CPPUNIT_ASSERT( node.ReadAttrString(attrName, &readValue) == B_OK ); 1001 CPPUNIT_ASSERT( readValue == attrValue ); 1002 } 1003 // bad args 1004 BString readValue; 1005 BString writeValue("test"); 1006 // R5: crashes, if supplying a NULL BString 1007 #if !TEST_R5 1008 CPPUNIT_ASSERT( node.WriteAttrString(attrNames[0], NULL) == B_BAD_VALUE ); 1009 CPPUNIT_ASSERT( node.ReadAttrString(attrNames[0], NULL) == B_BAD_VALUE ); 1010 #endif 1011 CPPUNIT_ASSERT( equals(node.WriteAttrString(NULL, &writeValue), 1012 B_BAD_ADDRESS, B_BAD_VALUE) ); 1013 CPPUNIT_ASSERT( equals(node.ReadAttrString(NULL, &readValue), 1014 B_BAD_ADDRESS, B_BAD_VALUE) ); 1015 #if !TEST_R5 1016 CPPUNIT_ASSERT( node.WriteAttrString(NULL, NULL) == B_BAD_VALUE ); 1017 #endif 1018 CPPUNIT_ASSERT( equals(node.ReadAttrString(NULL, NULL), 1019 B_BAD_ADDRESS, B_BAD_VALUE) ); 1020 // remove the attributes and try to read them 1021 for (int32 i = 0; i < attrCount; i++) { 1022 const char *attrName = attrNames[i]; 1023 CPPUNIT_ASSERT( node.RemoveAttr(attrName) == B_OK ); 1024 CPPUNIT_ASSERT( node.ReadAttrString(attrName, &readValue) 1025 == B_ENTRY_NOT_FOUND ); 1026 } 1027 // too long attribute name 1028 // R5: Read/WriteAttrString() do not return B_NAME_TOO_LONG 1029 char tooLongAttrName[B_ATTR_NAME_LENGTH + 2]; 1030 memset(tooLongAttrName, 'a', B_ATTR_NAME_LENGTH); 1031 tooLongAttrName[B_ATTR_NAME_LENGTH + 1] = '\0'; 1032 CPPUNIT_ASSERT( node.WriteAttrString(tooLongAttrName, &writeValue) 1033 == B_BAD_VALUE ); 1034 CPPUNIT_ASSERT( node.ReadAttrString(tooLongAttrName, &readValue) 1035 == B_ENTRY_NOT_FOUND ); 1036 } 1037 1038 // AttrBStringTest 1039 void 1040 NodeTest::AttrBStringTest() 1041 { 1042 // uninitialized objects 1043 NextSubTest(); 1044 TestNodes testEntries; 1045 CreateUninitializedNodes(testEntries); 1046 BNode *node; 1047 string nodeName; 1048 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 1049 BString value("test"); 1050 CPPUNIT_ASSERT( node->WriteAttrString("attr1", &value) 1051 == B_FILE_ERROR ); 1052 CPPUNIT_ASSERT( node->ReadAttrString("attr1", &value) 1053 == B_FILE_ERROR ); 1054 } 1055 testEntries.delete_all(); 1056 // existing entries 1057 NextSubTest(); 1058 CreateRWNodes(testEntries); 1059 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 1060 AttrBStringTest(*node); 1061 } 1062 testEntries.delete_all(); 1063 } 1064 1065 // This doesn't actually verify synching is occuring; just 1066 // checks for a B_OK return value. 1067 void 1068 NodeTest::SyncTest() { 1069 const char attr[] = "StorageKit::SomeAttribute"; 1070 const char str[] = "This string rules your world."; 1071 const int len = strlen(str) + 1; 1072 // uninitialized objects 1073 NextSubTest(); 1074 TestNodes testEntries; 1075 CreateUninitializedNodes(testEntries); 1076 BNode *node; 1077 string nodeName; 1078 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 1079 CPPUNIT_ASSERT( node->Sync() == B_FILE_ERROR ); 1080 } 1081 testEntries.delete_all(); 1082 // existing entries 1083 NextSubTest(); 1084 CreateRWNodes(testEntries); 1085 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 1086 CPPUNIT_ASSERT( node->WriteAttr(attr, B_STRING_TYPE, 0, str, len) 1087 == len ); 1088 CPPUNIT_ASSERT( node->Sync() == B_OK ); 1089 } 1090 testEntries.delete_all(); 1091 } 1092 1093 // DupTest 1094 void 1095 NodeTest::DupTest(BNode &node) 1096 { 1097 int fd = node.Dup(); 1098 CPPUNIT_ASSERT( fd != -1 ); 1099 ::close(fd); 1100 } 1101 1102 // DupTest 1103 void 1104 NodeTest::DupTest() 1105 { 1106 // uninitialized objects 1107 NextSubTest(); 1108 TestNodes testEntries; 1109 CreateUninitializedNodes(testEntries); 1110 BNode *node; 1111 string nodeName; 1112 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 1113 CPPUNIT_ASSERT( node->Dup() == -1 ); 1114 } 1115 testEntries.delete_all(); 1116 // existing entries 1117 NextSubTest(); 1118 CreateRWNodes(testEntries); 1119 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 1120 DupTest(*node); 1121 } 1122 testEntries.delete_all(); 1123 } 1124 1125 // n1 and n2 should both be uninitialized. y1a and y1b should be initialized 1126 // to the same node, y2 should be initialized to a different node 1127 void 1128 NodeTest::EqualityTest(BNode &n1, BNode &n2, BNode &y1a, BNode &y1b, BNode &y2) { 1129 CPPUNIT_ASSERT( n1 == n2 ); 1130 CPPUNIT_ASSERT( !(n1 != n2) ); 1131 CPPUNIT_ASSERT( n1 != y2 ); 1132 CPPUNIT_ASSERT( !(n1 == y2) ); 1133 1134 CPPUNIT_ASSERT( y1a != n2 ); 1135 CPPUNIT_ASSERT( !(y1a == n2) ); 1136 CPPUNIT_ASSERT( y1a == y1b ); 1137 CPPUNIT_ASSERT( !(y1a != y1b) ); 1138 CPPUNIT_ASSERT( y1a != y2 ); 1139 CPPUNIT_ASSERT( !(y1a == y2) ); 1140 1141 CPPUNIT_ASSERT( n1 == n1 ); 1142 CPPUNIT_ASSERT( !(n1 != n1) ); 1143 CPPUNIT_ASSERT( y2 == y2 ); 1144 CPPUNIT_ASSERT( !(y2 != y2) ); 1145 } 1146 1147 // EqualityTest 1148 void 1149 NodeTest::EqualityTest() 1150 { 1151 BNode n1, n2, y1a("/boot"), y1b("/boot"), y2("/"); 1152 1153 EqualityTest(n1, n2, y1a, y1b, y2); 1154 } 1155 1156 // AssignmentTest 1157 void 1158 NodeTest::AssignmentTest() 1159 { 1160 BNode n1, n2, y1a("/boot"), y1b("/boot"), y2("/"); 1161 1162 n1 = n1; // self n 1163 y1a = y1b; // psuedo self y 1164 y1a = y1a; // self y 1165 n2 = y2; // n = y 1166 y1b = n1; // y = n 1167 y2 = y1a; // y1 = y2 1168 1169 EqualityTest(n1, y1b, y1a, y2, n2); 1170 } 1171 1172 // Locking isn't really implemented yet... 1173 void 1174 NodeTest::LockTest(BNode &node, const char *entryName) 1175 { 1176 CPPUNIT_ASSERT( node.Lock() == B_OK ); 1177 BNode node2(entryName); 1178 CPPUNIT_ASSERT( node2.InitCheck() == B_BUSY ); 1179 CPPUNIT_ASSERT( node.Unlock() == B_OK ); 1180 CPPUNIT_ASSERT( node.Unlock() == B_BAD_VALUE ); 1181 CPPUNIT_ASSERT( node2.SetTo(entryName) == B_OK ); 1182 // R5: Since two file descriptors exist at this point, locking is supposed 1183 // to fail according to the BeBook, but it succeeds! 1184 CPPUNIT_ASSERT( node2.Lock() == B_OK ); 1185 CPPUNIT_ASSERT( node.Lock() == B_BUSY ); 1186 // 1187 CPPUNIT_ASSERT( node2.Unlock() == B_OK ); 1188 } 1189 1190 // Locking isn't really implemented yet... 1191 void 1192 NodeTest::LockTest() 1193 { 1194 // uninitialized objects 1195 NextSubTest(); 1196 TestNodes testEntries; 1197 CreateUninitializedNodes(testEntries); 1198 BNode *node; 1199 string nodeName; 1200 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 1201 CPPUNIT_ASSERT( node->Dup() == -1 ); 1202 } 1203 testEntries.delete_all(); 1204 // existing entries 1205 NextSubTest(); 1206 CreateRWNodes(testEntries); 1207 for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) { 1208 LockTest(*node, nodeName.c_str()); 1209 } 1210 testEntries.delete_all(); 1211 } 1212 1213 // entry names used in tests 1214 const char *NodeTest::existingFilename = "/tmp/existing-file"; 1215 const char *NodeTest::existingSuperFilename = "/tmp"; 1216 const char *NodeTest::existingRelFilename = "existing-file"; 1217 const char *NodeTest::existingDirname = "/tmp/existing-dir"; 1218 const char *NodeTest::existingSuperDirname = "/tmp"; 1219 const char *NodeTest::existingRelDirname = "existing-dir"; 1220 const char *NodeTest::existingSubDirname 1221 = "/tmp/existing-dir/existing-subdir"; 1222 const char *NodeTest::existingRelSubDirname = "existing-subdir"; 1223 const char *NodeTest::nonExistingFilename = "/tmp/non-existing-file"; 1224 const char *NodeTest::nonExistingDirname = "/tmp/non-existing-dir"; 1225 const char *NodeTest::nonExistingSuperDirname = "/tmp"; 1226 const char *NodeTest::nonExistingRelDirname = "non-existing-dir"; 1227 const char *NodeTest::testFilename1 = "/tmp/test-file1"; 1228 const char *NodeTest::testDirname1 = "/tmp/test-dir1"; 1229 const char *NodeTest::tooLongEntryname = 1230 "/tmp/This is an awfully long name for an entry. It is that kind of entry " 1231 "that just can't exist due to its long name. In fact its path name is not " 1232 "too long -- a path name can contain 1024 characters -- but the name of " 1233 "the entry itself is restricted to 256 characters, which this entry's " 1234 "name does exceed."; 1235 const char *NodeTest::tooLongSuperEntryname = "/tmp"; 1236 const char *NodeTest::tooLongRelEntryname = 1237 "This is an awfully long name for an entry. It is that kind of entry " 1238 "that just can't exist due to its long name. In fact its path name is not " 1239 "too long -- a path name can contain 1024 characters -- but the name of " 1240 "the entry itself is restricted to 256 characters, which this entry's " 1241 "name does exceed."; 1242 const char *NodeTest::fileDirname = "/tmp/test-file1/some-dir"; 1243 const char *NodeTest::fileSuperDirname = "/tmp"; 1244 const char *NodeTest::fileRelDirname = "test-file1/some-dir"; 1245 const char *NodeTest::dirLinkname = "/tmp/link-to-dir1"; 1246 const char *NodeTest::dirSuperLinkname = "/tmp"; 1247 const char *NodeTest::dirRelLinkname = "link-to-dir1"; 1248 const char *NodeTest::fileLinkname = "/tmp/link-to-file1"; 1249 const char *NodeTest::fileSuperLinkname = "/tmp"; 1250 const char *NodeTest::fileRelLinkname = "link-to-file1"; 1251 const char *NodeTest::relDirLinkname = "/tmp/rel-link-to-dir1"; 1252 const char *NodeTest::relFileLinkname = "/tmp/rel-link-to-file1"; 1253 const char *NodeTest::badLinkname = "/tmp/link-to-void"; 1254 const char *NodeTest::cyclicLinkname1 = "/tmp/cyclic-link1"; 1255 const char *NodeTest::cyclicLinkname2 = "/tmp/cyclic-link2"; 1256 1257 const char *NodeTest::allFilenames[] = { 1258 existingFilename, 1259 existingDirname, 1260 nonExistingFilename, 1261 nonExistingDirname, 1262 testFilename1, 1263 testDirname1, 1264 dirLinkname, 1265 fileLinkname, 1266 relDirLinkname, 1267 relFileLinkname, 1268 badLinkname, 1269 cyclicLinkname1, 1270 cyclicLinkname2, 1271 }; 1272 const int32 NodeTest::allFilenameCount 1273 = sizeof(allFilenames) / sizeof(const char*); 1274 1275