KiCad PCB EDA Suite
test_netlists.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
21 #include "eeschema_test_utils.h"
22 
23 #include <connection_graph.h>
24 #include <netlist_exporter_kicad.h>
27 #include <project.h>
28 #include <sch_io_mgr.h>
29 #include <sch_sheet.h>
30 #include <schematic.h>
33 
34 
36 {
37 public:
39  m_schematic( nullptr ),
40  m_manager( true )
41  {
42  m_pi = SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD );
43  }
44 
46  {
49  }
50 
51  void loadSchematic( const wxString& aBaseName );
52 
53  wxString getNetlistFileName( bool aTest = false );
54 
55  void writeNetlist();
56 
57  void compareNetlists();
58 
59  void cleanup();
60 
61  void doNetlistTest( const wxString& aBaseName );
62 
65 
67 
69 };
70 
71 
72 static wxString getSchematicFile( const wxString& aBaseName )
73 {
74  wxFileName fn = KI_TEST::GetEeschemaTestDataDir();
75  fn.AppendDir( "netlists" );
76  fn.AppendDir( aBaseName );
77  fn.SetName( aBaseName );
78  fn.SetExt( KiCadSchematicFileExtension );
79 
80  return fn.GetFullPath();
81 }
82 
83 
84 void TEST_NETLISTS_FIXTURE::loadSchematic( const wxString& aBaseName )
85 {
86  wxString fn = getSchematicFile( aBaseName );
87 
88  BOOST_TEST_MESSAGE( fn );
89 
90  wxFileName pro( fn );
91  pro.SetExt( ProjectFileExtension );
92 
93  m_manager.LoadProject( pro.GetFullPath() );
94 
96 
100 
101  BOOST_REQUIRE_EQUAL( m_pi->GetError().IsEmpty(), true );
102 
104 
105  SCH_SCREENS screens( m_schematic.Root() );
106 
107  for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
108  screen->UpdateLocalLibSymbolLinks();
109 
111 
112  // Restore all of the loaded symbol instances from the root sheet screen.
114 
115  sheets.AnnotatePowerSymbols();
116 
117  // NOTE: This is required for multi-unit symbols to be correct
118  // Normally called from SCH_EDIT_FRAME::FixupJunctions() but could be refactored
119  for( SCH_SHEET_PATH& sheet : sheets )
120  sheet.UpdateAllScreenReferences();
121 
122  // NOTE: SchematicCleanUp is not called; QA schematics must already be clean or else
123  // SchematicCleanUp must be freed from its UI dependencies.
124 
125  m_schematic.ConnectionGraph()->Recalculate( sheets, true );
126 }
127 
128 
130 {
131  wxFileName netFile = m_schematic.Prj().GetProjectFullName();
132 
133  if( aTest )
134  netFile.SetName( netFile.GetName() + "_test" );
135 
136  netFile.SetExt( NetlistFileExtension );
137 
138  return netFile.GetFullPath();
139 }
140 
141 
143 {
144  auto exporter = std::make_unique<NETLIST_EXPORTER_KICAD>( &m_schematic );
145  BOOST_REQUIRE_EQUAL( exporter->WriteNetlist( getNetlistFileName( true ), 0 ), true );
146 }
147 
148 
150 {
151  NETLIST golden;
152  NETLIST test;
153 
154  {
155  std::unique_ptr<NETLIST_READER> netlistReader( NETLIST_READER::GetNetlistReader(
156  &golden, getNetlistFileName(), wxEmptyString ) );
157 
158  BOOST_REQUIRE_NO_THROW( netlistReader->LoadNetlist() );
159  }
160 
161  {
162  std::unique_ptr<NETLIST_READER> netlistReader( NETLIST_READER::GetNetlistReader(
163  &test, getNetlistFileName( true ), wxEmptyString ) );
164 
165  BOOST_REQUIRE_NO_THROW( netlistReader->LoadNetlist() );
166  }
167 
168  // Number of components should match
169  BOOST_REQUIRE_EQUAL( golden.GetCount(), test.GetCount() );
170 
171  for( unsigned i = 0; i < golden.GetCount(); i++ )
172  {
173  COMPONENT* goldenComp = golden.GetComponent( i );
174  COMPONENT* refComp = test.GetComponentByReference( goldenComp->GetReference() );
175 
176  // Retrieval by reference
177  BOOST_REQUIRE_NE( refComp, nullptr );
178 
179  // Retrieval by KIID
180  KIID_PATH path = goldenComp->GetPath();
181 
182  BOOST_REQUIRE( !goldenComp->GetKIIDs().empty() );
183 
184  path.push_back( goldenComp->GetKIIDs().front() );
185 
186  COMPONENT* pathComp = test.GetComponentByPath( path );
187  BOOST_REQUIRE_NE( pathComp, nullptr );
188 
189  // We should have found the same component
190  BOOST_REQUIRE_EQUAL( refComp->GetReference(), pathComp->GetReference() );
191 
192  // And that component should have the same number of attached nets
193  BOOST_REQUIRE_EQUAL( goldenComp->GetNetCount(), refComp->GetNetCount() );
194 
195  for( unsigned net = 0; net < goldenComp->GetNetCount(); net++ )
196  {
197  const COMPONENT_NET& goldenNet = goldenComp->GetNet( net );
198  const COMPONENT_NET& testNet = refComp->GetNet( net );
199 
200  // The two nets at the same index should be identical
201  BOOST_REQUIRE_EQUAL( goldenNet.GetPinName(), testNet.GetPinName() );
202  BOOST_REQUIRE_EQUAL( goldenNet.GetNetName(), testNet.GetNetName() );
203  }
204  }
205 }
206 
207 
209 {
210  wxRemoveFile( getNetlistFileName( true ) );
211  m_schematic.Reset();
212 }
213 
214 
215 void TEST_NETLISTS_FIXTURE::doNetlistTest( const wxString& aBaseName )
216 {
217  loadSchematic( aBaseName );
218  writeNetlist();
219  compareNetlists();
220  cleanup();
221 }
222 
223 
224 BOOST_FIXTURE_TEST_SUITE( Netlists, TEST_NETLISTS_FIXTURE )
225 
226 
227 BOOST_AUTO_TEST_CASE( FindPlugin )
228 {
229  BOOST_CHECK_NE( m_pi, nullptr );
230 }
231 
232 
233 BOOST_AUTO_TEST_CASE( GlobalPromotion )
234 {
235  doNetlistTest( "test_global_promotion" );
236 }
237 
238 
239 BOOST_AUTO_TEST_CASE( GlobalPromotion2 )
240 {
241  doNetlistTest( "test_global_promotion_2" );
242 }
243 
244 
246 {
247  doNetlistTest( "video" );
248 }
249 
250 
251 BOOST_AUTO_TEST_CASE( ComplexHierarchy )
252 {
253  doNetlistTest( "complex_hierarchy" );
254 }
255 
256 
257 BOOST_AUTO_TEST_CASE( WeakVectorBusDisambiguation )
258 {
259  doNetlistTest( "weak_vector_bus_disambiguation" );
260 }
261 
262 
263 BOOST_AUTO_TEST_CASE( BusJunctions )
264 {
265  doNetlistTest( "bus_junctions" );
266 }
267 
268 
269 BOOST_AUTO_TEST_CASE( HierRenaming )
270 {
271  doNetlistTest( "test_hier_renaming" );
272 }
273 
274 
275 BOOST_AUTO_TEST_CASE( NoConnects )
276 {
277  doNetlistTest( "noconnects" );
278 }
279 
280 
281 BOOST_AUTO_TEST_SUITE_END()
const std::string NetlistFileExtension
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
void doNetlistTest(const wxString &aBaseName)
Holds all the data relating to one schematic A schematic may consist of one or more sheets (and one r...
Definition: schematic.h:58
CONNECTION_GRAPH * ConnectionGraph() const override
Definition: schematic.h:151
const std::string ProjectFileExtension
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
const std::vector< SYMBOL_INSTANCE_REFERENCE > & GetSymbolInstances() const
Definition: sch_screen.h:503
virtual SCH_SHEET * Load(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=NULL, const PROPERTIES *aProperties=NULL)
Load information from some input file format that this SCH_PLUGIN implementation knows about,...
Definition: sch_plugin.cpp:51
static NETLIST_READER * GetNetlistReader(NETLIST *aNetlist, const wxString &aNetlistFileName, const wxString &aCompFootprintFileName=wxEmptyString)
Function GetNetlistReader attempts to determine the net list file type of aNetlistFileName and return...
unsigned GetCount() const
Function GetCount.
Definition: pcb_netlist.h:237
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr)
Updates the connection graph for the given list of sheets.
virtual void SetElem(ELEM_T aIndex, _ELEM *aElem)
COMPONENT_NET is used to store the component pin name to net name (and pin function) associations sto...
Definition: pcb_netlist.h:44
void SetRoot(SCH_SHEET *aRootSheet)
Initializes the schematic with a new root sheet.
Definition: schematic.cpp:100
wxString getNetlistFileName(bool aTest=false)
const wxString & GetNetName() const
Definition: pcb_netlist.h:64
Base class that schematic file and library loading and saving plugins should derive from.
Definition: sch_io_mgr.h:153
NETLIST stores all of information read from a netlist along with the flags used to update the NETLIST...
Definition: pcb_netlist.h:207
unsigned GetNetCount() const
Definition: pcb_netlist.h:144
const wxString & GetReference() const
Definition: pcb_netlist.h:158
Definition of file extensions used in Kicad.
SCHEMATIC m_schematic
Schematic to load
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
void SetProject(PROJECT *aPrj)
Definition: schematic.cpp:73
const COMPONENT_NET & GetNet(unsigned aIndex) const
Definition: pcb_netlist.h:146
void UpdateSymbolInstances(const std::vector< SYMBOL_INSTANCE_REFERENCE > &aSymbolInstances)
Update all of the symbol instance information using aSymbolInstances.
wxFileName GetEeschemaTestDataDir()
Get the configured location of Eeschema test data.
COMPONENT is used to store components and all of their related information found in a netlist.
Definition: pcb_netlist.h:85
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:99
COMPONENT * GetComponent(unsigned aIndex)
Function GetComponent returns the COMPONENT at aIndex.
Definition: pcb_netlist.h:246
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Loads a project or sets up a new project with a specified path.
void Reset()
Initializes this schematic to a blank one, unloading anything existing.
Definition: schematic.cpp:50
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:111
SETTINGS_MANAGER m_manager
SCH_SHEET & Root() const
Definition: schematic.h:116
virtual ~TEST_NETLISTS_FIXTURE()
void loadSchematic(const wxString &aBaseName)
virtual const wxString & GetError() const
Return an error string to the caller.
Definition: sch_plugin.cpp:177
const std::string KiCadSchematicFileExtension
const wxString & GetPinName() const
Definition: pcb_netlist.h:63
static wxString getSchematicFile(const wxString &aBaseName)
void AnnotatePowerSymbols()
Silently annotate the not yet annotated power symbols of the entire hierarchy of the sheet path list.
SCH_SCREEN * RootScreen() const
Helper to retreive the screen of the root sheet.
Definition: schematic.cpp:113
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:141
const KIID_PATH & GetPath() const
Definition: pcb_netlist.h:173
BOOST_AUTO_TEST_CASE(FindPlugin)
static void ReleasePlugin(SCH_PLUGIN *aPlugin)
Release a SCH_PLUGIN back to the system, and may cause it to be unloaded from memory.
Definition: sch_io_mgr.cpp:77
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:534
const std::vector< KIID > & GetKIIDs() const
Definition: pcb_netlist.h:175