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