blob: 5a49eae86adb0c9cfb3768d18d425b3539a6fc14 [file] [log] [blame]
Andrew Jeffery9c766792022-08-10 23:12:49 +09301#include <endian.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +09302
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05303#include <algorithm>
4#include <cstdint>
Andrew Jeffery9c766792022-08-10 23:12:49 +09305#include <cstring>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05306#include <iterator>
Andrew Jeffery9c766792022-08-10 23:12:49 +09307#include <string>
8#include <utility>
9#include <vector>
10
11#include "libpldm/base.h"
12#include "libpldm/bios.h"
13#include "libpldm/bios_table.h"
14#include "libpldm/utils.h"
15
16#include <gmock/gmock.h>
17#include <gtest/gtest.h>
18
19using testing::ElementsAreArray;
20using Table = std::vector<uint8_t>;
21
22void buildTable(Table& table)
23{
24 auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
25 table.insert(table.end(), padSize, 0);
26 uint32_t checksum = crc32(table.data(), table.size());
27 checksum = htole32(checksum);
28 uint8_t a[4];
29 std::memcpy(a, &checksum, sizeof(checksum));
30 table.insert(table.end(), std::begin(a), std::end(a));
31}
32
33template <typename First, typename... Rest>
34void buildTable(Table& table, First& first, Rest&... rest)
35{
36 table.insert(table.end(), first.begin(), first.end());
37 buildTable(table, rest...);
38}
39
40TEST(AttrTable, HeaderDecodeTest)
41{
42 std::vector<uint8_t> enumEntry{
43 2, 0, /* attr handle */
44 0, /* attr type */
45 1, 0, /* attr name handle (string handle) */
46 2, /* number of possible value */
47 2, 0, /* possible value handle */
48 3, 0, /* possible value handle */
49 1, /* number of default value */
50 0 /* defaut value string handle index */
51 };
52 auto entry =
53 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
54 auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
55 EXPECT_EQ(attrHandle, 2);
56 auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
57 EXPECT_EQ(attrType, 0);
58 auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
59 EXPECT_EQ(stringHandle, 1);
60}
61
62TEST(AttrTable, EnumEntryDecodeTest)
63{
64 std::vector<uint8_t> enumEntry{
65 0, 0, /* attr handle */
66 0, /* attr type */
67 1, 0, /* attr name handle */
68 2, /* number of possible value */
69 2, 0, /* possible value handle */
70 3, 0, /* possible value handle */
71 1, /* number of default value */
72 1 /* defaut value string handle index */
73 };
74
75 auto entry =
76 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093077 uint8_t pvNumber;
78 ASSERT_EQ(
79 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber),
80 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093081 EXPECT_EQ(pvNumber, 2);
82 pvNumber = 0;
83 auto rc =
84 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
85 EXPECT_EQ(rc, PLDM_SUCCESS);
86 EXPECT_EQ(pvNumber, 2);
87
88 std::vector<uint16_t> pvHandles(pvNumber, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093089 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
90 entry, pvHandles.data(), pvHandles.size()),
91 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093092 EXPECT_EQ(pvNumber, 2);
93 EXPECT_EQ(pvHandles[0], 2);
94 EXPECT_EQ(pvHandles[1], 3);
95 pvHandles.resize(1);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093096 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
97 entry, pvHandles.data(), pvHandles.size()),
98 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093099 EXPECT_EQ(pvHandles[0], 2);
100
101 pvHandles.resize(2);
102 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
103 entry, pvHandles.data(), pvHandles.size());
104 EXPECT_EQ(rc, PLDM_SUCCESS);
105 EXPECT_EQ(pvHandles[0], 2);
106 EXPECT_EQ(pvHandles[1], 3);
107 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
108 entry, pvHandles.data(), 1);
Andrew Jeffery0c9f5a82023-06-14 15:01:06 +0930109 EXPECT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930110
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930111 uint8_t defNumber;
112 ASSERT_EQ(
113 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber),
114 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930115 EXPECT_EQ(defNumber, 1);
116 std::vector<uint8_t> defIndices(defNumber);
117 rc = pldm_bios_table_attr_entry_enum_decode_def_indices(
118 entry, defIndices.data(), defIndices.size());
119 EXPECT_EQ(rc, defNumber);
120 EXPECT_THAT(defIndices, ElementsAreArray({1}));
121
122 defNumber = 0;
123 rc =
124 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
125 EXPECT_EQ(rc, PLDM_SUCCESS);
126 EXPECT_EQ(defNumber, 1);
127
128 rc =
129 pldm_bios_table_attr_entry_enum_decode_pv_num_check(nullptr, &pvNumber);
130 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
131 rc = pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, nullptr);
132 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
133
134 entry->attr_type = PLDM_BIOS_STRING;
135 rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
136 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
137
138 rc =
139 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
140 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
141 rc =
142 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(entry, nullptr, 0);
143 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
144}
145
146TEST(AttrTable, EnumEntryEncodeTest)
147{
148 std::vector<uint8_t> enumEntry{
149 0, 0, /* attr handle */
150 0, /* attr type */
151 1, 0, /* attr name handle */
152 2, /* number of possible value */
153 2, 0, /* possible value handle */
154 3, 0, /* possible value handle */
155 1, /* number of default value */
156 0 /* defaut value string handle index */
157 };
158
159 std::vector<uint16_t> pv_hdls{2, 3};
160 std::vector<uint8_t> defs{0};
161
162 struct pldm_bios_table_attr_entry_enum_info info = {
163 1, /* name handle */
164 false, /* read only */
165 2, /* pv number */
166 pv_hdls.data(), /* pv handle */
167 1, /*def number */
168 defs.data() /*def index*/
169 };
170 auto encodeLength = pldm_bios_table_attr_entry_enum_encode_length(2, 1);
171 EXPECT_EQ(encodeLength, enumEntry.size());
172
173 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930174 ASSERT_EQ(pldm_bios_table_attr_entry_enum_encode_check(
175 encodeEntry.data(), encodeEntry.size(), &info),
176 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930177 // set attr handle = 0
178 encodeEntry[0] = 0;
179 encodeEntry[1] = 0;
180
181 EXPECT_EQ(enumEntry, encodeEntry);
182
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930183 EXPECT_NE(pldm_bios_table_attr_entry_enum_encode_check(
184 encodeEntry.data(), encodeEntry.size() - 1, &info),
185 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930186 auto rc = pldm_bios_table_attr_entry_enum_encode_check(
187 encodeEntry.data(), encodeEntry.size(), &info);
188 EXPECT_EQ(rc, PLDM_SUCCESS);
189 // set attr handle = 0
190 encodeEntry[0] = 0;
191 encodeEntry[1] = 0;
192
193 EXPECT_EQ(enumEntry, encodeEntry);
194 rc = pldm_bios_table_attr_entry_enum_encode_check(
195 encodeEntry.data(), encodeEntry.size() - 1, &info);
196 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
197}
198
199TEST(AttrTable, StringEntryDecodeTest)
200{
201 std::vector<uint8_t> stringEntry{
202 1, 0, /* attr handle */
203 1, /* attr type */
204 12, 0, /* attr name handle */
205 1, /* string type */
206 1, 0, /* minimum length of the string in bytes */
207 100, 0, /* maximum length of the string in bytes */
208 3, 0, /* length of default string in length */
209 'a', 'b', 'c' /* default string */
210 };
211
212 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
213 stringEntry.data());
214 auto stringType =
215 pldm_bios_table_attr_entry_string_decode_string_type(entry);
216 EXPECT_EQ(stringType, 1);
217 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
218 EXPECT_EQ(minLength, 1);
219 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
220 EXPECT_EQ(maxLength, 100);
221
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930222 uint16_t defStringLength;
223 ASSERT_EQ(pldm_bios_table_attr_entry_string_decode_def_string_length_check(
224 entry, &defStringLength),
225 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930226 EXPECT_EQ(defStringLength, 3);
227 std::vector<char> defString(defStringLength + 1);
228 auto rc = pldm_bios_table_attr_entry_string_decode_def_string(
229 entry, defString.data(), defString.size());
230 EXPECT_EQ(rc, 3);
231 EXPECT_STREQ(defString.data(), "abc");
232 rc = pldm_bios_table_attr_entry_string_decode_def_string(
233 entry, defString.data(), defString.size() - 1);
234 EXPECT_EQ(rc, 2);
235 EXPECT_STREQ(defString.data(), "ab");
236
237 defStringLength = 0;
238 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
239 entry, &defStringLength);
240 EXPECT_EQ(rc, PLDM_SUCCESS);
241 EXPECT_EQ(defStringLength, 3);
242
243 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
244 entry, nullptr);
245 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
246 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
247 nullptr, &defStringLength);
248 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
249 entry->attr_type = PLDM_BIOS_INTEGER;
250 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
251 entry, &defStringLength);
252 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
253 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
254 nullptr, &defStringLength);
255 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
256}
257
258TEST(AttrTable, StringEntryEncodeTest)
259{
260 std::vector<uint8_t> stringEntry{
261 0, 0, /* attr handle */
262 1, /* attr type */
263 3, 0, /* attr name handle */
264 1, /* string type */
265 1, 0, /* min string length */
266 100, 0, /* max string length */
267 3, 0, /* default string length */
268 'a', 'b', 'c', /* defaul string */
269 };
270
271 struct pldm_bios_table_attr_entry_string_info info = {
272 3, /* name handle */
273 false, /* read only */
274 1, /* string type ascii */
275 1, /* min length */
276 100, /* max length */
277 3, /* def length */
278 "abc", /* def string */
279 };
280 auto encodeLength = pldm_bios_table_attr_entry_string_encode_length(3);
281 EXPECT_EQ(encodeLength, stringEntry.size());
282
283 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930284 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check(
285 encodeEntry.data(), encodeEntry.size(), &info),
286 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930287 // set attr handle = 0
288 encodeEntry[0] = 0;
289 encodeEntry[1] = 0;
290
291 EXPECT_EQ(stringEntry, encodeEntry);
292
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930293 EXPECT_NE(pldm_bios_table_attr_entry_string_encode_check(
294 encodeEntry.data(), encodeEntry.size() - 1, &info),
295 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930296 auto rc = pldm_bios_table_attr_entry_string_encode_check(
297 encodeEntry.data(), encodeEntry.size(), &info);
298 EXPECT_EQ(rc, PLDM_SUCCESS);
299 // set attr handle = 0
300 encodeEntry[0] = 0;
301 encodeEntry[1] = 0;
302
303 EXPECT_EQ(stringEntry, encodeEntry);
304 rc = pldm_bios_table_attr_entry_string_encode_check(
305 encodeEntry.data(), encodeEntry.size() - 1, &info);
306 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
307 std::swap(info.max_length, info.min_length);
308 const char* errmsg;
309 rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
310 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
311 EXPECT_STREQ(
312 "MinimumStingLength should not be greater than MaximumStringLength",
313 errmsg);
314 rc = pldm_bios_table_attr_entry_string_encode_check(
315 encodeEntry.data(), encodeEntry.size(), &info);
316 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
317 std::swap(info.max_length, info.min_length);
318
319 std::vector<uint8_t> stringEntryLength0{
320 0, 0, /* attr handle */
321 1, /* attr type */
322 3, 0, /* attr name handle */
323 1, /* string type */
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930324 0, 0, /* min string length */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930325 100, 0, /* max string length */
326 0, 0, /* default string length */
327 };
328
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930329 info.min_length = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930330 info.def_length = 0;
331 info.def_string = nullptr;
332
333 encodeLength = pldm_bios_table_attr_entry_string_encode_length(0);
334 EXPECT_EQ(encodeLength, stringEntryLength0.size());
335
336 encodeEntry.resize(encodeLength);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930337 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check(
338 encodeEntry.data(), encodeEntry.size(), &info),
339 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930340 // set attr handle = 0
341 encodeEntry[0] = 0;
342 encodeEntry[1] = 0;
343
344 EXPECT_EQ(stringEntryLength0, encodeEntry);
345}
346
347TEST(AttrTable, integerEntryEncodeTest)
348{
349 std::vector<uint8_t> integerEntry{
350 0, 0, /* attr handle */
351 3, /* attr type */
352 1, 0, /* attr name handle */
353 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
354 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
355 2, 0, 0, 0, /* scalar increment */
356 3, 0, 0, 0, 0, 0, 0, 0, /* defaut value */
357 };
358
359 std::vector<uint16_t> pv_hdls{2, 3};
360 std::vector<uint8_t> defs{0};
361
362 struct pldm_bios_table_attr_entry_integer_info info = {
363 1, /* name handle */
364 false, /* read only */
365 1, /* lower bound */
366 10, /* upper bound */
367 2, /* sacalar increment */
368 3 /* default value */
369 };
370 auto encodeLength = pldm_bios_table_attr_entry_integer_encode_length();
371 EXPECT_EQ(encodeLength, integerEntry.size());
372
373 std::vector<uint8_t> encodeEntry(encodeLength, 0);
374 pldm_bios_table_attr_entry_integer_encode(encodeEntry.data(),
375 encodeEntry.size(), &info);
376 // set attr handle = 0
377 encodeEntry[0] = 0;
378 encodeEntry[1] = 0;
379
380 EXPECT_EQ(integerEntry, encodeEntry);
381
382 EXPECT_DEATH(pldm_bios_table_attr_entry_integer_encode(
383 encodeEntry.data(), encodeEntry.size() - 1, &info),
384 "length <= entry_length");
385
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};
586 pldm_bios_table_attr_value_entry_encode_enum(
587 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles);
588 EXPECT_EQ(encodeEntry, enumEntry);
589
590 EXPECT_DEATH(
591 pldm_bios_table_attr_value_entry_encode_enum(
592 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
593 "length <= entry_length");
594
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);
639}
640
641TEST(AttrValTable, stringEntryEncodeTest)
642{
643 std::vector<uint8_t> stringEntry{
644 0, 0, /* attr handle */
645 1, /* attr type */
646 3, 0, /* current string length */
647 'a', 'b', 'c', /* defaut value string handle index */
648 };
649
650 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
651 EXPECT_EQ(length, stringEntry.size());
652 std::vector<uint8_t> encodeEntry(length, 0);
653 pldm_bios_table_attr_value_entry_encode_string(
654 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc");
655 EXPECT_EQ(encodeEntry, stringEntry);
656
657 EXPECT_DEATH(
658 pldm_bios_table_attr_value_entry_encode_string(
659 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
660 "length <= entry_length");
661
662 auto rc = pldm_bios_table_attr_value_entry_encode_string_check(
663 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
664 EXPECT_EQ(rc, PLDM_SUCCESS);
665 EXPECT_EQ(encodeEntry, stringEntry);
666 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
667 stringEntry.data());
668 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
669 rc = pldm_bios_table_attr_value_entry_encode_string_check(
670 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
671 3, "abc");
672 EXPECT_EQ(rc, PLDM_SUCCESS);
673 EXPECT_EQ(encodeEntry, stringEntry);
674 rc = pldm_bios_table_attr_value_entry_encode_string_check(
675 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
676 "abc");
677 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
678 rc = pldm_bios_table_attr_value_entry_encode_string_check(
679 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
680 "abc");
681 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
682}
683
684TEST(AttrValTable, StringEntryDecodeTest)
685{
686 std::vector<uint8_t> stringEntry{
687 0, 0, /* attr handle */
688 1, /* attr type */
689 3, 0, /* current string length */
690 'a', 'b', 'c', /* defaut value string handle index */
691 };
692
693 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
694 stringEntry.data());
695 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
696 EXPECT_EQ(3, length);
697
698 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
699 EXPECT_EQ(0, handle);
700
701 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
702 EXPECT_EQ(stringEntry.size(), entryLength);
703
704 variable_field currentString{};
705 pldm_bios_table_attr_value_entry_string_decode_string(entry,
706 &currentString);
707 EXPECT_THAT(std::vector<uint8_t>(currentString.ptr,
708 currentString.ptr + currentString.length),
709 ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'}));
710}
711
712TEST(AttrValTable, integerEntryEncodeTest)
713{
714 std::vector<uint8_t> integerEntry{
715 0, 0, /* attr handle */
716 3, /* attr type */
717 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
718 };
719
720 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
721 EXPECT_EQ(length, integerEntry.size());
722 std::vector<uint8_t> encodeEntry(length, 0);
723 pldm_bios_table_attr_value_entry_encode_integer(
724 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
725 EXPECT_EQ(encodeEntry, integerEntry);
726
727 EXPECT_DEATH(pldm_bios_table_attr_value_entry_encode_integer(
728 encodeEntry.data(), encodeEntry.size() - 1, 0,
729 PLDM_BIOS_INTEGER, 10),
730 "length <= entry_length");
731
732 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
733 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
734 EXPECT_EQ(rc, PLDM_SUCCESS);
735 EXPECT_EQ(encodeEntry, integerEntry);
736 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
737 integerEntry.data());
738 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
739 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
740 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
741 10);
742 EXPECT_EQ(rc, PLDM_SUCCESS);
743 EXPECT_EQ(encodeEntry, integerEntry);
744
745 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
746 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
747 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
748 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
749 encodeEntry.data(), encodeEntry.size() - 1, 0,
750 PLDM_BIOS_INTEGER_READ_ONLY, 10);
751 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
752}
753
754TEST(AttrValTable, integerEntryDecodeTest)
755{
756 std::vector<uint8_t> integerEntry{
757 0, 0, /* attr handle */
758 3, /* attr type */
759 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
760 };
761
762 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
763 integerEntry.data());
764 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
765 EXPECT_EQ(cv, 10u);
766}
767
768TEST(AttrValTable, IteratorTest)
769{
770 std::vector<uint8_t> enumEntry{
771 0, 0, /* attr handle */
772 0, /* attr type */
773 2, /* number of current value */
774 0, /* current value string handle index */
775 1, /* current value string handle index */
776 };
777 std::vector<uint8_t> stringEntry{
778 0, 0, /* attr handle */
779 1, /* attr type */
780 3, 0, /* current string length */
781 'a', 'b', 'c', /* defaut value string handle index */
782 };
783 std::vector<uint8_t> integerEntry{
784 0, 0, /* attr handle */
785 3, /* attr type */
786 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
787 };
788
789 Table table;
790 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
791
792 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
793 PLDM_BIOS_ATTR_VAL_TABLE);
794 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
795
796 auto p = reinterpret_cast<const uint8_t*>(entry);
797 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
798 ElementsAreArray(enumEntry));
799
800 pldm_bios_table_iter_next(iter);
801 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
802 p = reinterpret_cast<const uint8_t*>(entry);
803 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
804 ElementsAreArray(stringEntry));
805
806 pldm_bios_table_iter_next(iter);
807 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
808 p = reinterpret_cast<const uint8_t*>(entry);
809 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
810 ElementsAreArray(integerEntry));
811
812 pldm_bios_table_iter_next(iter);
813 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
814 p = reinterpret_cast<const uint8_t*>(entry);
815 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
816 ElementsAreArray(enumEntry));
817
818 pldm_bios_table_iter_next(iter);
819 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
820
821 pldm_bios_table_iter_free(iter);
822}
823
824TEST(AttrValTable, FindTest)
825{
826 std::vector<uint8_t> enumEntry{
827 0, 0, /* attr handle */
828 0, /* attr type */
829 2, /* number of current value */
830 0, /* current value string handle index */
831 1, /* current value string handle index */
832 };
833 std::vector<uint8_t> stringEntry{
834 1, 0, /* attr handle */
835 1, /* attr type */
836 3, 0, /* current string length */
837 'a', 'b', 'c', /* defaut value string handle index */
838 };
839 std::vector<uint8_t> integerEntry{
840 2, 0, /* attr handle */
841 3, /* attr type */
842 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
843 };
844
845 Table table;
846 buildTable(table, enumEntry, stringEntry, integerEntry);
847
848 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
849 table.size(), 1);
850 EXPECT_NE(entry, nullptr);
851 auto p = reinterpret_cast<const uint8_t*>(entry);
852 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
853 ElementsAreArray(stringEntry));
854
855 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
856 table.size(), 3);
857 EXPECT_EQ(entry, nullptr);
858
859 auto firstEntry =
860 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
861 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
862 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
863 table.size(), 1),
864 "entry_length != NULL");
865}
866
867TEST(AttrValTable, CopyAndUpdateTest)
868{
869 std::vector<uint8_t> enumEntry{
870 0, 0, /* attr handle */
871 0, /* attr type */
872 2, /* number of current value */
873 0, /* current value string handle index */
874 1, /* current value string handle index */
875 };
876 std::vector<uint8_t> stringEntry{
877 1, 0, /* attr handle */
878 1, /* attr type */
879 3, 0, /* current string length */
880 'a', 'b', 'c', /* defaut value string handle index */
881 };
882 std::vector<uint8_t> integerEntry{
883 2, 0, /* attr handle */
884 3, /* attr type */
885 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
886 };
887
888 Table srcTable;
889 buildTable(srcTable, enumEntry, stringEntry, integerEntry);
890
891 std::vector<uint8_t> stringEntry1{
892 1, 0, /* attr handle */
893 1, /* attr type */
894 3, 0, /* current string length */
895 'd', 'e', 'f', /* defaut value string handle index */
896 };
897
898 Table expectTable;
899 buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
900 Table destTable(expectTable.size() + 10);
901 auto destLength = destTable.size();
902 auto rc = pldm_bios_table_attr_value_copy_and_update(
903 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
904 stringEntry1.data(), stringEntry1.size());
905
906 EXPECT_EQ(rc, PLDM_SUCCESS);
907 EXPECT_EQ(destLength, expectTable.size());
908 destTable.resize(destLength);
909 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
910
911 std::vector<uint8_t> stringEntry2{
912 1, 0, /* attr handle */
913 1, /* attr type */
914 5, 0, /* current string length */
915 'd', 'e', 'f', 'a', 'b', /* defaut value string handle index */
916 };
917 expectTable.resize(0);
918 buildTable(expectTable, enumEntry, stringEntry2, integerEntry);
919 destTable.resize(expectTable.size() + 10);
920 destLength = destTable.size();
921 rc = pldm_bios_table_attr_value_copy_and_update(
922 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
923 stringEntry2.data(), stringEntry2.size());
924 EXPECT_EQ(rc, PLDM_SUCCESS);
925 EXPECT_EQ(destLength, expectTable.size());
926 destTable.resize(destLength);
927 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
928
929 std::vector<uint8_t> stringEntry3{
930 1, 0, /* attr handle */
931 1, /* attr type */
932 1, 0, /* current string length */
933 'd', /* defaut value string handle index */
934 };
935 expectTable.resize(0);
936 buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
937 destTable.resize(expectTable.size() + 10);
938 destLength = destTable.size();
939 rc = pldm_bios_table_attr_value_copy_and_update(
940 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
941 stringEntry3.data(), stringEntry3.size());
942 EXPECT_EQ(rc, PLDM_SUCCESS);
943 EXPECT_EQ(destLength, expectTable.size());
944 destTable.resize(destLength);
945 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
946
947 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer
948 rc = pldm_bios_table_attr_value_copy_and_update(
949 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
950 stringEntry3.data(), stringEntry3.size());
951 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
952 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string
953
954 destTable.resize(expectTable.size() - 1);
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_ERROR_INVALID_LENGTH);
960}
961
962TEST(StringTable, EntryEncodeTest)
963{
964 std::vector<uint8_t> stringEntry{
965 0, 0, /* string handle*/
966 7, 0, /* string length */
967 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
968 };
969
970 const char* str = "Allowed";
971 auto str_length = std::strlen(str);
972 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
973 EXPECT_EQ(encodeLength, stringEntry.size());
974
975 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930976 ASSERT_EQ(pldm_bios_table_string_entry_encode_check(
977 encodeEntry.data(), encodeEntry.size(), str, str_length),
978 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930979 // set string handle = 0
980 encodeEntry[0] = 0;
981 encodeEntry[1] = 0;
982
983 EXPECT_EQ(stringEntry, encodeEntry);
984
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930985 EXPECT_NE(pldm_bios_table_string_entry_encode_check(
986 encodeEntry.data(), encodeEntry.size() - 1, str, str_length),
987 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930988 auto rc = pldm_bios_table_string_entry_encode_check(
989 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
990 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
991}
992
993TEST(StringTable, EntryDecodeTest)
994{
995 std::vector<uint8_t> stringEntry{
996 4, 0, /* string handle*/
997 7, 0, /* string length */
998 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
999 };
1000 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
1001 stringEntry.data());
1002 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1003 EXPECT_EQ(handle, 4);
1004 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
1005 EXPECT_EQ(strLength, 7);
1006
1007 std::vector<char> buffer(strLength + 1, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301008 pldm_bios_table_string_entry_decode_string_check(entry, buffer.data(),
1009 buffer.size());
1010 EXPECT_EQ(strlen(buffer.data()), strLength);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301011 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301012 EXPECT_EQ(pldm_bios_table_string_entry_decode_string_check(
1013 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/),
1014 PLDM_SUCCESS);
1015 EXPECT_EQ(strlen(buffer.data()), 2);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301016 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
1017
1018 auto rc = pldm_bios_table_string_entry_decode_string_check(
1019 entry, buffer.data(), buffer.size());
1020 EXPECT_EQ(rc, PLDM_SUCCESS);
1021 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
1022
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301023 /* Ensure equivalence with the unchecked API */
1024 rc = pldm_bios_table_string_entry_decode_string_check(
1025 entry, buffer.data(), 2 + 1 /* sizeof '\0' */);
1026 EXPECT_EQ(rc, std::strcmp("Al", buffer.data()));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301027}
1028
1029TEST(StringTable, IteratorTest)
1030{
1031 std::vector<uint8_t> stringHello{
1032 0, 0, /* string handle*/
1033 5, 0, /* string length */
1034 'H', 'e', 'l', 'l', 'o', /* string */
1035 };
1036 std::vector<uint8_t> stringWorld{
1037 1, 0, /* string handle*/
1038 6, 0, /* string length */
1039 'W', 'o', 'r', 'l', 'd', '!', /* string */
1040 };
1041
1042 Table table;
1043 buildTable(table, stringHello, stringWorld);
1044
1045 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1046 PLDM_BIOS_STRING_TABLE);
1047 auto entry = pldm_bios_table_iter_string_entry_value(iter);
1048 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
1049 EXPECT_EQ(rc, 0);
1050 pldm_bios_table_iter_next(iter);
1051 entry = pldm_bios_table_iter_string_entry_value(iter);
1052 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
1053 EXPECT_EQ(rc, 0);
1054 pldm_bios_table_iter_next(iter);
1055 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
1056 pldm_bios_table_iter_free(iter);
1057}
1058
1059TEST(StringTable, FindTest)
1060{
1061 std::vector<uint8_t> stringHello{
1062 1, 0, /* string handle*/
1063 5, 0, /* string length */
1064 'H', 'e', 'l', 'l', 'o', /* string */
1065 };
1066 std::vector<uint8_t> stringWorld{
1067 2, 0, /* string handle*/
1068 6, 0, /* string length */
1069 'W', 'o', 'r', 'l', 'd', '!', /* string */
1070 };
1071 std::vector<uint8_t> stringHi{
1072 3, 0, /* string handle*/
1073 2, 0, /* string length */
1074 'H', 'i', /* string */
1075 };
1076
1077 Table table;
1078 buildTable(table, stringHello, stringWorld, stringHi);
1079
1080 auto entry = pldm_bios_table_string_find_by_string(table.data(),
1081 table.size(), "World!");
1082 EXPECT_NE(entry, nullptr);
1083 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1084 EXPECT_EQ(handle, 2);
1085
1086 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
1087 "Worl");
1088 EXPECT_EQ(entry, nullptr);
1089
1090 entry =
1091 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
1092 EXPECT_NE(entry, nullptr);
1093 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
1094 EXPECT_EQ(str_length, 2);
1095 std::vector<char> strBuf(str_length + 1, 0);
1096 auto rc = pldm_bios_table_string_entry_decode_string_check(
1097 entry, strBuf.data(), strBuf.size());
1098 EXPECT_EQ(rc, PLDM_SUCCESS);
1099 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
1100
1101 entry =
1102 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
1103 EXPECT_EQ(entry, nullptr);
1104}
1105
1106TEST(Itearator, DeathTest)
1107{
1108
1109 Table table(256, 0);
1110
1111 /* first entry */
1112 auto attr_entry =
1113 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
1114 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1115 PLDM_BIOS_ATTR_TABLE);
1116 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
1117 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
1118 pldm_bios_table_iter_free(iter);
1119}
1120
1121TEST(PadAndChecksum, PadAndChecksum)
1122{
1123 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0));
1124 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1));
1125 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2));
1126 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3));
1127 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4));
1128
1129 // The table is borrowed from
1130 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
1131 // refer to the commit message
1132 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
1133 auto sizeWithoutPad = attrValTable.size();
1134 attrValTable.resize(sizeWithoutPad +
1135 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
1136 pldm_bios_table_append_pad_checksum(attrValTable.data(),
1137 attrValTable.size(), sizeWithoutPad);
1138 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
1139 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
1140 EXPECT_EQ(attrValTable, expectedTable);
1141}
1142
1143TEST(BIOSTableChecksum, testBIOSTableChecksum)
1144{
1145 std::vector<uint8_t> stringTable{
1146 1, 0, /* string handle*/
1147 5, 0, /* string length */
1148 'T', 'a', 'b', 'l', 'e', /* string */
1149 };
1150
1151 buildTable(stringTable);
1152
1153 EXPECT_EQ(true,
1154 pldm_bios_table_checksum(stringTable.data(), stringTable.size()));
1155}