1 #include "common/test/mocked_utils.hpp"
2 #include "libpldmresponder/bios_string_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::responder::bios;
13 using ::testing::_;
14 using ::testing::ElementsAreArray;
15 using ::testing::Return;
16 using ::testing::StrEq;
17 using ::testing::Throw;
18 
19 class TestBIOSStringAttribute : public ::testing::Test
20 {
21   public:
22     const auto& getStringInfo(const BIOSStringAttribute& biosStringAttribute)
23     {
24         return biosStringAttribute.stringInfo;
25     }
26 };
27 
28 TEST_F(TestBIOSStringAttribute, CtorTest)
29 {
30     auto jsonStringReadOnly = R"(  {
31             "attribute_name" : "str_example3",
32             "string_type" : "ASCII",
33             "minimum_string_length" : 1,
34             "maximum_string_length" : 100,
35             "default_string_length" : 2,
36             "default_string" : "ef",
37             "readOnly" : true,
38             "helpText" : "HelpText",
39             "displayName" : "DisplayName"
40         })"_json;
41     BIOSStringAttribute stringReadOnly{jsonStringReadOnly, nullptr};
42     EXPECT_EQ(stringReadOnly.name, "str_example3");
43     EXPECT_TRUE(stringReadOnly.readOnly);
44 
45     auto& stringInfo = getStringInfo(stringReadOnly);
46     EXPECT_EQ(stringInfo.stringType,
47               static_cast<uint8_t>(BIOSStringAttribute::Encoding::ASCII));
48     EXPECT_EQ(stringInfo.minLength, 1);
49     EXPECT_EQ(stringInfo.maxLength, 100);
50     EXPECT_EQ(stringInfo.defLength, 2);
51     EXPECT_EQ(stringInfo.defString, "ef");
52 
53     auto jsonStringReadOnlyError = R"(  {
54             "attribute_name" : "str_example3",
55             "string_type" : "ASCII",
56             "minimum_string_length" : 1,
57             "maximum_string_length" : 100,
58             "default_string" : "ef",
59             "helpText" : "HelpText",
60             "displayName" : "DisplayName"
61         })"_json; // missing default_string_length
62 
63     EXPECT_THROW((BIOSStringAttribute{jsonStringReadOnlyError, nullptr}),
64                  Json::exception);
65 
66     auto jsonStringReadWrite = R"({
67             "attribute_name" : "str_example1",
68             "string_type" : "ASCII",
69             "minimum_string_length" : 1,
70             "maximum_string_length" : 100,
71             "default_string_length" : 3,
72             "default_string" : "abc",
73             "readOnly" : false,
74             "helpText" : "HelpText",
75             "displayName" : "DisplayName",
76             "dbus" : {
77                 "object_path" : "/xyz/abc/def",
78                 "interface" : "xyz.openbmc_project.str_example1.value",
79                 "property_name" : "Str_example1",
80                 "property_type" : "string"
81             }
82         })"_json;
83     BIOSStringAttribute stringReadWrite{jsonStringReadWrite, nullptr};
84 
85     EXPECT_EQ(stringReadWrite.name, "str_example1");
86     EXPECT_TRUE(!stringReadWrite.readOnly);
87 }
88 
89 TEST_F(TestBIOSStringAttribute, ConstructEntry)
90 {
91     MockBIOSStringTable biosStringTable;
92     MockdBusHandler dbusHandler;
93 
94     auto jsonStringReadOnly = R"({
95             "attribute_name" : "str_example1",
96             "string_type" : "ASCII",
97             "minimum_string_length" : 1,
98             "maximum_string_length" : 100,
99             "default_string_length" : 3,
100             "default_string" : "abc",
101             "readOnly" : true,
102             "helpText" : "HelpText",
103             "displayName" : "DisplayName"
104         })"_json;
105 
106     std::vector<uint8_t> expectedAttrEntry{
107         0,    0,       /* attr handle */
108         0x81,          /* attr type string read-only */
109         5,    0,       /* attr name handle */
110         1,             /* string type */
111         1,    0,       /* minimum length of the string in bytes */
112         100,  0,       /* maximum length of the string in bytes */
113         3,    0,       /* length of default string in length */
114         'a',  'b', 'c' /* default string  */
115     };
116 
117     std::vector<uint8_t> expectedAttrValueEntry{
118         0,    0,        /* attr handle */
119         0x81,           /* attr type string read-only */
120         3,    0,        /* current string length */
121         'a',  'b', 'c', /* defaut value string handle index */
122     };
123 
124     ON_CALL(biosStringTable, findHandle(StrEq("str_example1")))
125         .WillByDefault(Return(5));
126     BIOSStringAttribute stringReadOnly{jsonStringReadOnly, nullptr};
127 
128     checkConstructEntry(stringReadOnly, biosStringTable, expectedAttrEntry,
129                         expectedAttrValueEntry);
130 
131     auto jsonStringReadWrite = R"({
132             "attribute_name" : "str_example1",
133             "string_type" : "ASCII",
134             "minimum_string_length" : 1,
135             "maximum_string_length" : 100,
136             "default_string_length" : 3,
137             "default_string" : "abc",
138             "readOnly" : false,
139             "helpText" : "HelpText",
140             "displayName" : "DisplayName",
141             "dbus" : {
142                 "object_path" : "/xyz/abc/def",
143                 "interface" : "xyz.openbmc_project.str_example1.value",
144                 "property_name" : "Str_example1",
145                 "property_type" : "string"
146             }
147         })"_json;
148     BIOSStringAttribute stringReadWrite{jsonStringReadWrite, &dbusHandler};
149 
150     /* Set expected attr type to read-write */
151     expectedAttrEntry[2] = PLDM_BIOS_STRING;
152     expectedAttrValueEntry[2] = PLDM_BIOS_STRING;
153 
154     EXPECT_CALL(
155         dbusHandler,
156         getDbusPropertyVariant(StrEq("/xyz/abc/def"), StrEq("Str_example1"),
157                                StrEq("xyz.openbmc_project.str_example1.value")))
158         .WillOnce(Throw(std::exception()));
159 
160     checkConstructEntry(stringReadWrite, biosStringTable, expectedAttrEntry,
161                         expectedAttrValueEntry);
162 
163     EXPECT_CALL(
164         dbusHandler,
165         getDbusPropertyVariant(StrEq("/xyz/abc/def"), StrEq("Str_example1"),
166                                StrEq("xyz.openbmc_project.str_example1.value")))
167         .WillOnce(Return(PropertyValue(std::string("abcd"))));
168 
169     expectedAttrValueEntry = {
170         0,   0,             /* attr handle */
171         1,                  /* attr type string read-write */
172         4,   0,             /* current string length */
173         'a', 'b', 'c', 'd', /* defaut value string handle index */
174     };
175 
176     checkConstructEntry(stringReadWrite, biosStringTable, expectedAttrEntry,
177                         expectedAttrValueEntry);
178 }
179 
180 TEST_F(TestBIOSStringAttribute, setAttrValueOnDbus)
181 {
182     auto jsonStringReadWrite = R"({
183             "attribute_name" : "str_example1",
184             "string_type" : "ASCII",
185             "minimum_string_length" : 1,
186             "maximum_string_length" : 100,
187             "default_string_length" : 3,
188             "default_string" : "abc",
189             "readOnly" : false,
190             "helpText" : "HelpText",
191             "displayName" : "DisplayName",
192             "dbus" : {
193                 "object_path" : "/xyz/abc/def",
194                 "interface" : "xyz.openbmc_project.str_example1.value",
195                 "property_name" : "Str_example1",
196                 "property_type" : "string"
197             }
198         })"_json;
199 
200     MockdBusHandler dbusHandler;
201     MockBIOSStringTable biosStringTable;
202 
203     BIOSStringAttribute stringReadWrite{jsonStringReadWrite, &dbusHandler};
204     DBusMapping dbusMapping{"/xyz/abc/def",
205                             "xyz.openbmc_project.str_example1.value",
206                             "Str_example1", "string"};
207     std::vector<uint8_t> attrValueEntry{
208         0,   0,             /* attr handle */
209         1,                  /* attr type string read-write */
210         4,   0,             /* current string length */
211         'a', 'b', 'c', 'd', /* defaut value string handle index */
212     };
213     auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>(
214         attrValueEntry.data());
215     PropertyValue value = std::string("abcd");
216     EXPECT_CALL(dbusHandler, setDbusProperty(dbusMapping, value)).Times(1);
217     stringReadWrite.setAttrValueOnDbus(entry, nullptr, biosStringTable);
218 }
219