JD2022-TU1/main/extern/FastBuild/Code/Tools/FBuild/FBuildTest/Tests/TestBuildFBuild.cpp

166 lines
5.5 KiB
C++

// TestBuildFBuild.cpp
//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include "FBuildTest.h"
#include "Tools/FBuild/FBuildCore/FBuild.h"
#include "Tools/FBuild/FBuildCore/Graph/NodeGraph.h"
#include "Core/FileIO/FileIO.h"
#include "Core/FileIO/MemoryStream.h"
#include "Core/Strings/AStackString.h"
#include "Core/Tracing/Tracing.h"
// Globals
//------------------------------------------------------------------------------
const char * dbFile = "../ftmp/Test/TestFBuild.db";
// TestBuildFBuild
//------------------------------------------------------------------------------
class TestBuildFBuild : public FBuildTest
{
private:
DECLARE_TESTS
// Helpers
FBuildStats BuildInternal( FBuildOptions options = FBuildOptions(), bool useDB = true ) const;
// Tests
void BuildClean() const;
void Build_NoRebuild() const;
void BuildCleanWithCache() const;
void DBSavePerformance() const;
};
// Register Tests
//------------------------------------------------------------------------------
REGISTER_TESTS_BEGIN( TestBuildFBuild )
REGISTER_TEST( BuildClean ) // clean build (populating cache)
REGISTER_TEST( Build_NoRebuild ) // check no rebuild
REGISTER_TEST( BuildCleanWithCache ) // clean, reading from cache
REGISTER_TEST( Build_NoRebuild ) // check no rebuild again
REGISTER_TEST( DBSavePerformance ) // Time to save a non-trivial DB
REGISTER_TESTS_END
// BuildInternal
//------------------------------------------------------------------------------
FBuildStats TestBuildFBuild::BuildInternal( FBuildOptions options, bool useDB ) const
{
AStackString<> codeDir;
GetCodeDir( codeDir );
options.m_ConfigFile = "Tools/FBuild/FBuildTest/Data/TestBuildFBuild/fbuild.bff";
options.m_ShowSummary = true;
options.SetWorkingDir( codeDir );
FBuild fBuild( options );
TEST_ASSERT( fBuild.Initialize( useDB ? dbFile : nullptr ) );
const AStackString<> lib( "../ftmp/Win32/Debug/Core/core.lib" );
const AStackString<> lib2( "../ftmp/Win32/Debug/Tools/FBuild/FBuildCore/fbuildcore.lib" );
const AStackString<> lib3( "../ftmp/Win32/Release/Tools/FBuild/FBuildApp/fbuildapp.lib" );
const AStackString<> exe( "../ftmp/Win32/Release/Tools/FBuild/FBuildApp/fbuild.exe" );
const AStackString<> target( "fbuild" );
TEST_ASSERT( fBuild.Build( target ) );
// make sure all output files are as expected
EnsureFileExists( lib );
EnsureFileExists( lib2 );
EnsureFileExists( lib3 );
EnsureFileExists( exe );
// save the db file - make sure it exists
TEST_ASSERT( fBuild.SaveDependencyGraph( dbFile ) );
EnsureFileExists( dbFile );
return fBuild.GetStats();
}
// BuildClean
//------------------------------------------------------------------------------
void TestBuildFBuild::BuildClean() const
{
// delete files from previous runs
Array< AString > files( 1024, true );
FileIO::GetFiles( AStackString<>( "../ftmp/" ), AStackString<>( "*" ), true, &files );
for ( Array< AString >::Iter it = files.Begin();
it != files.End();
it++ )
{
FileIO::FileDelete( (*it).Get() );
}
// Do a clean build and populate the cache
FBuildOptions options;
options.m_ForceCleanBuild = true;
options.m_UseCacheWrite = true;
FBuildStats stats = BuildInternal( options, false ); // don't use the DB so it's a clean build
// check everything was built and stored to the cache
const FBuildStats::Stats & objStats = stats.GetStatsFor( Node::OBJECT_NODE );
TEST_ASSERT( objStats.m_NumProcessed > 100 ); // not exact so we don't have to update it
TEST_ASSERT( objStats.m_NumBuilt == objStats.m_NumProcessed ); // everything rebuilt
TEST_ASSERT( objStats.m_NumCacheStores == objStats.m_NumBuilt ); // everything stored to the cache
}
// Build_NoRebuild
//------------------------------------------------------------------------------
void TestBuildFBuild::Build_NoRebuild() const
{
// ensure nothing is rebuilt
FBuildStats stats = BuildInternal();
// check nothing rebuilt
TEST_ASSERT( stats.GetStatsFor( Node::OBJECT_NODE ).m_NumBuilt == 0 );
TEST_ASSERT( stats.GetStatsFor( Node::LIBRARY_NODE ).m_NumBuilt == 0 );
TEST_ASSERT( stats.GetStatsFor( Node::EXE_NODE ).m_NumBuilt == 0 );
}
// BuildCleanWithCache
//------------------------------------------------------------------------------
void TestBuildFBuild::BuildCleanWithCache() const
{
FBuildOptions options;
options.m_ForceCleanBuild = true;
options.m_UseCacheRead = true;
FBuildStats stats = BuildInternal( options );
// test everything was retrieved from the cache
const FBuildStats::Stats & objStats = stats.GetStatsFor( Node::OBJECT_NODE );
TEST_ASSERT( objStats.m_NumProcessed > 100 ); // not exact so we don't have to update it
TEST_ASSERT( objStats.m_NumBuilt == 0 ); // nothing built
TEST_ASSERT( objStats.m_NumCacheHits == objStats.m_NumProcessed ); // everything read from cache
}
// DBSavePerformance
//------------------------------------------------------------------------------
void TestBuildFBuild::DBSavePerformance() const
{
AStackString<> codeDir;
GetCodeDir( codeDir );
FBuildOptions options;
options.m_ConfigFile = "Tools/FBuild/FBuildTest/Data/TestBuildFBuild/fbuild.bff";
options.SetWorkingDir( codeDir );
FBuild fBuild( options );
TEST_ASSERT( fBuild.Initialize( dbFile ) );
MemoryStream ms( 64 * 1024 * 1024 );
Timer t;
for ( size_t i=0; i<100; ++i )
{
fBuild.GetDependencyGraph().Save( ms );
}
const float time = ( t.GetElapsed() * 1000.0f ) / 100.0f;
OUTPUT( "DB Save Time: %2.3f ms\n", time);
}
//------------------------------------------------------------------------------