blob: e23c8026d9cab2ef4d44a79c220830fa8be77795 [file] [log] [blame]
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +00001#include "topology.hpp"
2
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);
Jeff Linb02752f2023-12-01 11:23:54 +080015const Association powerAssoc = std::make_tuple("powered_by", "powering",
16 subchassisPath);
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
58 EXPECT_EQ(assocs.size(), 0);
59}
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
71 EXPECT_EQ(assocs.size(), 0);
72}
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
93 EXPECT_EQ(assocs.size(), 0);
94}
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
106 EXPECT_EQ(assocs.size(), 0);
107}
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
120 EXPECT_EQ(assocs.size(), 0);
121}
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
133 EXPECT_EQ(assocs.size(), 0);
134}
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
147 EXPECT_EQ(assocs.size(), 1);
148 EXPECT_EQ(assocs[subchassisPath].size(), 1);
149 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
163 EXPECT_EQ(assocs.size(), 2);
164 EXPECT_EQ(assocs[subchassisPath].size(), 1);
165 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
166 EXPECT_EQ(assocs[superchassisPath].size(), 1);
167 EXPECT_EQ(assocs[superchassisPath][0], powerAssoc);
168}
169
Matt Spinler6eb60972023-08-14 16:36:20 -0500170TEST(Topology, NoNewBoards)
171{
172 Topology topo;
173 BoardMap boards;
174
175 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
176 topo.addBoard(superchassisPath, "Chassis", "BoardB",
177 superchassisExposesItem);
178
179 // Boards A and B aren't new, so no assocs are returned.
180 auto assocs = topo.getAssocs(boards);
181
182 EXPECT_EQ(assocs.size(), 0);
183}
184
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000185TEST(Topology, 2Subchassis)
186{
187 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500188 BoardMap boards{{subchassisPath, "BoardA"},
189 {subchassisPath + "2", "BoardB"},
190 {superchassisPath, "BoardC"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000191
Matt Spinler6eb60972023-08-14 16:36:20 -0500192 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
193 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB",
194 subchassisExposesItem);
195 topo.addBoard(superchassisPath, "Chassis", "BoardC",
196 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000197
Matt Spinler6eb60972023-08-14 16:36:20 -0500198 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000199
200 EXPECT_EQ(assocs.size(), 2);
201 EXPECT_EQ(assocs[subchassisPath].size(), 1);
202 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
203 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 1);
204 EXPECT_EQ(assocs[subchassisPath + "2"][0], subchassisAssoc);
205}
206
Matt Spinler6eb60972023-08-14 16:36:20 -0500207TEST(Topology, OneNewBoard)
208{
209 Topology topo;
210 BoardMap boards{{subchassisPath, "BoardA"}};
211
212 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
213 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB",
214 subchassisExposesItem);
215 topo.addBoard(superchassisPath, "Chassis", "BoardC",
216 superchassisExposesItem);
217
218 // Only the assoc for BoardA should be returned
219 auto assocs = topo.getAssocs(boards);
220
221 EXPECT_EQ(assocs.size(), 1);
222 EXPECT_EQ(assocs[subchassisPath].size(), 1);
223 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
224}
225
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000226TEST(Topology, 2Superchassis)
227{
228 const Association subchassisAssoc2 =
229 std::make_tuple("contained_by", "containing", superchassisPath + "2");
230
231 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500232 BoardMap boards{{subchassisPath, "BoardA"},
233 {superchassisPath, "BoardB"},
234 {superchassisPath + "2", "BoardC"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000235
Matt Spinler6eb60972023-08-14 16:36:20 -0500236 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
237 topo.addBoard(superchassisPath, "Chassis", "BoardB",
238 superchassisExposesItem);
239 topo.addBoard(superchassisPath + "2", "Chassis", "BoardC",
240 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000241
Matt Spinler6eb60972023-08-14 16:36:20 -0500242 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000243
244 EXPECT_EQ(assocs.size(), 1);
245 EXPECT_EQ(assocs[subchassisPath].size(), 2);
246
247 EXPECT_THAT(assocs[subchassisPath],
248 UnorderedElementsAre(subchassisAssoc, subchassisAssoc2));
249}
250
251TEST(Topology, 2SuperchassisAnd2Subchassis)
252{
253 const Association subchassisAssoc2 =
254 std::make_tuple("contained_by", "containing", superchassisPath + "2");
255
256 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500257 BoardMap boards{{subchassisPath, "BoardA"},
258 {subchassisPath + "2", "BoardB"},
259 {superchassisPath, "BoardC"},
260 {superchassisPath + "2", "BoardD"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000261
Matt Spinler6eb60972023-08-14 16:36:20 -0500262 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
263 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB",
264 subchassisExposesItem);
265 topo.addBoard(superchassisPath, "Chassis", "BoardC",
266 superchassisExposesItem);
267 topo.addBoard(superchassisPath + "2", "Chassis", "BoardD",
268 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000269
Matt Spinler6eb60972023-08-14 16:36:20 -0500270 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000271
272 EXPECT_EQ(assocs.size(), 2);
273 EXPECT_EQ(assocs[subchassisPath].size(), 2);
274 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 2);
275
276 EXPECT_THAT(assocs[subchassisPath],
277 UnorderedElementsAre(subchassisAssoc, subchassisAssoc2));
278 EXPECT_THAT(assocs[subchassisPath + "2"],
279 UnorderedElementsAre(subchassisAssoc, subchassisAssoc2));
280}
Matt Spinler6eb60972023-08-14 16:36:20 -0500281
282TEST(Topology, Remove)
283{
284 Topology topo;
285 BoardMap boards{{subchassisPath, "BoardA"},
286 {subchassisPath + "2", "BoardB"},
287 {superchassisPath, "BoardC"}};
288
289 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
290 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB",
291 subchassisExposesItem);
292 topo.addBoard(superchassisPath, "Chassis", "BoardC",
293 superchassisExposesItem);
294
295 {
296 auto assocs = topo.getAssocs(boards);
297
298 EXPECT_EQ(assocs.size(), 2);
299 EXPECT_EQ(assocs[subchassisPath].size(), 1);
300 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
301 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 1);
302 EXPECT_EQ(assocs[subchassisPath + "2"][0], subchassisAssoc);
303 }
304
305 {
306 topo.remove("BoardA");
307 auto assocs = topo.getAssocs(boards);
308
309 EXPECT_EQ(assocs.size(), 1);
310 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 1);
311 EXPECT_EQ(assocs[subchassisPath + "2"][0], subchassisAssoc);
312 }
313
314 {
315 topo.remove("BoardB");
316 auto assocs = topo.getAssocs(boards);
317
318 EXPECT_EQ(assocs.size(), 0);
319 }
320}