1 #include "entity_manager/topology.hpp" 2 3 #include "gmock/gmock.h" 4 #include "gtest/gtest.h" 5 6 using ::testing::UnorderedElementsAre; 7 8 const std::string subchassisPath = 9 "/xyz/openbmc_project/inventory/system/chassis/Subchassis"; 10 const std::string superchassisPath = 11 "/xyz/openbmc_project/inventory/system/chassis/Superchassis"; 12 13 const Association subchassisAssoc = 14 std::make_tuple("contained_by", "containing", superchassisPath); 15 const Association powerAssoc = 16 std::make_tuple("powering", "powered_by", superchassisPath); 17 18 const nlohmann::json subchassisExposesItem = nlohmann::json::parse(R"( 19 { 20 "ConnectsToType": "BackplanePort", 21 "Name": "MyDownstreamPort", 22 "Type": "DownstreamPort" 23 } 24 )"); 25 26 const nlohmann::json powerExposesItem = nlohmann::json::parse(R"( 27 { 28 "ConnectsToType": "BackplanePort", 29 "Name": "MyDownstreamPort", 30 "Type": "DownstreamPort", 31 "PowerPort": true 32 } 33 )"); 34 35 const nlohmann::json superchassisExposesItem = nlohmann::json::parse(R"( 36 { 37 "Name": "MyBackplanePort", 38 "Type": "BackplanePort" 39 } 40 )"); 41 42 const nlohmann::json otherExposesItem = nlohmann::json::parse(R"( 43 { 44 "Name": "MyExposes", 45 "Type": "OtherType" 46 } 47 )"); 48 49 using BoardMap = std::map<std::string, std::string>; 50 51 TEST(Topology, Empty) 52 { 53 Topology topo; 54 BoardMap boards; 55 56 auto assocs = topo.getAssocs(boards); 57 58 EXPECT_EQ(assocs.size(), 0U); 59 } 60 61 TEST(Topology, EmptyExposes) 62 { 63 Topology topo; 64 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}}; 65 66 topo.addBoard(subchassisPath, "Chassis", "BoardA", nlohmann::json()); 67 topo.addBoard(superchassisPath, "Chassis", "BoardB", nlohmann::json()); 68 69 auto assocs = topo.getAssocs(boards); 70 71 EXPECT_EQ(assocs.size(), 0U); 72 } 73 74 TEST(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; 84 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}}; 85 86 topo.addBoard(subchassisPath, "Chassis", "BoardA", 87 subchassisMissingConnectsTo); 88 topo.addBoard(superchassisPath, "Chassis", "BoardB", 89 superchassisExposesItem); 90 91 auto assocs = topo.getAssocs(boards); 92 93 EXPECT_EQ(assocs.size(), 0U); 94 } 95 96 TEST(Topology, OtherExposes) 97 { 98 Topology topo; 99 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}}; 100 101 topo.addBoard(subchassisPath, "Chassis", "BoardA", otherExposesItem); 102 topo.addBoard(superchassisPath, "Chassis", "BoardB", otherExposesItem); 103 104 auto assocs = topo.getAssocs(boards); 105 106 EXPECT_EQ(assocs.size(), 0U); 107 } 108 109 TEST(Topology, NoMatchSubchassis) 110 { 111 Topology topo; 112 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}}; 113 114 topo.addBoard(subchassisPath, "Chassis", "BoardA", otherExposesItem); 115 topo.addBoard(superchassisPath, "Chassis", "BoardB", 116 superchassisExposesItem); 117 118 auto assocs = topo.getAssocs(boards); 119 120 EXPECT_EQ(assocs.size(), 0U); 121 } 122 123 TEST(Topology, NoMatchSuperchassis) 124 { 125 Topology topo; 126 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}}; 127 128 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem); 129 topo.addBoard(superchassisPath, "Chassis", "BoardB", otherExposesItem); 130 131 auto assocs = topo.getAssocs(boards); 132 133 EXPECT_EQ(assocs.size(), 0U); 134 } 135 136 TEST(Topology, Basic) 137 { 138 Topology topo; 139 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}}; 140 141 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem); 142 topo.addBoard(superchassisPath, "Chassis", "BoardB", 143 superchassisExposesItem); 144 145 auto assocs = topo.getAssocs(boards); 146 147 EXPECT_EQ(assocs.size(), 1U); 148 EXPECT_EQ(assocs[subchassisPath].size(), 1U); 149 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc); 150 } 151 152 TEST(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(), 1U); 164 EXPECT_EQ(assocs[subchassisPath].size(), 2U); 165 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc); 166 EXPECT_EQ(assocs[subchassisPath][1], powerAssoc); 167 } 168 169 TEST(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 181 EXPECT_EQ(assocs.size(), 0U); 182 } 183 184 TEST(Topology, 2Subchassis) 185 { 186 Topology topo; 187 BoardMap boards{{subchassisPath, "BoardA"}, 188 {subchassisPath + "2", "BoardB"}, 189 {superchassisPath, "BoardC"}}; 190 191 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem); 192 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB", 193 subchassisExposesItem); 194 topo.addBoard(superchassisPath, "Chassis", "BoardC", 195 superchassisExposesItem); 196 197 auto assocs = topo.getAssocs(boards); 198 199 EXPECT_EQ(assocs.size(), 2U); 200 EXPECT_EQ(assocs[subchassisPath].size(), 1U); 201 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc); 202 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 1U); 203 EXPECT_EQ(assocs[subchassisPath + "2"][0], subchassisAssoc); 204 } 205 206 TEST(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 220 EXPECT_EQ(assocs.size(), 1U); 221 EXPECT_EQ(assocs[subchassisPath].size(), 1U); 222 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc); 223 } 224 225 TEST(Topology, 2Superchassis) 226 { 227 const Association subchassisAssoc2 = 228 std::make_tuple("contained_by", "containing", superchassisPath + "2"); 229 230 Topology topo; 231 BoardMap boards{{subchassisPath, "BoardA"}, 232 {superchassisPath, "BoardB"}, 233 {superchassisPath + "2", "BoardC"}}; 234 235 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem); 236 topo.addBoard(superchassisPath, "Chassis", "BoardB", 237 superchassisExposesItem); 238 topo.addBoard(superchassisPath + "2", "Chassis", "BoardC", 239 superchassisExposesItem); 240 241 auto assocs = topo.getAssocs(boards); 242 243 EXPECT_EQ(assocs.size(), 1U); 244 EXPECT_EQ(assocs[subchassisPath].size(), 2U); 245 246 EXPECT_THAT(assocs[subchassisPath], 247 UnorderedElementsAre(subchassisAssoc, subchassisAssoc2)); 248 } 249 250 TEST(Topology, 2SuperchassisAnd2Subchassis) 251 { 252 const Association subchassisAssoc2 = 253 std::make_tuple("contained_by", "containing", superchassisPath + "2"); 254 255 Topology topo; 256 BoardMap boards{{subchassisPath, "BoardA"}, 257 {subchassisPath + "2", "BoardB"}, 258 {superchassisPath, "BoardC"}, 259 {superchassisPath + "2", "BoardD"}}; 260 261 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); 268 269 auto assocs = topo.getAssocs(boards); 270 271 EXPECT_EQ(assocs.size(), 2U); 272 EXPECT_EQ(assocs[subchassisPath].size(), 2U); 273 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 2U); 274 275 EXPECT_THAT(assocs[subchassisPath], 276 UnorderedElementsAre(subchassisAssoc, subchassisAssoc2)); 277 EXPECT_THAT(assocs[subchassisPath + "2"], 278 UnorderedElementsAre(subchassisAssoc, subchassisAssoc2)); 279 } 280 281 TEST(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 297 EXPECT_EQ(assocs.size(), 2U); 298 EXPECT_EQ(assocs[subchassisPath].size(), 1U); 299 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc); 300 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 1U); 301 EXPECT_EQ(assocs[subchassisPath + "2"][0], subchassisAssoc); 302 } 303 304 { 305 topo.remove("BoardA"); 306 auto assocs = topo.getAssocs(boards); 307 308 EXPECT_EQ(assocs.size(), 1U); 309 EXPECT_EQ(assocs[subchassisPath + "2"].size(), 1U); 310 EXPECT_EQ(assocs[subchassisPath + "2"][0], subchassisAssoc); 311 } 312 313 { 314 topo.remove("BoardB"); 315 auto assocs = topo.getAssocs(boards); 316 317 EXPECT_EQ(assocs.size(), 0U); 318 } 319 } 320