blob: 34c708c73ab075e1493c92b8a49bf4c0a0d3861c [file] [log] [blame]
Christopher Meisfc9e7fd2025-04-03 13:13:35 +02001#include "entity_manager/topology.hpp"
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +00002
3#include "gmock/gmock.h"
4#include "gtest/gtest.h"
5
6using ::testing::UnorderedElementsAre;
7
8const std::string subchassisPath =
9 "/xyz/openbmc_project/inventory/system/chassis/Subchassis";
10const std::string superchassisPath =
11 "/xyz/openbmc_project/inventory/system/chassis/Superchassis";
12
13const Association subchassisAssoc =
14 std::make_tuple("contained_by", "containing", superchassisPath);
Patrick Williamsb7077432024-08-16 15:22:21 -040015const Association powerAssoc =
Chau Lya454b302025-07-09 09:22:25 +000016 std::make_tuple("powering", "powered_by", superchassisPath);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000017
18const nlohmann::json subchassisExposesItem = nlohmann::json::parse(R"(
19 {
20 "ConnectsToType": "BackplanePort",
21 "Name": "MyDownstreamPort",
22 "Type": "DownstreamPort"
23 }
24)");
25
Jeff Linb02752f2023-12-01 11:23:54 +080026const nlohmann::json powerExposesItem = nlohmann::json::parse(R"(
27 {
28 "ConnectsToType": "BackplanePort",
29 "Name": "MyDownstreamPort",
30 "Type": "DownstreamPort",
31 "PowerPort": true
32 }
33)");
34
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000035const nlohmann::json superchassisExposesItem = nlohmann::json::parse(R"(
36 {
37 "Name": "MyBackplanePort",
38 "Type": "BackplanePort"
39 }
40)");
41
42const nlohmann::json otherExposesItem = nlohmann::json::parse(R"(
43 {
44 "Name": "MyExposes",
45 "Type": "OtherType"
46 }
47)");
48
Matt Spinler6eb60972023-08-14 16:36:20 -050049using BoardMap = std::map<std::string, std::string>;
50
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000051TEST(Topology, Empty)
52{
53 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -050054 BoardMap boards;
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000055
Matt Spinler6eb60972023-08-14 16:36:20 -050056 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000057
Ed Tanousc6af85c2025-04-08 10:13:33 -070058 EXPECT_EQ(assocs.size(), 0U);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000059}
60
61TEST(Topology, EmptyExposes)
62{
63 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -050064 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000065
Matt Spinler6eb60972023-08-14 16:36:20 -050066 topo.addBoard(subchassisPath, "Chassis", "BoardA", nlohmann::json());
67 topo.addBoard(superchassisPath, "Chassis", "BoardB", nlohmann::json());
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000068
Matt Spinler6eb60972023-08-14 16:36:20 -050069 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000070
Ed Tanousc6af85c2025-04-08 10:13:33 -070071 EXPECT_EQ(assocs.size(), 0U);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000072}
73
74TEST(Topology, MissingConnectsTo)
75{
76 const nlohmann::json subchassisMissingConnectsTo = nlohmann::json::parse(R"(
77 {
78 "Name": "MyDownstreamPort",
79 "Type": "DownstreamPort"
80 }
81 )");
82
83 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -050084 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000085
Matt Spinler6eb60972023-08-14 16:36:20 -050086 topo.addBoard(subchassisPath, "Chassis", "BoardA",
87 subchassisMissingConnectsTo);
88 topo.addBoard(superchassisPath, "Chassis", "BoardB",
89 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000090
Matt Spinler6eb60972023-08-14 16:36:20 -050091 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000092
Ed Tanousc6af85c2025-04-08 10:13:33 -070093 EXPECT_EQ(assocs.size(), 0U);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000094}
95
96TEST(Topology, OtherExposes)
97{
98 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -050099 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000100
Matt Spinler6eb60972023-08-14 16:36:20 -0500101 topo.addBoard(subchassisPath, "Chassis", "BoardA", otherExposesItem);
102 topo.addBoard(superchassisPath, "Chassis", "BoardB", otherExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000103
Matt Spinler6eb60972023-08-14 16:36:20 -0500104 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000105
Ed Tanousc6af85c2025-04-08 10:13:33 -0700106 EXPECT_EQ(assocs.size(), 0U);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000107}
108
109TEST(Topology, NoMatchSubchassis)
110{
111 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500112 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000113
Matt Spinler6eb60972023-08-14 16:36:20 -0500114 topo.addBoard(subchassisPath, "Chassis", "BoardA", otherExposesItem);
115 topo.addBoard(superchassisPath, "Chassis", "BoardB",
116 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000117
Matt Spinler6eb60972023-08-14 16:36:20 -0500118 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000119
Ed Tanousc6af85c2025-04-08 10:13:33 -0700120 EXPECT_EQ(assocs.size(), 0U);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000121}
122
123TEST(Topology, NoMatchSuperchassis)
124{
125 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500126 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000127
Matt Spinler6eb60972023-08-14 16:36:20 -0500128 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
129 topo.addBoard(superchassisPath, "Chassis", "BoardB", otherExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000130
Matt Spinler6eb60972023-08-14 16:36:20 -0500131 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000132
Ed Tanousc6af85c2025-04-08 10:13:33 -0700133 EXPECT_EQ(assocs.size(), 0U);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000134}
135
136TEST(Topology, Basic)
137{
138 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500139 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000140
Matt Spinler6eb60972023-08-14 16:36:20 -0500141 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
142 topo.addBoard(superchassisPath, "Chassis", "BoardB",
143 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000144
Matt Spinler6eb60972023-08-14 16:36:20 -0500145 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000146
Ed Tanousc6af85c2025-04-08 10:13:33 -0700147 EXPECT_EQ(assocs.size(), 1U);
148 EXPECT_EQ(assocs[subchassisPath].size(), 1U);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000149 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
150}
151
Jeff Linb02752f2023-12-01 11:23:54 +0800152TEST(Topology, BasicPower)
153{
154 Topology topo;
155 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
156
157 topo.addBoard(subchassisPath, "Chassis", "BoardA", powerExposesItem);
158 topo.addBoard(superchassisPath, "Chassis", "BoardB",
159 superchassisExposesItem);
160
161 auto assocs = topo.getAssocs(boards);
162
Chau Lya454b302025-07-09 09:22:25 +0000163 EXPECT_EQ(assocs.size(), 1U);
164 EXPECT_EQ(assocs[subchassisPath].size(), 2U);
Jeff Linb02752f2023-12-01 11:23:54 +0800165 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
Chau Lya454b302025-07-09 09:22:25 +0000166 EXPECT_EQ(assocs[subchassisPath][1], powerAssoc);
Jeff Linb02752f2023-12-01 11:23:54 +0800167}
168
Matt Spinler6eb60972023-08-14 16:36:20 -0500169TEST(Topology, NoNewBoards)
170{
171 Topology topo;
172 BoardMap boards;
173
174 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
175 topo.addBoard(superchassisPath, "Chassis", "BoardB",
176 superchassisExposesItem);
177
178 // Boards A and B aren't new, so no assocs are returned.
179 auto assocs = topo.getAssocs(boards);
180
Ed Tanousc6af85c2025-04-08 10:13:33 -0700181 EXPECT_EQ(assocs.size(), 0U);
Matt Spinler6eb60972023-08-14 16:36:20 -0500182}
183
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000184TEST(Topology, 2Subchassis)
185{
186 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500187 BoardMap boards{{subchassisPath, "BoardA"},
188 {subchassisPath + "2", "BoardB"},
189 {superchassisPath, "BoardC"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000190
Matt Spinler6eb60972023-08-14 16:36:20 -0500191 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
192 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB",
193 subchassisExposesItem);
194 topo.addBoard(superchassisPath, "Chassis", "BoardC",
195 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000196
Matt Spinler6eb60972023-08-14 16:36:20 -0500197 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000198
Ed Tanousc6af85c2025-04-08 10:13:33 -0700199 EXPECT_EQ(assocs.size(), 2U);
200 EXPECT_EQ(assocs[subchassisPath].size(), 1U);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000201 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
Ed Tanousc6af85c2025-04-08 10:13:33 -0700202 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 1U);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000203 EXPECT_EQ(assocs[subchassisPath + "2"][0], subchassisAssoc);
204}
205
Matt Spinler6eb60972023-08-14 16:36:20 -0500206TEST(Topology, OneNewBoard)
207{
208 Topology topo;
209 BoardMap boards{{subchassisPath, "BoardA"}};
210
211 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
212 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB",
213 subchassisExposesItem);
214 topo.addBoard(superchassisPath, "Chassis", "BoardC",
215 superchassisExposesItem);
216
217 // Only the assoc for BoardA should be returned
218 auto assocs = topo.getAssocs(boards);
219
Ed Tanousc6af85c2025-04-08 10:13:33 -0700220 EXPECT_EQ(assocs.size(), 1U);
221 EXPECT_EQ(assocs[subchassisPath].size(), 1U);
Matt Spinler6eb60972023-08-14 16:36:20 -0500222 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
223}
224
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000225TEST(Topology, 2Superchassis)
226{
227 const Association subchassisAssoc2 =
228 std::make_tuple("contained_by", "containing", superchassisPath + "2");
229
230 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500231 BoardMap boards{{subchassisPath, "BoardA"},
232 {superchassisPath, "BoardB"},
233 {superchassisPath + "2", "BoardC"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000234
Matt Spinler6eb60972023-08-14 16:36:20 -0500235 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
236 topo.addBoard(superchassisPath, "Chassis", "BoardB",
237 superchassisExposesItem);
238 topo.addBoard(superchassisPath + "2", "Chassis", "BoardC",
239 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000240
Matt Spinler6eb60972023-08-14 16:36:20 -0500241 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000242
Ed Tanousc6af85c2025-04-08 10:13:33 -0700243 EXPECT_EQ(assocs.size(), 1U);
244 EXPECT_EQ(assocs[subchassisPath].size(), 2U);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000245
246 EXPECT_THAT(assocs[subchassisPath],
247 UnorderedElementsAre(subchassisAssoc, subchassisAssoc2));
248}
249
250TEST(Topology, 2SuperchassisAnd2Subchassis)
251{
252 const Association subchassisAssoc2 =
253 std::make_tuple("contained_by", "containing", superchassisPath + "2");
254
255 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500256 BoardMap boards{{subchassisPath, "BoardA"},
257 {subchassisPath + "2", "BoardB"},
258 {superchassisPath, "BoardC"},
259 {superchassisPath + "2", "BoardD"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000260
Matt Spinler6eb60972023-08-14 16:36:20 -0500261 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
262 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB",
263 subchassisExposesItem);
264 topo.addBoard(superchassisPath, "Chassis", "BoardC",
265 superchassisExposesItem);
266 topo.addBoard(superchassisPath + "2", "Chassis", "BoardD",
267 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000268
Matt Spinler6eb60972023-08-14 16:36:20 -0500269 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000270
Ed Tanousc6af85c2025-04-08 10:13:33 -0700271 EXPECT_EQ(assocs.size(), 2U);
272 EXPECT_EQ(assocs[subchassisPath].size(), 2U);
273 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 2U);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000274
275 EXPECT_THAT(assocs[subchassisPath],
276 UnorderedElementsAre(subchassisAssoc, subchassisAssoc2));
277 EXPECT_THAT(assocs[subchassisPath + "2"],
278 UnorderedElementsAre(subchassisAssoc, subchassisAssoc2));
279}
Matt Spinler6eb60972023-08-14 16:36:20 -0500280
281TEST(Topology, Remove)
282{
283 Topology topo;
284 BoardMap boards{{subchassisPath, "BoardA"},
285 {subchassisPath + "2", "BoardB"},
286 {superchassisPath, "BoardC"}};
287
288 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
289 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB",
290 subchassisExposesItem);
291 topo.addBoard(superchassisPath, "Chassis", "BoardC",
292 superchassisExposesItem);
293
294 {
295 auto assocs = topo.getAssocs(boards);
296
Ed Tanousc6af85c2025-04-08 10:13:33 -0700297 EXPECT_EQ(assocs.size(), 2U);
298 EXPECT_EQ(assocs[subchassisPath].size(), 1U);
Matt Spinler6eb60972023-08-14 16:36:20 -0500299 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
Ed Tanousc6af85c2025-04-08 10:13:33 -0700300 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 1U);
Matt Spinler6eb60972023-08-14 16:36:20 -0500301 EXPECT_EQ(assocs[subchassisPath + "2"][0], subchassisAssoc);
302 }
303
304 {
305 topo.remove("BoardA");
306 auto assocs = topo.getAssocs(boards);
307
Ed Tanousc6af85c2025-04-08 10:13:33 -0700308 EXPECT_EQ(assocs.size(), 1U);
309 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 1U);
Matt Spinler6eb60972023-08-14 16:36:20 -0500310 EXPECT_EQ(assocs[subchassisPath + "2"][0], subchassisAssoc);
311 }
312
313 {
314 topo.remove("BoardB");
315 auto assocs = topo.getAssocs(boards);
316
Ed Tanousc6af85c2025-04-08 10:13:33 -0700317 EXPECT_EQ(assocs.size(), 0U);
Matt Spinler6eb60972023-08-14 16:36:20 -0500318 }
319}