blob: 4d4b843ccd1a4ed282327b5f16714f01cfffd1bb [file] [log] [blame]
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05001#include "common/bios_utils.hpp"
Tom Joseph53279882021-04-28 06:29:13 -07002#include "common/test/mocked_utils.hpp"
John Wangd9659342020-02-27 16:46:05 +08003#include "libpldmresponder/bios_config.hpp"
4#include "libpldmresponder/bios_string_attribute.hpp"
5#include "mocked_bios.hpp"
John Wangd9659342020-02-27 16:46:05 +08006
George Liu6492f522020-06-16 10:34:05 +08007#include <nlohmann/json.hpp>
8
John Wangd9659342020-02-27 16:46:05 +08009#include <fstream>
10#include <memory>
John Wangd9659342020-02-27 16:46:05 +080011
12#include <gmock/gmock.h>
13#include <gtest/gtest.h>
14
15using namespace pldm::bios::utils;
Brad Bishop5079ac42021-08-19 18:35:06 -040016using namespace pldm::responder::bios;
17using namespace pldm::utils;
John Wangd9659342020-02-27 16:46:05 +080018
19using ::testing::_;
20using ::testing::ElementsAreArray;
21using ::testing::Throw;
22
23class TestBIOSConfig : public ::testing::Test
24{
25 public:
26 static void SetUpTestCase() // will execute once at the begining of all
27 // TestBIOSConfig objects
28 {
29 char tmpdir[] = "/tmp/BIOSTables.XXXXXX";
30 tableDir = fs::path(mkdtemp(tmpdir));
31
32 std::vector<fs::path> paths = {
33 "./bios_jsons/string_attrs.json",
John Wang95e6b3c2020-02-13 09:43:24 +080034 "./bios_jsons/integer_attrs.json",
John Wang3be70852020-02-13 15:59:04 +080035 "./bios_jsons/enum_attrs.json",
John Wangd9659342020-02-27 16:46:05 +080036 };
37
38 for (auto& path : paths)
39 {
40 std::ifstream file;
41 file.open(path);
42 auto j = Json::parse(file);
43 jsons.emplace_back(j);
44 }
45 }
46
47 std::optional<Json> findJsonEntry(const std::string& name)
48 {
49 for (auto& json : jsons)
50 {
51 auto entries = json.at("entries");
52 for (auto& entry : entries)
53 {
54 auto n = entry.at("attribute_name").get<std::string>();
55 if (n == name)
56 {
57 return entry;
58 }
59 }
60 }
61 return std::nullopt;
62 }
63
64 static void TearDownTestCase() // will be executed once at th end of all
65 // TestBIOSConfig objects
66 {
67 fs::remove_all(tableDir);
68 }
69
70 static fs::path tableDir;
71 static std::vector<Json> jsons;
72};
73
74fs::path TestBIOSConfig::tableDir;
75std::vector<Json> TestBIOSConfig::jsons;
76
77TEST_F(TestBIOSConfig, buildTablesTest)
78{
79 MockdBusHandler dbusHandler;
80
81 ON_CALL(dbusHandler, getDbusPropertyVariant(_, _, _))
82 .WillByDefault(Throw(std::exception()));
83
Tom Joseph7f839f92020-09-21 10:20:44 +053084 BIOSConfig biosConfig("./bios_jsons", tableDir.c_str(), &dbusHandler, 0, 0,
Sampa Misrac0c79482021-06-02 08:01:54 -050085 nullptr, nullptr);
John Wangd9659342020-02-27 16:46:05 +080086 biosConfig.buildTables();
87
88 auto stringTable = biosConfig.getBIOSTable(PLDM_BIOS_STRING_TABLE);
89 auto attrTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_TABLE);
90 auto attrValueTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
91
92 EXPECT_TRUE(stringTable);
93 EXPECT_TRUE(attrTable);
94 EXPECT_TRUE(attrValueTable);
95
96 std::set<std::string> expectedStrings = {"HMCManagedState",
97 "On",
98 "Off",
99 "FWBootSide",
100 "Perm",
101 "Temp",
102 "InbandCodeUpdate",
103 "Allowed",
104 "NotAllowed",
105 "CodeUpdatePolicy",
106 "Concurrent",
107 "Disruptive",
108 "VDD_AVSBUS_RAIL",
109 "SBE_IMAGE_MINIMUM_VALID_ECS",
110 "INTEGER_INVALID_CASE",
111 "str_example1",
112 "str_example2",
113 "str_example3"};
114 std::set<std::string> strings;
115 for (auto entry : BIOSTableIter<PLDM_BIOS_STRING_TABLE>(
116 stringTable->data(), stringTable->size()))
117 {
118 auto str = table::string::decodeString(entry);
119 strings.emplace(str);
120 }
121
122 EXPECT_EQ(strings, expectedStrings);
123
124 BIOSStringTable biosStringTable(*stringTable);
125
126 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable->data(),
127 attrTable->size()))
128 {
129 auto header = table::attribute::decodeHeader(entry);
130 auto attrName = biosStringTable.findString(header.stringHandle);
131 auto jsonEntry = findJsonEntry(attrName);
132 EXPECT_TRUE(jsonEntry);
133 switch (header.attrType)
134 {
135 case PLDM_BIOS_STRING:
136 case PLDM_BIOS_STRING_READ_ONLY:
137 {
138 auto stringField = table::attribute::decodeStringEntry(entry);
139 auto stringType = BIOSStringAttribute::strTypeMap.at(
140 jsonEntry->at("string_type").get<std::string>());
141 EXPECT_EQ(stringField.stringType,
142 static_cast<uint8_t>(stringType));
143
144 EXPECT_EQ(
145 stringField.minLength,
146 jsonEntry->at("minimum_string_length").get<uint16_t>());
147 EXPECT_EQ(
148 stringField.maxLength,
149 jsonEntry->at("maximum_string_length").get<uint16_t>());
150 EXPECT_EQ(
151 stringField.defLength,
152 jsonEntry->at("default_string_length").get<uint16_t>());
153 EXPECT_EQ(stringField.defString,
154 jsonEntry->at("default_string").get<std::string>());
155 break;
156 }
John Wang95e6b3c2020-02-13 09:43:24 +0800157 case PLDM_BIOS_INTEGER:
158 case PLDM_BIOS_INTEGER_READ_ONLY:
159 {
160 auto integerField = table::attribute::decodeIntegerEntry(entry);
161 EXPECT_EQ(integerField.lowerBound,
162 jsonEntry->at("lower_bound").get<uint64_t>());
163 EXPECT_EQ(integerField.upperBound,
164 jsonEntry->at("upper_bound").get<uint64_t>());
165 EXPECT_EQ(integerField.scalarIncrement,
166 jsonEntry->at("scalar_increment").get<uint32_t>());
167 EXPECT_EQ(integerField.defaultValue,
168 jsonEntry->at("default_value").get<uint64_t>());
169 break;
170 }
John Wang3be70852020-02-13 15:59:04 +0800171 case PLDM_BIOS_ENUMERATION:
172 case PLDM_BIOS_ENUMERATION_READ_ONLY:
173 {
174 auto [pvHdls, defInds] =
175 table::attribute::decodeEnumEntry(entry);
176 auto possibleValues = jsonEntry->at("possible_values")
177 .get<std::vector<std::string>>();
178 std::vector<std::string> strings;
179 for (auto pv : pvHdls)
180 {
181 auto s = biosStringTable.findString(pv);
182 strings.emplace_back(s);
183 }
184 EXPECT_EQ(strings, possibleValues);
185 EXPECT_EQ(defInds.size(), 1);
186
187 auto defValue = biosStringTable.findString(pvHdls[defInds[0]]);
188 auto defaultValues = jsonEntry->at("default_values")
189 .get<std::vector<std::string>>();
190 EXPECT_EQ(defValue, defaultValues[0]);
191
192 break;
193 }
John Wangd9659342020-02-27 16:46:05 +0800194 default:
195 EXPECT_TRUE(false);
196 break;
197 }
198 }
199
200 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
201 attrValueTable->data(), attrValueTable->size()))
202 {
203 auto header = table::attribute_value::decodeHeader(entry);
204 auto attrEntry =
205 table::attribute::findByHandle(*attrTable, header.attrHandle);
206 auto attrHeader = table::attribute::decodeHeader(attrEntry);
207 auto attrName = biosStringTable.findString(attrHeader.stringHandle);
208 auto jsonEntry = findJsonEntry(attrName);
209 EXPECT_TRUE(jsonEntry);
210 switch (header.attrType)
211 {
212 case PLDM_BIOS_STRING:
213 case PLDM_BIOS_STRING_READ_ONLY:
214 {
215 auto value = table::attribute_value::decodeStringEntry(entry);
216 auto defValue =
217 jsonEntry->at("default_string").get<std::string>();
218 EXPECT_EQ(value, defValue);
219 break;
220 }
John Wang95e6b3c2020-02-13 09:43:24 +0800221 case PLDM_BIOS_INTEGER:
222 case PLDM_BIOS_INTEGER_READ_ONLY:
223 {
224 auto value = table::attribute_value::decodeIntegerEntry(entry);
225 auto defValue = jsonEntry->at("default_value").get<uint64_t>();
226 EXPECT_EQ(value, defValue);
227 break;
228 }
John Wang3be70852020-02-13 15:59:04 +0800229 case PLDM_BIOS_ENUMERATION:
230 case PLDM_BIOS_ENUMERATION_READ_ONLY:
231 {
232 auto indices = table::attribute_value::decodeEnumEntry(entry);
233 EXPECT_EQ(indices.size(), 1);
234 auto possibleValues = jsonEntry->at("possible_values")
235 .get<std::vector<std::string>>();
236
237 auto defValues = jsonEntry->at("default_values")
238 .get<std::vector<std::string>>();
239 EXPECT_EQ(possibleValues[indices[0]], defValues[0]);
240 break;
241 }
John Wangd9659342020-02-27 16:46:05 +0800242 default:
243 EXPECT_TRUE(false);
244 break;
245 }
246 }
247}
248
249TEST_F(TestBIOSConfig, setAttrValue)
250{
251 MockdBusHandler dbusHandler;
252
Tom Joseph7f839f92020-09-21 10:20:44 +0530253 BIOSConfig biosConfig("./bios_jsons", tableDir.c_str(), &dbusHandler, 0, 0,
Sampa Misrac0c79482021-06-02 08:01:54 -0500254 nullptr, nullptr);
John Wangd9659342020-02-27 16:46:05 +0800255 biosConfig.removeTables();
256 biosConfig.buildTables();
257
258 auto stringTable = biosConfig.getBIOSTable(PLDM_BIOS_STRING_TABLE);
259 auto attrTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_TABLE);
260
261 BIOSStringTable biosStringTable(*stringTable);
262 BIOSTableIter<PLDM_BIOS_ATTR_TABLE> attrTableIter(attrTable->data(),
263 attrTable->size());
264 auto stringHandle = biosStringTable.findHandle("str_example1");
265 uint16_t attrHandle{};
266
267 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable->data(),
268 attrTable->size()))
269 {
270 auto header = table::attribute::decodeHeader(entry);
271 if (header.stringHandle == stringHandle)
272 {
273 attrHandle = header.attrHandle;
274 break;
275 }
276 }
277
278 EXPECT_NE(attrHandle, 0);
279
280 std::vector<uint8_t> attrValueEntry{
281 0, 0, /* attr handle */
282 1, /* attr type string read-write */
283 4, 0, /* current string length */
284 'a', 'b', 'c', 'd', /* defaut value string handle index */
285 };
286
287 attrValueEntry[0] = attrHandle & 0xff;
288 attrValueEntry[1] = (attrHandle >> 8) & 0xff;
289
290 DBusMapping dbusMapping{"/xyz/abc/def",
291 "xyz.openbmc_project.str_example1.value",
292 "Str_example1", "string"};
293 PropertyValue value = std::string("abcd");
294 EXPECT_CALL(dbusHandler, setDbusProperty(dbusMapping, value)).Times(1);
295
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600296 auto rc = biosConfig.setAttrValue(attrValueEntry.data(),
297 attrValueEntry.size(), false);
John Wangd9659342020-02-27 16:46:05 +0800298 EXPECT_EQ(rc, PLDM_SUCCESS);
299
300 auto attrValueTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
301 auto findEntry =
302 [&attrValueTable](
303 uint16_t handle) -> const pldm_bios_attr_val_table_entry* {
304 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
305 attrValueTable->data(), attrValueTable->size()))
306 {
307 auto [attrHandle, _] = table::attribute_value::decodeHeader(entry);
308 if (attrHandle == handle)
309 return entry;
310 }
311 return nullptr;
312 };
313
314 auto entry = findEntry(attrHandle);
315 EXPECT_NE(entry, nullptr);
316
317 auto p = reinterpret_cast<const uint8_t*>(entry);
318 EXPECT_THAT(std::vector<uint8_t>(p, p + attrValueEntry.size()),
319 ElementsAreArray(attrValueEntry));
320}