KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_drc_return_path_reference_net.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
20#include <boost/test/unit_test.hpp>
21
23
24#include <filesystem>
25#include <fstream>
26
27#include <board.h>
29#include <drc/drc_engine.h>
30#include <drc/drc_item.h>
31#include <netinfo.h>
32#include <pcb_marker.h>
34
35
36// One F.Cu chain track with two B.Cu zones underneath: one on net "/GND" and
37// one on net "/VCC". Both zones cover the trunk fully so without a net
38// filter the check passes. With `(net "GND")` the GND zone alone qualifies
39// and the trunk is still covered. With `(net "PWR_*")` no zone qualifies and
40// the trunk is reported as uncovered.
41static const char* DUAL_ZONE_PCB = "net_chains/return_path_dual_zone.kicad_pcb";
42
43
44namespace
45{
46size_t runDrc( const std::string& aDru, const std::string& aSubdir )
47{
48 namespace fs = std::filesystem;
49 fs::path tmpDir = fs::temp_directory_path() / aSubdir;
50 fs::create_directories( tmpDir );
51 fs::path druPath = tmpDir / "rn.kicad_dru";
52
53 {
54 std::ofstream out( druPath );
55 out << aDru;
56 }
57
58 PCB_IO_KICAD_SEXPR plugin;
59 std::unique_ptr<BOARD> board = plugin.LoadBoard( KI_TEST::GetPcbnewTestDataDir() + DUAL_ZONE_PCB );
60 board->BuildConnectivity();
61
62 NETINFO_ITEM* sig = board->FindNet( wxS( "/CHAIN_RN" ) );
63 BOOST_REQUIRE( sig );
64 sig->SetNetChain( wxS( "RN" ) );
65
66 BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
67 auto drcEngine = std::make_shared<DRC_ENGINE>( board.get(), &bds );
68 wxFileName ruleFile( druPath.string() );
69 drcEngine->InitEngine( ruleFile );
70 bds.m_DRCEngine = drcEngine;
71
79
80 size_t markerCount = 0;
81 drcEngine->SetViolationHandler(
82 [&]( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I&, int,
83 const std::function<void( PCB_MARKER* )>& )
84 {
85 if( aItem->GetErrorCode() == DRCE_NET_CHAIN_RETURN_PATH_BREAK )
86 markerCount++;
87 } );
88
89 drcEngine->RunTests( EDA_UNITS::MM, true, false );
90
91 fs::remove( druPath );
92 return markerCount;
93}
94}
95
96
97BOOST_AUTO_TEST_SUITE( DRCReturnPathReferenceNet )
98
99
100// Without (net …): both zones qualify, trunk fully covered → 0 markers.
101BOOST_AUTO_TEST_CASE( ReferenceNetEmptyAcceptsAnyZoneRegression )
102{
103 const std::string dru =
104 R"((version 1)
105(rule "RP"
106 (condition "A.NetClass == 'Default'")
107 (constraint length (min 0mm) (max 200mm))
108 (constraint return_path (layer "B.Cu"))
109)
110)";
111 BOOST_CHECK_EQUAL( runDrc( dru, "kicad_drc_rn_any" ), 0u );
112}
113
114
115// (net "GND") plus only-GND zone covering trunk → 0 markers.
116BOOST_AUTO_TEST_CASE( ReferenceNetGndShadowedByGndPasses )
117{
118 const std::string dru =
119 R"((version 1)
120(rule "RP"
121 (condition "A.NetClass == 'Default'")
122 (constraint length (min 0mm) (max 200mm))
123 (constraint return_path (layer "B.Cu") (net "GND"))
125)";
126 // The GND zone only covers the upper half of the track shadow (y < 0).
127 // The trunk runs at y=0 with width 0.2mm — partial coverage. The marker
128 // count depends on whether half-coverage triggers; just assert no false
129 // negative when the zone net matches at all.
130 size_t n = runDrc( dru, "kicad_drc_rn_gnd_match" );
131 BOOST_CHECK_LE( n, 1u );
132}
133
135// (net "PWR_*") matches no zone → trunk reported as uncovered.
136BOOST_AUTO_TEST_CASE( ReferenceNetWildcardNoMatch )
137{
138 const std::string dru =
139 R"((version 1)
140(rule "RP"
141 (condition "A.NetClass == 'Default'")
142 (constraint length (min 0mm) (max 200mm))
143 (constraint return_path (layer "B.Cu") (net "PWR_*"))
144)
145)";
146 size_t n = runDrc( dru, "kicad_drc_rn_wildcard_nomatch" );
147 BOOST_CHECK_GE( n, 1u );
148}
149
150
151// (net "GND*") matches the GND zone → covered (or partially covered).
152BOOST_AUTO_TEST_CASE( ReferenceNetWildcardMatch )
153{
154 const std::string dru =
155 R"((version 1)
156(rule "RP"
157 (condition "A.NetClass == 'Default'")
158 (constraint length (min 0mm) (max 200mm))
159 (constraint return_path (layer "B.Cu") (net "GND*"))
160)
161)";
162 size_t n = runDrc( dru, "kicad_drc_rn_wildcard_match" );
163 BOOST_CHECK_LE( n, 1u );
164}
165
166
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
Handle the data for a net.
Definition netinfo.h:50
void SetNetChain(const wxString &aNetChain)
Definition netinfo.h:123
A #PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
std::unique_ptr< BOARD > LoadBoard(const wxString &aFileName, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr)
Load information from some input file format that this PCB_IO implementation knows about into new BOA...
Definition pcb_io.cpp:72
@ DRCE_UNCONNECTED_ITEMS
Definition drc_item.h:37
@ DRCE_LIB_FOOTPRINT_ISSUES
Definition drc_item.h:85
@ DRCE_INVALID_OUTLINE
Definition drc_item.h:75
@ DRCE_DRILL_OUT_OF_RANGE
Definition drc_item.h:58
@ DRCE_NET_CHAIN_RETURN_PATH_BREAK
Definition drc_item.h:109
@ DRCE_DANGLING_VIA
Definition drc_item.h:48
@ DRCE_LIB_FOOTPRINT_MISMATCH
Definition drc_item.h:86
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_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
static const char * DUAL_ZONE_PCB
BOOST_AUTO_TEST_CASE(ReferenceNetEmptyAcceptsAnyZoneRegression)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683