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" : "ef",
37             "read_only" : true,
38             "help_text" : "HelpText",
39             "display_name" : "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 jsonStringReadWrite = R"({
54             "attribute_name" : "str_example1",
55             "string_type" : "ASCII",
56             "minimum_string_length" : 1,
57             "maximum_string_length" : 100,
58             "default_string" : "abc",
59             "read_only" : false,
60             "help_text" : "HelpText",
61             "display_name" : "DisplayName",
62             "dbus" : {
63                 "object_path" : "/xyz/abc/def",
64                 "interface" : "xyz.openbmc_project.str_example1.value",
65                 "property_name" : "Str_example1",
66                 "property_type" : "string"
67             }
68         })"_json;
69     BIOSStringAttribute stringReadWrite{jsonStringReadWrite, nullptr};
70 
71     EXPECT_EQ(stringReadWrite.name, "str_example1");
72     EXPECT_TRUE(!stringReadWrite.readOnly);
73 }
74 
75 TEST_F(TestBIOSStringAttribute, ConstructEntry)
76 {
77     MockBIOSStringTable biosStringTable;
78     MockdBusHandler dbusHandler;
79 
80     auto jsonStringReadOnly = R"({
81             "attribute_name" : "str_example1",
82             "string_type" : "ASCII",
83             "minimum_string_length" : 1,
84             "maximum_string_length" : 100,
85             "default_string" : "abc",
86             "read_only" : true,
87             "help_text" : "HelpText",
88             "display_name" : "DisplayName"
89         })"_json;
90 
91     std::vector<uint8_t> expectedAttrEntry{
92         0,    0,       /* attr handle */
93         0x81,          /* attr type string read-only */
94         5,    0,       /* attr name handle */
95         1,             /* string type */
96         1,    0,       /* minimum length of the string in bytes */
97         100,  0,       /* maximum length of the string in bytes */
98         3,    0,       /* length of default string in length */
99         'a',  'b', 'c' /* default string  */
100     };
101 
102     std::vector<uint8_t> expectedAttrValueEntry{
103         0,    0,        /* attr handle */
104         0x81,           /* attr type string read-only */
105         3,    0,        /* current string length */
106         'a',  'b', 'c', /* default value string handle index */
107     };
108 
109     ON_CALL(biosStringTable, findHandle(StrEq("str_example1")))
110         .WillByDefault(Return(5));
111     BIOSStringAttribute stringReadOnly{jsonStringReadOnly, nullptr};
112 
113     checkConstructEntry(stringReadOnly, biosStringTable, expectedAttrEntry,
114                         expectedAttrValueEntry);
115 
116     auto jsonStringReadWrite = R"({
117             "attribute_name" : "str_example1",
118             "string_type" : "ASCII",
119             "minimum_string_length" : 1,
120             "maximum_string_length" : 100,
121             "default_string" : "abc",
122             "read_only" : false,
123             "help_text" : "HelpText",
124             "display_name" : "DisplayName",
125             "dbus" : {
126                 "object_path" : "/xyz/abc/def",
127                 "interface" : "xyz.openbmc_project.str_example1.value",
128                 "property_name" : "Str_example1",
129                 "property_type" : "string"
130             }
131         })"_json;
132     BIOSStringAttribute stringReadWrite{jsonStringReadWrite, &dbusHandler};
133 
134     /* Set expected attr type to read-write */
135     expectedAttrEntry[2] = PLDM_BIOS_STRING;
136     expectedAttrValueEntry[2] = PLDM_BIOS_STRING;
137 
138     EXPECT_CALL(
139         dbusHandler,
140         getDbusPropertyVariant(StrEq("/xyz/abc/def"), StrEq("Str_example1"),
141                                StrEq("xyz.openbmc_project.str_example1.value")))
142         .WillOnce(Throw(std::exception()));
143 
144     checkConstructEntry(stringReadWrite, biosStringTable, expectedAttrEntry,
145                         expectedAttrValueEntry);
146 
147     EXPECT_CALL(
148         dbusHandler,
149         getDbusPropertyVariant(StrEq("/xyz/abc/def"), StrEq("Str_example1"),
150                                StrEq("xyz.openbmc_project.str_example1.value")))
151         .WillOnce(Return(PropertyValue(std::string("abcd"))));
152 
153     expectedAttrValueEntry = {
154         0,   0,             /* attr handle */
155         1,                  /* attr type string read-write */
156         4,   0,             /* current string length */
157         'a', 'b', 'c', 'd', /* default value string handle index */
158     };
159 
160     checkConstructEntry(stringReadWrite, biosStringTable, expectedAttrEntry,
161                         expectedAttrValueEntry);
162 }
163 
164 TEST_F(TestBIOSStringAttribute, setAttrValueOnDbus)
165 {
166     auto jsonStringReadWrite = R"({
167             "attribute_name" : "str_example1",
168             "string_type" : "ASCII",
169             "minimum_string_length" : 1,
170             "maximum_string_length" : 100,
171             "default_string" : "abc",
172             "read_only" : false,
173             "help_text" : "HelpText",
174             "display_name" : "DisplayName",
175             "dbus" : {
176                 "object_path" : "/xyz/abc/def",
177                 "interface" : "xyz.openbmc_project.str_example1.value",
178                 "property_name" : "Str_example1",
179                 "property_type" : "string"
180             }
181         })"_json;
182 
183     MockdBusHandler dbusHandler;
184     MockBIOSStringTable biosStringTable;
185 
186     BIOSStringAttribute stringReadWrite{jsonStringReadWrite, &dbusHandler};
187     DBusMapping dbusMapping{"/xyz/abc/def",
188                             "xyz.openbmc_project.str_example1.value",
189                             "Str_example1", "string"};
190     std::vector<uint8_t> attrValueEntry{
191         0,   0,             /* attr handle */
192         1,                  /* attr type string read-write */
193         4,   0,             /* current string length */
194         'a', 'b', 'c', 'd', /* default value string handle index */
195     };
196     auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>(
197         attrValueEntry.data());
198     PropertyValue value = std::string("abcd");
199     EXPECT_CALL(dbusHandler, setDbusProperty(dbusMapping, value)).Times(1);
200     stringReadWrite.setAttrValueOnDbus(entry, nullptr, biosStringTable);
201 }
202