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