Implement new native netlist QA test
This commit is contained in:
parent
1c2ef8678c
commit
f7578eb038
|
@ -536,6 +536,11 @@ public:
|
|||
return m_aliases;
|
||||
}
|
||||
|
||||
const std::vector<COMPONENT_INSTANCE_REFERENCE>& GetSymbolInstances() const
|
||||
{
|
||||
return m_symbolInstances;
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const override;
|
||||
#endif
|
||||
|
|
|
@ -696,7 +696,7 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::FindSheetForScreen( SCH_SCREEN* aScreen )
|
|||
|
||||
|
||||
void SCH_SHEET_LIST::UpdateSymbolInstances(
|
||||
std::vector<COMPONENT_INSTANCE_REFERENCE>& aSymbolInstances )
|
||||
const std::vector<COMPONENT_INSTANCE_REFERENCE>& aSymbolInstances )
|
||||
{
|
||||
SCH_REFERENCE_LIST symbolInstances;
|
||||
|
||||
|
@ -709,7 +709,7 @@ void SCH_SHEET_LIST::UpdateSymbolInstances(
|
|||
wxString path = symbolInstances[i].GetPath();
|
||||
|
||||
auto it = std::find_if( aSymbolInstances.begin(), aSymbolInstances.end(),
|
||||
[ path ]( COMPONENT_INSTANCE_REFERENCE& r )->bool
|
||||
[ path ]( const COMPONENT_INSTANCE_REFERENCE& r ) -> bool
|
||||
{
|
||||
return path == r.m_Path.AsString();
|
||||
}
|
||||
|
|
|
@ -453,7 +453,7 @@ public:
|
|||
* WARNING: Do not call this on anything other than the full hierarchy.
|
||||
* @param aSymbolInstances is the symbol path information loaded from the root schematic.
|
||||
*/
|
||||
void UpdateSymbolInstances( std::vector<COMPONENT_INSTANCE_REFERENCE>& aSymbolInstances );
|
||||
void UpdateSymbolInstances( const std::vector<COMPONENT_INSTANCE_REFERENCE>& aSymbolInstances );
|
||||
|
||||
std::vector<KIID_PATH> GetPaths() const;
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ void COMPONENT::SetModule( MODULE* aModule )
|
|||
COMPONENT_NET COMPONENT::m_emptyNet;
|
||||
|
||||
|
||||
const COMPONENT_NET& COMPONENT::GetNet( const wxString& aPinName )
|
||||
const COMPONENT_NET& COMPONENT::GetNet( const wxString& aPinName ) const
|
||||
{
|
||||
for( unsigned i = 0; i < m_nets.size(); i++ )
|
||||
{
|
||||
|
|
|
@ -136,7 +136,7 @@ public:
|
|||
|
||||
const COMPONENT_NET& GetNet( unsigned aIndex ) const { return m_nets[aIndex]; }
|
||||
|
||||
const COMPONENT_NET& GetNet( const wxString& aPinName );
|
||||
const COMPONENT_NET& GetNet( const wxString& aPinName ) const;
|
||||
|
||||
void SortPins() { sort( m_nets.begin(), m_nets.end() ); }
|
||||
|
||||
|
|
|
@ -24,6 +24,13 @@
|
|||
|
||||
include_directories( BEFORE ${INC_BEFORE} )
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_SOURCE_DIR}/pcbnew
|
||||
${INC_AFTER}
|
||||
)
|
||||
|
||||
set( QA_EESCHEMA_SRCS
|
||||
# stuff from common which is needed...why?
|
||||
${CMAKE_SOURCE_DIR}/common/colors.cpp
|
||||
|
@ -44,6 +51,7 @@ set( QA_EESCHEMA_SRCS
|
|||
test_eagle_plugin.cpp
|
||||
test_lib_arc.cpp
|
||||
test_lib_part.cpp
|
||||
test_netlists.cpp
|
||||
test_sch_pin.cpp
|
||||
test_sch_rtree.cpp
|
||||
test_sch_sheet.cpp
|
||||
|
@ -76,6 +84,7 @@ add_dependencies( qa_eeschema eeschema )
|
|||
|
||||
target_link_libraries( qa_eeschema
|
||||
common
|
||||
pcbcommon
|
||||
kimath
|
||||
qa_utils
|
||||
unit_test_utils
|
||||
|
@ -102,13 +111,3 @@ set_source_files_properties( eeschema_test_utils.cpp PROPERTIES
|
|||
|
||||
kicad_add_boost_test( qa_eeschema eeschema )
|
||||
|
||||
# eeschema netlist tests
|
||||
# technically this doesn't depend on KICAD_SCRIPTING but if we have that, we know we have Python.
|
||||
if( KICAD_SCRIPTING_MODULES AND KICAD_NETLIST_QA )
|
||||
|
||||
add_test( NAME qa_netlist
|
||||
COMMAND ${PYTHON_EXECUTABLE} test_netlists.py ${CMAKE_BINARY_DIR}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
endif()
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
(export (version "D")
|
||||
(design
|
||||
(source "/home/jon/work/kicad-master/qa/eeschema/data/netlists/test_global_promotion_2/test_global_promotion_2.sch")
|
||||
(date "Sun 19 Apr 2020 18:19:54 EDT")
|
||||
(tool "Eeschema (5.99.0-1348-g327eb1c7c-dirty)")
|
||||
(source "test_global_promotion_2.kicad_sch")
|
||||
(date "Sat 23 May 2020 16:07:49 EDT")
|
||||
(tool "Eeschema (5.99.0-1765-g3487670f2-dirty)")
|
||||
(sheet (number "1") (name "/") (tstamps "/")
|
||||
(title_block
|
||||
(title)
|
||||
(company)
|
||||
(rev)
|
||||
(date)
|
||||
(source "test_global_promotion_2.sch")
|
||||
(source "test_global_promotion_2.kicad_sch")
|
||||
(comment (number "1") (value ""))
|
||||
(comment (number "2") (value ""))
|
||||
(comment (number "3") (value ""))
|
||||
|
@ -25,7 +25,7 @@
|
|||
(company)
|
||||
(rev)
|
||||
(date)
|
||||
(source "subsheet.sch")
|
||||
(source "subsheet.kicad_sch")
|
||||
(comment (number "1") (value ""))
|
||||
(comment (number "2") (value ""))
|
||||
(comment (number "3") (value ""))
|
||||
|
@ -41,7 +41,7 @@
|
|||
(company)
|
||||
(rev)
|
||||
(date)
|
||||
(source "subsheet.sch")
|
||||
(source "subsheet.kicad_sch")
|
||||
(comment (number "1") (value ""))
|
||||
(comment (number "2") (value ""))
|
||||
(comment (number "3") (value ""))
|
||||
|
@ -102,8 +102,7 @@
|
|||
(fp "Connector*:*_1x??_*"))
|
||||
(fields
|
||||
(field (name "Reference") "J")
|
||||
(field (name "Value") "Conn_01x03_Male")
|
||||
(field (name "Datasheet") "~"))
|
||||
(field (name "Value") "Conn_01x03_Male"))
|
||||
(pins
|
||||
(pin (num "1") (name "Pin_1") (type "passive"))
|
||||
(pin (num "2") (name "Pin_2") (type "passive"))
|
||||
|
@ -115,28 +114,23 @@
|
|||
(fp "R_*"))
|
||||
(fields
|
||||
(field (name "Reference") "R")
|
||||
(field (name "Value") "R")
|
||||
(field (name "Datasheet") "~"))
|
||||
(field (name "Value") "R"))
|
||||
(pins
|
||||
(pin (num "1") (name "~") (type "passive"))
|
||||
(pin (num "2") (name "~") (type "passive")))))
|
||||
(libraries
|
||||
(library (logical "Connector")
|
||||
(uri "/home/jon/kicad-library/kicad-symbols//Connector.lib"))
|
||||
(library (logical "Device")
|
||||
(uri "/home/jon/kicad-library/kicad-symbols//Device.lib")))
|
||||
(libraries)
|
||||
(nets
|
||||
(net (code "1") (name "/LIVE")
|
||||
(node (ref "J2") (pin "1") (pinfunction "Pin_1"))
|
||||
(node (ref "R1") (pin "1"))
|
||||
(node (ref "R2") (pin "1")))
|
||||
(node (ref "J2") (pin "2") (pinfunction "Pin_2"))
|
||||
(node (ref "R3") (pin "1"))
|
||||
(node (ref "R4") (pin "1")))
|
||||
(net (code "2") (name "/LIVE_1")
|
||||
(node (ref "J1") (pin "2") (pinfunction "Pin_2"))
|
||||
(node (ref "R4") (pin "2")))
|
||||
(net (code "3") (name "/LIVE_2")
|
||||
(node (ref "J2") (pin "2") (pinfunction "Pin_2"))
|
||||
(node (ref "R3") (pin "1"))
|
||||
(node (ref "R4") (pin "1")))
|
||||
(node (ref "J2") (pin "1") (pinfunction "Pin_1"))
|
||||
(node (ref "R1") (pin "1"))
|
||||
(node (ref "R2") (pin "1")))
|
||||
(net (code "4") (name "/NEUTRAL")
|
||||
(node (ref "J2") (pin "3") (pinfunction "Pin_3"))
|
||||
(node (ref "R1") (pin "2"))
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
#include <sch_edit_frame.h>
|
||||
#include <settings/settings_manager.h>
|
||||
|
||||
// The main sheet of the project
|
||||
SCH_SHEET* g_RootSheet = nullptr;
|
||||
|
||||
// a transform matrix, to display components in lib editor
|
||||
TRANSFORM DefaultTransform = TRANSFORM( 1, 0, 0, -1 );
|
||||
|
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <unit_test_utils/unit_test_utils.h>
|
||||
#include "eeschema_test_utils.h"
|
||||
|
||||
#include <connection_graph.h>
|
||||
#include <netlist_exporter_kicad.h>
|
||||
#include <netlist_reader/netlist_reader.h>
|
||||
#include <netlist_reader/pcb_netlist.h>
|
||||
#include <project.h>
|
||||
#include <sch_io_mgr.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <schematic.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
|
||||
class TEST_NETLISTS_FIXTURE
|
||||
{
|
||||
public:
|
||||
TEST_NETLISTS_FIXTURE() :
|
||||
m_schematic( &m_project )
|
||||
{
|
||||
m_pi = SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD );
|
||||
}
|
||||
|
||||
void loadSchematic( const wxString& aBaseName );
|
||||
|
||||
wxString getNetlistFileName( bool aTest = false );
|
||||
|
||||
void writeNetlist();
|
||||
|
||||
void compareNetlists();
|
||||
|
||||
void cleanup();
|
||||
|
||||
void doNetlistTest( const wxString& aBaseName );
|
||||
|
||||
///> Schematic to load
|
||||
SCHEMATIC m_schematic;
|
||||
|
||||
///> Dummy project
|
||||
PROJECT m_project;
|
||||
|
||||
SCH_PLUGIN* m_pi;
|
||||
};
|
||||
|
||||
|
||||
static wxString getSchematicFile( const wxString& aBaseName )
|
||||
{
|
||||
wxFileName fn = KI_TEST::GetEeschemaTestDataDir();
|
||||
fn.AppendDir( "netlists" );
|
||||
fn.AppendDir( aBaseName );
|
||||
fn.SetName( aBaseName );
|
||||
fn.SetExt( KiCadSchematicFileExtension );
|
||||
|
||||
return fn.GetFullPath();
|
||||
}
|
||||
|
||||
|
||||
void TEST_NETLISTS_FIXTURE::loadSchematic( const wxString& aBaseName )
|
||||
{
|
||||
wxString fn = getSchematicFile( aBaseName );
|
||||
|
||||
BOOST_TEST_MESSAGE( fn );
|
||||
|
||||
wxFileName pro( fn );
|
||||
pro.SetExt( ProjectFileExtension );
|
||||
|
||||
m_project.SetProjectFullName( pro.GetFullPath() );
|
||||
m_project.SetElem( PROJECT::ELEM_SCH_PART_LIBS, nullptr );
|
||||
|
||||
m_schematic.Reset();
|
||||
m_schematic.SetRoot( m_pi->Load( fn, &m_schematic ) );
|
||||
|
||||
BOOST_REQUIRE_EQUAL( m_pi->GetError().IsEmpty(), true );
|
||||
|
||||
m_schematic.CurrentSheet().push_back( &m_schematic.Root() );
|
||||
|
||||
SCH_SCREENS screens( m_schematic.Root() );
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
|
||||
screen->UpdateLocalLibSymbolLinks();
|
||||
|
||||
SCH_SHEET_LIST sheets = m_schematic.GetSheets();
|
||||
|
||||
// Restore all of the loaded symbol instances from the root sheet screen.
|
||||
sheets.UpdateSymbolInstances( m_schematic.RootScreen()->GetSymbolInstances() );
|
||||
|
||||
sheets.AnnotatePowerSymbols();
|
||||
|
||||
// NOTE: This is required for multi-unit symbols to be correct
|
||||
// Normally called from SCH_EDIT_FRAME::FixupJunctions() but could be refactored
|
||||
for( SCH_SHEET_PATH& sheet : sheets )
|
||||
sheet.UpdateAllScreenReferences();
|
||||
|
||||
// NOTE: SchematicCleanUp is not called; QA schematics must already be clean or else
|
||||
// SchematicCleanUp must be freed from its UI dependencies.
|
||||
|
||||
m_schematic.ConnectionGraph()->Recalculate( sheets, true );
|
||||
}
|
||||
|
||||
|
||||
wxString TEST_NETLISTS_FIXTURE::getNetlistFileName( bool aTest )
|
||||
{
|
||||
wxFileName netFile = m_schematic.Prj().GetProjectFullName();
|
||||
|
||||
if( aTest )
|
||||
netFile.SetName( netFile.GetName() + "_test" );
|
||||
|
||||
netFile.SetExt( NetlistFileExtension );
|
||||
|
||||
return netFile.GetFullPath();
|
||||
}
|
||||
|
||||
|
||||
void TEST_NETLISTS_FIXTURE::writeNetlist()
|
||||
{
|
||||
auto exporter = std::make_unique<NETLIST_EXPORTER_KICAD>( &m_schematic );
|
||||
BOOST_REQUIRE_EQUAL( exporter->WriteNetlist( getNetlistFileName( true ), 0 ), true );
|
||||
}
|
||||
|
||||
|
||||
void TEST_NETLISTS_FIXTURE::compareNetlists()
|
||||
{
|
||||
NETLIST golden;
|
||||
NETLIST test;
|
||||
|
||||
{
|
||||
std::unique_ptr<NETLIST_READER> netlistReader(
|
||||
NETLIST_READER::GetNetlistReader( &golden, getNetlistFileName(), wxEmptyString ) );
|
||||
|
||||
BOOST_REQUIRE_NO_THROW( netlistReader->LoadNetlist() );
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_ptr<NETLIST_READER> netlistReader( NETLIST_READER::GetNetlistReader(
|
||||
&test, getNetlistFileName( true ), wxEmptyString ) );
|
||||
|
||||
BOOST_REQUIRE_NO_THROW( netlistReader->LoadNetlist() );
|
||||
}
|
||||
|
||||
// Number of components should match
|
||||
BOOST_REQUIRE_EQUAL( golden.GetCount(), test.GetCount() );
|
||||
|
||||
for( unsigned i = 0; i < golden.GetCount(); i++ )
|
||||
{
|
||||
COMPONENT* goldenComp = golden.GetComponent( i );
|
||||
COMPONENT* refComp = test.GetComponentByReference( goldenComp->GetReference() );
|
||||
|
||||
// Retrieval by reference
|
||||
BOOST_REQUIRE_NE( refComp, nullptr );
|
||||
|
||||
// Retrieval by KIID
|
||||
COMPONENT* pathComp = test.GetComponentByPath( goldenComp->GetPath() );
|
||||
BOOST_REQUIRE_NE( pathComp, nullptr );
|
||||
|
||||
// We should have found the same component
|
||||
BOOST_REQUIRE_EQUAL( refComp->GetReference(), pathComp->GetReference() );
|
||||
|
||||
// And that component should have the same number of attached nets
|
||||
BOOST_REQUIRE_EQUAL( goldenComp->GetNetCount(), refComp->GetNetCount() );
|
||||
|
||||
for( unsigned net = 0; net < goldenComp->GetNetCount(); net++ )
|
||||
{
|
||||
const COMPONENT_NET& goldenNet = goldenComp->GetNet( net );
|
||||
const COMPONENT_NET& testNet = refComp->GetNet( net );
|
||||
|
||||
// The two nets at the same index should be identical
|
||||
BOOST_REQUIRE_EQUAL( goldenNet.GetPinName(), testNet.GetPinName() );
|
||||
BOOST_REQUIRE_EQUAL( goldenNet.GetNetName(), testNet.GetNetName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TEST_NETLISTS_FIXTURE::cleanup()
|
||||
{
|
||||
wxRemoveFile( getNetlistFileName( true ) );
|
||||
}
|
||||
|
||||
|
||||
void TEST_NETLISTS_FIXTURE::doNetlistTest( const wxString& aBaseName )
|
||||
{
|
||||
loadSchematic( aBaseName );
|
||||
writeNetlist();
|
||||
compareNetlists();
|
||||
cleanup();
|
||||
}
|
||||
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE( Netlists, TEST_NETLISTS_FIXTURE )
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( FindPlugin )
|
||||
{
|
||||
BOOST_CHECK_NE( m_pi, nullptr );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( GlobalPromotion )
|
||||
{
|
||||
doNetlistTest( "test_global_promotion" );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( GlobalPromotion2 )
|
||||
{
|
||||
doNetlistTest( "test_global_promotion_2" );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( Video )
|
||||
{
|
||||
doNetlistTest( "video" );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( ComplexHierarchy )
|
||||
{
|
||||
doNetlistTest( "complex_hierarchy" );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue