15327988eSTom Joseph #include "common/test/mocked_utils.hpp"
25327988eSTom Joseph #include "libpldmresponder/bios_enum_attribute.hpp"
35327988eSTom Joseph #include "mocked_bios.hpp"
45327988eSTom Joseph 
55327988eSTom Joseph #include <nlohmann/json.hpp>
65327988eSTom Joseph 
75327988eSTom Joseph #include <memory>
85327988eSTom Joseph 
95327988eSTom Joseph #include <gmock/gmock.h>
105327988eSTom Joseph #include <gtest/gtest.h>
115327988eSTom Joseph 
125079ac4aSBrad Bishop using namespace pldm::responder::bios;
135079ac4aSBrad Bishop using namespace pldm::utils;
145079ac4aSBrad Bishop 
155327988eSTom Joseph using ::testing::_;
165327988eSTom Joseph using ::testing::ElementsAreArray;
175327988eSTom Joseph using ::testing::Return;
185327988eSTom Joseph using ::testing::StrEq;
195327988eSTom Joseph using ::testing::Throw;
205327988eSTom Joseph 
215327988eSTom Joseph class TestBIOSEnumAttribute : public ::testing::Test
225327988eSTom Joseph {
235327988eSTom Joseph   public:
getPossibleValues(const BIOSEnumAttribute & attribute)245327988eSTom Joseph     const auto& getPossibleValues(const BIOSEnumAttribute& attribute)
255327988eSTom Joseph     {
265327988eSTom Joseph         return attribute.possibleValues;
275327988eSTom Joseph     }
285327988eSTom Joseph 
getDefaultValue(const BIOSEnumAttribute & attribute)295327988eSTom Joseph     const auto& getDefaultValue(const BIOSEnumAttribute& attribute)
305327988eSTom Joseph     {
315327988eSTom Joseph         return attribute.defaultValue;
325327988eSTom Joseph     }
335327988eSTom Joseph };
345327988eSTom Joseph 
TEST_F(TestBIOSEnumAttribute,CtorTest)355327988eSTom Joseph TEST_F(TestBIOSEnumAttribute, CtorTest)
365327988eSTom Joseph {
375327988eSTom Joseph     auto jsonEnumReadOnly = R"({
385327988eSTom Joseph          "attribute_name" : "CodeUpdatePolicy",
395327988eSTom Joseph          "possible_values" : [ "Concurrent", "Disruptive" ],
407927f90cSSagar Srinivas          "value_names" : [ "Concurrent", "Disruptive" ],
415327988eSTom Joseph          "default_values" : [ "Concurrent" ],
42d6608096SArchana Kakani          "read_only" : true,
43d6608096SArchana Kakani          "help_text" : "HelpText",
44d6608096SArchana Kakani          "display_name" : "DisplayName"
455327988eSTom Joseph       })"_json;
465327988eSTom Joseph 
475327988eSTom Joseph     BIOSEnumAttribute enumReadOnly{jsonEnumReadOnly, nullptr};
485327988eSTom Joseph     EXPECT_EQ(enumReadOnly.name, "CodeUpdatePolicy");
495327988eSTom Joseph     EXPECT_TRUE(enumReadOnly.readOnly);
505327988eSTom Joseph     EXPECT_THAT(getPossibleValues(enumReadOnly),
515327988eSTom Joseph                 ElementsAreArray({"Concurrent", "Disruptive"}));
525327988eSTom Joseph     EXPECT_EQ(getDefaultValue(enumReadOnly), "Concurrent");
535327988eSTom Joseph 
545327988eSTom Joseph     auto jsonEnumReadOnlyError = R"({
555327988eSTom Joseph          "attribute_name" : "CodeUpdatePolicy",
565327988eSTom Joseph          "possible_value" : [ "Concurrent", "Disruptive" ],
577927f90cSSagar Srinivas          "value_names" : [ "Concurrent", "Disruptive" ],
585327988eSTom Joseph          "default_values" : [ "Concurrent" ],
59d6608096SArchana Kakani          "read_only" : true,
60d6608096SArchana Kakani          "help_text" : "HelpText",
61d6608096SArchana Kakani          "display_name" : "DisplayName"
625327988eSTom Joseph       })"_json; // possible_value -> possible_values
635327988eSTom Joseph     EXPECT_THROW((BIOSEnumAttribute{jsonEnumReadOnlyError, nullptr}),
645327988eSTom Joseph                  Json::exception);
655327988eSTom Joseph 
665327988eSTom Joseph     auto jsonEnumReadWrite = R"({
675327988eSTom Joseph          "attribute_name" : "FWBootSide",
685327988eSTom Joseph          "possible_values" : [ "Perm", "Temp" ],
697927f90cSSagar Srinivas          "value_names" : [ "Perm", "Temp" ],
705327988eSTom Joseph          "default_values" : [ "Perm" ],
71d6608096SArchana Kakani          "read_only" : false,
72d6608096SArchana Kakani          "help_text" : "HelpText",
73d6608096SArchana Kakani          "display_name" : "DisplayName",
745327988eSTom Joseph          "dbus":
755327988eSTom Joseph             {
765327988eSTom Joseph                "object_path" : "/xyz/abc/def",
775327988eSTom Joseph                "interface" : "xyz.openbmc.FWBoot.Side",
785327988eSTom Joseph                "property_name" : "Side",
795327988eSTom Joseph                "property_type" : "bool",
805327988eSTom Joseph                "property_values" : [true, false]
815327988eSTom Joseph             }
825327988eSTom Joseph       })"_json;
835327988eSTom Joseph 
845327988eSTom Joseph     BIOSEnumAttribute enumReadWrite{jsonEnumReadWrite, nullptr};
855327988eSTom Joseph     EXPECT_EQ(enumReadWrite.name, "FWBootSide");
865327988eSTom Joseph     EXPECT_TRUE(!enumReadWrite.readOnly);
875327988eSTom Joseph }
885327988eSTom Joseph 
TEST_F(TestBIOSEnumAttribute,ConstructEntry)895327988eSTom Joseph TEST_F(TestBIOSEnumAttribute, ConstructEntry)
905327988eSTom Joseph {
915327988eSTom Joseph     MockBIOSStringTable biosStringTable;
925327988eSTom Joseph     MockdBusHandler dbusHandler;
935327988eSTom Joseph 
945327988eSTom Joseph     auto jsonEnumReadOnly = R"({
955327988eSTom Joseph          "attribute_name" : "CodeUpdatePolicy",
965327988eSTom Joseph          "possible_values" : [ "Concurrent", "Disruptive" ],
977927f90cSSagar Srinivas          "value_names" : [ "Concurrent", "Disruptive" ],
985327988eSTom Joseph          "default_values" : [ "Disruptive" ],
99d6608096SArchana Kakani          "read_only" : true,
100d6608096SArchana Kakani          "help_text" : "HelpText",
101d6608096SArchana Kakani          "display_name" : "DisplayName"
1025327988eSTom Joseph       })"_json;
1035327988eSTom Joseph 
1045327988eSTom Joseph     std::vector<uint8_t> expectedAttrEntry{
1055327988eSTom Joseph         0,    0, /* attr handle */
1065327988eSTom Joseph         0x80,    /* attr type enum read-only*/
1075327988eSTom Joseph         4,    0, /* attr name handle */
1085327988eSTom Joseph         2,       /* number of possible value */
1095327988eSTom Joseph         2,    0, /* possible value handle */
1105327988eSTom Joseph         3,    0, /* possible value handle */
1115327988eSTom Joseph         1,       /* number of default value */
112*2576aecdSManojkiran Eda         1        /* default value string handle index */
1135327988eSTom Joseph     };
1145327988eSTom Joseph 
1155327988eSTom Joseph     std::vector<uint8_t> expectedAttrValueEntry{
1165327988eSTom Joseph         0, 0, /* attr handle */
1175327988eSTom Joseph         0x80, /* attr type enum read-only*/
1185327988eSTom Joseph         1,    /* number of current value */
1195327988eSTom Joseph         1     /* current value string handle index */
1205327988eSTom Joseph     };
1215327988eSTom Joseph 
1225327988eSTom Joseph     BIOSEnumAttribute enumReadOnly{jsonEnumReadOnly, nullptr};
1235327988eSTom Joseph 
1245327988eSTom Joseph     ON_CALL(biosStringTable, findHandle(StrEq("Concurrent")))
1255327988eSTom Joseph         .WillByDefault(Return(2));
1265327988eSTom Joseph     ON_CALL(biosStringTable, findHandle(StrEq("Disruptive")))
1275327988eSTom Joseph         .WillByDefault(Return(3));
1285327988eSTom Joseph     ON_CALL(biosStringTable, findHandle(StrEq("CodeUpdatePolicy")))
1295327988eSTom Joseph         .WillByDefault(Return(4));
1305327988eSTom Joseph 
1315327988eSTom Joseph     checkConstructEntry(enumReadOnly, biosStringTable, expectedAttrEntry,
1325327988eSTom Joseph                         expectedAttrValueEntry);
1335327988eSTom Joseph 
1345327988eSTom Joseph     auto jsonEnumReadWrite = R"({
1355327988eSTom Joseph          "attribute_name" : "CodeUpdatePolicy",
1365327988eSTom Joseph          "possible_values" : [ "Concurrent", "Disruptive" ],
1377927f90cSSagar Srinivas          "value_names" : [ "Concurrent", "Disruptive" ],
1385327988eSTom Joseph          "default_values" : [ "Disruptive" ],
139d6608096SArchana Kakani          "read_only" : false,
140d6608096SArchana Kakani          "help_text" : "HelpText",
141d6608096SArchana Kakani          "display_name" : "DisplayName",
1425327988eSTom Joseph          "dbus":
1435327988eSTom Joseph             {
1445327988eSTom Joseph                "object_path" : "/xyz/abc/def",
1455327988eSTom Joseph                "interface" : "xyz.openbmc.abc.def",
1465327988eSTom Joseph                "property_name" : "Policy",
1475327988eSTom Joseph                "property_type" : "bool",
1485327988eSTom Joseph                "property_values" : [true, false]
1495327988eSTom Joseph           }
1505327988eSTom Joseph       })"_json;
1515327988eSTom Joseph 
1525327988eSTom Joseph     BIOSEnumAttribute enumReadWrite{jsonEnumReadWrite, &dbusHandler};
1535327988eSTom Joseph 
1545327988eSTom Joseph     EXPECT_CALL(dbusHandler,
1555327988eSTom Joseph                 getDbusPropertyVariant(StrEq("/xyz/abc/def"), StrEq("Policy"),
1565327988eSTom Joseph                                        StrEq("xyz.openbmc.abc.def")))
1575327988eSTom Joseph         .WillOnce(Throw(std::exception()));
1585327988eSTom Joseph 
1595327988eSTom Joseph     /* Set expected attr type to read-write */
1605327988eSTom Joseph     expectedAttrEntry[2] = PLDM_BIOS_ENUMERATION;
1615327988eSTom Joseph     expectedAttrValueEntry[2] = PLDM_BIOS_ENUMERATION;
1625327988eSTom Joseph 
1635327988eSTom Joseph     checkConstructEntry(enumReadWrite, biosStringTable, expectedAttrEntry,
1645327988eSTom Joseph                         expectedAttrValueEntry);
1655327988eSTom Joseph 
1665327988eSTom Joseph     EXPECT_CALL(dbusHandler,
1675327988eSTom Joseph                 getDbusPropertyVariant(StrEq("/xyz/abc/def"), StrEq("Policy"),
1685327988eSTom Joseph                                        StrEq("xyz.openbmc.abc.def")))
1695327988eSTom Joseph         .WillOnce(Return(PropertyValue(true)));
1705327988eSTom Joseph 
1715327988eSTom Joseph     expectedAttrValueEntry = {
1725327988eSTom Joseph         0, 0, /* attr handle */
1735327988eSTom Joseph         0,    /* attr type enum read-write*/
1745327988eSTom Joseph         1,    /* number of current value */
1755327988eSTom Joseph         0     /* current value string handle index */
1765327988eSTom Joseph     };
1775327988eSTom Joseph 
1785327988eSTom Joseph     checkConstructEntry(enumReadWrite, biosStringTable, expectedAttrEntry,
1795327988eSTom Joseph                         expectedAttrValueEntry);
1805327988eSTom Joseph }
1815327988eSTom Joseph 
TEST_F(TestBIOSEnumAttribute,setAttrValueOnDbus)1825327988eSTom Joseph TEST_F(TestBIOSEnumAttribute, setAttrValueOnDbus)
1835327988eSTom Joseph {
1845327988eSTom Joseph     MockBIOSStringTable biosStringTable;
1855327988eSTom Joseph     MockdBusHandler dbusHandler;
1865327988eSTom Joseph 
1875327988eSTom Joseph     auto jsonEnumReadWrite = R"({
1885327988eSTom Joseph          "attribute_name" : "CodeUpdatePolicy",
1895327988eSTom Joseph          "possible_values" : [ "Concurrent", "Disruptive" ],
1907927f90cSSagar Srinivas          "value_names" : [ "Concurrent", "Disruptive" ],
1915327988eSTom Joseph          "default_values" : [ "Disruptive" ],
192d6608096SArchana Kakani          "read_only" : false,
193d6608096SArchana Kakani          "help_text" : "HelpText",
194d6608096SArchana Kakani          "display_name" : "DisplayName",
1955327988eSTom Joseph          "dbus":
1965327988eSTom Joseph             {
1975327988eSTom Joseph                "object_path" : "/xyz/abc/def",
1985327988eSTom Joseph                "interface" : "xyz.openbmc.abc.def",
1995327988eSTom Joseph                "property_name" : "Policy",
2005327988eSTom Joseph                "property_type" : "bool",
2015327988eSTom Joseph                "property_values" : [true, false]
2025327988eSTom Joseph           }
2035327988eSTom Joseph       })"_json;
2045327988eSTom Joseph     DBusMapping dbusMapping{"/xyz/abc/def", "xyz.openbmc.abc.def", "Policy",
2055327988eSTom Joseph                             "bool"};
2065327988eSTom Joseph 
2075327988eSTom Joseph     BIOSEnumAttribute enumReadWrite{jsonEnumReadWrite, &dbusHandler};
2085327988eSTom Joseph 
2095327988eSTom Joseph     std::vector<uint8_t> attrEntry{
2105327988eSTom Joseph         0, 0, /* attr handle */
2115327988eSTom Joseph         0,    /* attr type enum read-only*/
2125327988eSTom Joseph         4, 0, /* attr name handle */
2135327988eSTom Joseph         2,    /* number of possible value */
2145327988eSTom Joseph         2, 0, /* possible value handle */
2155327988eSTom Joseph         3, 0, /* possible value handle */
2165327988eSTom Joseph         1,    /* number of default value */
217*2576aecdSManojkiran Eda         1     /* default value string handle index */
2185327988eSTom Joseph     };
2195327988eSTom Joseph 
2205327988eSTom Joseph     ON_CALL(biosStringTable, findString(2))
2215327988eSTom Joseph         .WillByDefault(Return(std::string("Concurrent")));
2225327988eSTom Joseph     ON_CALL(biosStringTable, findString(3))
2235327988eSTom Joseph         .WillByDefault(Return(std::string("Disruptive")));
2245327988eSTom Joseph 
2255327988eSTom Joseph     std::vector<uint8_t> attrValueEntry{
2265327988eSTom Joseph         0, 0, /* attr handle */
2275327988eSTom Joseph         0,    /* attr type enum read-only*/
2285327988eSTom Joseph         1,    /* number of current value */
2295327988eSTom Joseph         0     /* current value string handle index */
2305327988eSTom Joseph     };
2315327988eSTom Joseph 
2325327988eSTom Joseph     EXPECT_CALL(dbusHandler,
2335327988eSTom Joseph                 setDbusProperty(dbusMapping, PropertyValue{bool(true)}))
2345327988eSTom Joseph         .Times(1);
2355327988eSTom Joseph     enumReadWrite.setAttrValueOnDbus(
2365327988eSTom Joseph         reinterpret_cast<pldm_bios_attr_val_table_entry*>(
2375327988eSTom Joseph             attrValueEntry.data()),
2385327988eSTom Joseph         reinterpret_cast<pldm_bios_attr_table_entry*>(attrEntry.data()),
2395327988eSTom Joseph         biosStringTable);
2405327988eSTom Joseph }
241