KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_drc_issue24264.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 <board.h>
29#include <drc/drc_engine.h>
30#include <drc/drc_item.h>
31#include <drc/drc_report.h>
32#include <pcb_marker.h>
34
35#include <fstream>
36#include <sstream>
37
38#include <json_common.h>
39
40
42{
44 std::unique_ptr<BOARD> m_board;
45};
46
47
48// https://gitlab.com/kicad/code/kicad/-/issues/24264
49//
50// A custom rule that pins a constraint to "(severity exclusion)" should produce a marker that
51// appears in the JSON DRC report as excluded. Before the fix, the JSON output reported these
52// markers as plain errors with "excluded": false, while the interactive DRC dialog correctly
53// treated them as exclusions.
54BOOST_FIXTURE_TEST_CASE( DRCRuleSeverityExclusionMarkedExcluded, ISSUE24264_FIXTURE )
55{
56 KI_TEST::LoadBoard( m_settingsManager, "issue24264/issue24264", m_board );
57
58 BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
59
60 // Silence unrelated checks that can fire on the imported reproduction board
65
66 auto& drcEngine = bds.m_DRCEngine;
67
68 BOOST_REQUIRE( drcEngine );
69
70 drcEngine->SetViolationHandler(
71 [&]( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I& aPos, int aLayer,
72 const std::function<void( PCB_MARKER* )>& aPathGenerator )
73 {
74 PCB_MARKER* marker = new PCB_MARKER( aItem, aPos, aLayer );
75
76 if( aPathGenerator )
77 aPathGenerator( marker );
78
79 m_board->Add( marker );
80 } );
81
82 drcEngine->RunTests( EDA_UNITS::MM, true, false );
83 drcEngine->ClearViolationHandler();
84
85 // Find the rule-driven courtyard exclusion marker
86 int courtyardCount = 0;
87 int courtyardExcluded = 0;
88
89 for( PCB_MARKER* marker : m_board->Markers() )
90 {
91 if( marker->GetRCItem()->GetErrorCode() == DRCE_OVERLAPPING_FOOTPRINTS )
92 {
93 ++courtyardCount;
94
95 if( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION )
96 ++courtyardExcluded;
97 }
98 }
99
100 BOOST_TEST_MESSAGE( "Courtyard markers found: " << courtyardCount
101 << ", excluded: " << courtyardExcluded );
102
103 BOOST_REQUIRE_GE( courtyardCount, 1 );
104 BOOST_CHECK_EQUAL( courtyardExcluded, courtyardCount );
105
106 // Now exercise the report writer path used by `kicad-cli pcb drc` and check the JSON output
107 auto markersProvider = std::make_shared<DRC_ITEMS_PROVIDER>(
109 auto ratsnestProvider = std::make_shared<DRC_ITEMS_PROVIDER>(
110 m_board.get(), MARKER_BASE::MARKER_RATSNEST );
111 auto fpWarningsProvider = std::make_shared<DRC_ITEMS_PROVIDER>(
112 m_board.get(), MARKER_BASE::MARKER_PARITY );
113
115 markersProvider->SetSeverities( allSev );
116 ratsnestProvider->SetSeverities( allSev );
117 fpWarningsProvider->SetSeverities( allSev );
118
119 DRC_REPORT report( m_board.get(), EDA_UNITS::MM, markersProvider, ratsnestProvider,
120 fpWarningsProvider );
121
122 // wxFileName::CreateTempFileName reserves a unique path; we write directly to it instead
123 // of swapping the extension so we do not leave the reserved file behind.
124 wxString jsonPath = wxFileName::CreateTempFileName( wxT( "kicad-drc-24264-json-" ) );
125 wxString textPath = wxFileName::CreateTempFileName( wxT( "kicad-drc-24264-text-" ) );
126
128 BOOST_REQUIRE( report.WriteTextReport( textPath ) );
129
130 std::ifstream reportStream( jsonPath.fn_str() );
131 BOOST_REQUIRE( reportStream.is_open() );
132
133 nlohmann::json reportJson;
134 reportStream >> reportJson;
135 reportStream.close();
136 wxRemoveFile( jsonPath );
137
138 BOOST_REQUIRE( reportJson.contains( "violations" ) );
139
140 int sawCourtyardExcluded = 0;
141
142 for( const auto& violation : reportJson["violations"] )
143 {
144 if( violation.value( "type", std::string() ) == "courtyards_overlap" )
145 {
146 BOOST_CHECK( violation.value( "excluded", false ) );
147
148 if( violation.value( "excluded", false ) )
149 ++sawCourtyardExcluded;
150 }
151 }
152
153 BOOST_CHECK_EQUAL( sawCourtyardExcluded, courtyardCount );
154
155 // Text report should also surface the exclusion suffix from RC_ITEM::ShowReport()
156 std::ifstream textStream( textPath.fn_str() );
157 BOOST_REQUIRE( textStream.is_open() );
158
159 std::stringstream textBuf;
160 textBuf << textStream.rdbuf();
161 textStream.close();
162 wxRemoveFile( textPath );
163
164 const std::string textReport = textBuf.str();
165
166 BOOST_TEST_MESSAGE( "Text report excerpt:\n" << textReport );
167 BOOST_CHECK( textReport.find( "courtyards_overlap" ) != std::string::npos );
168 BOOST_CHECK( textReport.find( "(excluded)" ) != std::string::npos );
169}
Container for design settings for a BOARD object.
std::map< int, SEVERITY > m_DRCSeverities
std::shared_ptr< DRC_ENGINE > m_DRCEngine
bool WriteJsonReport(const wxString &aFullFileName)
bool WriteTextReport(const wxString &aFullFileName)
@ MARKER_DRAWING_SHEET
Definition marker_base.h:56
@ DRCE_UNCONNECTED_ITEMS
Definition drc_item.h:40
@ DRCE_LIB_FOOTPRINT_ISSUES
Definition drc_item.h:83
@ DRCE_OVERLAPPING_FOOTPRINTS
Definition drc_item.h:66
@ DRCE_FOOTPRINT_TYPE_MISMATCH
Definition drc_item.h:82
@ DRCE_LIB_FOOTPRINT_MISMATCH
Definition drc_item.h:84
void LoadBoard(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< BOARD > &aBoard)
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_IGNORE
std::unique_ptr< BOARD > m_board
SETTINGS_MANAGER m_settingsManager
BOOST_FIXTURE_TEST_CASE(DRCRuleSeverityExclusionMarkedExcluded, ISSUE24264_FIXTURE)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687