From 674274ed06dfdf9488e7f3bc9e3b45b9f7f4fb18 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Fri, 28 May 2010 19:23:45 +0000 Subject: More myriad testing and unit test features, not unit tests that may take a while are welcome to provide progress info with some builtin functions. The Bu::Archive class now throws an exception if reading is interrupted by EOS --- src/archive.cpp | 3 +- src/unit/myriad.unit | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/unitsuite.cpp | 41 +++++++++++++++ src/unitsuite.h | 8 +++ 4 files changed, 193 insertions(+), 2 deletions(-) diff --git a/src/archive.cpp b/src/archive.cpp index d5f77c5..f29895c 100644 --- a/src/archive.cpp +++ b/src/archive.cpp @@ -33,7 +33,8 @@ void Bu::Archive::read( void *pData, int32_t nSize ) if( nSize == 0 || pData == NULL ) return; - rStream.read( (char *)pData, nSize ); + if( rStream.read( (char *)pData, nSize ) < nSize ) + throw Bu::ExceptionBase("Insufficient data to unarchive object."); } void Bu::Archive::close() diff --git a/src/unit/myriad.unit b/src/unit/myriad.unit index a88650f..ad8fb5d 100644 --- a/src/unit/myriad.unit +++ b/src/unit/myriad.unit @@ -13,11 +13,93 @@ #include "bu/array.h" #include "bu/sio.h" +#include "bu/archive.h" +#include "bu/md5.h" +#include "bu/unitsuite.h" #include using namespace Bu; +class VerifyObject +{ +friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const VerifyObject &vo ); +friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, VerifyObject &vo ); +public: + VerifyObject( int iUnits ) : + iUnits( iUnits ), + iBytesWritten( 0 ) + { + } + + virtual ~VerifyObject() + { + } + + int getBytesWritten() + { + return iBytesWritten; + } + +private: + int iUnits; + mutable int iBytesWritten; +}; + +Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const VerifyObject &vo ) +{ + Md5 sum; + ar << vo.iUnits; + vo.iBytesWritten = 4; + sum.addData( &vo.iUnits, 4 ); + for( int j = 0; j < vo.iUnits; j++ ) + { + int iRand = random()%128; +// ar << iRand; + Bu::FString sDat( iRand ); + for( int j = 0; j < iRand; j++ ) + sDat[j] = (char)((uint8_t)(random()%256)); + ar << sDat; + sum.addData( &iRand, 4 ); + sum.addData( sDat.getStr(), iRand ); + vo.iBytesWritten += 4 + iRand; + } + Bu::FString sRes = sum.getResult(); + ar << sRes; + vo.iBytesWritten += 4 + sRes.getSize(); + return ar; +} + +Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, VerifyObject &vo ) +{ + Md5 sum; + ar >> vo.iUnits; + sum.addData( &vo.iUnits, 4 ); + for( int j = 0; j < vo.iUnits; j++ ) + { + int iRand; +// ar >> iRand; + Bu::FString sStr; + ar >> sStr; + iRand = sStr.getSize(); + sum.addData( &iRand, 4 ); + sum.addData( sStr.getStr(), iRand ); + } + Bu::FString sSum; + ar >> sSum; + unitTest( sSum == sum.getResult() ); + int iTooMuch; + try + { + ar >> iTooMuch; + unitFailed("should have thrown an exception."); + } + catch( Bu::ExceptionBase &e ) + { + } + return ar; +} + suite Myriad { test setSize @@ -211,13 +293,16 @@ suite Myriad Array aStream; + setStepCount( 5*2500 + 5 ); + { File fMyriad = tempFile( sFileName ); - Myriad m( fMyriad, 64 ); + Myriad m( fMyriad, 128 ); for( int j = 0; j < 5; j++ ) { aStream.append( m.createStream() ); + incProgress(); } } @@ -237,6 +322,62 @@ suite Myriad ms.setPos( 0 ); verifyBlock( ms ); unitTest( ms.read( &b, 1 ) == 0 ); + incProgress(); + } + } + } + + test stressArchive + { + FString sFileName("myriad-XXXXXX"); + Array aStream; + + srandom( 2096 ); + + setStepCount( 15*250 + 15 ); + + { + File fMyriad = tempFile( sFileName ); + Myriad m( fMyriad, 1024 ); + + for( int j = 0; j < 15; j++ ) + { + int iStream = m.createStream(); + aStream.append( iStream ); + VerifyObject vo( random()%1024 ); + { + MyriadStream ms = m.openStream( iStream ); + Archive ar( ms, Archive::save ); + ar << vo; + unitTest( ms.tell() == vo.getBytesWritten() ); + ms.setSize( ms.tell() ); + } + unitTest( m.getStreamSize( iStream ) == vo.getBytesWritten() ); + incProgress(); + } + } + + for( int iter = 0; iter < 250; iter++ ) + { + File fMyriad( sFileName, File::ReadWrite ); + Myriad m( fMyriad ); + for( Array::iterator i = aStream.begin(); i; i++ ) + { + VerifyObject vo( random()%1024 ); + { + MyriadStream ms = m.openStream( *i ); + Archive ar( ms, Archive::load ); + ar >> vo; + } + { + MyriadStream ms = m.openStream( *i ); + Archive ar( ms, Archive::save ); + ar << vo; + unitTest( ms.tell() == vo.getBytesWritten() ); + ms.setSize( ms.tell() ); + } + unitTest( m.getStreamSize( *i ) == vo.getBytesWritten() ); + incProgress(); } } } diff --git a/src/unitsuite.cpp b/src/unitsuite.cpp index 0a531c0..7a20128 100644 --- a/src/unitsuite.cpp +++ b/src/unitsuite.cpp @@ -10,6 +10,7 @@ #include "bu/sio.h" #include "bu/optparser.h" #include +#include using namespace Bu; @@ -53,6 +54,8 @@ int Bu::UnitSuite::run( int argc, char *argv[] ) << sio.flush; try { + iStepCount = -1; + iProgress = 0; (this->*(i->fTest))(); switch( i->eExpect ) { @@ -185,6 +188,44 @@ void Bu::UnitSuite::setName( const FString &sName ) sSuiteName = sName; } +void Bu::UnitSuite::dispProgress() +{ + if( tLastUpdate == time( NULL ) ) + return; + sio << Fmt(3) << (iProgress*100/iStepCount) << "%" << "\b\b\b\b" + << sio.flush; + tLastUpdate = time( NULL ); +} + +void Bu::UnitSuite::setStepCount( int iSteps ) +{ + iStepCount = iSteps; + if( iStepCount < 0 ) + return; + tLastUpdate = 0; + dispProgress(); +} + +void Bu::UnitSuite::incProgress( int iAmnt ) +{ + iProgress += iAmnt; + if( iProgress < 0 ) + iProgress = 0; + if( iProgress > iStepCount ) + iProgress = iStepCount; + dispProgress(); +} + +void Bu::UnitSuite::setProgress( int iAmnt ) +{ + iProgress = iAmnt; + if( iProgress < 0 ) + iProgress = 0; + if( iProgress > iStepCount ) + iProgress = iStepCount; + dispProgress(); +} + int Bu::UnitSuite::onListCases( StrArray ) { sio << "Test cases:" << sio.nl; diff --git a/src/unitsuite.h b/src/unitsuite.h index ddd3835..475ee48 100644 --- a/src/unitsuite.h +++ b/src/unitsuite.h @@ -96,6 +96,11 @@ namespace Bu void add( Test fTest, const Bu::FString &sName, Expect e=expectPass ); void setName( const FString &sName ); + void dispProgress(); + void setStepCount( int iSteps ); + void incProgress( int iAmnt = 1 ); + void setProgress( int iAmnt ); + private: int onListCases( Bu::Array aParam ); @@ -116,6 +121,9 @@ namespace Bu typedef Bu::List StrList; StrList lFileCleanup; int iNameWidth; + int iStepCount; + int iProgress; + time_t tLastUpdate; }; Bu::Formatter &operator<<( Bu::Formatter &f, const Bu::UnitSuite::Expect &e ); -- cgit v1.2.3