blob: f9beee34b9b2270ba27adfc814ce3ce193fdbc55 [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);
15
16const nlohmann::json subchassisExposesItem = nlohmann::json::parse(R"(
17 {
18 "ConnectsToType": "BackplanePort",
19 "Name": "MyDownstreamPort",
20 "Type": "DownstreamPort"
21 }
22)");
23
24const nlohmann::json superchassisExposesItem = nlohmann::json::parse(R"(
25 {
26 "Name": "MyBackplanePort",
27 "Type": "BackplanePort"
28 }
29)");
30
31const nlohmann::json otherExposesItem = nlohmann::json::parse(R"(
32 {
33 "Name": "MyExposes",
34 "Type": "OtherType"
35 }
36)");
37
Matt Spinler6eb60972023-08-14 16:36:20 -050038using BoardMap = std::map<std::string, std::string>;
39
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000040TEST(Topology, Empty)
41{
42 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -050043 BoardMap boards;
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000044
Matt Spinler6eb60972023-08-14 16:36:20 -050045 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000046
47 EXPECT_EQ(assocs.size(), 0);
48}
49
50TEST(Topology, EmptyExposes)
51{
52 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -050053 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000054
Matt Spinler6eb60972023-08-14 16:36:20 -050055 topo.addBoard(subchassisPath, "Chassis", "BoardA", nlohmann::json());
56 topo.addBoard(superchassisPath, "Chassis", "BoardB", nlohmann::json());
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000057
Matt Spinler6eb60972023-08-14 16:36:20 -050058 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000059
60 EXPECT_EQ(assocs.size(), 0);
61}
62
63TEST(Topology, MissingConnectsTo)
64{
65 const nlohmann::json subchassisMissingConnectsTo = nlohmann::json::parse(R"(
66 {
67 "Name": "MyDownstreamPort",
68 "Type": "DownstreamPort"
69 }
70 )");
71
72 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -050073 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000074
Matt Spinler6eb60972023-08-14 16:36:20 -050075 topo.addBoard(subchassisPath, "Chassis", "BoardA",
76 subchassisMissingConnectsTo);
77 topo.addBoard(superchassisPath, "Chassis", "BoardB",
78 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000079
Matt Spinler6eb60972023-08-14 16:36:20 -050080 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000081
82 EXPECT_EQ(assocs.size(), 0);
83}
84
85TEST(Topology, OtherExposes)
86{
87 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -050088 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000089
Matt Spinler6eb60972023-08-14 16:36:20 -050090 topo.addBoard(subchassisPath, "Chassis", "BoardA", otherExposesItem);
91 topo.addBoard(superchassisPath, "Chassis", "BoardB", otherExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000092
Matt Spinler6eb60972023-08-14 16:36:20 -050093 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000094
95 EXPECT_EQ(assocs.size(), 0);
96}
97
98TEST(Topology, NoMatchSubchassis)
99{
100 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500101 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000102
Matt Spinler6eb60972023-08-14 16:36:20 -0500103 topo.addBoard(subchassisPath, "Chassis", "BoardA", otherExposesItem);
104 topo.addBoard(superchassisPath, "Chassis", "BoardB",
105 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000106
Matt Spinler6eb60972023-08-14 16:36:20 -0500107 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000108
109 EXPECT_EQ(assocs.size(), 0);
110}
111
112TEST(Topology, NoMatchSuperchassis)
113{
114 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500115 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000116
Matt Spinler6eb60972023-08-14 16:36:20 -0500117 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
118 topo.addBoard(superchassisPath, "Chassis", "BoardB", otherExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000119
Matt Spinler6eb60972023-08-14 16:36:20 -0500120 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000121
122 EXPECT_EQ(assocs.size(), 0);
123}
124
125TEST(Topology, Basic)
126{
127 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500128 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000129
Matt Spinler6eb60972023-08-14 16:36:20 -0500130 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
131 topo.addBoard(superchassisPath, "Chassis", "BoardB",
132 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000133
Matt Spinler6eb60972023-08-14 16:36:20 -0500134 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000135
136 EXPECT_EQ(assocs.size(), 1);
137 EXPECT_EQ(assocs[subchassisPath].size(), 1);
138 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
139}
140
Matt Spinler6eb60972023-08-14 16:36:20 -0500141TEST(Topology, NoNewBoards)
142{
143 Topology topo;
144 BoardMap boards;
145
146 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
147 topo.addBoard(superchassisPath, "Chassis", "BoardB",
148 superchassisExposesItem);
149
150 // Boards A and B aren't new, so no assocs are returned.
151 auto assocs = topo.getAssocs(boards);
152
153 EXPECT_EQ(assocs.size(), 0);
154}
155
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000156TEST(Topology, 2Subchassis)
157{
158 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500159 BoardMap boards{{subchassisPath, "BoardA"},
160 {subchassisPath + "2", "BoardB"},
161 {superchassisPath, "BoardC"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000162
Matt Spinler6eb60972023-08-14 16:36:20 -0500163 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
164 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB",
165 subchassisExposesItem);
166 topo.addBoard(superchassisPath, "Chassis", "BoardC",
167 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000168
Matt Spinler6eb60972023-08-14 16:36:20 -0500169 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000170
171 EXPECT_EQ(assocs.size(), 2);
172 EXPECT_EQ(assocs[subchassisPath].size(), 1);
173 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
174 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 1);
175 EXPECT_EQ(assocs[subchassisPath + "2"][0], subchassisAssoc);
176}
177
Matt Spinler6eb60972023-08-14 16:36:20 -0500178TEST(Topology, OneNewBoard)
179{
180 Topology topo;
181 BoardMap boards{{subchassisPath, "BoardA"}};
182
183 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
184 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB",
185 subchassisExposesItem);
186 topo.addBoard(superchassisPath, "Chassis", "BoardC",
187 superchassisExposesItem);
188
189 // Only the assoc for BoardA should be returned
190 auto assocs = topo.getAssocs(boards);
191
192 EXPECT_EQ(assocs.size(), 1);
193 EXPECT_EQ(assocs[subchassisPath].size(), 1);
194 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
195}
196
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000197TEST(Topology, 2Superchassis)
198{
199 const Association subchassisAssoc2 =
200 std::make_tuple("contained_by", "containing", superchassisPath + "2");
201
202 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500203 BoardMap boards{{subchassisPath, "BoardA"},
204 {superchassisPath, "BoardB"},
205 {superchassisPath + "2", "BoardC"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000206
Matt Spinler6eb60972023-08-14 16:36:20 -0500207 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
208 topo.addBoard(superchassisPath, "Chassis", "BoardB",
209 superchassisExposesItem);
210 topo.addBoard(superchassisPath + "2", "Chassis", "BoardC",
211 superchassisExposesItem);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000212
Matt Spinler6eb60972023-08-14 16:36:20 -0500213 auto assocs = topo.getAssocs(boards);
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000214
215 EXPECT_EQ(assocs.size(), 1);
216 EXPECT_EQ(assocs[subchassisPath].size(), 2);
217
218 EXPECT_THAT(assocs[subchassisPath],
219 UnorderedElementsAre(subchassisAssoc, subchassisAssoc2));
220}
221
222TEST(Topology, 2SuperchassisAnd2Subchassis)
223{
224 const Association subchassisAssoc2 =
225 std::make_tuple("contained_by", "containing", superchassisPath + "2");
226
227 Topology topo;
Matt Spinler6eb60972023-08-14 16:36:20 -0500228 BoardMap boards{{subchassisPath, "BoardA"},
229 {subchassisPath + "2", "BoardB"},
230 {superchassisPath, "BoardC"},
231 {superchassisPath + "2", "BoardD"}};
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +0000232
Matt Spinler6eb60972023-08-14 16:36:20 -0500233 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
234 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB",
235 subchassisExposesItem);
236 topo.addBoard(superchassisPath, "Chassis", "BoardC",
237 superchassisExposesItem);
238 topo.addBoard(superchassisPath + "2", "Chassis", "BoardD",
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
243 EXPECT_EQ(assocs.size(), 2);
244 EXPECT_EQ(assocs[subchassisPath].size(), 2);
245 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 2);
246
247 EXPECT_THAT(assocs[subchassisPath],
248 UnorderedElementsAre(subchassisAssoc, subchassisAssoc2));
249 EXPECT_THAT(assocs[subchassisPath + "2"],
250 UnorderedElementsAre(subchassisAssoc, subchassisAssoc2));
251}
Matt Spinler6eb60972023-08-14 16:36:20 -0500252
253TEST(Topology, Remove)
254{
255 Topology topo;
256 BoardMap boards{{subchassisPath, "BoardA"},
257 {subchassisPath + "2", "BoardB"},
258 {superchassisPath, "BoardC"}};
259
260 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem);
261 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB",
262 subchassisExposesItem);
263 topo.addBoard(superchassisPath, "Chassis", "BoardC",
264 superchassisExposesItem);
265
266 {
267 auto assocs = topo.getAssocs(boards);
268
269 EXPECT_EQ(assocs.size(), 2);
270 EXPECT_EQ(assocs[subchassisPath].size(), 1);
271 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc);
272 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 1);
273 EXPECT_EQ(assocs[subchassisPath + "2"][0], subchassisAssoc);
274 }
275
276 {
277 topo.remove("BoardA");
278 auto assocs = topo.getAssocs(boards);
279
280 EXPECT_EQ(assocs.size(), 1);
281 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 1);
282 EXPECT_EQ(assocs[subchassisPath + "2"][0], subchassisAssoc);
283 }
284
285 {
286 topo.remove("BoardB");
287 auto assocs = topo.getAssocs(boards);
288
289 EXPECT_EQ(assocs.size(), 0);
290 }
291}