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