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-2021 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_CASE( PrefixBusAlias )
282 {
283  doNetlistTest( "prefix_bus_alias" );
284 }
285 
286 
287 BOOST_AUTO_TEST_CASE( GroupBusMatching )
288 {
289  doNetlistTest( "group_bus_matching" );
290 }
291 
292 
293 BOOST_AUTO_TEST_CASE( TopLevelHierPins )
294 {
295  doNetlistTest( "top_level_hier_pins" );
296 }
297 
298 
299 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.
Definition: schematic.h:59
CONNECTION_GRAPH * ConnectionGraph() const override
Definition: schematic.h:129
const std::string ProjectFileExtension
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
virtual SCH_SHEET * Load(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const PROPERTIES *aProperties=nullptr)
Load information from some input file format that this SCH_PLUGIN implementation knows about,...
Definition: sch_plugin.cpp:51
const std::vector< SYMBOL_INSTANCE_REFERENCE > & GetSymbolInstances() const
Definition: sch_screen.h:453
static NETLIST_READER * GetNetlistReader(NETLIST *aNetlist, const wxString &aNetlistFileName, const wxString &aCompFootprintFileName=wxEmptyString)
Attempt to determine the net list file type of aNetlistFileName and return the appropriate NETLIST_RE...
unsigned GetCount() const
Definition: pcb_netlist.h:228
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)
Definition: project.cpp:259
Used to store the component pin name to net name (and pin function) associations stored in a netlist.
Definition: pcb_netlist.h:43
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
Definition: schematic.cpp:104
wxString getNetlistFileName(bool aTest=false)
const wxString & GetNetName() const
Definition: pcb_netlist.h:58
Base class that schematic file and library loading and saving plugins should derive from.
Definition: sch_io_mgr.h:151
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
Definition: pcb_netlist.h:206
unsigned GetNetCount() const
Definition: pcb_netlist.h:109
const wxString & GetReference() const
Definition: pcb_netlist.h:123
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.
Definition: project.cpp:117
void SetProject(PROJECT *aPrj)
Definition: schematic.cpp:76
const COMPONENT_NET & GetNet(unsigned aIndex) const
Definition: pcb_netlist.h:111
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.
Store all of the related footprint information found in a netlist.
Definition: pcb_netlist.h:84
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:75
COMPONENT * GetComponent(unsigned aIndex)
Return the COMPONENT at aIndex.
Definition: pcb_netlist.h:236
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Loads a project or sets up a new project with a specified path.
void Reset()
Initialize this schematic to a blank one, unloading anything existing.
Definition: schematic.cpp:51
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:87
SETTINGS_MANAGER m_manager
SCH_SHEET & Root() const
Definition: schematic.h:92
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:57
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 retrieve the screen of the root sheet.
Definition: schematic.cpp:117
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:119
const KIID_PATH & GetPath() const
Definition: pcb_netlist.h:138
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:69
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:551
const std::vector< KIID > & GetKIIDs() const
Definition: pcb_netlist.h:140