KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_connectivity_engine.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 modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * 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
25#include <schematic.h>
26#include <sch_label.h>
27#include <sch_screen.h>
28#include <sch_connection.h>
29#include <bus_alias.h>
30#include <connection_graph.h>
31#include <sch_no_connect.h>
32#include <sch_symbol.h>
33#include <sch_line.h>
34#include <sch_pin.h>
36#include <thread_pool.h>
37#include <algorithm>
38
39using namespace SCH_CONNECTIVITY;
40
41BOOST_AUTO_TEST_SUITE( ConnectivityEngine )
42
43BOOST_AUTO_TEST_CASE( NativePublicationIsStableAcrossWorkerCounts )
44{
45 SETTINGS_MANAGER settings;
46 std::unique_ptr<SCHEMATIC> schematic;
47 KI_TEST::LoadSchematic( settings, "issue9673/issue9673", schematic );
48 auto& pool = GetKiCadThreadPool();
49 struct RESTORE_POOL
50 {
51 thread_pool& pool;
52 size_t count;
53 ~RESTORE_POOL() { pool.reset( count ); }
54 } restore{ pool, pool.get_thread_count() };
55 FACADE facade;
56 std::string expected;
57 std::string expectedChanged;
58 std::shared_ptr<BUS_ALIAS> alias;
59
60 for( const auto& candidate : schematic->GetAllBusAliases() )
61 {
62 if( candidate && candidate->GetName() == wxS( "MIXED_BUS" ) )
63 alias = candidate;
64 }
65
66 BOOST_REQUIRE( alias );
67 const auto members = alias->Members();
68
69 for( size_t count : { 1, 2, 8 } )
70 {
71 pool.reset( count );
72 facade.Update( *schematic, true );
73 const auto actual = Dump( *schematic, facade );
74
75 if( expected.empty() )
77
79 facade.Update( *schematic );
80 BOOST_CHECK( facade.Published().Changes().Empty() );
81 BOOST_CHECK_EQUAL( Dump( *schematic, facade ), expected );
82
83 alias->AddMember( wxS( "HAM" ) );
84 facade.Update( *schematic );
85 const auto changed = Dump( *schematic, facade );
86 BOOST_CHECK_NE( changed, expected );
87
88 if( expectedChanged.empty() )
89 expectedChanged = changed;
90
91 BOOST_CHECK_EQUAL( changed, expectedChanged );
92 facade.Update( *schematic, true );
93 BOOST_CHECK_EQUAL( Dump( *schematic, facade ), changed );
94 alias->SetMembers( members );
95 }
96}
97
98BOOST_AUTO_TEST_CASE( NativeNoConnectNamingRetainsExcludedPinWitnesses )
99{
100 SETTINGS_MANAGER settings;
101 std::unique_ptr<SCHEMATIC> schematic;
102 KI_TEST::LoadSchematic( settings, "NoConnectPinsConnectedByLine", schematic );
103 const auto path = schematic->Hierarchy().front();
104 SCH_NO_CONNECT* marker = nullptr;
105 SCH_SYMBOL* excluded = nullptr;
106 SCH_PIN* pin = nullptr;
107 SCH_LINE* bridge = nullptr;
108
109 for( SCH_ITEM* item : path.LastScreen()->Items() )
110 {
111 if( auto* candidate = dynamic_cast<SCH_NO_CONNECT*>( item ) )
112 marker = candidate;
113
114 if( auto* line = dynamic_cast<SCH_LINE*>( item ); line && line->GetStartPoint().y == line->GetEndPoint().y )
115 bridge = line;
116
117 if( auto* symbol = dynamic_cast<SCH_SYMBOL*>( item ) )
118 {
119 if( symbol->GetRef( &path ) == "TP1" )
120 pin = symbol->GetPins( &path ).front();
121 else
122 excluded = symbol;
123 }
124 }
125
126 BOOST_REQUIRE( marker );
127 BOOST_REQUIRE( excluded );
129 BOOST_REQUIRE( bridge );
130 ENGINE engine;
131 const auto check = [&]( bool aUnconnected )
132 {
133 schematic->ConnectionGraph()->Recalculate( schematic->Hierarchy(), true );
134 BOOST_REQUIRE( pin->Connection( &path ) );
135 const wxString expected = pin->Connection( &path )->Name();
136 BOOST_CHECK_EQUAL( expected.StartsWith( "unconnected-(" ), aUnconnected );
137 engine.Update( schematic->Hierarchy(), 1, {} );
138 size_t checked = 0;
139
140 for( const auto& entry : engine.Signals().Entries() )
141 {
142 const auto& signal = entry->value;
143
144 if( std::none_of( signal.items.begin(), signal.items.end(),
145 [&]( const ITEM_KEY& item )
146 {
147 return item.item == pin->m_Uuid;
148 } ) )
149 continue;
150
151 BOOST_REQUIRE_NE( signal.baseName, INVALID_ID );
152 BOOST_CHECK_EQUAL( engine.Keys().Name( signal.baseName ), expected );
153 ++checked;
154 }
155
156 BOOST_CHECK_EQUAL( checked, 1 );
157 };
158 check( true );
159 const VECTOR2I original = marker->GetPosition();
160 marker->SetPosition( original + VECTOR2I( 10000000, 10000000 ) );
161 marker->SetConnectivityDirty( true );
162 check( false );
163 excluded->SetExcludedFromBoard( true );
164 excluded->SetConnectivityDirty( true );
165 check( false );
166 excluded->SetExcludedFromBoard( false );
167 excluded->SetConnectivityDirty( true );
168 check( false );
169 marker->SetPosition( original );
170 marker->SetConnectivityDirty( true );
171 check( true );
172 marker->SetPosition( original + VECTOR2I( 10000000, 10000000 ) );
173 marker->SetConnectivityDirty( true );
174 check( false );
175}
176
177BOOST_AUTO_TEST_CASE( JoinedLabelsUseTheirIslandLocalName )
178{
179 SETTINGS_MANAGER settings;
180 std::unique_ptr<SCHEMATIC> schematic;
181 KI_TEST::LoadSchematic( settings, "netlists/multinetclasses/multinetclasses", schematic );
182 const auto path = schematic->Hierarchy().front();
183 SCH_LABEL_BASE* first = nullptr;
184 SCH_LABEL_BASE* second = nullptr;
185
186 for( SCH_ITEM* item : path.LastScreen()->Items() )
187 {
188 auto* label = dynamic_cast<SCH_LABEL_BASE*>( item );
189
190 if( label && label->GetText() == "NET_1" )
191 first = label;
192 else if( label && label->GetText() == "NET_2" )
193 second = label;
194 }
195
196 BOOST_REQUIRE( first );
197 BOOST_REQUIRE( second );
198 second->SetPosition( first->GetPosition() );
199 second->SetConnectivityDirty( true );
200 schematic->ConnectionGraph()->Recalculate( schematic->Hierarchy(), true );
201 ENGINE engine;
202 engine.Update( schematic->Hierarchy(), 1, {} );
203 size_t checked = 0;
204
205 for( const auto& [key, row] : engine.Published().Rows() )
206 {
207 SCH_LABEL_BASE* label = key.item == first->m_Uuid ? first : key.item == second->m_Uuid ? second : nullptr;
208
209 if( !label )
210 continue;
211
212 const auto* connection = label->Connection( &path );
213 BOOST_REQUIRE( connection );
214 BOOST_CHECK_EQUAL( engine.Keys().Name( row.localName ), first->GetText() );
215 BOOST_CHECK_EQUAL( engine.Keys().Name( row.localName ), connection->LocalName() );
216 BOOST_CHECK_EQUAL( engine.Keys().Name( row.fullLocalName ), connection->FullLocalName() );
217 BOOST_CHECK_EQUAL( engine.Keys().Name( row.name ), connection->Name() );
218 BOOST_CHECK( row.itemType == connection->Type() );
219 ++checked;
220 }
221
222 BOOST_CHECK_EQUAL( checked, 2 );
223}
224
const KIID m_Uuid
Definition eda_item.h:597
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:118
Owns one key/version session and its current stage evaluations; main-thread use only.
const PUBLICATION & Published() const
const COMPONENT_CACHE< SIGNAL_RESULT > & Signals() const
const SESSION_KEYS & Keys() const
void Update(const SCH_SHEET_LIST &aPaths, uint64_t aTextEpoch, const BUS_ALIASES &aAliases, bool aRebuild=false)
Refresh inputs, bundle slots and signal summaries with the source text epoch and effective aliases.
Model-owned source resolver.
void Update(SCHEMATIC &aSchematic, bool aRebuild=false)
const PUBLICATION & Published() const
const ROWS & Rows() const
const CHANGE_SET & Changes() const
const wxString & Name(NAME_ID aId) const
Definition conn_keys.h:163
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:170
void SetConnectivityDirty(bool aDirty=true)
Set the dirty flag.
Definition sch_item.cpp:309
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition sch_item.cpp:579
void SetPosition(const VECTOR2I &aPosition) override
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:39
VECTOR2I GetStartPoint() const
Definition sch_line.h:136
VECTOR2I GetPosition() const override
void SetPosition(const VECTOR2I &aPosition) override
Schematic symbol object.
Definition sch_symbol.h:74
void SetExcludedFromBoard(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
VECTOR2I GetPosition() const override
Definition sch_text.h:143
void LoadSchematic(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< SCHEMATIC > &aSchematic)
Value keys and the key session of the schematic connectivity engine.
std::string Dump(SCHEMATIC &aSchematic)
Canonical, pointer-free connectivity rows for migration and rebuild comparisons.
constexpr uint32_t INVALID_ID
Marks an unset handle.
Definition conn_keys.h:47
One item or pin in one sheet instance.
Definition conn_keys.h:77
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(NativePublicationIsStableAcrossWorkerCounts)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
std::string path
KIBIS_PIN * pin
VECTOR3I expected(15, 30, 45)
int actual
BOOST_CHECK_EQUAL(result, "25.4")
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::priority_thread_pool thread_pool
Definition thread_pool.h:27
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683