aad997bd6c
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@292 a95241bf-73f2-0310-859d-f6bbb57e9c96
1258 lines
39 KiB
C++
1258 lines
39 KiB
C++
// NodeTest.cpp
|
|
|
|
#include <cppunit/TestCase.h>
|
|
#include <cppunit/TestCaller.h>
|
|
#include <cppunit/TestSuite.h>
|
|
#include <TestUtils.h>
|
|
#include <NodeTest.h>
|
|
|
|
#include <errno.h>
|
|
#include <fs_attr.h> // For struct attr_info
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <sys/stat.h> // For struct stat
|
|
|
|
#include <Directory.h>
|
|
#include <Entry.h>
|
|
#include <Node.h>
|
|
#include <StorageDefs.h>
|
|
#include <String.h>
|
|
#include <TypeConstants.h>
|
|
|
|
|
|
// == for attr_info
|
|
static
|
|
inline
|
|
bool
|
|
operator==(const attr_info &info1, const attr_info &info2)
|
|
{
|
|
return (info1.type == info2.type && info1.size == info2.size);
|
|
}
|
|
|
|
// Suite
|
|
CppUnit::Test*
|
|
NodeTest::Suite() {
|
|
CppUnit::TestSuite *suite = new CppUnit::TestSuite();
|
|
|
|
StatableTest::AddBaseClassTests<NodeTest>("BNode::", suite);
|
|
|
|
suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Init Test1", &NodeTest::InitTest1) );
|
|
suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Init Test2", &NodeTest::InitTest2) );
|
|
suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Attribute Directory Test", &NodeTest::AttrDirTest) );
|
|
suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Attribute Read/Write/Remove Test", &NodeTest::AttrTest) );
|
|
suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Attribute Rename Test"
|
|
#if TEST_R5
|
|
" (NOTE: test not actually performed with R5 libraries)"
|
|
#endif
|
|
, &NodeTest::AttrRenameTest) );
|
|
suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Attribute Info Test", &NodeTest::AttrInfoTest) );
|
|
suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Attribute BString Test", &NodeTest::AttrBStringTest) );
|
|
suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Sync Test", &NodeTest::SyncTest) );
|
|
suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Dup Test", &NodeTest::DupTest) );
|
|
suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Equality Test", &NodeTest::EqualityTest) );
|
|
suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Assignment Test", &NodeTest::AssignmentTest) );
|
|
suite->addTest( new CppUnit::TestCaller<NodeTest>("BNode::Lock Test"
|
|
#if TEST_OBOS /* !!!POSIX ONLY!!! */
|
|
" (NOTE: test not actually performed with OpenBeOS Posix libraries)"
|
|
#endif
|
|
, &NodeTest::LockTest) );
|
|
|
|
return suite;
|
|
}
|
|
|
|
// ConvertTestNodesToStatables
|
|
static
|
|
void
|
|
ConvertTestStatablesToNodes(TestNodes& testNodes, TestStatables& testStatables)
|
|
{
|
|
BNode *node;
|
|
string entryName;
|
|
for (testNodes.rewind(); testNodes.getNext(node, entryName); )
|
|
testStatables.add(node, entryName);
|
|
testNodes.clear(); // avoid deletion
|
|
}
|
|
|
|
// CreateROStatables
|
|
void
|
|
NodeTest::CreateROStatables(TestStatables& testEntries)
|
|
{
|
|
TestNodes testNodes;
|
|
CreateRONodes(testNodes);
|
|
ConvertTestStatablesToNodes(testNodes, testEntries);
|
|
}
|
|
|
|
// CreateRWStatables
|
|
void
|
|
NodeTest::CreateRWStatables(TestStatables& testEntries)
|
|
{
|
|
TestNodes testNodes;
|
|
CreateRWNodes(testNodes);
|
|
ConvertTestStatablesToNodes(testNodes, testEntries);
|
|
}
|
|
|
|
// CreateUninitializedStatables
|
|
void
|
|
NodeTest::CreateUninitializedStatables(TestStatables& testEntries)
|
|
{
|
|
TestNodes testNodes;
|
|
CreateUninitializedNodes(testNodes);
|
|
ConvertTestStatablesToNodes(testNodes, testEntries);
|
|
}
|
|
|
|
// CreateRONodes
|
|
void
|
|
NodeTest::CreateRONodes(TestNodes& testEntries)
|
|
{
|
|
const char *filename;
|
|
filename = "/tmp";
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = "/";
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = "/boot";
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = "/boot/home";
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = "/boot/home/Desktop";
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = existingFilename;
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = dirLinkname;
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = fileLinkname;
|
|
testEntries.add(new BNode(filename), filename);
|
|
}
|
|
|
|
// CreateRWNodes
|
|
void
|
|
NodeTest::CreateRWNodes(TestNodes& testEntries)
|
|
{
|
|
const char *filename;
|
|
filename = existingFilename;
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = existingDirname;
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = existingSubDirname;
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = dirLinkname;
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = fileLinkname;
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = relDirLinkname;
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = relFileLinkname;
|
|
testEntries.add(new BNode(filename), filename);
|
|
filename = cyclicLinkname1;
|
|
testEntries.add(new BNode(filename), filename);
|
|
}
|
|
|
|
// CreateUninitializedNodes
|
|
void
|
|
NodeTest::CreateUninitializedNodes(TestNodes& testEntries)
|
|
{
|
|
testEntries.add(new BNode, "");
|
|
}
|
|
|
|
// setUp
|
|
void
|
|
NodeTest::setUp()
|
|
{
|
|
StatableTest::setUp();
|
|
execCommand(
|
|
string("touch ") + existingFilename
|
|
+ "; mkdir " + existingDirname
|
|
+ "; mkdir " + existingSubDirname
|
|
+ "; ln -s " + existingDirname + " " + dirLinkname
|
|
+ "; ln -s " + existingFilename + " " + fileLinkname
|
|
+ "; ln -s " + existingRelDirname + " " + relDirLinkname
|
|
+ "; ln -s " + existingRelFilename + " " + relFileLinkname
|
|
+ "; ln -s " + nonExistingDirname + " " + badLinkname
|
|
+ "; ln -s " + cyclicLinkname1 + " " + cyclicLinkname2
|
|
+ "; ln -s " + cyclicLinkname2 + " " + cyclicLinkname1
|
|
);
|
|
}
|
|
|
|
// tearDown
|
|
void
|
|
NodeTest::tearDown()
|
|
{
|
|
StatableTest::tearDown();
|
|
// cleanup
|
|
string cmdLine("rm -rf ");
|
|
for (int32 i = 0; i < allFilenameCount; i++)
|
|
cmdLine += string(" ") + allFilenames[i];
|
|
if (allFilenameCount > 0)
|
|
execCommand(cmdLine);
|
|
}
|
|
|
|
// InitTest1
|
|
void
|
|
NodeTest::InitTest1()
|
|
{
|
|
const char *dirLink = dirLinkname;
|
|
const char *dirSuperLink = dirSuperLinkname;
|
|
const char *dirRelLink = dirRelLinkname;
|
|
const char *fileLink = fileLinkname;
|
|
const char *existingDir = existingDirname;
|
|
const char *existingSuperDir = existingSuperDirname;
|
|
const char *existingRelDir = existingRelDirname;
|
|
const char *existingFile = existingFilename;
|
|
const char *existingSuperFile = existingSuperFilename;
|
|
const char *existingRelFile = existingRelFilename;
|
|
const char *nonExisting = nonExistingDirname;
|
|
const char *nonExistingSuper = nonExistingSuperDirname;
|
|
const char *nonExistingRel = nonExistingRelDirname;
|
|
// 1. default constructor
|
|
NextSubTest();
|
|
{
|
|
BNode node;
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_NO_INIT );
|
|
}
|
|
|
|
// 2. BNode(const char*)
|
|
NextSubTest();
|
|
{
|
|
BNode node(fileLink);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BNode node(nonExisting);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BNode node((const char *)NULL);
|
|
CPPUNIT_ASSERT( equals(node.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BNode node("");
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BNode node(existingFile);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BNode node(existingDir);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BNode node(tooLongEntryname);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_NAME_TOO_LONG );
|
|
}
|
|
|
|
// 3. BNode(const BEntry*)
|
|
NextSubTest();
|
|
{
|
|
BEntry entry(dirLink);
|
|
CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
|
|
BNode node(&entry);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BEntry entry(nonExisting);
|
|
CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
|
|
BNode node(&entry);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BNode node((BEntry *)NULL);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BEntry entry;
|
|
BNode node(&entry);
|
|
CPPUNIT_ASSERT( equals(node.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BEntry entry(existingFile);
|
|
CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
|
|
BNode node(&entry);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BEntry entry(existingDir);
|
|
CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
|
|
BNode node(&entry);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BEntry entry(tooLongEntryname);
|
|
// R5 returns E2BIG instead of B_NAME_TOO_LONG
|
|
CPPUNIT_ASSERT( equals(entry.InitCheck(), E2BIG, B_NAME_TOO_LONG) );
|
|
BNode node(&entry);
|
|
CPPUNIT_ASSERT( equals(node.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
}
|
|
|
|
// 4. BNode(const entry_ref*)
|
|
NextSubTest();
|
|
{
|
|
BEntry entry(dirLink);
|
|
CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
|
|
entry_ref ref;
|
|
CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
|
|
BNode node(&ref);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BEntry entry(nonExisting);
|
|
CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
|
|
entry_ref ref;
|
|
CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
|
|
BNode node(&ref);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BNode node((entry_ref *)NULL);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BEntry entry(existingFile);
|
|
CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
|
|
entry_ref ref;
|
|
CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
|
|
BNode node(&ref);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BEntry entry(existingDir);
|
|
CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
|
|
entry_ref ref;
|
|
CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
|
|
BNode node(&ref);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
}
|
|
|
|
// 5. BNode(const BDirectory*, const char*)
|
|
NextSubTest();
|
|
{
|
|
BDirectory pathDir(dirSuperLink);
|
|
CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
|
|
BNode node(&pathDir, dirRelLink);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BDirectory pathDir(dirSuperLink);
|
|
CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
|
|
BNode node(&pathDir, dirLink);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BDirectory pathDir(nonExistingSuper);
|
|
CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
|
|
BNode node(&pathDir, nonExistingRel);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BNode node((BDirectory *)NULL, (const char *)NULL);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BNode node((BDirectory *)NULL, dirLink);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BDirectory pathDir(dirSuperLink);
|
|
CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
|
|
BNode node(&pathDir, (const char *)NULL);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BDirectory pathDir(dirSuperLink);
|
|
CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
|
|
BNode node(&pathDir, "");
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BDirectory pathDir(existingSuperFile);
|
|
CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
|
|
BNode node(&pathDir, existingRelFile);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BDirectory pathDir(existingSuperDir);
|
|
CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
|
|
BNode node(&pathDir, existingRelDir);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BDirectory pathDir(tooLongSuperEntryname);
|
|
CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
|
|
BNode node(&pathDir, tooLongRelEntryname);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_NAME_TOO_LONG );
|
|
}
|
|
NextSubTest();
|
|
{
|
|
BDirectory pathDir(fileSuperDirname);
|
|
CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
|
|
BNode node(&pathDir, fileRelDirname);
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND );
|
|
}
|
|
}
|
|
|
|
// InitTest2
|
|
void
|
|
NodeTest::InitTest2()
|
|
{
|
|
const char *dirLink = dirLinkname;
|
|
const char *dirSuperLink = dirSuperLinkname;
|
|
const char *dirRelLink = dirRelLinkname;
|
|
const char *fileLink = fileLinkname;
|
|
const char *existingDir = existingDirname;
|
|
const char *existingSuperDir = existingSuperDirname;
|
|
const char *existingRelDir = existingRelDirname;
|
|
const char *existingFile = existingFilename;
|
|
const char *existingSuperFile = existingSuperFilename;
|
|
const char *existingRelFile = existingRelFilename;
|
|
const char *nonExisting = nonExistingDirname;
|
|
const char *nonExistingSuper = nonExistingSuperDirname;
|
|
const char *nonExistingRel = nonExistingRelDirname;
|
|
BNode node;
|
|
// 2. BNode(const char*)
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( node.SetTo(fileLink) == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( node.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( equals(node.SetTo((const char *)NULL), B_BAD_VALUE,
|
|
B_NO_INIT) );
|
|
CPPUNIT_ASSERT( equals(node.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( node.SetTo("") == B_ENTRY_NOT_FOUND );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( node.SetTo(existingFile) == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( node.SetTo(existingDir) == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( node.SetTo(tooLongEntryname) == B_NAME_TOO_LONG );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_NAME_TOO_LONG );
|
|
|
|
// 3. BNode(const BEntry*)
|
|
NextSubTest();
|
|
BEntry entry(dirLink);
|
|
CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&entry) == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( entry.SetTo(nonExisting) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&entry) == B_ENTRY_NOT_FOUND );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( node.SetTo((BEntry *)NULL) == B_BAD_VALUE );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE );
|
|
//
|
|
NextSubTest();
|
|
entry.Unset();
|
|
CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
|
|
CPPUNIT_ASSERT( equals(node.SetTo(&entry), B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&entry) == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&entry) == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
//
|
|
NextSubTest();
|
|
// R5 returns E2BIG instead of B_NAME_TOO_LONG
|
|
CPPUNIT_ASSERT( equals(entry.SetTo(tooLongEntryname), E2BIG, B_NAME_TOO_LONG) );
|
|
CPPUNIT_ASSERT( equals(node.SetTo(&entry), B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
|
|
// 4. BNode(const entry_ref*)
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( entry.SetTo(dirLink) == B_OK );
|
|
entry_ref ref;
|
|
CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&ref) == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( entry.SetTo(nonExisting) == B_OK );
|
|
CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&ref) == B_ENTRY_NOT_FOUND );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( node.SetTo((entry_ref *)NULL) == B_BAD_VALUE );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
|
|
CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&ref) == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
|
|
CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&ref) == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
|
|
// 5. BNode(const BDirectory*, const char*)
|
|
NextSubTest();
|
|
BDirectory pathDir(dirSuperLink);
|
|
CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&pathDir, dirRelLink) == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( pathDir.SetTo(dirSuperLink) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&pathDir, dirLink) == B_BAD_VALUE );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( pathDir.SetTo(nonExistingSuper) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&pathDir, nonExistingRel) == B_ENTRY_NOT_FOUND );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( node.SetTo((BDirectory *)NULL, (const char *)NULL)
|
|
== B_BAD_VALUE );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( node.SetTo((BDirectory *)NULL, dirLink) == B_BAD_VALUE );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( pathDir.SetTo(dirSuperLink) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&pathDir, (const char *)NULL) == B_BAD_VALUE );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_BAD_VALUE );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( pathDir.SetTo(dirSuperLink) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&pathDir, "") == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( pathDir.SetTo(existingSuperFile) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&pathDir, existingRelFile) == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( pathDir.SetTo(existingSuperDir) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&pathDir, existingRelDir) == B_OK );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_OK );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( pathDir.SetTo(tooLongSuperEntryname) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&pathDir, tooLongRelEntryname) == B_NAME_TOO_LONG );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_NAME_TOO_LONG );
|
|
//
|
|
NextSubTest();
|
|
CPPUNIT_ASSERT( pathDir.SetTo(fileSuperDirname) == B_OK );
|
|
CPPUNIT_ASSERT( node.SetTo(&pathDir, fileRelDirname) == B_ENTRY_NOT_FOUND );
|
|
CPPUNIT_ASSERT( node.InitCheck() == B_ENTRY_NOT_FOUND );
|
|
}
|
|
|
|
// WriteAttributes
|
|
static
|
|
void
|
|
WriteAttributes(BNode &node, const char **attrNames, const char **attrValues,
|
|
int32 attrCount)
|
|
{
|
|
for (int32 i = 0; i < attrCount; i++) {
|
|
const char *attrName = attrNames[i];
|
|
const char *attrValue = attrValues[i];
|
|
int32 valueSize = strlen(attrValue) + 1;
|
|
CPPUNIT_ASSERT( node.WriteAttr(attrName, B_STRING_TYPE, 0, attrValue,
|
|
valueSize) == valueSize );
|
|
}
|
|
}
|
|
|
|
// AttrDirTest
|
|
void
|
|
NodeTest::AttrDirTest(BNode &node)
|
|
{
|
|
// node should not have any attributes at the beginning
|
|
char nameBuffer[B_ATTR_NAME_LENGTH];
|
|
CPPUNIT_ASSERT( node.GetNextAttrName(nameBuffer) == B_ENTRY_NOT_FOUND );
|
|
// add some
|
|
const char *attrNames[] = {
|
|
"attr1", "attr2", "attr3", "attr4", "attr5"
|
|
};
|
|
const char *attrValues[] = {
|
|
"value1", "value2", "value3", "value4", "value5"
|
|
};
|
|
int32 attrCount = sizeof(attrNames) / sizeof(const char *);
|
|
WriteAttributes(node, attrNames, attrValues, attrCount);
|
|
TestSet testSet;
|
|
for (int32 i = 0; i < attrCount; i++)
|
|
testSet.add(attrNames[i]);
|
|
// get all attribute names
|
|
// R5: We have to rewind, we wouldn't get any attribute otherwise.
|
|
CPPUNIT_ASSERT( node.RewindAttrs() == B_OK );
|
|
while (node.GetNextAttrName(nameBuffer) == B_OK)
|
|
CPPUNIT_ASSERT( testSet.test(nameBuffer) == true );
|
|
CPPUNIT_ASSERT( testSet.testDone() == true );
|
|
CPPUNIT_ASSERT( node.GetNextAttrName(nameBuffer) == B_ENTRY_NOT_FOUND );
|
|
// rewind, get one attribute, rewind again and iterate through the whole
|
|
// list again
|
|
CPPUNIT_ASSERT( node.RewindAttrs() == B_OK );
|
|
testSet.rewind();
|
|
CPPUNIT_ASSERT( node.GetNextAttrName(nameBuffer) == B_OK );
|
|
CPPUNIT_ASSERT( testSet.test(nameBuffer) == true );
|
|
CPPUNIT_ASSERT( node.RewindAttrs() == B_OK );
|
|
testSet.rewind();
|
|
while (node.GetNextAttrName(nameBuffer) == B_OK)
|
|
CPPUNIT_ASSERT( testSet.test(nameBuffer) == true );
|
|
CPPUNIT_ASSERT( testSet.testDone() == true );
|
|
CPPUNIT_ASSERT( node.GetNextAttrName(nameBuffer) == B_ENTRY_NOT_FOUND );
|
|
// bad args
|
|
CPPUNIT_ASSERT( node.RewindAttrs() == B_OK );
|
|
testSet.rewind();
|
|
// R5: crashs, if passing a NULL buffer
|
|
#if !TEST_R5
|
|
CPPUNIT_ASSERT( node.GetNextAttrName(NULL) == B_BAD_VALUE );
|
|
#endif
|
|
}
|
|
|
|
// AttrDirTest
|
|
void
|
|
NodeTest::AttrDirTest()
|
|
{
|
|
// uninitialized objects
|
|
NextSubTest();
|
|
TestNodes testEntries;
|
|
CreateUninitializedNodes(testEntries);
|
|
BNode *node;
|
|
string nodeName;
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
char nameBuffer[B_ATTR_NAME_LENGTH];
|
|
CPPUNIT_ASSERT( node->RewindAttrs() != B_OK );
|
|
CPPUNIT_ASSERT( node->GetNextAttrName(nameBuffer) != B_OK );
|
|
}
|
|
testEntries.delete_all();
|
|
// existing entries
|
|
NextSubTest();
|
|
CreateRWNodes(testEntries);
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
AttrDirTest(*node);
|
|
}
|
|
testEntries.delete_all();
|
|
}
|
|
|
|
// AttrTest
|
|
void
|
|
NodeTest::AttrTest(BNode &node)
|
|
{
|
|
// add some attributes
|
|
const char *attrNames[] = {
|
|
"attr1", "attr2", "attr3", "attr4", "attr5"
|
|
};
|
|
const char *attrValues[] = {
|
|
"value1", "value2", "value3", "value4", "value5"
|
|
};
|
|
const char *newAttrValues[] = {
|
|
"fd", "kkgkjsdhfgkjhsd", "lihuhuh", "", "alkfgnakdfjgn"
|
|
};
|
|
int32 attrCount = sizeof(attrNames) / sizeof(const char *);
|
|
WriteAttributes(node, attrNames, attrValues, attrCount);
|
|
char buffer[1024];
|
|
// read and check them
|
|
for (int32 i = 0; i < attrCount; i++) {
|
|
const char *attrName = attrNames[i];
|
|
const char *attrValue = attrValues[i];
|
|
int32 valueSize = strlen(attrValue) + 1;
|
|
CPPUNIT_ASSERT( node.ReadAttr(attrName, B_STRING_TYPE, 0, buffer,
|
|
sizeof(buffer)) == valueSize );
|
|
CPPUNIT_ASSERT( strcmp(buffer, attrValue) == 0 );
|
|
}
|
|
// write a new value for each attribute
|
|
WriteAttributes(node, attrNames, newAttrValues, attrCount);
|
|
// read and check them
|
|
for (int32 i = 0; i < attrCount; i++) {
|
|
const char *attrName = attrNames[i];
|
|
const char *attrValue = newAttrValues[i];
|
|
int32 valueSize = strlen(attrValue) + 1;
|
|
CPPUNIT_ASSERT( node.ReadAttr(attrName, B_STRING_TYPE, 0, buffer,
|
|
sizeof(buffer)) == valueSize );
|
|
CPPUNIT_ASSERT( strcmp(buffer, attrValue) == 0 );
|
|
}
|
|
// bad args
|
|
CPPUNIT_ASSERT( equals(node.ReadAttr(NULL, B_STRING_TYPE, 0, buffer,
|
|
sizeof(buffer)),
|
|
B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.ReadAttr(attrNames[0], B_STRING_TYPE, 0, NULL,
|
|
sizeof(buffer)),
|
|
B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.ReadAttr(NULL, B_STRING_TYPE, 0, NULL,
|
|
sizeof(buffer)),
|
|
B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.WriteAttr(NULL, B_STRING_TYPE, 0, buffer,
|
|
sizeof(buffer)),
|
|
B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.WriteAttr(attrNames[0], B_STRING_TYPE, 0, NULL,
|
|
sizeof(buffer)),
|
|
B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.WriteAttr(NULL, B_STRING_TYPE, 0, NULL,
|
|
sizeof(buffer)),
|
|
B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.RemoveAttr(NULL), B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
// too long attribute name
|
|
// R5: Read/RemoveAttr() do not return B_NAME_TOO_LONG, but B_ENTRY_NOT_FOUND
|
|
// R5: WriteAttr() does not return B_NAME_TOO_LONG, but B_BAD_VALUE
|
|
char tooLongAttrName[B_ATTR_NAME_LENGTH + 1];
|
|
memset(tooLongAttrName, 'a', B_ATTR_NAME_LENGTH);
|
|
tooLongAttrName[B_ATTR_NAME_LENGTH + 1] = 0;
|
|
CPPUNIT_ASSERT( node.WriteAttr(tooLongAttrName, B_STRING_TYPE, 0, buffer,
|
|
sizeof(buffer)) == B_BAD_VALUE );
|
|
CPPUNIT_ASSERT( node.ReadAttr(tooLongAttrName, B_STRING_TYPE, 0, buffer,
|
|
sizeof(buffer)) == B_ENTRY_NOT_FOUND );
|
|
CPPUNIT_ASSERT( node.RemoveAttr(tooLongAttrName) == B_ENTRY_NOT_FOUND );
|
|
// remove the attributes and try to read them
|
|
for (int32 i = 0; i < attrCount; i++) {
|
|
const char *attrName = attrNames[i];
|
|
CPPUNIT_ASSERT( node.RemoveAttr(attrName) == B_OK );
|
|
CPPUNIT_ASSERT( node.ReadAttr(attrName, B_STRING_TYPE, 0, buffer,
|
|
sizeof(buffer)) == B_ENTRY_NOT_FOUND );
|
|
}
|
|
// try to remove a non-existing attribute
|
|
CPPUNIT_ASSERT( node.RemoveAttr("non existing attribute")
|
|
== B_ENTRY_NOT_FOUND );
|
|
}
|
|
|
|
// AttrTest
|
|
void
|
|
NodeTest::AttrTest()
|
|
{
|
|
// uninitialized objects
|
|
NextSubTest();
|
|
TestNodes testEntries;
|
|
CreateUninitializedNodes(testEntries);
|
|
BNode *node;
|
|
string nodeName;
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
char buffer[1024];
|
|
CPPUNIT_ASSERT( node->ReadAttr("attr1", B_STRING_TYPE, 0, buffer,
|
|
sizeof(buffer)) == B_FILE_ERROR );
|
|
CPPUNIT_ASSERT( node->WriteAttr("attr1", B_STRING_TYPE, 0, buffer,
|
|
sizeof(buffer)) == B_FILE_ERROR );
|
|
CPPUNIT_ASSERT( node->RemoveAttr("attr1") == B_FILE_ERROR );
|
|
}
|
|
testEntries.delete_all();
|
|
// existing entries
|
|
NextSubTest();
|
|
CreateRWNodes(testEntries);
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
AttrTest(*node);
|
|
}
|
|
testEntries.delete_all();
|
|
}
|
|
|
|
// AttrRenameTest
|
|
void
|
|
NodeTest::AttrRenameTest(BNode &node)
|
|
{
|
|
#if !TEST_R5
|
|
const char attr1[] = "StorageKit::SomeAttribute";
|
|
const char attr2[] = "StorageKit::AnotherAttribute";
|
|
const char str[] = "This is my testing string and it rules your world.";
|
|
const int strLen = strlen(str) + 1;
|
|
const int dataLen = 1024;
|
|
char data[dataLen];
|
|
|
|
node.SetTo("./");
|
|
|
|
// Test the case of the first attribute not existing
|
|
node.RemoveAttr(attr1);
|
|
CPPUNIT_ASSERT( node.RenameAttr(attr1, attr2) == B_BAD_VALUE );
|
|
|
|
// Write an attribute, read it to verify it, rename it, read the
|
|
// new attribute, read the old (which fails), and then remove the new.
|
|
CPPUNIT_ASSERT( node.WriteAttr(attr1, B_STRING_TYPE, 0, str, strLen) == strLen );
|
|
CPPUNIT_ASSERT( node.ReadAttr(attr1, B_STRING_TYPE, 0, data, dataLen) == strLen );
|
|
CPPUNIT_ASSERT( strcmp(data, str) == 0 );
|
|
CPPUNIT_ASSERT( node.RenameAttr(attr1, attr2) == B_OK ); // <<< This fails with R5::BNode
|
|
CPPUNIT_ASSERT( node.ReadAttr(attr1, B_STRING_TYPE, 0, data, dataLen) == B_ENTRY_NOT_FOUND );
|
|
CPPUNIT_ASSERT( node.ReadAttr(attr2, B_STRING_TYPE, 0, data, dataLen) == strLen );
|
|
CPPUNIT_ASSERT( strcmp(data, str) == 0 );
|
|
CPPUNIT_ASSERT( node.RemoveAttr(attr2) == B_OK );
|
|
|
|
// bad args
|
|
CPPUNIT_ASSERT( equals(node.RenameAttr(attr1, NULL), B_BAD_ADDRESS,
|
|
B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.RenameAttr(NULL, attr2), B_BAD_ADDRESS,
|
|
B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.RenameAttr(NULL, NULL), B_BAD_ADDRESS,
|
|
B_BAD_VALUE) );
|
|
// too long attribute name
|
|
// R5: RenameAttr() returns B_BAD_VALUE instead of B_NAME_TOO_LONG
|
|
char tooLongAttrName[B_ATTR_NAME_LENGTH + 1];
|
|
memset(tooLongAttrName, 'a', B_ATTR_NAME_LENGTH);
|
|
tooLongAttrName[B_ATTR_NAME_LENGTH + 1] = 0;
|
|
CPPUNIT_ASSERT( node.RenameAttr(attr1, tooLongAttrName)
|
|
== B_BAD_VALUE );
|
|
CPPUNIT_ASSERT( node.RenameAttr(tooLongAttrName, attr1)
|
|
== B_BAD_VALUE );
|
|
#endif
|
|
}
|
|
|
|
|
|
// AttrRenameTest
|
|
void
|
|
NodeTest::AttrRenameTest()
|
|
{
|
|
// uninitialized objects
|
|
NextSubTest();
|
|
TestNodes testEntries;
|
|
CreateUninitializedNodes(testEntries);
|
|
BNode *node;
|
|
string nodeName;
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
CPPUNIT_ASSERT( node->RenameAttr("attr1", "attr2") == B_FILE_ERROR );
|
|
}
|
|
testEntries.delete_all();
|
|
// existing entries
|
|
NextSubTest();
|
|
CreateRWNodes(testEntries);
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
AttrRenameTest(*node);
|
|
}
|
|
testEntries.delete_all();
|
|
}
|
|
|
|
// AttrInfoTest
|
|
void
|
|
NodeTest::AttrInfoTest(BNode &node)
|
|
{
|
|
// add some attributes
|
|
const char *attrNames[] = {
|
|
"attr1", "attr2", "attr3", "attr4", "attr5"
|
|
};
|
|
const int32 attrCount = sizeof(attrNames) / sizeof(const char*);
|
|
const char attrValue1[] = "This is the greatest string ever.";
|
|
int32 attrValue2 = 17;
|
|
uint64 attrValue3 = 42;
|
|
double attrValue4 = 435.5;
|
|
struct flat_entry_ref { dev_t device; ino_t directory; char name[256]; }
|
|
attrValue5 = { 9, 16, "Hello world!" };
|
|
const void *attrValues[] = {
|
|
attrValue1, &attrValue2, &attrValue3, &attrValue4, &attrValue5
|
|
};
|
|
attr_info attrInfos[] = {
|
|
{ B_STRING_TYPE, sizeof(attrValue1) },
|
|
{ B_INT32_TYPE, sizeof(attrValue2) },
|
|
{ B_UINT64_TYPE, sizeof(attrValue3) },
|
|
{ B_DOUBLE_TYPE, sizeof(attrValue4) },
|
|
{ B_REF_TYPE, sizeof(attrValue5) }
|
|
};
|
|
for (int32 i = 0; i < attrCount; i++) {
|
|
const char *attrName = attrNames[i];
|
|
const void *attrValue = attrValues[i];
|
|
int32 valueSize = attrInfos[i].size;
|
|
uint32 attrType = attrInfos[i].type;
|
|
CPPUNIT_ASSERT( node.WriteAttr(attrName, attrType, 0, attrValue,
|
|
valueSize) == valueSize );
|
|
}
|
|
// get the attribute infos
|
|
for (int32 i = 0; i < attrCount; i++) {
|
|
const char *attrName = attrNames[i];
|
|
attr_info info;
|
|
CPPUNIT_ASSERT( node.GetAttrInfo(attrName, &info) == B_OK );
|
|
CPPUNIT_ASSERT( info == attrInfos[i] );
|
|
}
|
|
// try get an info for a non-existing attribute
|
|
attr_info info;
|
|
CPPUNIT_ASSERT( node.GetAttrInfo("non-existing attribute", &info)
|
|
== B_ENTRY_NOT_FOUND );
|
|
// bad values
|
|
CPPUNIT_ASSERT( equals(node.GetAttrInfo(NULL, &info), B_BAD_ADDRESS,
|
|
B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.GetAttrInfo(attrNames[0], NULL), B_BAD_ADDRESS,
|
|
B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.GetAttrInfo(NULL, NULL), B_BAD_ADDRESS,
|
|
B_BAD_VALUE) );
|
|
// too long attribute name
|
|
// R5: GetAttrInfo() does not return B_NAME_TOO_LONG
|
|
char tooLongAttrName[B_ATTR_NAME_LENGTH + 1];
|
|
memset(tooLongAttrName, 'a', B_ATTR_NAME_LENGTH);
|
|
tooLongAttrName[B_ATTR_NAME_LENGTH + 1] = 0;
|
|
CPPUNIT_ASSERT( node.GetAttrInfo(tooLongAttrName, &info)
|
|
== B_ENTRY_NOT_FOUND );
|
|
}
|
|
|
|
// AttrInfoTest
|
|
void
|
|
NodeTest::AttrInfoTest()
|
|
{
|
|
// uninitialized objects
|
|
NextSubTest();
|
|
TestNodes testEntries;
|
|
CreateUninitializedNodes(testEntries);
|
|
BNode *node;
|
|
string nodeName;
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
attr_info info;
|
|
CPPUNIT_ASSERT( node->GetAttrInfo("attr1", &info) == B_FILE_ERROR );
|
|
}
|
|
testEntries.delete_all();
|
|
// existing entries
|
|
NextSubTest();
|
|
CreateRWNodes(testEntries);
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
AttrInfoTest(*node);
|
|
}
|
|
testEntries.delete_all();
|
|
}
|
|
|
|
// AttrBStringTest
|
|
void
|
|
NodeTest::AttrBStringTest(BNode &node)
|
|
{
|
|
// add some attributes
|
|
const char *attrNames[] = {
|
|
"attr1", "attr2", "attr3", "attr4", "attr5"
|
|
};
|
|
const char *attrValues[] = {
|
|
"value1", "value2", "value3", "value4", "value5"
|
|
};
|
|
const char *newAttrValues[] = {
|
|
"fd", "kkgkjsdhfgkjhsd", "lihuhuh", "", "alkfgnakdfjgn"
|
|
};
|
|
int32 attrCount = sizeof(attrNames) / sizeof(const char *);
|
|
for (int32 i = 0; i < attrCount; i++) {
|
|
const char *attrName = attrNames[i];
|
|
BString attrValue(attrValues[i]);
|
|
CPPUNIT_ASSERT( node.WriteAttrString(attrName, &attrValue) == B_OK );
|
|
}
|
|
// read and check them
|
|
for (int32 i = 0; i < attrCount; i++) {
|
|
const char *attrName = attrNames[i];
|
|
const char *attrValue = attrValues[i];
|
|
BString readValue;
|
|
CPPUNIT_ASSERT( node.ReadAttrString(attrName, &readValue) == B_OK );
|
|
CPPUNIT_ASSERT( readValue == attrValue );
|
|
}
|
|
// write a new value for each attribute
|
|
for (int32 i = 0; i < attrCount; i++) {
|
|
const char *attrName = attrNames[i];
|
|
BString attrValue(newAttrValues[i]);
|
|
CPPUNIT_ASSERT( node.WriteAttrString(attrName, &attrValue) == B_OK );
|
|
}
|
|
// read and check them
|
|
for (int32 i = 0; i < attrCount; i++) {
|
|
const char *attrName = attrNames[i];
|
|
const char *attrValue = newAttrValues[i];
|
|
BString readValue;
|
|
CPPUNIT_ASSERT( node.ReadAttrString(attrName, &readValue) == B_OK );
|
|
CPPUNIT_ASSERT( readValue == attrValue );
|
|
}
|
|
// bad args
|
|
BString readValue;
|
|
BString writeValue("test");
|
|
// R5: crashes, if supplying a NULL BString
|
|
#if !TEST_R5
|
|
CPPUNIT_ASSERT( node.WriteAttrString(attrNames[0], NULL) == B_BAD_VALUE );
|
|
CPPUNIT_ASSERT( node.ReadAttrString(attrNames[0], NULL) == B_BAD_VALUE );
|
|
#endif
|
|
CPPUNIT_ASSERT( equals(node.WriteAttrString(NULL, &writeValue),
|
|
B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
CPPUNIT_ASSERT( equals(node.ReadAttrString(NULL, &readValue),
|
|
B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
#if !TEST_R5
|
|
CPPUNIT_ASSERT( node.WriteAttrString(NULL, NULL) == B_BAD_VALUE );
|
|
#endif
|
|
CPPUNIT_ASSERT( equals(node.ReadAttrString(NULL, NULL),
|
|
B_BAD_ADDRESS, B_BAD_VALUE) );
|
|
// remove the attributes and try to read them
|
|
for (int32 i = 0; i < attrCount; i++) {
|
|
const char *attrName = attrNames[i];
|
|
CPPUNIT_ASSERT( node.RemoveAttr(attrName) == B_OK );
|
|
CPPUNIT_ASSERT( node.ReadAttrString(attrName, &readValue)
|
|
== B_ENTRY_NOT_FOUND );
|
|
}
|
|
// too long attribute name
|
|
// R5: Read/WriteAttrString() do not return B_NAME_TOO_LONG
|
|
char tooLongAttrName[B_ATTR_NAME_LENGTH + 1];
|
|
memset(tooLongAttrName, 'a', B_ATTR_NAME_LENGTH);
|
|
tooLongAttrName[B_ATTR_NAME_LENGTH + 1] = 0;
|
|
CPPUNIT_ASSERT( node.WriteAttrString(tooLongAttrName, &writeValue)
|
|
== B_BAD_VALUE );
|
|
CPPUNIT_ASSERT( node.ReadAttrString(tooLongAttrName, &readValue)
|
|
== B_ENTRY_NOT_FOUND );
|
|
}
|
|
|
|
// AttrBStringTest
|
|
void
|
|
NodeTest::AttrBStringTest()
|
|
{
|
|
// uninitialized objects
|
|
NextSubTest();
|
|
TestNodes testEntries;
|
|
CreateUninitializedNodes(testEntries);
|
|
BNode *node;
|
|
string nodeName;
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
BString value("test");
|
|
CPPUNIT_ASSERT( node->WriteAttrString("attr1", &value)
|
|
== B_FILE_ERROR );
|
|
CPPUNIT_ASSERT( node->ReadAttrString("attr1", &value)
|
|
== B_FILE_ERROR );
|
|
}
|
|
testEntries.delete_all();
|
|
// existing entries
|
|
NextSubTest();
|
|
CreateRWNodes(testEntries);
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
AttrBStringTest(*node);
|
|
}
|
|
testEntries.delete_all();
|
|
}
|
|
|
|
// This doesn't actually verify synching is occuring; just
|
|
// checks for a B_OK return value.
|
|
void
|
|
NodeTest::SyncTest() {
|
|
const char attr[] = "StorageKit::SomeAttribute";
|
|
const char str[] = "This string rules your world.";
|
|
const int len = strlen(str) + 1;
|
|
// uninitialized objects
|
|
NextSubTest();
|
|
TestNodes testEntries;
|
|
CreateUninitializedNodes(testEntries);
|
|
BNode *node;
|
|
string nodeName;
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
CPPUNIT_ASSERT( node->Sync() == B_FILE_ERROR );
|
|
}
|
|
testEntries.delete_all();
|
|
// existing entries
|
|
NextSubTest();
|
|
CreateRWNodes(testEntries);
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
CPPUNIT_ASSERT( node->WriteAttr(attr, B_STRING_TYPE, 0, str, len)
|
|
== len );
|
|
CPPUNIT_ASSERT( node->Sync() == B_OK );
|
|
}
|
|
testEntries.delete_all();
|
|
}
|
|
|
|
// DupTest
|
|
void
|
|
NodeTest::DupTest(BNode &node)
|
|
{
|
|
int fd = node.Dup();
|
|
CPPUNIT_ASSERT( fd != -1 );
|
|
::close(fd);
|
|
}
|
|
|
|
// DupTest
|
|
void
|
|
NodeTest::DupTest()
|
|
{
|
|
// uninitialized objects
|
|
NextSubTest();
|
|
TestNodes testEntries;
|
|
CreateUninitializedNodes(testEntries);
|
|
BNode *node;
|
|
string nodeName;
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
CPPUNIT_ASSERT( node->Dup() == -1 );
|
|
}
|
|
testEntries.delete_all();
|
|
// existing entries
|
|
NextSubTest();
|
|
CreateRWNodes(testEntries);
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
DupTest(*node);
|
|
}
|
|
testEntries.delete_all();
|
|
}
|
|
|
|
// n1 and n2 should both be uninitialized. y1a and y1b should be initialized
|
|
// to the same node, y2 should be initialized to a different node
|
|
void
|
|
NodeTest::EqualityTest(BNode &n1, BNode &n2, BNode &y1a, BNode &y1b, BNode &y2) {
|
|
CPPUNIT_ASSERT( n1 == n2 );
|
|
CPPUNIT_ASSERT( !(n1 != n2) );
|
|
CPPUNIT_ASSERT( n1 != y2 );
|
|
CPPUNIT_ASSERT( !(n1 == y2) );
|
|
|
|
CPPUNIT_ASSERT( y1a != n2 );
|
|
CPPUNIT_ASSERT( !(y1a == n2) );
|
|
CPPUNIT_ASSERT( y1a == y1b );
|
|
CPPUNIT_ASSERT( !(y1a != y1b) );
|
|
CPPUNIT_ASSERT( y1a != y2 );
|
|
CPPUNIT_ASSERT( !(y1a == y2) );
|
|
|
|
CPPUNIT_ASSERT( n1 == n1 );
|
|
CPPUNIT_ASSERT( !(n1 != n1) );
|
|
CPPUNIT_ASSERT( y2 == y2 );
|
|
CPPUNIT_ASSERT( !(y2 != y2) );
|
|
}
|
|
|
|
// EqualityTest
|
|
void
|
|
NodeTest::EqualityTest()
|
|
{
|
|
BNode n1, n2, y1a("/boot"), y1b("/boot"), y2("/");
|
|
|
|
EqualityTest(n1, n2, y1a, y1b, y2);
|
|
}
|
|
|
|
// AssignmentTest
|
|
void
|
|
NodeTest::AssignmentTest()
|
|
{
|
|
BNode n1, n2, y1a("/boot"), y1b("/boot"), y2("/");
|
|
|
|
n1 = n1; // self n
|
|
y1a = y1b; // psuedo self y
|
|
y1a = y1a; // self y
|
|
n2 = y2; // n = y
|
|
y1b = n1; // y = n
|
|
y2 = y1a; // y1 = y2
|
|
|
|
EqualityTest(n1, y1b, y1a, y2, n2);
|
|
}
|
|
|
|
// Locking isn't really implemented yet...
|
|
void
|
|
NodeTest::LockTest(BNode &node, const char *entryName)
|
|
{
|
|
CPPUNIT_ASSERT( node.Lock() == B_OK );
|
|
BNode node2(entryName);
|
|
CPPUNIT_ASSERT( node2.InitCheck() == B_BUSY );
|
|
CPPUNIT_ASSERT( node.Unlock() == B_OK );
|
|
CPPUNIT_ASSERT( node.Unlock() == B_BAD_VALUE );
|
|
CPPUNIT_ASSERT( node2.SetTo(entryName) == B_OK );
|
|
// R5: Since two file descriptors exist at this point, locking is supposed
|
|
// to fail according to the BeBook, but it succeeds!
|
|
CPPUNIT_ASSERT( node2.Lock() == B_OK );
|
|
CPPUNIT_ASSERT( node.Lock() == B_BUSY );
|
|
//
|
|
CPPUNIT_ASSERT( node2.Unlock() == B_OK );
|
|
}
|
|
|
|
// Locking isn't really implemented yet...
|
|
void
|
|
NodeTest::LockTest()
|
|
{
|
|
#if !TEST_OBOS /* !!!POSIX ONLY!!! */
|
|
// uninitialized objects
|
|
NextSubTest();
|
|
TestNodes testEntries;
|
|
CreateUninitializedNodes(testEntries);
|
|
BNode *node;
|
|
string nodeName;
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
CPPUNIT_ASSERT( node->Dup() == -1 );
|
|
}
|
|
testEntries.delete_all();
|
|
// existing entries
|
|
NextSubTest();
|
|
CreateRWNodes(testEntries);
|
|
for (testEntries.rewind(); testEntries.getNext(node, nodeName); ) {
|
|
LockTest(*node, nodeName.c_str());
|
|
}
|
|
testEntries.delete_all();
|
|
#endif
|
|
}
|
|
|
|
// entry names used in tests
|
|
const char *NodeTest::existingFilename = "/tmp/existing-file";
|
|
const char *NodeTest::existingSuperFilename = "/tmp";
|
|
const char *NodeTest::existingRelFilename = "existing-file";
|
|
const char *NodeTest::existingDirname = "/tmp/existing-dir";
|
|
const char *NodeTest::existingSuperDirname = "/tmp";
|
|
const char *NodeTest::existingRelDirname = "existing-dir";
|
|
const char *NodeTest::existingSubDirname
|
|
= "/tmp/existing-dir/existing-subdir";
|
|
const char *NodeTest::existingRelSubDirname = "existing-subdir";
|
|
const char *NodeTest::nonExistingFilename = "/tmp/non-existing-file";
|
|
const char *NodeTest::nonExistingDirname = "/tmp/non-existing-dir";
|
|
const char *NodeTest::nonExistingSuperDirname = "/tmp";
|
|
const char *NodeTest::nonExistingRelDirname = "non-existing-dir";
|
|
const char *NodeTest::testFilename1 = "/tmp/test-file1";
|
|
const char *NodeTest::testDirname1 = "/tmp/test-dir1";
|
|
const char *NodeTest::tooLongEntryname =
|
|
"/tmp/This is an awfully long name for an entry. It is that kind of entry "
|
|
"that just can't exist due to its long name. In fact its path name is not "
|
|
"too long -- a path name can contain 1024 characters -- but the name of "
|
|
"the entry itself is restricted to 256 characters, which this entry's "
|
|
"name does exceed.";
|
|
const char *NodeTest::tooLongSuperEntryname = "/tmp";
|
|
const char *NodeTest::tooLongRelEntryname =
|
|
"This is an awfully long name for an entry. It is that kind of entry "
|
|
"that just can't exist due to its long name. In fact its path name is not "
|
|
"too long -- a path name can contain 1024 characters -- but the name of "
|
|
"the entry itself is restricted to 256 characters, which this entry's "
|
|
"name does exceed.";
|
|
const char *NodeTest::fileDirname = "/tmp/test-file1/some-dir";
|
|
const char *NodeTest::fileSuperDirname = "/tmp";
|
|
const char *NodeTest::fileRelDirname = "test-file1/some-dir";
|
|
const char *NodeTest::dirLinkname = "/tmp/link-to-dir1";
|
|
const char *NodeTest::dirSuperLinkname = "/tmp";
|
|
const char *NodeTest::dirRelLinkname = "link-to-dir1";
|
|
const char *NodeTest::fileLinkname = "/tmp/link-to-file1";
|
|
const char *NodeTest::fileSuperLinkname = "/tmp";
|
|
const char *NodeTest::fileRelLinkname = "link-to-file1";
|
|
const char *NodeTest::relDirLinkname = "/tmp/rel-link-to-dir1";
|
|
const char *NodeTest::relFileLinkname = "/tmp/rel-link-to-file1";
|
|
const char *NodeTest::badLinkname = "/tmp/link-to-void";
|
|
const char *NodeTest::cyclicLinkname1 = "/tmp/cyclic-link1";
|
|
const char *NodeTest::cyclicLinkname2 = "/tmp/cyclic-link2";
|
|
|
|
const char *NodeTest::allFilenames[] = {
|
|
existingFilename,
|
|
existingDirname,
|
|
nonExistingFilename,
|
|
nonExistingDirname,
|
|
testFilename1,
|
|
testDirname1,
|
|
dirLinkname,
|
|
fileLinkname,
|
|
relDirLinkname,
|
|
relFileLinkname,
|
|
badLinkname,
|
|
cyclicLinkname1,
|
|
cyclicLinkname2,
|
|
};
|
|
const int32 NodeTest::allFilenameCount
|
|
= sizeof(allFilenames) / sizeof(const char*);
|
|
|