1 #include "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 16 const nlohmann::json subchassisExposesItem = nlohmann::json::parse(R"( 17 { 18 "ConnectsToType": "BackplanePort", 19 "Name": "MyDownstreamPort", 20 "Type": "DownstreamPort" 21 } 22 )"); 23 24 const nlohmann::json superchassisExposesItem = nlohmann::json::parse(R"( 25 { 26 "Name": "MyBackplanePort", 27 "Type": "BackplanePort" 28 } 29 )"); 30 31 const nlohmann::json otherExposesItem = nlohmann::json::parse(R"( 32 { 33 "Name": "MyExposes", 34 "Type": "OtherType" 35 } 36 )"); 37 38 using BoardMap = std::map<std::string, std::string>; 39 40 TEST(Topology, Empty) 41 { 42 Topology topo; 43 BoardMap boards; 44 45 auto assocs = topo.getAssocs(boards); 46 47 EXPECT_EQ(assocs.size(), 0); 48 } 49 50 TEST(Topology, EmptyExposes) 51 { 52 Topology topo; 53 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}}; 54 55 topo.addBoard(subchassisPath, "Chassis", "BoardA", nlohmann::json()); 56 topo.addBoard(superchassisPath, "Chassis", "BoardB", nlohmann::json()); 57 58 auto assocs = topo.getAssocs(boards); 59 60 EXPECT_EQ(assocs.size(), 0); 61 } 62 63 TEST(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; 73 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}}; 74 75 topo.addBoard(subchassisPath, "Chassis", "BoardA", 76 subchassisMissingConnectsTo); 77 topo.addBoard(superchassisPath, "Chassis", "BoardB", 78 superchassisExposesItem); 79 80 auto assocs = topo.getAssocs(boards); 81 82 EXPECT_EQ(assocs.size(), 0); 83 } 84 85 TEST(Topology, OtherExposes) 86 { 87 Topology topo; 88 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}}; 89 90 topo.addBoard(subchassisPath, "Chassis", "BoardA", otherExposesItem); 91 topo.addBoard(superchassisPath, "Chassis", "BoardB", otherExposesItem); 92 93 auto assocs = topo.getAssocs(boards); 94 95 EXPECT_EQ(assocs.size(), 0); 96 } 97 98 TEST(Topology, NoMatchSubchassis) 99 { 100 Topology topo; 101 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}}; 102 103 topo.addBoard(subchassisPath, "Chassis", "BoardA", otherExposesItem); 104 topo.addBoard(superchassisPath, "Chassis", "BoardB", 105 superchassisExposesItem); 106 107 auto assocs = topo.getAssocs(boards); 108 109 EXPECT_EQ(assocs.size(), 0); 110 } 111 112 TEST(Topology, NoMatchSuperchassis) 113 { 114 Topology topo; 115 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}}; 116 117 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem); 118 topo.addBoard(superchassisPath, "Chassis", "BoardB", otherExposesItem); 119 120 auto assocs = topo.getAssocs(boards); 121 122 EXPECT_EQ(assocs.size(), 0); 123 } 124 125 TEST(Topology, Basic) 126 { 127 Topology topo; 128 BoardMap boards{{subchassisPath, "BoardA"}, {superchassisPath, "BoardB"}}; 129 130 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem); 131 topo.addBoard(superchassisPath, "Chassis", "BoardB", 132 superchassisExposesItem); 133 134 auto assocs = topo.getAssocs(boards); 135 136 EXPECT_EQ(assocs.size(), 1); 137 EXPECT_EQ(assocs[subchassisPath].size(), 1); 138 EXPECT_EQ(assocs[subchassisPath][0], subchassisAssoc); 139 } 140 141 TEST(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 156 TEST(Topology, 2Subchassis) 157 { 158 Topology topo; 159 BoardMap boards{{subchassisPath, "BoardA"}, 160 {subchassisPath + "2", "BoardB"}, 161 {superchassisPath, "BoardC"}}; 162 163 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem); 164 topo.addBoard(subchassisPath + "2", "Chassis", "BoardB", 165 subchassisExposesItem); 166 topo.addBoard(superchassisPath, "Chassis", "BoardC", 167 superchassisExposesItem); 168 169 auto assocs = topo.getAssocs(boards); 170 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 178 TEST(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 197 TEST(Topology, 2Superchassis) 198 { 199 const Association subchassisAssoc2 = 200 std::make_tuple("contained_by", "containing", superchassisPath + "2"); 201 202 Topology topo; 203 BoardMap boards{{subchassisPath, "BoardA"}, 204 {superchassisPath, "BoardB"}, 205 {superchassisPath + "2", "BoardC"}}; 206 207 topo.addBoard(subchassisPath, "Chassis", "BoardA", subchassisExposesItem); 208 topo.addBoard(superchassisPath, "Chassis", "BoardB", 209 superchassisExposesItem); 210 topo.addBoard(superchassisPath + "2", "Chassis", "BoardC", 211 superchassisExposesItem); 212 213 auto assocs = topo.getAssocs(boards); 214 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 222 TEST(Topology, 2SuperchassisAnd2Subchassis) 223 { 224 const Association subchassisAssoc2 = 225 std::make_tuple("contained_by", "containing", superchassisPath + "2"); 226 227 Topology topo; 228 BoardMap boards{{subchassisPath, "BoardA"}, 229 {subchassisPath + "2", "BoardB"}, 230 {superchassisPath, "BoardC"}, 231 {superchassisPath + "2", "BoardD"}}; 232 233 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); 240 241 auto assocs = topo.getAssocs(boards); 242 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 } 252 253 TEST(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 } 292