1 #include "common/test/mocked_utils.hpp"
2 #include "libpldmresponder/bios_integer_attribute.hpp"
3 #include "mocked_bios.hpp"
4 
5 #include <nlohmann/json.hpp>
6 
7 #include <memory>
8 
9 #include <gmock/gmock.h>
10 #include <gtest/gtest.h>
11 
12 using ::testing::_;
13 using ::testing::ElementsAreArray;
14 using ::testing::Return;
15 using ::testing::StrEq;
16 using ::testing::Throw;
17 
18 class TestBIOSIntegerAttribute : public ::testing::Test
19 {
20   public:
21     const auto& getIntegerInfo(const BIOSIntegerAttribute& attribute)
22     {
23         return attribute.integerInfo;
24     }
25 };
26 
27 TEST_F(TestBIOSIntegerAttribute, CtorTest)
28 {
29     auto jsonIntegerReadOnly = R"({
30          "attribute_name" : "SBE_IMAGE_MINIMUM_VALID_ECS",
31          "lower_bound" : 1,
32          "upper_bound" : 15,
33          "scalar_increment" : 1,
34          "default_value" : 2,
35          "readOnly" : true,
36          "helpText" : "HelpText",
37          "displayName" : "DisplayName"
38       })"_json;
39 
40     BIOSIntegerAttribute integerReadOnly{jsonIntegerReadOnly, nullptr};
41     EXPECT_EQ(integerReadOnly.name, "SBE_IMAGE_MINIMUM_VALID_ECS");
42     EXPECT_TRUE(integerReadOnly.readOnly);
43     auto& integerInfo = getIntegerInfo(integerReadOnly);
44     EXPECT_EQ(integerInfo.lowerBound, 1);
45     EXPECT_EQ(integerInfo.upperBound, 15);
46     EXPECT_EQ(integerInfo.scalarIncrement, 1);
47     EXPECT_EQ(integerInfo.defaultValue, 2);
48 
49     auto jsonIntegerReadOnlyError = R"({
50          "attribute_name" : "SBE_IMAGE_MINIMUM_VALID_ECS",
51          "lower_bound" : 1,
52          "upper_bound" : 15,
53          "scalar_increment" : 1,
54          "default_valu" : 2,
55          "readOnly" : true,
56          "helpText" : "HelpText",
57          "displayName" : "DisplayName"
58       })"_json; // default_valu -> default_value
59     EXPECT_THROW((BIOSIntegerAttribute{jsonIntegerReadOnlyError, nullptr}),
60                  Json::exception);
61 
62     auto jsonIntegerReadWrite = R"({
63          "attribute_name" : "VDD_AVSBUS_RAIL",
64          "lower_bound" : 0,
65          "upper_bound" : 15,
66          "scalar_increment" : 1,
67          "default_value" : 0,
68          "readOnly" : false,
69          "helpText" : "HelpText",
70          "displayName" : "DisplayName",
71          "dbus":{
72             "object_path" : "/xyz/openbmc_project/avsbus",
73             "interface" : "xyz.openbmc.AvsBus.Manager",
74             "property_type" : "uint8_t",
75             "property_name" : "Rail"
76          }
77       })"_json;
78 
79     BIOSIntegerAttribute integerReadWrite{jsonIntegerReadWrite, nullptr};
80     EXPECT_EQ(integerReadWrite.name, "VDD_AVSBUS_RAIL");
81     EXPECT_TRUE(!integerReadWrite.readOnly);
82 }
83 
84 TEST_F(TestBIOSIntegerAttribute, ConstructEntry)
85 {
86     MockBIOSStringTable biosStringTable;
87     MockdBusHandler dbusHandler;
88 
89     auto jsonIntegerReadOnly = R"({
90          "attribute_name" : "VDD_AVSBUS_RAIL",
91          "lower_bound" : 1,
92          "upper_bound" : 15,
93          "scalar_increment" : 1,
94          "default_value" : 2,
95          "readOnly" : true,
96          "helpText" : "HelpText",
97          "displayName" : "DisplayName"
98       })"_json;
99 
100     std::vector<uint8_t> expectedAttrEntry{
101         0,    0,                   /* attr handle */
102         0x83,                      /* attr type integer read-only*/
103         5,    0,                   /* attr name handle */
104         1,    0, 0, 0, 0, 0, 0, 0, /* lower bound */
105         15,   0, 0, 0, 0, 0, 0, 0, /* upper bound */
106         1,    0, 0, 0,             /* scalar increment */
107         2,    0, 0, 0, 0, 0, 0, 0, /* defaut value */
108     };
109     std::vector<uint8_t> expectedAttrValueEntry{
110         0,    0,                   /* attr handle */
111         0x83,                      /* attr type integer read-only*/
112         2,    0, 0, 0, 0, 0, 0, 0, /* current value */
113     };
114 
115     BIOSIntegerAttribute integerReadOnly{jsonIntegerReadOnly, nullptr};
116 
117     ON_CALL(biosStringTable, findHandle(StrEq("VDD_AVSBUS_RAIL")))
118         .WillByDefault(Return(5));
119 
120     checkConstructEntry(integerReadOnly, biosStringTable, expectedAttrEntry,
121                         expectedAttrValueEntry);
122 
123     auto jsonIntegerReadWrite = R"({
124          "attribute_name" : "VDD_AVSBUS_RAIL",
125          "lower_bound" : 1,
126          "upper_bound" : 15,
127          "scalar_increment" : 1,
128          "default_value" : 2,
129          "readOnly" : false,
130          "helpText" : "HelpText",
131          "displayName" : "DisplayName",
132          "dbus":{
133             "object_path" : "/xyz/openbmc_project/avsbus",
134             "interface" : "xyz.openbmc.AvsBus.Manager",
135             "property_type" : "uint8_t",
136             "property_name" : "Rail"
137          }
138       })"_json;
139     BIOSIntegerAttribute integerReadWrite{jsonIntegerReadWrite, &dbusHandler};
140 
141     EXPECT_CALL(dbusHandler,
142                 getDbusPropertyVariant(StrEq("/xyz/openbmc_project/avsbus"),
143                                        StrEq("Rail"),
144                                        StrEq("xyz.openbmc.AvsBus.Manager")))
145         .WillOnce(Throw(std::exception()));
146 
147     /* Set expected attr type to read-write */
148     expectedAttrEntry[2] = PLDM_BIOS_INTEGER;
149     expectedAttrValueEntry[2] = PLDM_BIOS_INTEGER;
150 
151     checkConstructEntry(integerReadWrite, biosStringTable, expectedAttrEntry,
152                         expectedAttrValueEntry);
153 
154     EXPECT_CALL(dbusHandler,
155                 getDbusPropertyVariant(StrEq("/xyz/openbmc_project/avsbus"),
156                                        StrEq("Rail"),
157                                        StrEq("xyz.openbmc.AvsBus.Manager")))
158         .WillOnce(Return(PropertyValue(uint8_t(7))));
159 
160     expectedAttrValueEntry = {
161         0, 0,                   /* attr handle */
162         3,                      /* attr type integer read-write*/
163         7, 0, 0, 0, 0, 0, 0, 0, /* current value */
164     };
165 
166     checkConstructEntry(integerReadWrite, biosStringTable, expectedAttrEntry,
167                         expectedAttrValueEntry);
168 }
169 
170 TEST_F(TestBIOSIntegerAttribute, setAttrValueOnDbus)
171 {
172     MockdBusHandler dbusHandler;
173     MockBIOSStringTable biosStringTable;
174 
175     auto jsonIntegerReadWrite = R"({
176          "attribute_name" : "VDD_AVSBUS_RAIL",
177          "lower_bound" : 1,
178          "upper_bound" : 15,
179          "scalar_increment" : 1,
180          "default_value" : 2,
181          "readOnly" : false,
182          "helpText" : "HelpText",
183          "displayName" : "DisplayName",
184          "dbus":{
185             "object_path" : "/xyz/openbmc_project/avsbus",
186             "interface" : "xyz.openbmc.AvsBus.Manager",
187             "property_type" : "uint8_t",
188             "property_name" : "Rail"
189          }
190       })"_json;
191     BIOSIntegerAttribute integerReadWrite{jsonIntegerReadWrite, &dbusHandler};
192     DBusMapping dbusMapping{"/xyz/openbmc_project/avsbus",
193                             "xyz.openbmc.AvsBus.Manager", "Rail", "uint8_t"};
194     std::vector<uint8_t> attrValueEntry = {
195         0, 0,                   /* attr handle */
196         3,                      /* attr type integer read-write*/
197         7, 0, 0, 0, 0, 0, 0, 0, /* current value */
198     };
199 
200     auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>(
201         attrValueEntry.data());
202     EXPECT_CALL(dbusHandler,
203                 setDbusProperty(dbusMapping, PropertyValue{uint8_t(7)}))
204         .Times(1);
205     integerReadWrite.setAttrValueOnDbus(entry, nullptr, biosStringTable);
206 }
207