blob: 54173b6e52d13cb49f24c40f82e91fe76eb1e410 [file] [log] [blame]
Andrew Jeffery9c766792022-08-10 23:12:49 +09301#include <endian.h>
Andrew Jefferyefb40062023-11-10 13:48:39 +10302#include <libpldm/base.h>
3#include <libpldm/bios.h>
4#include <libpldm/bios_table.h>
5#include <libpldm/utils.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +09306
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05307#include <algorithm>
8#include <cstdint>
Andrew Jeffery9c766792022-08-10 23:12:49 +09309#include <cstring>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053010#include <iterator>
Andrew Jeffery9c766792022-08-10 23:12:49 +093011#include <string>
12#include <utility>
13#include <vector>
14
Andrew Jeffery9c766792022-08-10 23:12:49 +093015#include <gmock/gmock.h>
16#include <gtest/gtest.h>
17
18using testing::ElementsAreArray;
19using Table = std::vector<uint8_t>;
20
21void buildTable(Table& table)
22{
23 auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
24 table.insert(table.end(), padSize, 0);
25 uint32_t checksum = crc32(table.data(), table.size());
26 checksum = htole32(checksum);
27 uint8_t a[4];
28 std::memcpy(a, &checksum, sizeof(checksum));
29 table.insert(table.end(), std::begin(a), std::end(a));
30}
31
32template <typename First, typename... Rest>
33void buildTable(Table& table, First& first, Rest&... rest)
34{
35 table.insert(table.end(), first.begin(), first.end());
36 buildTable(table, rest...);
37}
38
39TEST(AttrTable, HeaderDecodeTest)
40{
41 std::vector<uint8_t> enumEntry{
42 2, 0, /* attr handle */
43 0, /* attr type */
44 1, 0, /* attr name handle (string handle) */
45 2, /* number of possible value */
46 2, 0, /* possible value handle */
47 3, 0, /* possible value handle */
48 1, /* number of default value */
49 0 /* defaut value string handle index */
50 };
51 auto entry =
52 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
53 auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
54 EXPECT_EQ(attrHandle, 2);
55 auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
56 EXPECT_EQ(attrType, 0);
57 auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
58 EXPECT_EQ(stringHandle, 1);
59}
60
61TEST(AttrTable, EnumEntryDecodeTest)
62{
63 std::vector<uint8_t> enumEntry{
64 0, 0, /* attr handle */
65 0, /* attr type */
66 1, 0, /* attr name handle */
67 2, /* number of possible value */
68 2, 0, /* possible value handle */
69 3, 0, /* possible value handle */
70 1, /* number of default value */
71 1 /* defaut value string handle index */
72 };
73
74 auto entry =
75 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093076 uint8_t pvNumber;
77 ASSERT_EQ(
78 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber),
79 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093080 EXPECT_EQ(pvNumber, 2);
81 pvNumber = 0;
82 auto rc =
83 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
84 EXPECT_EQ(rc, PLDM_SUCCESS);
85 EXPECT_EQ(pvNumber, 2);
86
87 std::vector<uint16_t> pvHandles(pvNumber, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093088 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
89 entry, pvHandles.data(), pvHandles.size()),
90 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093091 EXPECT_EQ(pvNumber, 2);
92 EXPECT_EQ(pvHandles[0], 2);
93 EXPECT_EQ(pvHandles[1], 3);
94 pvHandles.resize(1);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093095 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
96 entry, pvHandles.data(), pvHandles.size()),
97 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093098 EXPECT_EQ(pvHandles[0], 2);
99
100 pvHandles.resize(2);
101 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
102 entry, pvHandles.data(), pvHandles.size());
103 EXPECT_EQ(rc, PLDM_SUCCESS);
104 EXPECT_EQ(pvHandles[0], 2);
105 EXPECT_EQ(pvHandles[1], 3);
106 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
107 entry, pvHandles.data(), 1);
Andrew Jeffery0c9f5a82023-06-14 15:01:06 +0930108 EXPECT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930109
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930110 uint8_t defNumber;
111 ASSERT_EQ(
112 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber),
113 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930114 EXPECT_EQ(defNumber, 1);
115 std::vector<uint8_t> defIndices(defNumber);
116 rc = pldm_bios_table_attr_entry_enum_decode_def_indices(
117 entry, defIndices.data(), defIndices.size());
118 EXPECT_EQ(rc, defNumber);
119 EXPECT_THAT(defIndices, ElementsAreArray({1}));
120
121 defNumber = 0;
122 rc =
123 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
124 EXPECT_EQ(rc, PLDM_SUCCESS);
125 EXPECT_EQ(defNumber, 1);
126
127 rc =
128 pldm_bios_table_attr_entry_enum_decode_pv_num_check(nullptr, &pvNumber);
129 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
130 rc = pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, nullptr);
131 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
132
133 entry->attr_type = PLDM_BIOS_STRING;
134 rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
135 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
136
137 rc =
138 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
139 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
140 rc =
141 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(entry, nullptr, 0);
142 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
143}
144
145TEST(AttrTable, EnumEntryEncodeTest)
146{
147 std::vector<uint8_t> enumEntry{
148 0, 0, /* attr handle */
149 0, /* attr type */
150 1, 0, /* attr name handle */
151 2, /* number of possible value */
152 2, 0, /* possible value handle */
153 3, 0, /* possible value handle */
154 1, /* number of default value */
155 0 /* defaut value string handle index */
156 };
157
158 std::vector<uint16_t> pv_hdls{2, 3};
159 std::vector<uint8_t> defs{0};
160
161 struct pldm_bios_table_attr_entry_enum_info info = {
162 1, /* name handle */
163 false, /* read only */
164 2, /* pv number */
165 pv_hdls.data(), /* pv handle */
166 1, /*def number */
167 defs.data() /*def index*/
168 };
169 auto encodeLength = pldm_bios_table_attr_entry_enum_encode_length(2, 1);
170 EXPECT_EQ(encodeLength, enumEntry.size());
171
172 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930173 ASSERT_EQ(pldm_bios_table_attr_entry_enum_encode_check(
174 encodeEntry.data(), encodeEntry.size(), &info),
175 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930176 // set attr handle = 0
177 encodeEntry[0] = 0;
178 encodeEntry[1] = 0;
179
180 EXPECT_EQ(enumEntry, encodeEntry);
181
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930182 EXPECT_NE(pldm_bios_table_attr_entry_enum_encode_check(
183 encodeEntry.data(), encodeEntry.size() - 1, &info),
184 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930185 auto rc = pldm_bios_table_attr_entry_enum_encode_check(
186 encodeEntry.data(), encodeEntry.size(), &info);
187 EXPECT_EQ(rc, PLDM_SUCCESS);
188 // set attr handle = 0
189 encodeEntry[0] = 0;
190 encodeEntry[1] = 0;
191
192 EXPECT_EQ(enumEntry, encodeEntry);
193 rc = pldm_bios_table_attr_entry_enum_encode_check(
194 encodeEntry.data(), encodeEntry.size() - 1, &info);
195 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
196}
197
198TEST(AttrTable, StringEntryDecodeTest)
199{
200 std::vector<uint8_t> stringEntry{
201 1, 0, /* attr handle */
202 1, /* attr type */
203 12, 0, /* attr name handle */
204 1, /* string type */
205 1, 0, /* minimum length of the string in bytes */
206 100, 0, /* maximum length of the string in bytes */
207 3, 0, /* length of default string in length */
208 'a', 'b', 'c' /* default string */
209 };
210
211 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
212 stringEntry.data());
213 auto stringType =
214 pldm_bios_table_attr_entry_string_decode_string_type(entry);
215 EXPECT_EQ(stringType, 1);
216 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
217 EXPECT_EQ(minLength, 1);
218 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
219 EXPECT_EQ(maxLength, 100);
220
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930221 uint16_t defStringLength;
222 ASSERT_EQ(pldm_bios_table_attr_entry_string_decode_def_string_length_check(
223 entry, &defStringLength),
224 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930225 EXPECT_EQ(defStringLength, 3);
226 std::vector<char> defString(defStringLength + 1);
227 auto rc = pldm_bios_table_attr_entry_string_decode_def_string(
228 entry, defString.data(), defString.size());
229 EXPECT_EQ(rc, 3);
230 EXPECT_STREQ(defString.data(), "abc");
231 rc = pldm_bios_table_attr_entry_string_decode_def_string(
232 entry, defString.data(), defString.size() - 1);
233 EXPECT_EQ(rc, 2);
234 EXPECT_STREQ(defString.data(), "ab");
235
236 defStringLength = 0;
237 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
238 entry, &defStringLength);
239 EXPECT_EQ(rc, PLDM_SUCCESS);
240 EXPECT_EQ(defStringLength, 3);
241
242 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
243 entry, nullptr);
244 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
245 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
246 nullptr, &defStringLength);
247 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
248 entry->attr_type = PLDM_BIOS_INTEGER;
249 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
250 entry, &defStringLength);
251 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
252 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
253 nullptr, &defStringLength);
254 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
255}
256
257TEST(AttrTable, StringEntryEncodeTest)
258{
259 std::vector<uint8_t> stringEntry{
260 0, 0, /* attr handle */
261 1, /* attr type */
262 3, 0, /* attr name handle */
263 1, /* string type */
264 1, 0, /* min string length */
265 100, 0, /* max string length */
266 3, 0, /* default string length */
267 'a', 'b', 'c', /* defaul string */
268 };
269
270 struct pldm_bios_table_attr_entry_string_info info = {
271 3, /* name handle */
272 false, /* read only */
273 1, /* string type ascii */
274 1, /* min length */
275 100, /* max length */
276 3, /* def length */
277 "abc", /* def string */
278 };
279 auto encodeLength = pldm_bios_table_attr_entry_string_encode_length(3);
280 EXPECT_EQ(encodeLength, stringEntry.size());
281
282 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930283 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check(
284 encodeEntry.data(), encodeEntry.size(), &info),
285 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930286 // set attr handle = 0
287 encodeEntry[0] = 0;
288 encodeEntry[1] = 0;
289
290 EXPECT_EQ(stringEntry, encodeEntry);
291
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930292 EXPECT_NE(pldm_bios_table_attr_entry_string_encode_check(
293 encodeEntry.data(), encodeEntry.size() - 1, &info),
294 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930295 auto rc = pldm_bios_table_attr_entry_string_encode_check(
296 encodeEntry.data(), encodeEntry.size(), &info);
297 EXPECT_EQ(rc, PLDM_SUCCESS);
298 // set attr handle = 0
299 encodeEntry[0] = 0;
300 encodeEntry[1] = 0;
301
302 EXPECT_EQ(stringEntry, encodeEntry);
303 rc = pldm_bios_table_attr_entry_string_encode_check(
304 encodeEntry.data(), encodeEntry.size() - 1, &info);
305 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
306 std::swap(info.max_length, info.min_length);
307 const char* errmsg;
308 rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
309 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
310 EXPECT_STREQ(
311 "MinimumStingLength should not be greater than MaximumStringLength",
312 errmsg);
313 rc = pldm_bios_table_attr_entry_string_encode_check(
314 encodeEntry.data(), encodeEntry.size(), &info);
315 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
316 std::swap(info.max_length, info.min_length);
317
318 std::vector<uint8_t> stringEntryLength0{
319 0, 0, /* attr handle */
320 1, /* attr type */
321 3, 0, /* attr name handle */
322 1, /* string type */
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930323 0, 0, /* min string length */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930324 100, 0, /* max string length */
325 0, 0, /* default string length */
326 };
327
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930328 info.min_length = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930329 info.def_length = 0;
330 info.def_string = nullptr;
331
332 encodeLength = pldm_bios_table_attr_entry_string_encode_length(0);
333 EXPECT_EQ(encodeLength, stringEntryLength0.size());
334
335 encodeEntry.resize(encodeLength);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930336 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check(
337 encodeEntry.data(), encodeEntry.size(), &info),
338 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930339 // set attr handle = 0
340 encodeEntry[0] = 0;
341 encodeEntry[1] = 0;
342
343 EXPECT_EQ(stringEntryLength0, encodeEntry);
344}
345
346TEST(AttrTable, integerEntryEncodeTest)
347{
348 std::vector<uint8_t> integerEntry{
349 0, 0, /* attr handle */
350 3, /* attr type */
351 1, 0, /* attr name handle */
352 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
353 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
354 2, 0, 0, 0, /* scalar increment */
355 3, 0, 0, 0, 0, 0, 0, 0, /* defaut value */
356 };
357
358 std::vector<uint16_t> pv_hdls{2, 3};
359 std::vector<uint8_t> defs{0};
360
361 struct pldm_bios_table_attr_entry_integer_info info = {
362 1, /* name handle */
363 false, /* read only */
364 1, /* lower bound */
365 10, /* upper bound */
366 2, /* sacalar increment */
367 3 /* default value */
368 };
369 auto encodeLength = pldm_bios_table_attr_entry_integer_encode_length();
370 EXPECT_EQ(encodeLength, integerEntry.size());
371
372 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930373 ASSERT_EQ(pldm_bios_table_attr_entry_integer_encode_check(
374 encodeEntry.data(), encodeEntry.size(), &info),
375 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930376 // set attr handle = 0
377 encodeEntry[0] = 0;
378 encodeEntry[1] = 0;
379
380 EXPECT_EQ(integerEntry, encodeEntry);
381
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930382 EXPECT_NE(pldm_bios_table_attr_entry_integer_encode_check(
383 encodeEntry.data(), encodeEntry.size() - 1, &info),
384 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930385
386 auto rc = pldm_bios_table_attr_entry_integer_encode_check(
387 encodeEntry.data(), encodeEntry.size(), &info);
388 EXPECT_EQ(rc, PLDM_SUCCESS);
389 // set attr handle = 0
390 encodeEntry[0] = 0;
391 encodeEntry[1] = 0;
392
393 EXPECT_EQ(integerEntry, encodeEntry);
394
395 rc = pldm_bios_table_attr_entry_integer_encode_check(
396 encodeEntry.data(), encodeEntry.size() - 1, &info);
397 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
398
399 info.lower_bound = 100;
400 info.upper_bound = 50;
401 const char* errmsg;
402 rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
403 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
404 EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg);
405 rc = pldm_bios_table_attr_entry_integer_encode_check(
406 encodeEntry.data(), encodeEntry.size(), &info);
407 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
408}
409
410TEST(AttrTable, integerEntryDecodeTest)
411{
412 std::vector<uint8_t> integerEntry{
413 0, 0, /* attr handle */
414 3, /* attr type */
415 1, 0, /* attr name handle */
416 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
417 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
418 2, 0, 0, 0, /* scalar increment */
419 3, 0, 0, 0, 0, 0, 0, 0, /* defaut value */
420 };
421
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930422 uint64_t lower;
423 uint64_t upper;
424 uint64_t def;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930425 uint32_t scalar;
426 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
427 integerEntry.data());
428 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
429 &def);
430 EXPECT_EQ(lower, 1u);
431 EXPECT_EQ(upper, 10u);
432 EXPECT_EQ(scalar, 2u);
433 EXPECT_EQ(def, 3u);
434}
435
436TEST(AttrTable, ItearatorTest)
437{
438 std::vector<uint8_t> enumEntry{
439 0, 0, /* attr handle */
440 0, /* attr type */
441 1, 0, /* attr name handle */
442 2, /* number of possible value */
443 2, 0, /* possible value handle */
444 3, 0, /* possible value handle */
445 1, /* number of default value */
446 0 /* defaut value string handle index */
447 };
448 std::vector<uint8_t> stringEntry{
449 1, 0, /* attr handle */
450 1, /* attr type */
451 12, 0, /* attr name handle */
452 1, /* string type */
453 1, 0, /* minimum length of the string in bytes */
454 100, 0, /* maximum length of the string in bytes */
455 3, 0, /* length of default string in length */
456 'a', 'b', 'c' /* default string */
457 };
458 std::vector<uint8_t> integerEntry{
459 0, 0, /* attr handle */
460 3, /* attr type */
461 1, 0, /* attr name handle */
462 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
463 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
464 2, 0, 0, 0, /* scalar increment */
465 3, 0, 0, 0, 0, 0, 0, 0, /* defaut value */
466 };
467
468 Table table;
469 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
470 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
471 PLDM_BIOS_ATTR_TABLE);
472 auto entry = pldm_bios_table_iter_attr_entry_value(iter);
473 auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
474 EXPECT_EQ(rc, 0);
475
476 pldm_bios_table_iter_next(iter);
477 entry = pldm_bios_table_iter_attr_entry_value(iter);
478 rc = std::memcmp(entry, stringEntry.data(), stringEntry.size());
479 EXPECT_EQ(rc, 0);
480
481 pldm_bios_table_iter_next(iter);
482 entry = pldm_bios_table_iter_attr_entry_value(iter);
483 rc = std::memcmp(entry, integerEntry.data(), integerEntry.size());
484 EXPECT_EQ(rc, 0);
485
486 pldm_bios_table_iter_next(iter);
487 entry = pldm_bios_table_iter_attr_entry_value(iter);
488 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
489 EXPECT_EQ(rc, 0);
490
491 pldm_bios_table_iter_next(iter);
492 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
493 pldm_bios_table_iter_free(iter);
494}
495
496TEST(AttrTable, FindTest)
497{
498 std::vector<uint8_t> enumEntry{
499 0, 0, /* attr handle */
500 0, /* attr type */
501 1, 0, /* attr name handle */
502 2, /* number of possible value */
503 2, 0, /* possible value handle */
504 3, 0, /* possible value handle */
505 1, /* number of default value */
506 0 /* defaut value string handle index */
507 };
508 std::vector<uint8_t> stringEntry{
509 1, 0, /* attr handle */
510 1, /* attr type */
511 2, 0, /* attr name handle */
512 1, /* string type */
513 1, 0, /* minimum length of the string in bytes */
514 100, 0, /* maximum length of the string in bytes */
515 3, 0, /* length of default string in length */
516 'a', 'b', 'c' /* default string */
517 };
518 std::vector<uint8_t> integerEntry{
519 0, 0, /* attr handle */
520 3, /* attr type */
521 3, 0, /* attr name handle */
522 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
523 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
524 2, 0, 0, 0, /* scalar increment */
525 3, 0, 0, 0, 0, 0, 0, 0, /* defaut value */
526 };
527
528 Table table;
529 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
530
531 auto entry =
532 pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 1);
533 EXPECT_NE(entry, nullptr);
534 auto p = reinterpret_cast<const uint8_t*>(entry);
535 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
536 ElementsAreArray(stringEntry));
537
538 entry = pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 3);
539 EXPECT_EQ(entry, nullptr);
540
541 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
542 table.size(), 2);
543 EXPECT_NE(entry, nullptr);
544 p = reinterpret_cast<const uint8_t*>(entry);
545 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
546 ElementsAreArray(stringEntry));
547
548 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
549 table.size(), 4);
550 EXPECT_EQ(entry, nullptr);
551}
552
553TEST(AttrValTable, HeaderDecodeTest)
554{
555 std::vector<uint8_t> enumEntry{
556 1, 0, /* attr handle */
557 0, /* attr type */
558 2, /* number of current value */
559 0, /* current value string handle index */
560 1, /* current value string handle index */
561 };
562 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
563 enumEntry.data());
564 auto attrHandle =
565 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
566 EXPECT_EQ(attrHandle, 1);
567 auto attrType =
568 pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
569 EXPECT_EQ(attrType, 0);
570}
571
572TEST(AttrValTable, EnumEntryEncodeTest)
573{
574 std::vector<uint8_t> enumEntry{
575 0, 0, /* attr handle */
576 0, /* attr type */
577 2, /* number of current value */
578 0, /* current value string handle index */
579 1, /* current value string handle index */
580 };
581
582 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2);
583 EXPECT_EQ(length, enumEntry.size());
584 std::vector<uint8_t> encodeEntry(length, 0);
585 uint8_t handles[] = {0, 1};
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930586 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_enum_check(
587 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles),
588 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930589 EXPECT_EQ(encodeEntry, enumEntry);
590
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930591 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_enum_check(
592 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
593 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930594
595 auto rc = pldm_bios_table_attr_value_entry_encode_enum_check(
596 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2,
597 handles);
598 EXPECT_EQ(rc, PLDM_SUCCESS);
599 EXPECT_EQ(encodeEntry, enumEntry);
600 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
601 enumEntry.data());
602 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY;
603 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
604 encodeEntry.data(), encodeEntry.size(), 0,
605 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles);
606 EXPECT_EQ(rc, PLDM_SUCCESS);
607 EXPECT_EQ(encodeEntry, enumEntry);
608 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
609 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2,
610 handles);
611 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
612 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
613 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2,
614 handles);
615 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
616}
617
618TEST(AttrValTable, EnumEntryDecodeTest)
619{
620 std::vector<uint8_t> enumEntry{
621 0, 0, /* attr handle */
622 0, /* attr type */
623 2, /* number of current value */
624 0, /* current value string handle index */
625 1, /* current value string handle index */
626 };
627
628 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
629 enumEntry.data());
630 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
631 EXPECT_EQ(2, number);
632
633 std::vector<uint8_t> handles(2, 0);
634 auto rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
635 entry, handles.data(), handles.size());
636 EXPECT_EQ(rc, 2);
637 EXPECT_EQ(handles[0], 0);
638 EXPECT_EQ(handles[1], 1);
Archana Kakanib9d951f2023-10-17 05:47:58 -0500639
640 /* Buffer size is more than the number of current string handles */
641 std::vector<uint8_t> handleIndexes(3, 0);
642 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
643 entry, handleIndexes.data(), handleIndexes.size());
644 EXPECT_EQ(rc, 2);
645 EXPECT_EQ(handleIndexes[0], 0);
646 EXPECT_EQ(handleIndexes[1], 1);
647
648 /* Buffersize is less than the number of current string handles */
649 std::vector<uint8_t> strHandles(1, 0);
650 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
651 entry, strHandles.data(), strHandles.size());
652 EXPECT_EQ(rc, 1);
653 EXPECT_EQ(strHandles[0], 0);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930654}
655
656TEST(AttrValTable, stringEntryEncodeTest)
657{
658 std::vector<uint8_t> stringEntry{
659 0, 0, /* attr handle */
660 1, /* attr type */
661 3, 0, /* current string length */
662 'a', 'b', 'c', /* defaut value string handle index */
663 };
664
665 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
666 EXPECT_EQ(length, stringEntry.size());
667 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery46d07682023-07-14 15:51:51 +0930668 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_string_check(
669 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc"),
670 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930671 EXPECT_EQ(encodeEntry, stringEntry);
672
Andrew Jeffery46d07682023-07-14 15:51:51 +0930673 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_string_check(
674 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
675 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930676
677 auto rc = pldm_bios_table_attr_value_entry_encode_string_check(
678 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
679 EXPECT_EQ(rc, PLDM_SUCCESS);
680 EXPECT_EQ(encodeEntry, stringEntry);
681 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
682 stringEntry.data());
683 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
684 rc = pldm_bios_table_attr_value_entry_encode_string_check(
685 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
686 3, "abc");
687 EXPECT_EQ(rc, PLDM_SUCCESS);
688 EXPECT_EQ(encodeEntry, stringEntry);
689 rc = pldm_bios_table_attr_value_entry_encode_string_check(
690 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
691 "abc");
692 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
693 rc = pldm_bios_table_attr_value_entry_encode_string_check(
694 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
695 "abc");
696 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
697}
698
699TEST(AttrValTable, StringEntryDecodeTest)
700{
701 std::vector<uint8_t> stringEntry{
702 0, 0, /* attr handle */
703 1, /* attr type */
704 3, 0, /* current string length */
705 'a', 'b', 'c', /* defaut value string handle index */
706 };
707
708 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
709 stringEntry.data());
710 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
711 EXPECT_EQ(3, length);
712
713 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
714 EXPECT_EQ(0, handle);
715
716 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
717 EXPECT_EQ(stringEntry.size(), entryLength);
718
719 variable_field currentString{};
720 pldm_bios_table_attr_value_entry_string_decode_string(entry,
721 &currentString);
722 EXPECT_THAT(std::vector<uint8_t>(currentString.ptr,
723 currentString.ptr + currentString.length),
724 ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'}));
725}
726
727TEST(AttrValTable, integerEntryEncodeTest)
728{
729 std::vector<uint8_t> integerEntry{
730 0, 0, /* attr handle */
731 3, /* attr type */
732 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
733 };
734
735 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
736 EXPECT_EQ(length, integerEntry.size());
737 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930738 ASSERT_EQ(
739 pldm_bios_table_attr_value_entry_encode_integer_check(
740 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10),
741 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930742 EXPECT_EQ(encodeEntry, integerEntry);
743
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930744 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_integer_check(
745 encodeEntry.data(), encodeEntry.size() - 1, 0,
746 PLDM_BIOS_INTEGER, 10),
747 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930748
749 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
750 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
751 EXPECT_EQ(rc, PLDM_SUCCESS);
752 EXPECT_EQ(encodeEntry, integerEntry);
753 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
754 integerEntry.data());
755 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
756 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
757 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
758 10);
759 EXPECT_EQ(rc, PLDM_SUCCESS);
760 EXPECT_EQ(encodeEntry, integerEntry);
761
762 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
763 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
764 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
765 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
766 encodeEntry.data(), encodeEntry.size() - 1, 0,
767 PLDM_BIOS_INTEGER_READ_ONLY, 10);
768 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
769}
770
771TEST(AttrValTable, integerEntryDecodeTest)
772{
773 std::vector<uint8_t> integerEntry{
774 0, 0, /* attr handle */
775 3, /* attr type */
776 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
777 };
778
779 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
780 integerEntry.data());
781 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
782 EXPECT_EQ(cv, 10u);
783}
784
785TEST(AttrValTable, IteratorTest)
786{
787 std::vector<uint8_t> enumEntry{
788 0, 0, /* attr handle */
789 0, /* attr type */
790 2, /* number of current value */
791 0, /* current value string handle index */
792 1, /* current value string handle index */
793 };
794 std::vector<uint8_t> stringEntry{
795 0, 0, /* attr handle */
796 1, /* attr type */
797 3, 0, /* current string length */
798 'a', 'b', 'c', /* defaut value string handle index */
799 };
800 std::vector<uint8_t> integerEntry{
801 0, 0, /* attr handle */
802 3, /* attr type */
803 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
804 };
805
806 Table table;
807 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
808
809 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
810 PLDM_BIOS_ATTR_VAL_TABLE);
811 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
812
813 auto p = reinterpret_cast<const uint8_t*>(entry);
814 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
815 ElementsAreArray(enumEntry));
816
817 pldm_bios_table_iter_next(iter);
818 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
819 p = reinterpret_cast<const uint8_t*>(entry);
820 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
821 ElementsAreArray(stringEntry));
822
823 pldm_bios_table_iter_next(iter);
824 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
825 p = reinterpret_cast<const uint8_t*>(entry);
826 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
827 ElementsAreArray(integerEntry));
828
829 pldm_bios_table_iter_next(iter);
830 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
831 p = reinterpret_cast<const uint8_t*>(entry);
832 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
833 ElementsAreArray(enumEntry));
834
835 pldm_bios_table_iter_next(iter);
836 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
837
838 pldm_bios_table_iter_free(iter);
839}
840
841TEST(AttrValTable, FindTest)
842{
843 std::vector<uint8_t> enumEntry{
844 0, 0, /* attr handle */
845 0, /* attr type */
846 2, /* number of current value */
847 0, /* current value string handle index */
848 1, /* current value string handle index */
849 };
850 std::vector<uint8_t> stringEntry{
851 1, 0, /* attr handle */
852 1, /* attr type */
853 3, 0, /* current string length */
854 'a', 'b', 'c', /* defaut value string handle index */
855 };
856 std::vector<uint8_t> integerEntry{
857 2, 0, /* attr handle */
858 3, /* attr type */
859 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
860 };
861
862 Table table;
863 buildTable(table, enumEntry, stringEntry, integerEntry);
864
865 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
866 table.size(), 1);
867 EXPECT_NE(entry, nullptr);
868 auto p = reinterpret_cast<const uint8_t*>(entry);
869 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
870 ElementsAreArray(stringEntry));
871
872 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
873 table.size(), 3);
874 EXPECT_EQ(entry, nullptr);
875
876 auto firstEntry =
877 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
878 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
879 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
880 table.size(), 1),
881 "entry_length != NULL");
882}
883
884TEST(AttrValTable, CopyAndUpdateTest)
885{
886 std::vector<uint8_t> enumEntry{
887 0, 0, /* attr handle */
888 0, /* attr type */
889 2, /* number of current value */
890 0, /* current value string handle index */
891 1, /* current value string handle index */
892 };
893 std::vector<uint8_t> stringEntry{
894 1, 0, /* attr handle */
895 1, /* attr type */
896 3, 0, /* current string length */
897 'a', 'b', 'c', /* defaut value string handle index */
898 };
899 std::vector<uint8_t> integerEntry{
900 2, 0, /* attr handle */
901 3, /* attr type */
902 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
903 };
904
905 Table srcTable;
906 buildTable(srcTable, enumEntry, stringEntry, integerEntry);
907
908 std::vector<uint8_t> stringEntry1{
909 1, 0, /* attr handle */
910 1, /* attr type */
911 3, 0, /* current string length */
912 'd', 'e', 'f', /* defaut value string handle index */
913 };
914
915 Table expectTable;
916 buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
917 Table destTable(expectTable.size() + 10);
918 auto destLength = destTable.size();
919 auto rc = pldm_bios_table_attr_value_copy_and_update(
920 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
921 stringEntry1.data(), stringEntry1.size());
922
923 EXPECT_EQ(rc, PLDM_SUCCESS);
924 EXPECT_EQ(destLength, expectTable.size());
925 destTable.resize(destLength);
926 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
927
928 std::vector<uint8_t> stringEntry2{
929 1, 0, /* attr handle */
930 1, /* attr type */
931 5, 0, /* current string length */
932 'd', 'e', 'f', 'a', 'b', /* defaut value string handle index */
933 };
934 expectTable.resize(0);
935 buildTable(expectTable, enumEntry, stringEntry2, integerEntry);
936 destTable.resize(expectTable.size() + 10);
937 destLength = destTable.size();
938 rc = pldm_bios_table_attr_value_copy_and_update(
939 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
940 stringEntry2.data(), stringEntry2.size());
941 EXPECT_EQ(rc, PLDM_SUCCESS);
942 EXPECT_EQ(destLength, expectTable.size());
943 destTable.resize(destLength);
944 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
945
946 std::vector<uint8_t> stringEntry3{
947 1, 0, /* attr handle */
948 1, /* attr type */
949 1, 0, /* current string length */
950 'd', /* defaut value string handle index */
951 };
952 expectTable.resize(0);
953 buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
954 destTable.resize(expectTable.size() + 10);
955 destLength = destTable.size();
956 rc = pldm_bios_table_attr_value_copy_and_update(
957 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
958 stringEntry3.data(), stringEntry3.size());
959 EXPECT_EQ(rc, PLDM_SUCCESS);
960 EXPECT_EQ(destLength, expectTable.size());
961 destTable.resize(destLength);
962 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
963
964 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer
965 rc = pldm_bios_table_attr_value_copy_and_update(
966 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
967 stringEntry3.data(), stringEntry3.size());
968 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
969 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string
970
971 destTable.resize(expectTable.size() - 1);
972 destLength = destTable.size();
973 rc = pldm_bios_table_attr_value_copy_and_update(
974 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
975 stringEntry3.data(), stringEntry3.size());
976 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
977}
978
979TEST(StringTable, EntryEncodeTest)
980{
981 std::vector<uint8_t> stringEntry{
982 0, 0, /* string handle*/
983 7, 0, /* string length */
984 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
985 };
986
987 const char* str = "Allowed";
988 auto str_length = std::strlen(str);
989 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
990 EXPECT_EQ(encodeLength, stringEntry.size());
991
992 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930993 ASSERT_EQ(pldm_bios_table_string_entry_encode_check(
994 encodeEntry.data(), encodeEntry.size(), str, str_length),
995 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930996 // set string handle = 0
997 encodeEntry[0] = 0;
998 encodeEntry[1] = 0;
999
1000 EXPECT_EQ(stringEntry, encodeEntry);
1001
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301002 EXPECT_NE(pldm_bios_table_string_entry_encode_check(
1003 encodeEntry.data(), encodeEntry.size() - 1, str, str_length),
1004 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301005 auto rc = pldm_bios_table_string_entry_encode_check(
1006 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
1007 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1008}
1009
1010TEST(StringTable, EntryDecodeTest)
1011{
1012 std::vector<uint8_t> stringEntry{
1013 4, 0, /* string handle*/
1014 7, 0, /* string length */
1015 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
1016 };
1017 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
1018 stringEntry.data());
1019 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1020 EXPECT_EQ(handle, 4);
1021 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
1022 EXPECT_EQ(strLength, 7);
1023
1024 std::vector<char> buffer(strLength + 1, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301025 pldm_bios_table_string_entry_decode_string_check(entry, buffer.data(),
1026 buffer.size());
1027 EXPECT_EQ(strlen(buffer.data()), strLength);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301028 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301029 EXPECT_EQ(pldm_bios_table_string_entry_decode_string_check(
1030 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/),
1031 PLDM_SUCCESS);
1032 EXPECT_EQ(strlen(buffer.data()), 2);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301033 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
1034
1035 auto rc = pldm_bios_table_string_entry_decode_string_check(
1036 entry, buffer.data(), buffer.size());
1037 EXPECT_EQ(rc, PLDM_SUCCESS);
1038 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
1039
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301040 /* Ensure equivalence with the unchecked API */
1041 rc = pldm_bios_table_string_entry_decode_string_check(
1042 entry, buffer.data(), 2 + 1 /* sizeof '\0' */);
1043 EXPECT_EQ(rc, std::strcmp("Al", buffer.data()));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301044}
1045
1046TEST(StringTable, IteratorTest)
1047{
1048 std::vector<uint8_t> stringHello{
1049 0, 0, /* string handle*/
1050 5, 0, /* string length */
1051 'H', 'e', 'l', 'l', 'o', /* string */
1052 };
1053 std::vector<uint8_t> stringWorld{
1054 1, 0, /* string handle*/
1055 6, 0, /* string length */
1056 'W', 'o', 'r', 'l', 'd', '!', /* string */
1057 };
1058
1059 Table table;
1060 buildTable(table, stringHello, stringWorld);
1061
1062 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1063 PLDM_BIOS_STRING_TABLE);
1064 auto entry = pldm_bios_table_iter_string_entry_value(iter);
1065 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
1066 EXPECT_EQ(rc, 0);
1067 pldm_bios_table_iter_next(iter);
1068 entry = pldm_bios_table_iter_string_entry_value(iter);
1069 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
1070 EXPECT_EQ(rc, 0);
1071 pldm_bios_table_iter_next(iter);
1072 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
1073 pldm_bios_table_iter_free(iter);
1074}
1075
1076TEST(StringTable, FindTest)
1077{
1078 std::vector<uint8_t> stringHello{
1079 1, 0, /* string handle*/
1080 5, 0, /* string length */
1081 'H', 'e', 'l', 'l', 'o', /* string */
1082 };
1083 std::vector<uint8_t> stringWorld{
1084 2, 0, /* string handle*/
1085 6, 0, /* string length */
1086 'W', 'o', 'r', 'l', 'd', '!', /* string */
1087 };
1088 std::vector<uint8_t> stringHi{
1089 3, 0, /* string handle*/
1090 2, 0, /* string length */
1091 'H', 'i', /* string */
1092 };
1093
1094 Table table;
1095 buildTable(table, stringHello, stringWorld, stringHi);
1096
1097 auto entry = pldm_bios_table_string_find_by_string(table.data(),
1098 table.size(), "World!");
1099 EXPECT_NE(entry, nullptr);
1100 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1101 EXPECT_EQ(handle, 2);
1102
1103 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
1104 "Worl");
1105 EXPECT_EQ(entry, nullptr);
1106
1107 entry =
1108 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
1109 EXPECT_NE(entry, nullptr);
1110 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
1111 EXPECT_EQ(str_length, 2);
1112 std::vector<char> strBuf(str_length + 1, 0);
1113 auto rc = pldm_bios_table_string_entry_decode_string_check(
1114 entry, strBuf.data(), strBuf.size());
1115 EXPECT_EQ(rc, PLDM_SUCCESS);
1116 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
1117
1118 entry =
1119 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
1120 EXPECT_EQ(entry, nullptr);
1121}
1122
Andrew Jefferybf6699b2023-07-05 16:27:59 +09301123TEST(Iterator, DeathTest)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301124{
1125
1126 Table table(256, 0);
1127
1128 /* first entry */
1129 auto attr_entry =
1130 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
1131 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1132 PLDM_BIOS_ATTR_TABLE);
1133 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
1134 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
1135 pldm_bios_table_iter_free(iter);
1136}
1137
1138TEST(PadAndChecksum, PadAndChecksum)
1139{
1140 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0));
1141 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1));
1142 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2));
1143 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3));
1144 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4));
1145
1146 // The table is borrowed from
1147 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
1148 // refer to the commit message
1149 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
1150 auto sizeWithoutPad = attrValTable.size();
1151 attrValTable.resize(sizeWithoutPad +
1152 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
Andrew Jeffery50dd1592023-07-14 16:02:05 +09301153 ASSERT_EQ(pldm_bios_table_append_pad_checksum_check(
1154 attrValTable.data(), attrValTable.size(), &sizeWithoutPad),
1155 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301156 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
1157 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
1158 EXPECT_EQ(attrValTable, expectedTable);
1159}
1160
1161TEST(BIOSTableChecksum, testBIOSTableChecksum)
1162{
1163 std::vector<uint8_t> stringTable{
1164 1, 0, /* string handle*/
1165 5, 0, /* string length */
1166 'T', 'a', 'b', 'l', 'e', /* string */
1167 };
1168
1169 buildTable(stringTable);
1170
1171 EXPECT_EQ(true,
1172 pldm_bios_table_checksum(stringTable.data(), stringTable.size()));
1173}