Redo hierdatabase & dbdatasource unit tests so they do something useful; add sanity checks to cBlockRecordFile::FindRoomForData and cDbDataSourceIter::SetFCOData, the need for these was exposed by the new tests. Also update debug-only DB Explore mode with a few more commands

This commit is contained in:
Brian Cox 2017-04-19 20:20:08 -07:00
parent fdb25ca903
commit 5a425591ce
6 changed files with 441 additions and 574 deletions

View File

@ -266,11 +266,14 @@ int cBlockRecordFile::FindRoomForData( int32 dataSize ) //throw (eArchive)
// first, try the last added to block...
//
d.TraceDetail( "Looking for room for %d bytes; first trying mLastAddedTo (%d)\n", dataSize, mLastAddedTo );
util_InitBlockArray( mvBlocks[mLastAddedTo] );
if( mvBlocks[mLastAddedTo].GetAvailableSpace() >= dataSize )
if( mLastAddedTo >= 0 )
{
d.TraceDetail( "---Found room in block %d\n", mLastAddedTo );
return mLastAddedTo;
util_InitBlockArray( mvBlocks[mLastAddedTo] );
if( mvBlocks[mLastAddedTo].GetAvailableSpace() >= dataSize )
{
d.TraceDetail( "---Found room in block %d\n", mLastAddedTo );
return mLastAddedTo;
}
}
//
// ok, I guess we will have to iterate through all the blocks...

View File

