Add checks to copper sliver QA

Fedora still doesn't like our copper sliver QA sometimes.  This adds a
bit more to try and get to the bottom of the issue
This commit is contained in:
Seth Hillbrand 2025-08-26 13:27:03 -07:00
parent 8592b2ee70
commit b832ae7f45
2 changed files with 135 additions and 11 deletions

View File

@ -126,24 +126,64 @@ void LoadBoard( SETTINGS_MANAGER& aSettingsManager, const wxString& aRelPath,
aBoard->GetDesignSettings().m_DRCEngine = m_DRCEngine;
BOOST_TEST_CHECKPOINT( "Build list of nets" );
aBoard->BuildListOfNets();
try
{
aBoard->BuildListOfNets();
}
catch( const std::exception& e )
{
BOOST_TEST_ERROR( "Exception in BuildListOfNets: " << e.what() );
return;
}
BOOST_TEST_CHECKPOINT( "Build connectivity" );
aBoard->BuildConnectivity();
try
{
aBoard->BuildConnectivity();
}
catch( const std::exception& e )
{
BOOST_TEST_ERROR( "Exception in BuildConnectivity: " << e.what() );
return;
}
BOOST_TEST_CHECKPOINT( "Synchronize Time Domain Properties" );
aBoard->GetLengthCalculation()->SynchronizeTimeDomainProperties();
try
{
aBoard->GetLengthCalculation()->SynchronizeTimeDomainProperties();
}
catch( const std::exception& e )
{
BOOST_TEST_ERROR( "Exception in SynchronizeTimeDomainProperties: " << e.what() );
return;
}
if( aBoard->GetProject() )
{
std::unordered_set<wxString> dummy;
BOOST_TEST_CHECKPOINT( "Synchronize Component Classes" );
aBoard->SynchronizeComponentClasses( dummy );
try
{
aBoard->SynchronizeComponentClasses( dummy );
}
catch( const std::exception& e )
{
BOOST_TEST_ERROR( "Exception in SynchronizeComponentClasses: " << e.what() );
return;
}
BOOST_TEST_CHECKPOINT( "Run DRC cache generator" );
DRC_CACHE_GENERATOR cacheGenerator;
cacheGenerator.SetDRCEngine( m_DRCEngine.get() );
cacheGenerator.Run();
try
{
DRC_CACHE_GENERATOR cacheGenerator;
cacheGenerator.SetDRCEngine( m_DRCEngine.get() );
cacheGenerator.Run();
}
catch( const std::exception& e )
{
BOOST_TEST_ERROR( "Exception in DRC cache generator: " << e.what() );
return;
}
}
}

View File

@ -35,6 +35,10 @@
#include <drc/drc_item.h>
#include <settings/settings_manager.h>
#include <thread>
#include <chrono>
#include <exception>
struct DRC_REGRESSION_TEST_FIXTURE
{
@ -42,6 +46,21 @@ struct DRC_REGRESSION_TEST_FIXTURE
m_settingsManager( true /* headless */ )
{ }
~DRC_REGRESSION_TEST_FIXTURE()
{
// Ensure proper cleanup
if( m_board && m_board->GetDesignSettings().m_DRCEngine )
{
m_board->GetDesignSettings().m_DRCEngine->ClearViolationHandler();
}
if( m_board )
{
m_board->SetProject( nullptr );
m_board = nullptr;
}
}
SETTINGS_MANAGER m_settingsManager;
std::unique_ptr<BOARD> m_board;
};
@ -65,11 +84,18 @@ BOOST_DATA_TEST_CASE_F( DRC_REGRESSION_TEST_FIXTURE, DRCCopperSliver,
// Check for minimum copper connection errors
KI_TEST::LoadBoard( m_settingsManager, test.first, m_board );
// Validate board was loaded successfully
BOOST_REQUIRE_MESSAGE( m_board, "Failed to load board for test: " + test.first.ToStdString() );
KI_TEST::FillZones( m_board.get() );
std::vector<DRC_ITEM> violations;
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
// Validate DRC engine is properly initialized
BOOST_REQUIRE_MESSAGE( bds.m_DRCEngine, "DRC engine not initialized for test: " + test.first.ToStdString() );
// Disable DRC tests not useful or not handled in this testcase
for( int ii = DRCE_FIRST; ii <= DRCE_LAST; ++ii )
bds.m_DRCSeverities[ii] = SEVERITY::RPT_SEVERITY_IGNORE;
@ -86,7 +112,33 @@ BOOST_DATA_TEST_CASE_F( DRC_REGRESSION_TEST_FIXTURE, DRCCopperSliver,
} );
BOOST_TEST_CHECKPOINT( "Running copper sliver drc" );
bds.m_DRCEngine->RunTests( EDA_UNITS::MM, true, false );
// Add exception handling around DRC engine run to catch potential crashes
try
{
bds.m_DRCEngine->RunTests( EDA_UNITS::MM, true, false );
// Add a small delay to allow any background threads to complete
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
BOOST_TEST_CHECKPOINT( "DRC engine run completed successfully" );
}
catch( const std::exception& e )
{
BOOST_ERROR( wxString::Format( "DRC copper sliver: %s, exception during RunTests: %s",
test.first, e.what() ) );
return;
}
catch( ... )
{
BOOST_ERROR( wxString::Format( "DRC copper sliver: %s, unknown exception during RunTests",
test.first ) );
return;
}
// Clear the violation handler to prevent any potential issues with cleanup
BOOST_TEST_CHECKPOINT( "Clearing violation handler" );
bds.m_DRCEngine->ClearViolationHandler();
if( violations.size() == test.second )
{
@ -98,10 +150,42 @@ BOOST_DATA_TEST_CASE_F( DRC_REGRESSION_TEST_FIXTURE, DRCCopperSliver,
UNITS_PROVIDER unitsProvider( pcbIUScale, EDA_UNITS::INCH );
std::map<KIID, EDA_ITEM*> itemMap;
m_board->FillItemMap( itemMap );
for( const DRC_ITEM& item : violations )
BOOST_TEST_MESSAGE( item.ShowReport( &unitsProvider, RPT_SEVERITY_ERROR, itemMap ) );
// Safely build the item map with error handling
try
{
m_board->FillItemMap( itemMap );
}
catch( const std::exception& e )
{
BOOST_ERROR( wxString::Format( "DRC copper sliver: %s, exception in FillItemMap: %s",
test.first, e.what() ) );
return;
}
catch( ... )
{
BOOST_ERROR( wxString::Format( "DRC copper sliver: %s, unknown exception in FillItemMap",
test.first ) );
return;
}
// Safely report violations with bounds checking
for( size_t i = 0; i < violations.size() && i < 100; ++i ) // Limit output to prevent excessive logging
{
try
{
const DRC_ITEM& item = violations[i];
BOOST_TEST_MESSAGE( item.ShowReport( &unitsProvider, RPT_SEVERITY_ERROR, itemMap ) );
}
catch( const std::exception& e )
{
BOOST_TEST_MESSAGE( wxString::Format( "Error reporting violation %zu: %s", i, e.what() ) );
}
catch( ... )
{
BOOST_TEST_MESSAGE( wxString::Format( "Unknown error reporting violation %zu", i ) );
}
}
BOOST_ERROR( wxString::Format( "DRC copper sliver: %s, failed (violations found %d "
"expected %d)",