// CheckStatsNode //------------------------------------------------------------------------------ void FBuildTest::CheckStatsNode( const FBuildStats & stats, size_t numSeen, size_t numBuilt, Node::Type nodeType ) const { const FBuildStats::Stats & nodeStats = stats.GetStatsFor( nodeType ); size_t actualNumSeen = nodeStats.m_NumProcessed; TEST_ASSERT( actualNumSeen == numSeen ); size_t actualNumBuilt = nodeStats.m_NumBuilt; TEST_ASSERT( actualNumBuilt == numBuilt ); }
// TestPCH //------------------------------------------------------------------------------ void TestPrecompiledHeaders::TestPCH() const { FBuildOptions options; options.m_ForceCleanBuild = true; options.m_UseCacheWrite = true; options.m_ShowSummary = true; // required to generate stats for node count checks #if defined( __WINDOWS__ ) AStackString<> obj( "../../../../ftmp/Test/PrecompiledHeaders/PCHUser.obj" ); #else AStackString<> obj( "../../../../ftmp/Test/PrecompiledHeaders/PCHUser.o" ); #endif AStackString<> pch( "../../../../ftmp/Test/PrecompiledHeaders/PrecompiledHeader.pch" ); AStackString<> lib( "../../../../ftmp/Test/PrecompiledHeaders/TestPCH.lib" ); EnsureFileDoesNotExist( obj ); EnsureFileDoesNotExist( pch ); EnsureFileDoesNotExist( lib ); FBuildStats stats = Build( options, false ); // don't use DB EnsureFileExists( obj ); EnsureFileExists( pch ); EnsureFileExists( lib ); // Check stats // Seen, Built, Type CheckStatsNode ( stats, 3, 2, Node::FILE_NODE ); // cpp + pch CheckStatsNode ( stats, 1, 1, Node::COMPILER_NODE ); CheckStatsNode ( stats, 2, 2, Node::OBJECT_NODE );// obj + pch obj CheckStatsNode ( stats, 1, 1, Node::LIBRARY_NODE ); CheckStatsNode ( stats, 1, 1, Node::DIRECTORY_LIST_NODE ); CheckStatsNode ( stats, 1, 1, Node::ALIAS_NODE ); CheckStatsNode ( stats, 1, 1, Node::DLL_NODE ); CheckStatsTotal( stats, 10, 9 ); // check we wrote all objects to the cache TEST_ASSERT( stats.GetStatsFor( Node::OBJECT_NODE ).m_NumCacheStores == 1 ); // only the main obj can be cached }
// DoCPUTimeByType //------------------------------------------------------------------------------ void Report::DoCPUTimeByType( const FBuildStats & stats ) { DoSectionTitle( "CPU Time by Node Type", "cpuTimeByNodeType" ); // Summary Pie Chart Array< PieItem > items( 32, true ); for ( size_t i=0; i < (size_t)Node::NUM_NODE_TYPES; ++i ) { const FBuildStats::Stats & nodeStats = stats.GetStatsFor( (Node::Type)i ); if ( nodeStats.m_NumProcessed == 0 ) { continue; } // label const char * typeName = Node::GetTypeName( Node::Type( i ) ); const float value = (float)( (double)nodeStats.m_ProcessingTimeMS / (double)1000 ); const uint32_t color = g_ReportNodeColors[ i ]; PieItem item( typeName, value, color, (void *)i ); items.Append( item ); } items.Sort(); // pie chart DoPieChart( items, " s" ); // table DoTableStart(); Write( "<tr><th width=80>Type</th><th width=80>Time</th><th width=80>Processed</th><th width=80>Built</th><th width=80>Cache Hits</th></tr>\n" ); for ( size_t i=0; i < items.GetSize(); ++i ) { Node::Type type = (Node::Type)(size_t)items[ i ].userData; const FBuildStats::Stats & nodeStats = stats.GetStatsFor( type ); if ( nodeStats.m_NumProcessed == 0 ) { continue; } const char * typeName = Node::GetTypeName( type ); const float value = (float)( (double)nodeStats.m_ProcessingTimeMS / (double)1000 ); const uint32_t processed = nodeStats.m_NumProcessed; const uint32_t built = nodeStats.m_NumBuilt; const uint32_t cacheHits = nodeStats.m_NumCacheHits; Write( "<tr><td>%s</td><td>%2.3fs</td><td>%u</td><td>%u</td>", typeName, value, processed, built, cacheHits ); if ( type == Node::OBJECT_NODE ) { // cacheable Write( "<td>%u</td></tr>\n", cacheHits ); } else { // non-cacheable Write( "<td>-</td></tr>\n" ); } } DoTableStop(); }