@ -263,20 +263,24 @@ void cDbDataSourceIter::SetFCOData( const iFCO* pFCO ) //throw (eError)
{
mDbIter.RemoveData();
}
//
// write the fco's property set to a memory archive...
//
// TODO -- does this need to be static?
static cMemoryArchive arch;
arch.Seek ( 0, cBidirArchive::BEGINNING );
cSerializerImpl ser (arch, cSerializerImpl::S_WRITE);
ser.Init();
ser.WriteObject ( pFCO->GetPropSet() );
ser.Finit();
//
// write this to the archive...
//
mDbIter.SetData( arch.GetMemory(), arch.CurrentPos() );
if( pFCO )
{
//
// write the fco's property set to a memory archive...
//
// TODO -- does this need to be static?
static cMemoryArchive arch;
arch.Seek ( 0, cBidirArchive::BEGINNING );
cSerializerImpl ser (arch, cSerializerImpl::S_WRITE);
ser.Init();
ser.WriteObject ( pFCO->GetPropSet() );
ser.Finit();
//
// write this to the archive...
//
mDbIter.SetData( arch.GetMemory(), arch.CurrentPos() );
}
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -250,6 +250,104 @@ void cDbExplore::Execute( cFCODatabaseFileIter& dbIter )
}
}
//-----------------------------------------------------------------
// mkdir
//-----------------------------------------------------------------
else if( verb.compare( _T("mkdir") ) == 0 )
{
GetNoun(noun);
TCOUT << "Making a child of " << noun << std::endl;
if( pIter->SeekTo( noun.c_str() ) )
{
pIter->AddChildArray();
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
//-----------------------------------------------------------------
// mk
//-----------------------------------------------------------------
else if( verb.compare( _T("mk") ) == 0 )
{
GetNoun(noun);
TCOUT << "Making object " << noun << std::endl;
if( pIter->SeekTo( noun.c_str() ) )
{
TCOUT << "Error: object already exists!" << std::endl;
}
else
{
pIter->AddFCO( noun, 0 ); // add a null fco for now
}
}
//-----------------------------------------------------------------
// rmdir
//-----------------------------------------------------------------
else if( verb.compare( _T("rmdir") ) == 0 )
{
GetNoun(noun);
TCOUT << "Removing the child of " << noun << std::endl;
if( pIter->SeekTo( noun.c_str() ) )
{
if( pIter->CanRemoveChildArray() )
{
pIter->RemoveChildArray();
}
else
{
TCOUT << "Can't delete object; it still has children." << std::endl;
}
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
//-----------------------------------------------------------------
// rm
//-----------------------------------------------------------------
else if( verb.compare( _T("rm") ) == 0 )
{
GetNoun(noun);
TCOUT << "Removing object " << noun << std::endl;
if( pIter->SeekTo( noun.c_str() ) )
{
if( pIter->CanDescend() )
{
TCOUT << "Can't delete object; it still has children." << std::endl;
}
else
{
pIter->RemoveFCO();
}
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
else if( verb.compare( _T("rmdata") ) == 0 )
{
GetNoun(noun);
TCOUT << "Removing object data " << noun << std::endl;
if( pIter->SeekTo( noun.c_str() ) )
{
if( pIter->CanDescend() )
{
TCOUT << "Can't delete object; it still has children." << std::endl;
}
else
{
pIter->RemoveFCOData();
}
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
//-----------------------------------------------------------------
// pwd
//-----------------------------------------------------------------
else if( verb.compare( _T("pwd") ) == 0 )
@ -380,11 +478,11 @@ void cDbExplore::Execute( cFCODatabaseFileIter& dbIter )
// make sure the file is still valid...
//
/*
#ifdef _BLOCKFILE_DEBUG
db.AssertAllBlocksValid() ;
dbIter.GetDb().AssertAllBlocksValid();
#endif
*/
}
delete pIter;

View File

@ -41,268 +41,174 @@
#include "fco/fcoprop.h"
#include "fco/fco.h"
#include "twtest/test.h"
#include "fs/fsobject.h"
static void GetNoun( TSTRING& noun )
static void AddFile(cDbDataSourceIter& iter, const TSTRING& filename, bool with_data=false)
{
static TSTRING prevNoun;
TCIN >> noun;
if( noun.compare( _T("!$") ) == 0 )
if (iter.SeekTo(filename.c_str()))
TCOUT << "Object " << filename << " already exists!" << std::endl;
cFCOName fname(filename);
if (with_data)
{
noun = prevNoun;
iFCO* pFCO = new cFSObject(fname);
iter.AddFCO(filename,pFCO);
}
prevNoun = noun;
else
{
iter.AddFCO(filename,0);
}
TEST(iter.HasFCOData() == with_data);
}
//
// TODO -- implement this with the prop displayer as well!
//
static void PrintFCO( const iFCO* pFCO )
static void AddDirectory(cDbDataSourceIter& iter, const TSTRING& filename)
{
TCOUT.setf(std::ios::left);
TCOUT << "------- " << pFCO->GetName().AsString() << " -------" << std::endl;
//
// iterate over all of the properties
//
const iFCOPropSet* pPropSet = pFCO->GetPropSet();
cFCOPropVector v = pPropSet->GetValidVector();
for( int i=0; i < pPropSet->GetNumProps(); i++ )
{
if( v.ContainsItem( i ) )
if (iter.SeekTo(filename.c_str()))
TCOUT << "Object " << filename << " already exists!" << std::endl;
iter.AddFCO(filename, 0);
iter.AddChildArray();
TEST(iter.CanDescend());
}
static void RemoveDirectory(cDbDataSourceIter& iter, const TSTRING& filename)
{
TCOUT << "Removing the child of " << filename << std::endl;
if( iter.SeekTo( filename.c_str() ) )
{
//TODO -- check that it has an empty child
iter.RemoveChildArray();
iter.RemoveFCO();
}
else
{
TCOUT << "Unable to find object " << filename << std::endl;
}
}
static void RemoveFile(cDbDataSourceIter& iter, const TSTRING& filename)
{
TCOUT << "Removing object " << filename << std::endl;
cFCOName fname(filename);
iter.SeekToFCO(fname);
if( iter.CanDescend() )
{
TCOUT << "Can't delete object; it still has children." << std::endl;
}
else
{
iter.RemoveFCOData();
iter.RemoveFCO();
}
}
static void ChDir(cDbDataSourceIter& iter, const TSTRING& filename)
{
if( filename.compare( _T("..") ) == 0 )
{
if( iter.AtRoot() )
TCOUT << "At root already" << std::endl;
TCOUT << "Ascending..." << std::endl;
iter.Ascend();
}
else
{
if( iter.SeekTo( filename.c_str() ) )
{
TCOUT << "[";
TCOUT.width(2);
TCOUT << i << "]" ;
TCOUT.width(25);
TCOUT << pPropSet->GetPropName(i);
TCOUT.width(0);
TCOUT << pPropSet->GetPropAt( i )->AsString() << std::endl;
if( !iter.CanDescend())
TCOUT << filename << " has no children; can't descend." << std::endl;
TCOUT << "Descending into " << filename << std::endl;
iter.Descend();
}
else
{
TCOUT << "Unable to find object " << filename << std::endl;
}
}
TCOUT << "--------------------------------------------" << std::endl;
}
void TestDbDataSource()
static void AssertData(cDbDataSourceIter& iter, const TSTRING& filename, bool should_have)
{
bool exists = iter.SeekTo( filename.c_str() );
TEST(exists == should_have);
if (exists)
{
bool has_data = iter.HasFCOData();
TEST(has_data == should_have);
if (has_data)
{
iFCO* pFCO = iter.CreateFCO();
TEST(pFCO);
TCOUT << "Roundtrip FCOName = " << pFCO->GetName().AsString() << std::endl;
TSTRING expected = filename + "/";
TEST(pFCO->GetName().AsString() == expected);
}
}
}
static void AssertExists(cDbDataSourceIter& iter, const TSTRING& filename, bool should_have)
{
bool exists = iter.SeekTo( filename.c_str() );
TEST(exists == should_have);
}
static void AssertChildren(cDbDataSourceIter& iter, const TSTRING& filename, bool should_have)
{
bool exists = iter.SeekTo( filename.c_str() );
if (exists)
{
bool has_children = iter.CanDescend();
TEST(has_children == should_have);
}
}
void TestDbDataSourceBasic()
{
TCERR << std::endl << "TestDbDataSource needs to be redesigned so it doesn't require user interaction" << std::endl;
#if 0
cDebug d("TestDbDataSource");
cHierDatabase db;
db.Open( _T("test.db"), 5, true);
cDbDataSourceIter iter(&db);
const TSTRING dbName = _T("tw.db");
AddFile(iter, "file1", true);
AddFile(iter, "file2", false);
AddFile(iter, "file3", false);
AddDirectory(iter, "dir1");
AddDirectory(iter, "dir2");
AddDirectory(iter, "dir3");
AssertData(iter, "file1", true);
ChDir(iter, "dir1");
AddFile(iter, "dir1_file1");
ChDir(iter, "..");
RemoveFile(iter, "file1");
RemoveFile(iter, "file2");
AssertExists(iter, "file1", false);
AssertExists(iter, "file2", false);
AssertExists(iter, "file3", true);
RemoveDirectory(iter, "dir2");
AssertExists(iter, "dir1", true);
AssertExists(iter, "dir2", false);
AssertExists(iter, "dir3", true);
AssertChildren(iter, "dir1", true);
AssertChildren(iter, "dir3", true);
AssertChildren(iter, "file3", false);
try
{
// TODO -- get the case sensitiveness and delimiting char out of the factory instead of iFSServices
//
TCOUT << _T("Opening database ") << dbName << std::endl;
db.Open( dbName, 5, false );
cDbDataSourceIter iter( &db );
////////////////////////////
// the main event loop...
////////////////////////////
while( true )
{
TSTRING verb, noun;
TCOUT << _T(">>");
TCIN >> verb;
//
// ok, now we switch on the command...
//
//-----------------------------------------------------------------
// quit
//-----------------------------------------------------------------
if( verb.compare( _T("quit") ) == 0 )
{
// the quit command...
break;
}
//-----------------------------------------------------------------
// print
//-----------------------------------------------------------------
if( verb.compare( _T("print") ) == 0 )
{
GetNoun(noun);
if( iter.SeekTo( noun.c_str() ) )
{
if( iter.HasFCOData() )
{
iFCO* pFCO = iter.CreateFCO();
PrintFCO( pFCO );
pFCO->Release();
}
else
{
TCOUT << "Object has no data associated with it." << std::endl;
}
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
//-----------------------------------------------------------------
// mkdir
//-----------------------------------------------------------------
else if( verb.compare( _T("mkdir") ) == 0 )
{
GetNoun(noun);
TCOUT << "Making a child of " << noun << std::endl;
if( iter.SeekTo( noun.c_str() ) )
{
iter.AddChildArray();
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
//-----------------------------------------------------------------
// mk
//-----------------------------------------------------------------
else if( verb.compare( _T("mk") ) == 0 )
{
GetNoun(noun);
TCOUT << "Making object " << noun << std::endl;
if( iter.SeekTo( noun.c_str() ) )
{
TCOUT << "Error: object already exists!" << std::endl;
}
else
{
iter.AddFCO( noun, 0 ); // add a null fco for now
}
}
//-----------------------------------------------------------------
// rmdir
//-----------------------------------------------------------------
// TODO -- still needs to be implemented in the iterator class!
//
/*
else if( verb.compare( _T("rmdir") ) == 0 )
{
GetNoun(noun);
TCOUT << "Removing the child of " << noun << std::endl;
if( iter.SeekTo( noun.c_str() ) )
{
//TODO -- check that it has an empty child
iter.DeleteChildArray();
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
*/
//-----------------------------------------------------------------
// rm
//-----------------------------------------------------------------
else if( verb.compare( _T("rm") ) == 0 )
{
GetNoun(noun);
TCOUT << "Removing object " << noun << std::endl;
if( iter.SeekTo( noun.c_str() ) )
{
if( iter.CanDescend() )
{
TCOUT << "Can't delete object; it still has children." << std::endl;
}
else
{
iter.RemoveFCO();
}
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
//-----------------------------------------------------------------
// pwd
//-----------------------------------------------------------------
else if( verb.compare( _T("pwd") ) == 0 )
{
TCOUT << iter.GetParentName().AsString() << std::endl;
}
//-----------------------------------------------------------------
// ls
//-----------------------------------------------------------------
else if( verb.compare( _T("ls") ) == 0 )
{
int cnt = 0;
for( iter.SeekBegin(); ! iter.Done(); iter.Next(), cnt++ )
{
TCOUT << "[" << cnt ;
if( iter.CanDescend() )
{
TCOUT << "]*\t" ;
}
else
{
TCOUT << "]\t" ;
}
TCOUT << iter.GetShortName() << std::endl;
}
}
//-----------------------------------------------------------------
// cd
//-----------------------------------------------------------------
else if( verb.compare( _T("cd") ) == 0 )
{
GetNoun(noun);
if( noun.compare( _T("..") ) == 0 )
{
if( iter.AtRoot() )
{
TCOUT << "Can't ascend above root." << std::endl;
}
else
{
TCOUT << "Ascending..." << std::endl;
iter.Ascend();
}
}
else
{
if( iter.SeekTo( noun.c_str() ) )
{
if( iter.CanDescend() )
{
TCOUT << "Descending into " << noun << std::endl;
iter.Descend();
}
else
{
TCOUT << noun << " has no children; can't descend." << std::endl;
}
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
}
// make sure the file is still valid...
//
#ifdef _BLOCKFILE_DEBUG
db.AssertAllBlocksValid() ;
#endif
}
TCOUT << "Exiting..." << std::endl;
}
catch( eError& e )
{
d.TraceError("*** Caught error: %d %s\n", e.GetID(), e.GetMsg().c_str() );
TEST(false);
}
#ifdef DEBUG
db.AssertAllBlocksValid();
#endif
}

View File

@ -35,319 +35,175 @@
#include "test.h"
#include "core/error.h"
/*static void PrintDb( cHierDatabase::iterator iter, cDebug d, bool bFirst = true )
{
if( ! bFirst )
{
iter.Descend();
}
d.TraceDebug( "-- Processing directory %s\n", iter.GetCwd().c_str() );
for( iter.SeekBegin(); ! iter.Done(); iter.Next() )
static const TSTRING g_block_data = "Hello World Hello World Hello World Hello World";
static void AddFile(cHierDatabase::iterator& iter, const TSTRING& filename, bool with_data=false)
{
if (iter.SeekTo(filename.c_str()))
TCOUT << "Object " << filename << " already exists!" << std::endl;
iter.CreateEntry(filename);
if (with_data)
{
iter.SetData( (int8*)g_block_data.c_str(), g_block_data.length() + 1 );
}
TEST(iter.HasData() == with_data);
}
static void AddDirectory(cHierDatabase::iterator& iter, const TSTRING& filename)
{
if (iter.SeekTo(filename.c_str()))
TCOUT << "Object " << filename << " already exists!" << std::endl;
iter.CreateEntry(filename);
iter.CreateChildArray();
TEST(iter.CanDescend());
}
static void RemoveDirectory(cHierDatabase::iterator& iter, const TSTRING& filename)
{
TCOUT << "Removing the child of " << filename << std::endl;
if( iter.SeekTo( filename.c_str() ) )
{
//TODO -- check that it has an empty child
iter.DeleteChildArray();
iter.DeleteEntry();
}
else
{
TCOUT << "Unable to find object " << filename << std::endl;
}
}
static void RemoveFile(cHierDatabase::iterator& iter, const TSTRING& filename)
{
TCOUT << "Removing object " << filename << std::endl;
if( iter.SeekTo( filename.c_str() ) )
{
d.TraceDebug( "Processing entry %s\n", iter.GetName() );
if( iter.CanDescend() )
{
d.TraceDebug( ">>Descending...\n" );
PrintDb(iter, d, false);
TCOUT << "Can't delete object; it still has children." << std::endl;
}
}
d.TraceDebug( "-- Done Processing directory %s\n", iter.GetCwd().c_str() );
}*/
static void GetNoun( TSTRING& noun )
{
static TSTRING prevNoun;
TCIN >> noun;
if( noun.compare( _T("!$") ) == 0 )
{
noun = prevNoun;
}
prevNoun = noun;
}
///////////////////////////////////////////////////////////////////////////////
// TestHierDatabaseInteractive -- this provides an interactive interface to
// the database
///////////////////////////////////////////////////////////////////////////////
void TestHierDatabaseInteractive()
{
TCERR << std::endl << "TestHierDatabaseInteractive needs to be redesigned (& renamed) to not require user interaction" << std::endl;
#if 0
cDebug d( "TestHierDatabaseInteractive" );
try
{
cHierDatabase db;
//db.Open( _T("c:/tmp/tw.hdb"), 5, true);
db.Open( _T("tw.db"), 5, false);
cHierDatabase::iterator iter(&db);
while( true )
else
{
TSTRING verb, noun;
TCOUT << _T(">>");
TCIN >> verb;
//
// ok, now we switch on the command...
//
//-----------------------------------------------------------------
// quit
//-----------------------------------------------------------------
if( verb.compare( _T("quit") ) == 0 )
{
// the quit command...
break;
}
//-----------------------------------------------------------------
// print
//-----------------------------------------------------------------
if( verb.compare( _T("print") ) == 0 )
{
// the print command...
ASSERT( false );
// TODO -- Implement this!
}
//-----------------------------------------------------------------
// mkdir
//-----------------------------------------------------------------
else if( verb.compare( _T("mkdir") ) == 0 )
{
GetNoun(noun);
TCOUT << "Making a child of " << noun << std::endl;
if( iter.SeekTo( noun.c_str() ) )
{
iter.CreateChildArray();
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
//-----------------------------------------------------------------
// mk
//-----------------------------------------------------------------
else if( verb.compare( _T("mk") ) == 0 )
{
GetNoun(noun);
TCOUT << "Making object " << noun << std::endl;
if( iter.SeekTo( noun.c_str() ) )
{
TCOUT << "Error: object already exists!" << std::endl;
}
else
{
iter.CreateEntry( noun );
}
}
//-----------------------------------------------------------------
// rmdir
//-----------------------------------------------------------------
else if( verb.compare( _T("rmdir") ) == 0 )
{
GetNoun(noun);
TCOUT << "Removing the child of " << noun << std::endl;
if( iter.SeekTo( noun.c_str() ) )
{
//TODO -- check that it has an empty child
iter.DeleteChildArray();
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
//-----------------------------------------------------------------
// rm
//-----------------------------------------------------------------
else if( verb.compare( _T("rm") ) == 0 )
{
GetNoun(noun);
TCOUT << "Removing object " << noun << std::endl;
if( iter.SeekTo( noun.c_str() ) )
{
if( iter.CanDescend() )
{
TCOUT << "Can't delete object; it still has children." << std::endl;
}
else
{
iter.DeleteEntry();
}
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
//-----------------------------------------------------------------
// pwd
//-----------------------------------------------------------------
else if( verb.compare( _T("pwd") ) == 0 )
{
TCOUT << iter.GetCwd() << std::endl;
}
//-----------------------------------------------------------------
// ls
//-----------------------------------------------------------------
else if( verb.compare( _T("ls") ) == 0 )
{
int cnt = 0;
for( iter.SeekBegin(); ! iter.Done(); iter.Next(), cnt++ )
{
TCOUT << "[" << cnt ;
if( iter.CanDescend() )
{
TCOUT << "]*\t" ;
}
else
{
TCOUT << "]\t" ;
}
TCOUT << iter.GetName() << std::endl;
}
}
//-----------------------------------------------------------------
// cd
//-----------------------------------------------------------------
else if( verb.compare( _T("cd") ) == 0 )
{
GetNoun(noun);
if( noun.compare( _T("..") ) == 0 )
{
if( iter.AtRoot() )
{
TCOUT << "Can't ascend above root." << std::endl;
}
else
{
TCOUT << "Ascending..." << std::endl;
iter.Ascend();
}
}
else
{
if( iter.SeekTo( noun.c_str() ) )
{
if( iter.CanDescend() )
{
TCOUT << "Descending into " << noun << std::endl;
iter.Descend();
}
else
{
TCOUT << noun << " has no children; can't descend." << std::endl;
}
}
else
{
TCOUT << "Unable to find object " << noun << std::endl;
}
}
}
//-----------------------------------------------------------------
// rmdir
//-----------------------------------------------------------------
else if( verb.compare( _T("rmdir") ) == 0 )
{
GetNoun(noun);
if( iter.SeekTo( noun.c_str() ) )
{
if( iter.CanDescend() )
{
TCOUT << "Deleting child of " << iter.GetName() << std::endl;
iter.DeleteChildArray();
}
else
{
TCOUT << noun << " has no child; can't delete." << std::endl;
}
}
}
//-----------------------------------------------------------------
// rm
//-----------------------------------------------------------------
else if( verb.compare( _T("rm") ) == 0 )
{
GetNoun(noun);
if( iter.SeekTo( noun.c_str() ) )
{
if( iter.CanDescend() )
{
TCOUT << noun << " doesn't exist; can't delete." << std::endl;
}
else
{
TCOUT << "Deleting " << iter.GetName() << std::endl;
iter.DeleteEntry();
}
}
}
//-----------------------------------------------------------------
// set
//-----------------------------------------------------------------
else if( verb.compare( _T("set") ) == 0 )
{
GetNoun(noun);
if( iter.SeekTo( noun.c_str() ) )
{
if( iter.HasData() )
{
iter.RemoveData();
}
TSTRING data;
TCIN >> data;
iter.SetData( (int8*)data.c_str(), data.length() + 1 );
TCOUT << "Setting " << noun << "'s data to " << data << std::endl;
}
else
{
TCOUT << "Can't find object " << noun << std::endl;
}
}
//-----------------------------------------------------------------
// get
//-----------------------------------------------------------------
else if( verb.compare( _T("get") ) == 0 )
{
GetNoun(noun);
if( iter.SeekTo( noun.c_str() ) )
{
if( ! iter.HasData() )
{
TCOUT << "Object has no data!" << std::endl;
}
else
{
int32 dummyLength;
TCOUT << noun << "'s data is: " << (TCHAR*)iter.GetData(dummyLength) << std::endl;
}
}
else
{
TCOUT << "Can't find object " << noun << std::endl;
}
}
// make sure the file is still valid...
//
#ifdef _BLOCKFILE_DEBUG
db.AssertAllBlocksValid() ;
#endif
iter.RemoveData();
iter.DeleteEntry();
}
TCOUT << "Exiting..." << std::endl;
}
catch( eError& e )
else
{
d.TraceError( "Exception caught: %d %s\n", e.GetID(), e.GetMsg().c_str() );
TEST( false );
TCOUT << "Unable to find object " << filename << std::endl;
}
}
static void ChDir(cHierDatabase::iterator& iter, const TSTRING& filename)
{
if( filename.compare( _T("..") ) == 0 )
{
if( iter.AtRoot() )
TCOUT << "At root already" << std::endl;
TCOUT << "Ascending..." << std::endl;
iter.Ascend();
}
else
{
if( iter.SeekTo( filename.c_str() ) )
{
if( !iter.CanDescend())
TCOUT << filename << " has no children; can't descend." << std::endl;
TCOUT << "Descending into " << filename << std::endl;
iter.Descend();
}
else
{
TCOUT << "Unable to find object " << filename << std::endl;
}
}
}
static void AssertData(cHierDatabase::iterator& iter, const TSTRING& filename, bool should_have)
{
bool exists = iter.SeekTo( filename.c_str() );
TEST(exists == should_have);
if (exists)
{
bool has_data = iter.HasData();
TEST(has_data == should_have);
if (has_data)
{
int32 dummyLength;
TSTRING read_str( (TCHAR*)iter.GetData(dummyLength) );
TEST(read_str == g_block_data);
}
}
}
static void AssertExists(cHierDatabase::iterator& iter, const TSTRING& filename, bool should_have)
{
bool exists = iter.SeekTo( filename.c_str() );
TEST(exists == should_have);
}
static void AssertChildren(cHierDatabase::iterator& iter, const TSTRING& filename, bool should_have)
{
bool exists = iter.SeekTo( filename.c_str() );
if (exists)
{
bool has_children = iter.CanDescend();
TEST(has_children == should_have);
}
}
void TestHierDatabaseBasic()
{
cHierDatabase db;
db.Open( _T("test.db"), 5, true);
cHierDatabase::iterator iter(&db);
AddFile(iter, "file1", true);
AddFile(iter, "file2", false);
AddFile(iter, "file3", false);
AddDirectory(iter, "dir1");
AddDirectory(iter, "dir2");
AddDirectory(iter, "dir3");
AssertData(iter, "file1", true);
ChDir(iter, "dir1");
AddFile(iter, "dir1_file1");
ChDir(iter, "..");
RemoveFile(iter, "file1");
RemoveFile(iter, "file2");
AssertExists(iter, "file1", false);
AssertExists(iter, "file2", false);
AssertExists(iter, "file3", true);
RemoveDirectory(iter, "dir2");
AssertExists(iter, "dir1", true);
AssertExists(iter, "dir2", false);
AssertExists(iter, "dir3", true);
AssertChildren(iter, "dir1", true);
AssertChildren(iter, "dir3", true);
AssertChildren(iter, "file3", false);
#ifdef DEBUG
db.AssertAllBlocksValid();
#endif
}

View File

@ -112,9 +112,9 @@ void TestFSPropDisplayer();
void TestGenre();
void TestFSDataSourceIter();
void TestGenerateDb();
void TestHierDatabaseInteractive();
void TestHierDatabaseBasic();
void TestGenreSwitcher();
void TestDbDataSource();
void TestDbDataSourceBasic();
void TestGenreSpecList();
void TestIntegrityCheck();
void TestFCODatabaseFile();
@ -213,9 +213,9 @@ static void Test(int testID)
case 52: TestGenre(); break;
case 53: TestFSDataSourceIter(); break;
//case 54: TestGenerateDb(); break;
case 55: TestHierDatabaseInteractive(); break;
case 55: TestHierDatabaseBasic(); break;
case 56: TestGenreSwitcher(); break;
case 57: TestDbDataSource(); break;
case 57: TestDbDataSourceBasic(); break;
case 58: TestGenreSpecList(); break;
//case 59: TestIntegrityCheck(); break;