From 7fbaf6242fb8371d226f7980849261826e329f98 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 9 Aug 2023 13:00:44 -0700 Subject: rununits now tracks status and has options. When we encounter unexpected test results it logs them to a status file, subsequent runs without other options will only re-run the tests that had unexpected results, updating the status file as you go. When all tests are returning expected results again then the status file is deleted and the next run will process all tests again. Of course, the --all parameter will force it to run all tests and ignore the current status. --- src/tools/rununits.cpp | 100 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 8 deletions(-) diff --git a/src/tools/rununits.cpp b/src/tools/rununits.cpp index 769d3ab..ee847d3 100644 --- a/src/tools/rununits.cpp +++ b/src/tools/rununits.cpp @@ -4,10 +4,13 @@ #include #include #include +#include #include #include +typedef Bu::List BlobList; + Bu::Blob getSuiteName( const Bu::Blob &bSuiteExec ) { Bu::Process proc( @@ -23,14 +26,29 @@ Bu::Blob getSuiteName( const Bu::Blob &bSuiteExec ) return bRet; } -Bu::Json *runSuite( const Bu::Blob &bSuiteExec ) +Bu::Json *runSuite( const Bu::Blob &bSuiteExec, Bu::Json *pSuiteStatus=NULL ) { + BlobList lCmd; + lCmd.append( bSuiteExec ); + lCmd.append( "--interop" ); + if( pSuiteStatus != NULL ) + { + for( Bu::Json::iterator i = (*pSuiteStatus)["tests"].begin(); i; i++ ) + { + lCmd.append( (**i)["name"].getString().get() ); + } + } + char **argv = new char*[lCmd.getSize()+1]; + int j = 0; + for( BlobList::iterator i = lCmd.begin(); i; j++, i++ ) + { + argv[j] = (*i).getData(); + } + argv[lCmd.getSize()] = NULL; Bu::Process proc( Bu::Process::StdOut, bSuiteExec.getData(), - bSuiteExec.getData(), - "--interop", - NULL + argv ); Bu::BlobBuilder bbReport; while( proc.isRunning() ) @@ -43,13 +61,12 @@ Bu::Json *runSuite( const Bu::Blob &bSuiteExec ) bbReport.append( dRead, iRead ); } } + delete[] argv; Bu::Json *pReport = new Bu::Json(); pReport->parse( bbReport.getBlob() ); return pReport; } -typedef Bu::List BlobList; - BlobList getSuitePaths( const Bu::Blob &bDir ) { BlobList lPaths; @@ -80,10 +97,54 @@ BlobList getSuitePaths( const Bu::Blob &bDir ) return lPaths; } -int main( int /*argc*/, char * /*argv*/[] ) +int main( int argc, char *argv[] ) { Bu::Blob bDir("unit"); + bool bAll = false; + bool bHasStatus = false; + Bu::Json jsLastStatus; + + Bu::OptParser options; + options.addOption( bDir, 'p', "path", "Directory to look for unit tests."); + options.addOption( bAll, 'a', "all", "Execute all tests, ignoring state."); + options.setOverride("all", "true"); + options.addHelpOption(); + options.parse( argc, argv ); + + if( !bAll ) + { + try + { + Bu::String sData = + Bu::File("rununits.status.json", Bu::File::Read ) + .readAll(); + jsLastStatus.parse( sData ); + bHasStatus = true; + Bu::println("Current status loaded, created: %1") + .arg( jsLastStatus["date"].getString().get() ); + } + catch(...) + { + } + } + BlobList lPaths = getSuitePaths( bDir ); + Bu::Hash hStatusSuitesByPath; + + if( bHasStatus ) + { + BlobList lNewPaths; + for( Bu::Json::iterator i = jsLastStatus["suites"].begin(); i; i++ ) + { + hStatusSuitesByPath.insert( (**i)["path"].getString().get(), (*i) ); + } + for( BlobList::iterator i = lPaths.begin(); i; i++ ) + { + if( hStatusSuitesByPath.has( *i ) ) + lNewPaths.append( *i ); + } + lPaths = lNewPaths; + } int iNumLen = Bu::String("%1").arg( lPaths.getSize() ).end().getSize(); int iMaxSuiteName = 0; @@ -109,7 +170,13 @@ int main( int /*argc*/, char * /*argv*/[] ) .arg( bSuiteName, Bu::Fmt().width( iMaxSuiteName ).fill(' ').left() ); Bu::sio << Bu::sio.flush; - Bu::Json *pReport = runSuite( (*i) ); + Bu::Json *pSuiteStatus = NULL; + if( bHasStatus ) + { + pSuiteStatus = hStatusSuitesByPath.get( *i ); + } + Bu::Json *pReport = runSuite( (*i), pSuiteStatus ); + pReport->insert("path", *i ); int iUnexpected = 0; int iTotal = 0; iTotal = (*pReport)["tests"].getSize(); @@ -137,13 +204,23 @@ int main( int /*argc*/, char * /*argv*/[] ) if( lReport.getSize() == 0 ) { Bu::println("\nNothing unexpected in unit tests."); + unlink("rununits.status.json"); } else { + Bu::Json jStatus( Bu::Json::Object ); + + time_t tNow = time( NULL ); + jStatus.insert("date", Bu::String(ctime( &tNow )).trimWhitespace() ); + jStatus.insertArray("suites"); for( Bu::List::iterator i = lReport.begin(); i; i++ ) { Bu::println("\nUnexpected results in: %1") .arg( (**i)["suite"].getString().get() ); + Bu::Json &jStSuite = jStatus["suites"].appendObject(); + jStSuite.insert("name", (**i)["suite"].getString() ); + jStSuite.insert("path", (**i)["path"].getString() ); + Bu::Json &jStTests = jStSuite.insertArray("tests"); for( Bu::Json::iterator iTest = (**i)["tests"].begin(); iTest; iTest++ ) @@ -153,6 +230,10 @@ int main( int /*argc*/, char * /*argv*/[] ) { continue; } + Bu::Json &jsTest = jStTests.appendObject(); + jsTest.insert("name", (**iTest)["name"].getString() ); + jsTest.insert("result", (**iTest)["result"].getString() ); + jsTest.insert("expected", (**iTest)["expected"].getString() ); Bu::println(" %1: unexpected %2") .arg( (**iTest)["name"].getString().get() ) @@ -180,6 +261,9 @@ int main( int /*argc*/, char * /*argv*/[] ) } delete *i; } + + Bu::File("rununits.status.json", Bu::File::WriteNew ) + .write( jStatus.toString() ); } return 0; -- cgit v1.2.3