REGISTER_TESTS_END // Validate //------------------------------------------------------------------------------ void TestTimer::Validate() const { Timer t; t.Start(); const uint64_t before = t.GetNow(); Thread::Sleep( 100 ); // sleep for 100ms const float elapsed = t.GetElapsed(); const float elapsedMS = t.GetElapsedMS(); const uint64_t after = t.GetNow(); // some time must have elapsed TEST_ASSERT( after > before ); // sanity check TEST_ASSERT( elapsed >= 0.001f ); // at least 1ms TEST_ASSERT( elapsed < 1.000f ); // some sensible value // sanity check TEST_ASSERT( elapsedMS >= 1.0f ); // at least 1ms TEST_ASSERT( elapsedMS < 1000.0f ); // some sensible value }
// DoBuild //------------------------------------------------------------------------------ /*static*/ Node::BuildResult JobQueue::DoBuild( Job * job ) { Timer timer; // track how long the item takes Node * node = job->GetNode(); // make sure the output path exists for files // (but don't bother for input files) if ( node->IsAFile() && ( node->GetType() != Node::FILE_NODE ) && ( node->GetType() != Node::COMPILER_NODE ) ) { if ( Node::EnsurePathExistsForFile( node->GetName() ) == false ) { // error already output by EnsurePathExistsForFile return Node::NODE_RESULT_FAILED; } } Node::BuildResult result = node->DoBuild( job ); uint32_t timeTakenMS = uint32_t( timer.GetElapsedMS() ); if ( result == Node::NODE_RESULT_OK ) { // record new build time only if built (i.e. if cached or failed, the time // does not represent how long it takes to create this resource) node->SetLastBuildTime( timeTakenMS ); node->SetStatFlag( Node::STATS_BUILT ); FLOG_INFO( "-Build: %u ms\t%s", timeTakenMS, node->GetName().Get() ); } if ( result == Node::NODE_RESULT_NEED_SECOND_BUILD_PASS ) { // nothing to check } else if ( node->IsAFile() ) { if ( result == Node::NODE_RESULT_FAILED ) { if ( node->GetControlFlags() & Node::FLAG_NO_DELETE_ON_FAIL ) { // node failed, but builder wants result left on disc } else { // build of file failed - if there is a file.... if ( FileIO::FileExists( node->GetName().Get() ) ) { // ... it is invalid, so try to delete it if ( FileIO::FileDelete( node->GetName().Get() ) == false ) { // failed to delete it - this might cause future build problems! FLOG_ERROR( "Post failure deletion failed for '%s'", node->GetName().Get() ); } } } } else { // build completed ok, or retrieved from cache... ASSERT( ( result == Node::NODE_RESULT_OK ) || ( result == Node::NODE_RESULT_OK_CACHE ) ); // (don't check existence of input files) if ( node->GetType() != Node::FILE_NODE ) { // ... ensure file exists (to detect builder logic problems) if ( !FileIO::FileExists( node->GetName().Get() ) ) { FLOG_ERROR( "File missing despite success for '%s'", node->GetName().Get() ); result = Node::NODE_RESULT_FAILED; } } } } // log processing time node->AddProcessingTime( timeTakenMS ); return result; }
// DoBuild //------------------------------------------------------------------------------ /*static*/ Node::BuildResult JobQueueRemote::DoBuild( Job * job, bool racingRemoteJob ) { Timer timer; // track how long the item takes ObjectNode * node = job->GetNode()->CastTo< ObjectNode >(); // remote tasks must output to a tmp file if ( job->IsLocal() == false ) { // file name should be the same as on host const char * fileName = ( job->GetRemoteName().FindLast( NATIVE_SLASH ) + 1 ); AStackString<> tmpFileName; WorkerThread::CreateTempFilePath( fileName, tmpFileName ); node->ReplaceDummyName( tmpFileName ); #ifdef DEBUG DEBUGSPAM( "REMOTE: %s (%s)\n", fileName, job->GetRemoteName().Get() ); #endif } ASSERT( node->IsAFile() ); // make sure the output path exists if ( Node::EnsurePathExistsForFile( node->GetName() ) == false ) { // error already output by EnsurePathExistsForFile return Node::NODE_RESULT_FAILED; } // Delete any left over PDB from a previous run (to be sure we have a clean pdb) if ( node->IsUsingPDB() && ( job->IsLocal() == false ) ) { AStackString<> pdbName; node->GetPDBName( pdbName ); FileIO::FileDelete( pdbName.Get() ); } Node::BuildResult result; { PROFILE_SECTION( racingRemoteJob ? "RACE" : "LOCAL" ); result = ((Node *)node )->DoBuild2( job, racingRemoteJob ); } uint32_t timeTakenMS = uint32_t( timer.GetElapsedMS() ); if ( result == Node::NODE_RESULT_OK ) { // record new build time only if built (i.e. if failed, the time // does not represent how long it takes to create this resource) node->SetLastBuildTime( timeTakenMS ); node->SetStatFlag( Node::STATS_BUILT ); //FLOG_INFO( "-Build: %u ms\t%s", timeTakenMS, node->GetName().Get() ); #ifdef DEBUG if ( job->IsLocal() ) { // record new file time for remote job we built locally ASSERT( node->m_Stamp == FileIO::GetFileLastWriteTime(node->GetName()) ); } #endif } if ( result == Node::NODE_RESULT_FAILED ) { // build of file failed - if there is a file.... if ( FileIO::FileExists( node->GetName().Get() ) ) { // ... it is invalid, so try to delete it if ( FileIO::FileDelete( node->GetName().Get() ) == false ) { // failed to delete it - this might cause future build problems! FLOG_ERROR( "Post failure deletion failed for '%s'", node->GetName().Get() ); } } } else { // build completed ok, or retrieved from cache... ASSERT( result == Node::NODE_RESULT_OK ); // TODO:A Also read into job if cache is being used if ( job->IsLocal() == false ) { // read results into memory to send back to client if ( ReadResults( job ) == false ) { result = Node::NODE_RESULT_FAILED; } } } // if compiling to a tmp file, do cleanup if ( job->IsLocal() == false ) { // Cleanup obj file FileIO::FileDelete( node->GetName().Get() ); // Cleanup PDB file if ( node->IsUsingPDB() ) { AStackString<> pdbName; node->GetPDBName( pdbName ); FileIO::FileDelete( pdbName.Get() ); } } // log processing time node->AddProcessingTime( timeTakenMS ); return result; }