KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_drc_issue24211.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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
26
27#include <set>
28
29#include <board.h>
31#include <board_loader.h>
33#include <drc/drc_engine.h>
34#include <drc/drc_item.h>
35#include <drc/drc_rule.h>
36#include <footprint.h>
37#include <pcb_io/pcb_io_mgr.h>
38#include <project.h>
40#include <wx/filename.h>
41
42
44{
46
48 {
49 wxFileName projectFile( wxString::FromUTF8( KI_TEST::GetPcbnewTestDataDir() )
50 + "issue24211/issue24211.kicad_pro" );
51
52 m_settingsManager.LoadProject( projectFile.GetFullPath() );
53
54 PROJECT* project = m_settingsManager.GetProject( projectFile.GetFullPath() );
55 BOOST_REQUIRE_MESSAGE( project, "Could not load project" );
56 return project;
57 }
58
59 wxString boardPath() const
60 {
61 return wxString::FromUTF8( KI_TEST::GetPcbnewTestDataDir() )
62 + "issue24211/issue24211.kicad_pcb";
63 }
64};
65
66
67// Regression test for https://gitlab.com/kicad/code/kicad/-/issues/24211
68//
69// BOARD_LOADER::Load is the entry point for CLI and API consumers (kicad-cli pcb drc and the
70// api-server). It must produce a board with component class assignments applied so that custom
71// DRC rules using A.hasComponentClass(...) match the same items they would in the interactive
72// DRC dialog. Before the fix, dynamic class assignments were only applied in the GUI load path.
73BOOST_FIXTURE_TEST_CASE( DRCIssue24211ComponentClassesAfterLoad, DRC_ISSUE_24211_FIXTURE )
74{
75 PROJECT* project = loadProject();
76
77 std::unique_ptr<BOARD> board = BOARD_LOADER::Load( boardPath(), PCB_IO_MGR::KICAD_SEXP,
78 project );
79
80 BOOST_REQUIRE( board );
81
82 // The reproduction project assigns the "Inductor" class to reference L1. After
83 // BOARD_LOADER::Load with initialize_after_load=true (the CLI / API default), every footprint
84 // matched by an assignment rule must already report that class.
85 FOOTPRINT* l1 = board->FindFootprintByReference( wxT( "L1" ) );
86
87 BOOST_REQUIRE_MESSAGE( l1, "Reference L1 not present in test board" );
88
89 const COMPONENT_CLASS* compClass = l1->GetComponentClass();
90
91 BOOST_REQUIRE_MESSAGE( compClass, "L1 has no component class after BOARD_LOADER::Load" );
92 BOOST_TEST_MESSAGE( "L1 class: " << compClass->GetName().ToStdString() );
93 BOOST_CHECK( compClass->ContainsClassName( wxT( "Inductor" ) ) );
94}
95
96
97// Runs the custom-rule DRC against the issue24211 board through the same load path the CLI uses
98// (BOARD_LOADER::Load). Without the fix, the second custom rule
99// ("pcblint_inductor_sensitive_trace_keepout_no_track") never fires because no footprint has the
100// 'Inductor' component class assigned; only the first ("buck_feedback_away_from_switch_node")
101// reports violations. After the fix, both rules report violations, matching the interactive DRC.
102BOOST_FIXTURE_TEST_CASE( DRCIssue24211BothCustomRulesFire, DRC_ISSUE_24211_FIXTURE )
103{
104 PROJECT* project = loadProject();
105
106 std::unique_ptr<BOARD> board = BOARD_LOADER::Load( boardPath(), PCB_IO_MGR::KICAD_SEXP,
107 project );
108
109 BOOST_REQUIRE( board );
110
111 BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
112
114
115 // Ignore checks unrelated to the custom clearance rules under test
116 for( int code = DRCE_FIRST; code <= DRCE_LAST; ++code )
118
120
121 std::set<wxString> firedRules;
122
124 [&]( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I&, int,
125 const std::function<void( PCB_MARKER* )>& )
126 {
127 if( aItem->GetViolatingRule() )
128 firedRules.insert( aItem->GetViolatingRule()->m_Name );
129 } );
130
131 bds.m_DRCEngine->RunTests( EDA_UNITS::MM, true, false );
132
133 BOOST_TEST_MESSAGE( "Fired rules:" );
134
135 for( const wxString& r : firedRules )
136 BOOST_TEST_MESSAGE( " " << r.ToStdString() );
137
138 BOOST_CHECK_MESSAGE( firedRules.count( wxT( "pcblint_buck_feedback_away_from_switch_node" ) ),
139 "Netclass-based custom rule did not fire" );
140
142 firedRules.count( wxT( "pcblint_inductor_sensitive_trace_keepout_no_track" ) ),
143 "Component-class-based custom rule did not fire after BOARD_LOADER::Load" );
144}
General utilities for PCB file IO for QA programs.
Container for design settings for a BOARD object.
std::map< int, SEVERITY > m_DRCSeverities
std::shared_ptr< DRC_ENGINE > m_DRCEngine
static std::unique_ptr< BOARD > Load(const wxString &aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, PROJECT *aProject, const OPTIONS &aOptions)
A lightweight representation of a component class.
bool ContainsClassName(const wxString &className) const
Determines if this (effective) component class contains a specific constituent class.
const wxString & GetName() const
Fetches the full name of this component class.
void RunTests(EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints, BOARD_COMMIT *aCommit=nullptr)
Run the DRC tests.
void SetViolationHandler(DRC_VIOLATION_HANDLER aHandler)
Set an optional DRC violation handler (receives DRC_ITEMs and positions).
Definition drc_engine.h:168
const COMPONENT_CLASS * GetComponentClass() const
Returns the component class for this footprint.
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition pcb_io_mgr.h:58
Container for project specific data.
Definition project.h:66
@ DRCE_CLEARANCE
Definition drc_item.h:44
@ DRCE_FIRST
Definition drc_item.h:39
@ DRCE_LAST
Definition drc_item.h:124
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_IGNORE
BOOST_FIXTURE_TEST_CASE(DRCIssue24211ComponentClassesAfterLoad, DRC_ISSUE_24211_FIXTURE)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687