test: group priority
Test for the group priority feature. When configuring different groups,
they should overwrite each other based on their priority.
The examples are based on [1]
[1] OCP Panel Indicator Specification_rev1.0.pdf
Change-Id: I91b96d9dc9307afb1a2abbde6278862045a28355
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
diff --git a/test/utest-group-priority.cpp b/test/utest-group-priority.cpp
new file mode 100644
index 0000000..43fa289
--- /dev/null
+++ b/test/utest-group-priority.cpp
@@ -0,0 +1,379 @@
+#include "ledlayout.hpp"
+#include "manager.hpp"
+
+#include <sdbusplus/bus.hpp>
+#include <xyz/openbmc_project/Led/Physical/server.hpp>
+
+#include <set>
+
+#include <gtest/gtest.h>
+
+using namespace phosphor::led;
+class LedTest : public ::testing::Test
+{
+ public:
+ sdbusplus::bus_t bus;
+ LedTest() : bus(sdbusplus::bus::new_default())
+ {
+ // Nothing here
+ }
+ ~LedTest()
+ {
+ // Leaving up to auto cleanup.
+ }
+};
+
+static void assertMap(std::map<LedName, Layout::LedAction> map,
+ std::map<LedName, Layout::Action> expect)
+{
+ EXPECT_EQ(map.size(), expect.size());
+ for (auto& [key, expect_value] : expect)
+ {
+ ASSERT_TRUE(map.contains(key));
+ EXPECT_EQ(expect_value, map[key].action);
+ }
+}
+
+static const phosphor::led::GroupMap groups1 = {
+ {"/xyz/openbmc_project/ledmanager/groups/groupA",
+ {0,
+ {
+ {"led1", Layout::Action::On, 0, 0, std::nullopt},
+ {"led2", Layout::Action::On, 0, 0, std::nullopt},
+ }}},
+ {"/xyz/openbmc_project/ledmanager/groups/groupB",
+ {0,
+ {
+ {"led3", Layout::Action::On, 0, 0, std::nullopt},
+ {"led4", Layout::Action::On, 0, 0, std::nullopt},
+ }}},
+};
+
+/** @brief Assert one group*/
+TEST_F(LedTest, assertOneGroup)
+{
+ Manager manager(bus, groups1);
+
+ std::set<const Layout::GroupLayout*> assertedGroups;
+
+ Layout::GroupLayout mygroup =
+ groups1.at("/xyz/openbmc_project/ledmanager/groups/groupA");
+
+ assertedGroups.insert(&mygroup);
+
+ std::map<LedName, Layout::LedAction> map =
+ manager.getNewMap(assertedGroups);
+
+ assertMap(map, {
+ {"led1", Layout::Action::On},
+ {"led2", Layout::Action::On},
+ });
+}
+
+static const phosphor::led::GroupMap groups2 = {
+ {"/xyz/openbmc_project/ledmanager/groups/groupA",
+ {0,
+ {
+ {"led1", Layout::Action::On, 0, 0, std::nullopt},
+ {"led2", Layout::Action::On, 0, 0, std::nullopt},
+ }}},
+ {"/xyz/openbmc_project/ledmanager/groups/groupB",
+ {2,
+ {
+ {"led2", Layout::Action::Off, 0, 0, std::nullopt},
+ {"led3", Layout::Action::On, 0, 0, std::nullopt},
+ }}},
+ {"/xyz/openbmc_project/ledmanager/groups/groupC",
+ {1,
+ {
+ {"led3", Layout::Action::Blink, 0, 0, std::nullopt},
+ {"led4", Layout::Action::Blink, 0, 0, std::nullopt},
+ }}},
+};
+
+/** @brief Assert multiple groups which overwrite each other*/
+TEST_F(LedTest, assertMultipleGroups)
+{
+ Manager manager(bus, groups2);
+
+ std::set<const Layout::GroupLayout*> assertedGroups;
+
+ Layout::GroupLayout groupA =
+ groups2.at("/xyz/openbmc_project/ledmanager/groups/groupA");
+ Layout::GroupLayout groupB =
+ groups2.at("/xyz/openbmc_project/ledmanager/groups/groupB");
+ Layout::GroupLayout groupC =
+ groups2.at("/xyz/openbmc_project/ledmanager/groups/groupC");
+
+ assertedGroups.insert(&groupA);
+ assertedGroups.insert(&groupB);
+ assertedGroups.insert(&groupC);
+
+ std::map<LedName, Layout::LedAction> map =
+ manager.getNewMap(assertedGroups);
+
+ assertMap(map, {
+ {"led1", Layout::Action::On},
+ {"led2", Layout::Action::Off},
+ {"led3", Layout::Action::On},
+ {"led4", Layout::Action::Blink},
+ });
+}
+
+TEST_F(LedTest, test_OCP_Panel_Indicator_6_1_System_Power_Status)
+{
+ const int dutyon = 50; // Spec says 50% duty cycle
+ const int period = 1; // Spec says 1Hz
+
+ // Example from OCP Panel Indicator Specification rev 1.0, Section 6.1
+ // "System Power Control / Status"
+ // The group priorities here are chosen arbitrarily, assuming that locating
+ // the hw has highest priority
+ const std::string groupOffServiceAction =
+ "/xyz/openbmc_project/ledmanager/groups/SysOffServiceAction";
+ const std::string groupSysOnOk =
+ "/xyz/openbmc_project/ledmanager/groups/SysOnOK";
+ const std::string groupSysOffFault =
+ "/xyz/openbmc_project/ledmanager/groups/SysOffFault";
+ const std::string groupSysOnLocate =
+ "/xyz/openbmc_project/ledmanager/groups/SysOnLocate";
+ const std::string groupSysOffLocate =
+ "/xyz/openbmc_project/ledmanager/groups/SysOffLocate";
+ const std::string groupSysOnFault =
+ "/xyz/openbmc_project/ledmanager/groups/SysOnFault";
+
+ const std::string pwr = "pwr";
+ const std::string fault = "fault";
+
+ static const phosphor::led::GroupMap groups_ocp_6_1_power_control = {
+ {groupOffServiceAction,
+ {2,
+ {
+ {pwr, Layout::Action::Off, 0, 0, std::nullopt},
+ {fault, Layout::Action::Off, 0, 0, std::nullopt},
+ }}},
+ {groupSysOnOk,
+ {3,
+ {
+ {pwr, Layout::Action::On, 0, 0, std::nullopt},
+ {fault, Layout::Action::Off, 0, 0, std::nullopt},
+ }}},
+ {groupSysOffFault,
+ {38,
+ {
+ {pwr, Layout::Action::Off, 0, 0, std::nullopt},
+ {fault, Layout::Action::On, 0, 0, std::nullopt},
+ }}},
+ {groupSysOnLocate,
+ {99,
+ {
+ {pwr, Layout::Action::On, 0, 0, std::nullopt},
+ {fault, Layout::Action::Blink, dutyon, period, std::nullopt},
+ }}},
+ {groupSysOffLocate,
+ {98,
+ {
+ {pwr, Layout::Action::Off, 0, 0, std::nullopt},
+ {fault, Layout::Action::Blink, dutyon, period, std::nullopt},
+ }}},
+ {groupSysOnFault,
+ {39,
+ {
+ {pwr, Layout::Action::On, 0, 0, std::nullopt},
+ {fault, Layout::Action::On, 0, 0, std::nullopt},
+ }}},
+ };
+
+ const phosphor::led::GroupMap* groups = &groups_ocp_6_1_power_control;
+
+ Manager manager(bus, *groups);
+
+ std::set<const Layout::GroupLayout*> assertedGroups;
+
+ // Off Service Action
+ assertedGroups.insert(&groups->at(groupOffServiceAction));
+
+ assertMap(manager.getNewMap(assertedGroups),
+ {
+ {pwr, Layout::Action::Off},
+ {fault, Layout::Action::Off},
+ });
+
+ // On Ok
+ assertedGroups.insert(&groups->at(groupSysOnOk));
+ assertMap(manager.getNewMap(assertedGroups),
+ {
+ {pwr, Layout::Action::On},
+ {fault, Layout::Action::Off},
+ });
+
+ // Off Fault
+ assertedGroups.insert(&groups->at(groupSysOffFault));
+ assertMap(manager.getNewMap(assertedGroups),
+ {
+ {pwr, Layout::Action::Off},
+ {fault, Layout::Action::On},
+ });
+
+ // Off Fault
+ assertedGroups.insert(&groups->at(groupSysOffFault));
+ assertMap(manager.getNewMap(assertedGroups),
+ {
+ {pwr, Layout::Action::Off},
+ {fault, Layout::Action::On},
+ });
+
+ // On Fault
+ assertedGroups.insert(&groups->at(groupSysOnFault));
+ assertMap(manager.getNewMap(assertedGroups),
+ {
+ {pwr, Layout::Action::On},
+ {fault, Layout::Action::On},
+ });
+
+ // Off Locate
+ assertedGroups.insert(&groups->at(groupSysOffLocate));
+ assertMap(manager.getNewMap(assertedGroups),
+ {
+ {pwr, Layout::Action::Off},
+ {fault, Layout::Action::Blink},
+ });
+
+ // On Locate
+ assertedGroups.insert(&groups->at(groupSysOnLocate));
+ assertMap(manager.getNewMap(assertedGroups),
+ {
+ {pwr, Layout::Action::On},
+ {fault, Layout::Action::Blink},
+ });
+}
+
+TEST_F(LedTest, test_OCP_Panel_Indicator_6_5_BBU_status)
+{
+ // Example from OCP Panel Indicator Specification rev 1.0, Section 6.5
+ // "BBU Status"
+ // The group priorities here are chosen arbitrarily, assuming that locating
+ // the hw has highest priority
+ const std::string gBBUSleep =
+ "/xyz/openbmc_project/ledmanager/groups/BBUSleep";
+ const std::string gBBUOn = "/xyz/openbmc_project/ledmanager/groups/BBUOn";
+ const std::string gBBUFault =
+ "/xyz/openbmc_project/ledmanager/groups/BBUFault";
+ const std::string gBBUUnderVolt =
+ "/xyz/openbmc_project/ledmanager/groups/BBUUnderVolt";
+ const std::string gBBUEOL = "/xyz/openbmc_project/ledmanager/groups/BBUEOL";
+ const std::string gBBUOffLocate =
+ "/xyz/openbmc_project/ledmanager/groups/BBUOffLocate";
+ const std::string gBBUOnLocate =
+ "/xyz/openbmc_project/ledmanager/groups/BBUOnLocate";
+
+ const std::string bbu_ok = "bbu_ok";
+ const std::string bbu_fault = "bbu_fault";
+ const std::string bbu_lowv = "bbu_lowv";
+ const std::string bbu_eol = "bbu_eol";
+
+ static const phosphor::led::GroupMap groups_ocp_6_5_bbu_status = {
+ {gBBUSleep,
+ {9,
+ {
+ {bbu_ok, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_fault, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_lowv, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_eol, Layout::Action::Off, 0, 0, std::nullopt},
+ }}},
+ {gBBUOn,
+ {10,
+ {
+ {bbu_ok, Layout::Action::On, 0, 0, std::nullopt},
+ {bbu_fault, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_lowv, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_eol, Layout::Action::Off, 0, 0, std::nullopt},
+ }}},
+ {gBBUFault,
+ {38,
+ {
+ {bbu_ok, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_fault, Layout::Action::On, 0, 0, std::nullopt},
+ {bbu_lowv, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_eol, Layout::Action::Off, 0, 0, std::nullopt},
+ }}},
+ {gBBUUnderVolt,
+ {39,
+ {
+ {bbu_ok, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_fault, Layout::Action::On, 0, 0, std::nullopt},
+ {bbu_lowv, Layout::Action::On, 0, 0, std::nullopt},
+ {bbu_eol, Layout::Action::Off, 0, 0, std::nullopt},
+ }}},
+ {gBBUEOL,
+ {40,
+ {
+ {bbu_ok, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_fault, Layout::Action::On, 0, 0, std::nullopt},
+ {bbu_lowv, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_eol, Layout::Action::On, 0, 0, std::nullopt},
+ }}},
+ {gBBUOffLocate,
+ {98,
+ {
+ {bbu_ok, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_fault, Layout::Action::Blink, 0, 0, std::nullopt},
+ {bbu_lowv, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_eol, Layout::Action::Off, 0, 0, std::nullopt},
+ }}},
+ {gBBUOnLocate,
+ {99,
+ {
+ {bbu_ok, Layout::Action::On, 0, 0, std::nullopt},
+ {bbu_fault, Layout::Action::Blink, 0, 0, std::nullopt},
+ {bbu_lowv, Layout::Action::Off, 0, 0, std::nullopt},
+ {bbu_eol, Layout::Action::Off, 0, 0, std::nullopt},
+ }}},
+ };
+
+ const phosphor::led::GroupMap* groups = &groups_ocp_6_5_bbu_status;
+
+ Manager manager(bus, *groups);
+
+ std::set<const Layout::GroupLayout*> assertedGroups;
+
+ // Sleep
+ assertedGroups.insert(&groups->at(gBBUSleep));
+ assertMap(manager.getNewMap(assertedGroups),
+ {
+ {bbu_ok, Layout::Action::Off},
+ {bbu_fault, Layout::Action::Off},
+ {bbu_lowv, Layout::Action::Off},
+ {bbu_eol, Layout::Action::Off},
+ });
+
+ // Fault
+ assertedGroups.insert(&groups->at(gBBUFault));
+ assertMap(manager.getNewMap(assertedGroups),
+ {
+ {bbu_ok, Layout::Action::Off},
+ {bbu_fault, Layout::Action::On},
+ {bbu_lowv, Layout::Action::Off},
+ {bbu_eol, Layout::Action::Off},
+ });
+
+ // EOL
+ assertedGroups.insert(&groups->at(gBBUEOL));
+ assertMap(manager.getNewMap(assertedGroups),
+ {
+ {bbu_ok, Layout::Action::Off},
+ {bbu_fault, Layout::Action::On},
+ {bbu_lowv, Layout::Action::Off},
+ {bbu_eol, Layout::Action::On},
+ });
+
+ // On + Locate
+ assertedGroups.insert(&groups->at(gBBUOnLocate));
+ assertMap(manager.getNewMap(assertedGroups),
+ {
+ {bbu_ok, Layout::Action::On},
+ {bbu_fault, Layout::Action::Blink},
+ {bbu_lowv, Layout::Action::Off},
+ {bbu_eol, Layout::Action::Off},
+ });
+}