1 #include "ledlayout.hpp" 2 #include "manager.hpp" 3 4 #include <sdbusplus/bus.hpp> 5 #include <xyz/openbmc_project/Led/Physical/server.hpp> 6 7 #include <set> 8 9 #include <gtest/gtest.h> 10 11 using namespace phosphor::led; 12 class LedTest : public ::testing::Test 13 { 14 public: 15 sdbusplus::bus_t bus; 16 LedTest() : bus(sdbusplus::bus::new_default()) 17 { 18 // Nothing here 19 } 20 ~LedTest() 21 { 22 // Leaving up to auto cleanup. 23 } 24 }; 25 26 static void assertMap(std::map<LedName, Layout::LedAction> map, 27 std::map<LedName, Layout::Action> expect) 28 { 29 EXPECT_EQ(map.size(), expect.size()); 30 for (auto& [key, expect_value] : expect) 31 { 32 ASSERT_TRUE(map.contains(key)); 33 EXPECT_EQ(expect_value, map[key].action); 34 } 35 } 36 37 static const phosphor::led::GroupMap groups1 = { 38 {"/xyz/openbmc_project/ledmanager/groups/groupA", 39 {0, 40 { 41 {"led1", Layout::Action::On, 0, 0, std::nullopt}, 42 {"led2", Layout::Action::On, 0, 0, std::nullopt}, 43 }}}, 44 {"/xyz/openbmc_project/ledmanager/groups/groupB", 45 {0, 46 { 47 {"led3", Layout::Action::On, 0, 0, std::nullopt}, 48 {"led4", Layout::Action::On, 0, 0, std::nullopt}, 49 }}}, 50 }; 51 52 /** @brief Assert one group*/ 53 TEST_F(LedTest, assertOneGroup) 54 { 55 Manager manager(bus, groups1); 56 57 std::set<const Layout::GroupLayout*> assertedGroups; 58 59 Layout::GroupLayout mygroup = 60 groups1.at("/xyz/openbmc_project/ledmanager/groups/groupA"); 61 62 assertedGroups.insert(&mygroup); 63 64 std::map<LedName, Layout::LedAction> map = 65 manager.getNewMap(assertedGroups); 66 67 assertMap(map, { 68 {"led1", Layout::Action::On}, 69 {"led2", Layout::Action::On}, 70 }); 71 } 72 73 static const phosphor::led::GroupMap groups2 = { 74 {"/xyz/openbmc_project/ledmanager/groups/groupA", 75 {0, 76 { 77 {"led1", Layout::Action::On, 0, 0, std::nullopt}, 78 {"led2", Layout::Action::On, 0, 0, std::nullopt}, 79 }}}, 80 {"/xyz/openbmc_project/ledmanager/groups/groupB", 81 {2, 82 { 83 {"led2", Layout::Action::Off, 0, 0, std::nullopt}, 84 {"led3", Layout::Action::On, 0, 0, std::nullopt}, 85 }}}, 86 {"/xyz/openbmc_project/ledmanager/groups/groupC", 87 {1, 88 { 89 {"led3", Layout::Action::Blink, 0, 0, std::nullopt}, 90 {"led4", Layout::Action::Blink, 0, 0, std::nullopt}, 91 }}}, 92 }; 93 94 /** @brief Assert multiple groups which overwrite each other*/ 95 TEST_F(LedTest, assertMultipleGroups) 96 { 97 Manager manager(bus, groups2); 98 99 std::set<const Layout::GroupLayout*> assertedGroups; 100 101 Layout::GroupLayout groupA = 102 groups2.at("/xyz/openbmc_project/ledmanager/groups/groupA"); 103 Layout::GroupLayout groupB = 104 groups2.at("/xyz/openbmc_project/ledmanager/groups/groupB"); 105 Layout::GroupLayout groupC = 106 groups2.at("/xyz/openbmc_project/ledmanager/groups/groupC"); 107 108 assertedGroups.insert(&groupA); 109 assertedGroups.insert(&groupB); 110 assertedGroups.insert(&groupC); 111 112 std::map<LedName, Layout::LedAction> map = 113 manager.getNewMap(assertedGroups); 114 115 assertMap(map, { 116 {"led1", Layout::Action::On}, 117 {"led2", Layout::Action::Off}, 118 {"led3", Layout::Action::On}, 119 {"led4", Layout::Action::Blink}, 120 }); 121 } 122 123 TEST_F(LedTest, test_OCP_Panel_Indicator_6_1_System_Power_Status) 124 { 125 const int dutyon = 50; // Spec says 50% duty cycle 126 const int period = 1; // Spec says 1Hz 127 128 // Example from OCP Panel Indicator Specification rev 1.0, Section 6.1 129 // "System Power Control / Status" 130 // The group priorities here are chosen arbitrarily, assuming that locating 131 // the hw has highest priority 132 const std::string groupOffServiceAction = 133 "/xyz/openbmc_project/ledmanager/groups/SysOffServiceAction"; 134 const std::string groupSysOnOk = 135 "/xyz/openbmc_project/ledmanager/groups/SysOnOK"; 136 const std::string groupSysOffFault = 137 "/xyz/openbmc_project/ledmanager/groups/SysOffFault"; 138 const std::string groupSysOnLocate = 139 "/xyz/openbmc_project/ledmanager/groups/SysOnLocate"; 140 const std::string groupSysOffLocate = 141 "/xyz/openbmc_project/ledmanager/groups/SysOffLocate"; 142 const std::string groupSysOnFault = 143 "/xyz/openbmc_project/ledmanager/groups/SysOnFault"; 144 145 const std::string pwr = "pwr"; 146 const std::string fault = "fault"; 147 148 static const phosphor::led::GroupMap groups_ocp_6_1_power_control = { 149 {groupOffServiceAction, 150 {2, 151 { 152 {pwr, Layout::Action::Off, 0, 0, std::nullopt}, 153 {fault, Layout::Action::Off, 0, 0, std::nullopt}, 154 }}}, 155 {groupSysOnOk, 156 {3, 157 { 158 {pwr, Layout::Action::On, 0, 0, std::nullopt}, 159 {fault, Layout::Action::Off, 0, 0, std::nullopt}, 160 }}}, 161 {groupSysOffFault, 162 {38, 163 { 164 {pwr, Layout::Action::Off, 0, 0, std::nullopt}, 165 {fault, Layout::Action::On, 0, 0, std::nullopt}, 166 }}}, 167 {groupSysOnLocate, 168 {99, 169 { 170 {pwr, Layout::Action::On, 0, 0, std::nullopt}, 171 {fault, Layout::Action::Blink, dutyon, period, std::nullopt}, 172 }}}, 173 {groupSysOffLocate, 174 {98, 175 { 176 {pwr, Layout::Action::Off, 0, 0, std::nullopt}, 177 {fault, Layout::Action::Blink, dutyon, period, std::nullopt}, 178 }}}, 179 {groupSysOnFault, 180 {39, 181 { 182 {pwr, Layout::Action::On, 0, 0, std::nullopt}, 183 {fault, Layout::Action::On, 0, 0, std::nullopt}, 184 }}}, 185 }; 186 187 const phosphor::led::GroupMap* groups = &groups_ocp_6_1_power_control; 188 189 Manager manager(bus, *groups); 190 191 std::set<const Layout::GroupLayout*> assertedGroups; 192 193 // Off Service Action 194 assertedGroups.insert(&groups->at(groupOffServiceAction)); 195 196 assertMap(manager.getNewMap(assertedGroups), 197 { 198 {pwr, Layout::Action::Off}, 199 {fault, Layout::Action::Off}, 200 }); 201 202 // On Ok 203 assertedGroups.insert(&groups->at(groupSysOnOk)); 204 assertMap(manager.getNewMap(assertedGroups), 205 { 206 {pwr, Layout::Action::On}, 207 {fault, Layout::Action::Off}, 208 }); 209 210 // Off Fault 211 assertedGroups.insert(&groups->at(groupSysOffFault)); 212 assertMap(manager.getNewMap(assertedGroups), 213 { 214 {pwr, Layout::Action::Off}, 215 {fault, Layout::Action::On}, 216 }); 217 218 // Off Fault 219 assertedGroups.insert(&groups->at(groupSysOffFault)); 220 assertMap(manager.getNewMap(assertedGroups), 221 { 222 {pwr, Layout::Action::Off}, 223 {fault, Layout::Action::On}, 224 }); 225 226 // On Fault 227 assertedGroups.insert(&groups->at(groupSysOnFault)); 228 assertMap(manager.getNewMap(assertedGroups), 229 { 230 {pwr, Layout::Action::On}, 231 {fault, Layout::Action::On}, 232 }); 233 234 // Off Locate 235 assertedGroups.insert(&groups->at(groupSysOffLocate)); 236 assertMap(manager.getNewMap(assertedGroups), 237 { 238 {pwr, Layout::Action::Off}, 239 {fault, Layout::Action::Blink}, 240 }); 241 242 // On Locate 243 assertedGroups.insert(&groups->at(groupSysOnLocate)); 244 assertMap(manager.getNewMap(assertedGroups), 245 { 246 {pwr, Layout::Action::On}, 247 {fault, Layout::Action::Blink}, 248 }); 249 } 250 251 TEST_F(LedTest, test_OCP_Panel_Indicator_6_5_BBU_status) 252 { 253 // Example from OCP Panel Indicator Specification rev 1.0, Section 6.5 254 // "BBU Status" 255 // The group priorities here are chosen arbitrarily, assuming that locating 256 // the hw has highest priority 257 const std::string gBBUSleep = 258 "/xyz/openbmc_project/ledmanager/groups/BBUSleep"; 259 const std::string gBBUOn = "/xyz/openbmc_project/ledmanager/groups/BBUOn"; 260 const std::string gBBUFault = 261 "/xyz/openbmc_project/ledmanager/groups/BBUFault"; 262 const std::string gBBUUnderVolt = 263 "/xyz/openbmc_project/ledmanager/groups/BBUUnderVolt"; 264 const std::string gBBUEOL = "/xyz/openbmc_project/ledmanager/groups/BBUEOL"; 265 const std::string gBBUOffLocate = 266 "/xyz/openbmc_project/ledmanager/groups/BBUOffLocate"; 267 const std::string gBBUOnLocate = 268 "/xyz/openbmc_project/ledmanager/groups/BBUOnLocate"; 269 270 const std::string bbu_ok = "bbu_ok"; 271 const std::string bbu_fault = "bbu_fault"; 272 const std::string bbu_lowv = "bbu_lowv"; 273 const std::string bbu_eol = "bbu_eol"; 274 275 static const phosphor::led::GroupMap groups_ocp_6_5_bbu_status = { 276 {gBBUSleep, 277 {9, 278 { 279 {bbu_ok, Layout::Action::Off, 0, 0, std::nullopt}, 280 {bbu_fault, Layout::Action::Off, 0, 0, std::nullopt}, 281 {bbu_lowv, Layout::Action::Off, 0, 0, std::nullopt}, 282 {bbu_eol, Layout::Action::Off, 0, 0, std::nullopt}, 283 }}}, 284 {gBBUOn, 285 {10, 286 { 287 {bbu_ok, Layout::Action::On, 0, 0, std::nullopt}, 288 {bbu_fault, Layout::Action::Off, 0, 0, std::nullopt}, 289 {bbu_lowv, Layout::Action::Off, 0, 0, std::nullopt}, 290 {bbu_eol, Layout::Action::Off, 0, 0, std::nullopt}, 291 }}}, 292 {gBBUFault, 293 {38, 294 { 295 {bbu_ok, Layout::Action::Off, 0, 0, std::nullopt}, 296 {bbu_fault, Layout::Action::On, 0, 0, std::nullopt}, 297 {bbu_lowv, Layout::Action::Off, 0, 0, std::nullopt}, 298 {bbu_eol, Layout::Action::Off, 0, 0, std::nullopt}, 299 }}}, 300 {gBBUUnderVolt, 301 {39, 302 { 303 {bbu_ok, Layout::Action::Off, 0, 0, std::nullopt}, 304 {bbu_fault, Layout::Action::On, 0, 0, std::nullopt}, 305 {bbu_lowv, Layout::Action::On, 0, 0, std::nullopt}, 306 {bbu_eol, Layout::Action::Off, 0, 0, std::nullopt}, 307 }}}, 308 {gBBUEOL, 309 {40, 310 { 311 {bbu_ok, Layout::Action::Off, 0, 0, std::nullopt}, 312 {bbu_fault, Layout::Action::On, 0, 0, std::nullopt}, 313 {bbu_lowv, Layout::Action::Off, 0, 0, std::nullopt}, 314 {bbu_eol, Layout::Action::On, 0, 0, std::nullopt}, 315 }}}, 316 {gBBUOffLocate, 317 {98, 318 { 319 {bbu_ok, Layout::Action::Off, 0, 0, std::nullopt}, 320 {bbu_fault, Layout::Action::Blink, 0, 0, std::nullopt}, 321 {bbu_lowv, Layout::Action::Off, 0, 0, std::nullopt}, 322 {bbu_eol, Layout::Action::Off, 0, 0, std::nullopt}, 323 }}}, 324 {gBBUOnLocate, 325 {99, 326 { 327 {bbu_ok, Layout::Action::On, 0, 0, std::nullopt}, 328 {bbu_fault, Layout::Action::Blink, 0, 0, std::nullopt}, 329 {bbu_lowv, Layout::Action::Off, 0, 0, std::nullopt}, 330 {bbu_eol, Layout::Action::Off, 0, 0, std::nullopt}, 331 }}}, 332 }; 333 334 const phosphor::led::GroupMap* groups = &groups_ocp_6_5_bbu_status; 335 336 Manager manager(bus, *groups); 337 338 std::set<const Layout::GroupLayout*> assertedGroups; 339 340 // Sleep 341 assertedGroups.insert(&groups->at(gBBUSleep)); 342 assertMap(manager.getNewMap(assertedGroups), 343 { 344 {bbu_ok, Layout::Action::Off}, 345 {bbu_fault, Layout::Action::Off}, 346 {bbu_lowv, Layout::Action::Off}, 347 {bbu_eol, Layout::Action::Off}, 348 }); 349 350 // Fault 351 assertedGroups.insert(&groups->at(gBBUFault)); 352 assertMap(manager.getNewMap(assertedGroups), 353 { 354 {bbu_ok, Layout::Action::Off}, 355 {bbu_fault, Layout::Action::On}, 356 {bbu_lowv, Layout::Action::Off}, 357 {bbu_eol, Layout::Action::Off}, 358 }); 359 360 // EOL 361 assertedGroups.insert(&groups->at(gBBUEOL)); 362 assertMap(manager.getNewMap(assertedGroups), 363 { 364 {bbu_ok, Layout::Action::Off}, 365 {bbu_fault, Layout::Action::On}, 366 {bbu_lowv, Layout::Action::Off}, 367 {bbu_eol, Layout::Action::On}, 368 }); 369 370 // On + Locate 371 assertedGroups.insert(&groups->at(gBBUOnLocate)); 372 assertMap(manager.getNewMap(assertedGroups), 373 { 374 {bbu_ok, Layout::Action::On}, 375 {bbu_fault, Layout::Action::Blink}, 376 {bbu_lowv, Layout::Action::Off}, 377 {bbu_eol, Layout::Action::Off}, 378 }); 379 } 380