KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_sim_regressions.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 The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21#include <boost/test/results_collector.hpp> // To check if the current test failed (to be moved?).
22#include <eeschema_test_utils.h>
25#include <sim/spice_generator.h>
26#include <reporter.h>
27#include <wx/ffile.h>
28#include <wx/filename.h>
29#include <wx/tokenzr.h>
30#include <mock_pgm_base.h>
31#include <locale_io.h>
32#include <set>
33
34
35namespace
36{
37// The exporter emits absolute, machine-specific paths, so tests compare `.include` directives on
38// the file name only.
39std::set<wxString> collectIncludeFileNames( const wxString& aNetlist )
40{
41 std::set<wxString> names;
42 wxStringTokenizer lines( aNetlist, wxS( "\n" ), wxTOKEN_RET_EMPTY_ALL );
43
44 while( lines.HasMoreTokens() )
45 {
46 wxString line = lines.GetNextToken();
47
48 if( line.StartsWith( wxS( ".include " ) ) )
49 {
50 wxFileName fn( line.AfterFirst( '"' ).BeforeLast( '"' ) );
51 names.insert( fn.GetFullName() );
52 }
53 }
54
55 return names;
56}
57} // namespace
58
59
61{
62public:
67
71
72 wxFileName SchematicQAPath( const wxString& aBaseName ) override
73 {
74 wxFileName fn( KI_TEST::GetEeschemaTestDataDir() );
75 fn.SetName( aBaseName );
77
78 return fn;
79 }
80
81 wxString GetNetlistPath( bool aTest = false ) override
82 {
83 wxFileName netFile = m_schematic->Project().GetProjectFullName();
84
85 if( aTest )
86 netFile.SetName( netFile.GetName() + "_test" );
87
88 netFile.SetExt( "spice" );
89 return netFile.GetFullPath();
90 }
91
109
110public:
112 bool m_SaveVoltages = true;
113 bool m_SaveCurrents = true;
114};
115
116
118{
120
121 // const MOCK_PGM_BASE& program = static_cast<MOCK_PGM_BASE&>( Pgm() );
122 // MOCK_EXPECT( program.GetLocalEnvVariables ).returns( ENV_VAR_MAP() );
123
124 TestNetlist( "issue13591" );
125 TestTranPoint( 100e-6, { { "I(R1)", 0 }, { "I(R2)", 0 } }, 0.00001 );
126 TestTranPoint( 500e-6, { { "I(R1)", 0 }, { "I(R2)", 0 } }, 0.00001 );
127}
128
129
131{
133
134 m_SaveCurrents = false;
135
136 TestNetlist( "issue13431" );
137 TestTranPoint( 0.005, { { "V(/soft_start)", 2.489 } } );
138 TestTranPoint( 0.012, { { "V(/soft_start)", 5.100 } } );
139}
140
141
142// This test is flaky and fails on ngspice-42 / Linux.
143// Please replace it with something that is more stable
144#if 0
146{
148
149 const MOCK_PGM_BASE& program = static_cast<MOCK_PGM_BASE&>( Pgm() );
150 MOCK_EXPECT( program.GetLocalEnvVariables ).returns( ENV_VAR_MAP() );
151
152 TestNetlist( "issue13112" );
153 TestTranPoint( 0.01, { { "V(out)", -0.060 } } );
154 TestTranPoint( 0.02, { { "V(out)", 0.856 } } );
155}
156#endif
157
158
160{
162
163 // const MOCK_PGM_BASE& program = static_cast<MOCK_PGM_BASE&>( Pgm() );
164 // MOCK_EXPECT( program.GetLocalEnvVariables ).returns( ENV_VAR_MAP() );
165
166 TestNetlist( "issue13162" );
167 TestTranPoint( 0.030, { { "V(out)", 0.000829682 } } );
168 TestTranPoint( 0.035, { { "V(out)", -0.000829692 } } );
169}
170
171
173{
175
176 // const MOCK_PGM_BASE& program = static_cast<MOCK_PGM_BASE&>( Pgm() );
177 // MOCK_EXPECT( program.GetLocalEnvVariables ).returns( ENV_VAR_MAP() );
178
179 TestNetlist( "issue12505" );
180 TestTranPoint( 0.015, { { "V(Net-_R1-Pad2_)", -311 } } );
181 TestTranPoint( 0.025, { { "V(Net-_R1-Pad2_)", 311 } } );
182}
183
184
186{
188
189 // const MOCK_PGM_BASE& program = static_cast<MOCK_PGM_BASE&>( Pgm() );
190 // MOCK_EXPECT( program.GetLocalEnvVariables ).returns( ENV_VAR_MAP() );
191
192 TestNetlist( "issue16223" );
193 TestTranPoint( 0.0, { { "V(PRBS_OUTPUT)", 5.114 } } );
194 TestTranPoint( 1e-6, { { "V(PRBS_OUTPUT)", -0.1144 } } );
195}
196
197
198// An IBIS driver generates a per-reference <ref>.cache device that must be pulled into the netlist
199// as a `.include`. The include is supplied solely by SIM_MODEL_IBIS::GetSpiceIncludes(), so this
200// guards it independently of the simulator.
202{
204
205 LoadSchematic( SchematicQAPath( wxS( "issue16223" ) ) );
206 WriteNetlist();
207
208 wxFFile netlistFile( GetNetlistPath( true ), "rt" );
209 BOOST_REQUIRE( netlistFile.IsOpened() );
210
211 wxString netlist;
212 netlistFile.ReadAll( &netlist );
213 netlistFile.Close();
214
215 BOOST_TEST_INFO( "Netlist:\n" << netlist );
216
217 std::set<wxString> includes = collectIncludeFileNames( netlist );
218
219 // The fixture carries six IBIS symbols; asserting the exact names pins the per-reference
220 // cache naming.
221 for( const wxString& ref : { wxS( "U1" ), wxS( "U2" ), wxS( "U3" ),
222 wxS( "U4" ), wxS( "U5" ), wxS( "U6" ) } )
223 {
224 wxString cacheName = ref + wxS( ".cache" );
225
226 BOOST_CHECK_MESSAGE( includes.count( cacheName ) == 1,
227 "IBIS cache device " << cacheName << " was not emitted as a .include" );
228 }
229
230 Cleanup();
231}
232
233
234// A raw-Spice model that carries a library path must offer it back through GetSpiceIncludes() so
235// the exporter can emit it as a `.include`. No schematic fixture reaches this path, because any
236// resolvable library gets registered and emitted through the SPICE library path instead.
237BOOST_AUTO_TEST_CASE( RawSpiceModelSuppliesLibraryInclude )
238{
240 SPICE_ITEM item;
241
242 BOOST_CHECK( model.GetSpiceIncludes( item, nullptr, NULL_REPORTER::GetInstance() ).empty() );
243
244 model.SetParamValue( "lib", "device.lib" );
245
246 std::vector<wxString> includes = model.GetSpiceIncludes( item, nullptr,
248
249 BOOST_REQUIRE_EQUAL( includes.size(), 1u );
250 BOOST_CHECK_EQUAL( includes.front(), wxString( wxS( "device.lib" ) ) );
251}
252
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
static REPORTER & GetInstance()
Definition reporter.cpp:120
wxFileName SchematicQAPath(const wxString &aBaseName) override
wxString GetNetlistPath(bool aTest=false) override
static const std::string KiCadSchematicFileExtension
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
std::string GetEeschemaTestDataDir()
Get the configured location of Eeschema test data.
PGM_BASE & Pgm()
The global program "get" accessor.
static void LoadSchematic(SCHEMATIC *aSchematic, SCH_SHEET *aRootSheet, const wxString &aFileName)
PGM_SINGLE_TOP program
std::vector< FAB_LAYER_COLOR > dummy
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
std::string netlist
KIBIS_MODEL * model
BOOST_TEST_INFO("Two-port Series .op current = "<< iDevice)
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
BOOST_FIXTURE_TEST_CASE(WindowsPaths, TEST_SIM_REGRESSIONS_FIXTURE)
BOOST_AUTO_TEST_CASE(RawSpiceModelSuppliesLibraryInclude)
BOOST_CHECK_EQUAL(result, "25.4")