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