From 5a425591cea68af7f5a80ac0a330dcd98bfa937e Mon Sep 17 00:00:00 2001 From: Brian Cox Date: Wed, 19 Apr 2017 20:20:08 -0700 Subject: [PATCH] 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 --- src/db/blockrecordfile.cpp | 11 +- src/tw/dbdatasource.cpp | 32 ++- src/tw/dbexplore.cpp | 104 +++++++- src/twtest/dbdatasource_t.cpp | 396 +++++++++++------------------ src/twtest/hierdatabase_t.cpp | 464 ++++++++++++---------------------- src/twtest/test.cpp | 8 +- 6 files changed, 441 insertions(+), 574 deletions(-) diff --git a/src/db/blockrecordfile.cpp b/src/db/blockrecordfile.cpp index 194a5db..96f8de1 100644 --- a/src/db/blockrecordfile.cpp +++ b/src/db/blockrecordfile.cpp @@ -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... diff --git a/src/tw/dbdatasource.cpp b/src/tw/dbdatasource.cpp index 2f96ca9..faacfb7 100644 --- a/src/tw/dbdatasource.cpp +++ b/src/tw/dbdatasource.cpp @@ -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() ); + } } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/tw/dbexplore.cpp b/src/tw/dbexplore.cpp index 4d4692f..40d3c16 100644 --- a/src/tw/dbexplore.cpp +++ b/src/tw/dbexplore.cpp @@ -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; diff --git a/src/twtest/dbdatasource_t.cpp b/src/twtest/dbdatasource_t.cpp index 15c4322..00d077d 100644 --- a/src/twtest/dbdatasource_t.cpp +++ b/src/twtest/dbdatasource_t.cpp @@ -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 } diff --git a/src/twtest/hierdatabase_t.cpp b/src/twtest/hierdatabase_t.cpp index 22d6d49..1091494 100644 --- a/src/twtest/hierdatabase_t.cpp +++ b/src/twtest/hierdatabase_t.cpp @@ -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 } + diff --git a/src/twtest/test.cpp b/src/twtest/test.cpp index 799d587..2c5d4c0 100644 --- a/src/twtest/test.cpp +++ b/src/twtest/test.cpp @@ -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;