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