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, see <https://www.gnu.org/licenses/>.
18 */
19
22
23#include <set>
24
25#include <board.h>
27#include <board_loader.h>
29#include <drc/drc_engine.h>
30#include <drc/drc_item.h>
31#include <drc/drc_rule.h>
32#include <footprint.h>
33#include <pcb_io/pcb_io_mgr.h>
34#include <project.h>
36#include <wx/filename.h>
37
38
40{
42
44 {
45 wxFileName projectFile( wxString::FromUTF8( KI_TEST::GetPcbnewTestDataDir() )
46 + "issue24211/issue24211.kicad_pro" );
47
48 m_settingsManager.LoadProject( projectFile.GetFullPath() );
49
50 PROJECT* project = m_settingsManager.GetProject( projectFile.GetFullPath() );
51 BOOST_REQUIRE_MESSAGE( project, "Could not load project" );
52 return project;
53 }
54
55 wxString boardPath() const
56 {
57 return wxString::FromUTF8( KI_TEST::GetPcbnewTestDataDir() )
58 + "issue24211/issue24211.kicad_pcb";
59 }
60};
61
62
63// Regression test for https://gitlab.com/kicad/code/kicad/-/issues/24211
64//
65// BOARD_LOADER::Load is the entry point for CLI and API consumers (kicad-cli pcb drc and the
66// api-server). It must produce a board with component class assignments applied so that custom
67// DRC rules using A.hasComponentClass(...) match the same items they would in the interactive
68// DRC dialog. Before the fix, dynamic class assignments were only applied in the GUI load path.
69BOOST_FIXTURE_TEST_CASE( DRCIssue24211ComponentClassesAfterLoad, DRC_ISSUE_24211_FIXTURE )
70{
71 PROJECT* project = loadProject();
72
73 std::unique_ptr<BOARD> board = BOARD_LOADER::Load( boardPath(), PCB_IO_MGR::KICAD_SEXP,
74 project );
75
76 BOOST_REQUIRE( board );
77
78 // The reproduction project assigns the "Inductor" class to reference L1. After
79 // BOARD_LOADER::Load with initialize_after_load=true (the CLI / API default), every footprint
80 // matched by an assignment rule must already report that class.
81 FOOTPRINT* l1 = board->FindFootprintByReference( wxT( "L1" ) );
82
83 BOOST_REQUIRE_MESSAGE( l1, "Reference L1 not present in test board" );
84
85 const COMPONENT_CLASS* compClass = l1->GetComponentClass();
86
87 BOOST_REQUIRE_MESSAGE( compClass, "L1 has no component class after BOARD_LOADER::Load" );
88 BOOST_TEST_MESSAGE( "L1 class: " << compClass->GetName().ToStdString() );
89 BOOST_CHECK( compClass->ContainsClassName( wxT( "Inductor" ) ) );
90}
91
92
93// Runs the custom-rule DRC against the issue24211 board through the same load path the CLI uses
94// (BOARD_LOADER::Load). Without the fix, the second custom rule
95// ("pcblint_inductor_sensitive_trace_keepout_no_track") never fires because no footprint has the
96// 'Inductor' component class assigned; only the first ("buck_feedback_away_from_switch_node")
97// reports violations. After the fix, both rules report violations, matching the interactive DRC.
98BOOST_FIXTURE_TEST_CASE( DRCIssue24211BothCustomRulesFire, DRC_ISSUE_24211_FIXTURE )
99{
100 PROJECT* project = loadProject();
101
102 std::unique_ptr<BOARD> board = BOARD_LOADER::Load( boardPath(), PCB_IO_MGR::KICAD_SEXP,
103 project );
104
105 BOOST_REQUIRE( board );
106
107 BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
108
110
111 // Ignore checks unrelated to the custom clearance rules under test
112 for( int code = DRCE_FIRST; code <= DRCE_LAST; ++code )
114
116
117 std::set<wxString> firedRules;
118
120 [&]( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I&, int,
121 const std::function<void( PCB_MARKER* )>& )
122 {
123 if( aItem->GetViolatingRule() )
124 firedRules.insert( aItem->GetViolatingRule()->m_Name );
125 } );
126
127 bds.m_DRCEngine->RunTests( EDA_UNITS::MM, true, false );
128
129 BOOST_TEST_MESSAGE( "Fired rules:" );
130
131 for( const wxString& r : firedRules )
132 BOOST_TEST_MESSAGE( " " << r.ToStdString() );
133
134 BOOST_CHECK_MESSAGE( firedRules.count( wxT( "pcblint_buck_feedback_away_from_switch_node" ) ),
135 "Netclass-based custom rule did not fire" );
136
138 firedRules.count( wxT( "pcblint_inductor_sensitive_trace_keepout_no_track" ) ),
139 "Component-class-based custom rule did not fire after BOARD_LOADER::Load" );
140}
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:164
const COMPONENT_CLASS * GetComponentClass() const
Returns the component class for this footprint.
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition pcb_io_mgr.h:54
Container for project specific data.
Definition project.h:62
@ DRCE_CLEARANCE
Definition drc_item.h:40
@ DRCE_FIRST
Definition drc_item.h:35
@ DRCE_LAST
Definition drc_item.h:121
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:683