blob: 974ed1918b0f5513eac7aaac363a385175cca24a [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);
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930374 ASSERT_EQ(pldm_bios_table_attr_entry_integer_encode_check(
375 encodeEntry.data(), encodeEntry.size(), &info),
376 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930377 // set attr handle = 0
378 encodeEntry[0] = 0;
379 encodeEntry[1] = 0;
380
381 EXPECT_EQ(integerEntry, encodeEntry);
382
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930383 EXPECT_NE(pldm_bios_table_attr_entry_integer_encode_check(
384 encodeEntry.data(), encodeEntry.size() - 1, &info),
385 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930386
387 auto rc = pldm_bios_table_attr_entry_integer_encode_check(
388 encodeEntry.data(), encodeEntry.size(), &info);
389 EXPECT_EQ(rc, PLDM_SUCCESS);
390 // set attr handle = 0
391 encodeEntry[0] = 0;
392 encodeEntry[1] = 0;
393
394 EXPECT_EQ(integerEntry, encodeEntry);
395
396 rc = pldm_bios_table_attr_entry_integer_encode_check(
397 encodeEntry.data(), encodeEntry.size() - 1, &info);
398 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
399
400 info.lower_bound = 100;
401 info.upper_bound = 50;
402 const char* errmsg;
403 rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
404 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
405 EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg);
406 rc = pldm_bios_table_attr_entry_integer_encode_check(
407 encodeEntry.data(), encodeEntry.size(), &info);
408 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
409}
410
411TEST(AttrTable, integerEntryDecodeTest)
412{
413 std::vector<uint8_t> integerEntry{
414 0, 0, /* attr handle */
415 3, /* attr type */
416 1, 0, /* attr name handle */
417 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
418 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
419 2, 0, 0, 0, /* scalar increment */
420 3, 0, 0, 0, 0, 0, 0, 0, /* defaut value */
421 };
422
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930423 uint64_t lower;
424 uint64_t upper;
425 uint64_t def;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930426 uint32_t scalar;
427 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
428 integerEntry.data());
429 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
430 &def);
431 EXPECT_EQ(lower, 1u);
432 EXPECT_EQ(upper, 10u);
433 EXPECT_EQ(scalar, 2u);
434 EXPECT_EQ(def, 3u);
435}
436
437TEST(AttrTable, ItearatorTest)
438{
439 std::vector<uint8_t> enumEntry{
440 0, 0, /* attr handle */
441 0, /* attr type */
442 1, 0, /* attr name handle */
443 2, /* number of possible value */
444 2, 0, /* possible value handle */
445 3, 0, /* possible value handle */
446 1, /* number of default value */
447 0 /* defaut value string handle index */
448 };
449 std::vector<uint8_t> stringEntry{
450 1, 0, /* attr handle */
451 1, /* attr type */
452 12, 0, /* attr name handle */
453 1, /* string type */
454 1, 0, /* minimum length of the string in bytes */
455 100, 0, /* maximum length of the string in bytes */
456 3, 0, /* length of default string in length */
457 'a', 'b', 'c' /* default string */
458 };
459 std::vector<uint8_t> integerEntry{
460 0, 0, /* attr handle */
461 3, /* attr type */
462 1, 0, /* attr name handle */
463 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
464 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
465 2, 0, 0, 0, /* scalar increment */
466 3, 0, 0, 0, 0, 0, 0, 0, /* defaut value */
467 };
468
469 Table table;
470 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
471 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
472 PLDM_BIOS_ATTR_TABLE);
473 auto entry = pldm_bios_table_iter_attr_entry_value(iter);
474 auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
475 EXPECT_EQ(rc, 0);
476
477 pldm_bios_table_iter_next(iter);
478 entry = pldm_bios_table_iter_attr_entry_value(iter);
479 rc = std::memcmp(entry, stringEntry.data(), stringEntry.size());
480 EXPECT_EQ(rc, 0);
481
482 pldm_bios_table_iter_next(iter);
483 entry = pldm_bios_table_iter_attr_entry_value(iter);
484 rc = std::memcmp(entry, integerEntry.data(), integerEntry.size());
485 EXPECT_EQ(rc, 0);
486
487 pldm_bios_table_iter_next(iter);
488 entry = pldm_bios_table_iter_attr_entry_value(iter);
489 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
490 EXPECT_EQ(rc, 0);
491
492 pldm_bios_table_iter_next(iter);
493 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
494 pldm_bios_table_iter_free(iter);
495}
496
497TEST(AttrTable, FindTest)
498{
499 std::vector<uint8_t> enumEntry{
500 0, 0, /* attr handle */
501 0, /* attr type */
502 1, 0, /* attr name handle */
503 2, /* number of possible value */
504 2, 0, /* possible value handle */
505 3, 0, /* possible value handle */
506 1, /* number of default value */
507 0 /* defaut value string handle index */
508 };
509 std::vector<uint8_t> stringEntry{
510 1, 0, /* attr handle */
511 1, /* attr type */
512 2, 0, /* attr name handle */
513 1, /* string type */
514 1, 0, /* minimum length of the string in bytes */
515 100, 0, /* maximum length of the string in bytes */
516 3, 0, /* length of default string in length */
517 'a', 'b', 'c' /* default string */
518 };
519 std::vector<uint8_t> integerEntry{
520 0, 0, /* attr handle */
521 3, /* attr type */
522 3, 0, /* attr name handle */
523 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
524 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
525 2, 0, 0, 0, /* scalar increment */
526 3, 0, 0, 0, 0, 0, 0, 0, /* defaut value */
527 };
528
529 Table table;
530 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
531
532 auto entry =
533 pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 1);
534 EXPECT_NE(entry, nullptr);
535 auto p = reinterpret_cast<const uint8_t*>(entry);
536 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
537 ElementsAreArray(stringEntry));
538
539 entry = pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 3);
540 EXPECT_EQ(entry, nullptr);
541
542 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
543 table.size(), 2);
544 EXPECT_NE(entry, nullptr);
545 p = reinterpret_cast<const uint8_t*>(entry);
546 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
547 ElementsAreArray(stringEntry));
548
549 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
550 table.size(), 4);
551 EXPECT_EQ(entry, nullptr);
552}
553
554TEST(AttrValTable, HeaderDecodeTest)
555{
556 std::vector<uint8_t> enumEntry{
557 1, 0, /* attr handle */
558 0, /* attr type */
559 2, /* number of current value */
560 0, /* current value string handle index */
561 1, /* current value string handle index */
562 };
563 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
564 enumEntry.data());
565 auto attrHandle =
566 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
567 EXPECT_EQ(attrHandle, 1);
568 auto attrType =
569 pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
570 EXPECT_EQ(attrType, 0);
571}
572
573TEST(AttrValTable, EnumEntryEncodeTest)
574{
575 std::vector<uint8_t> enumEntry{
576 0, 0, /* attr handle */
577 0, /* attr type */
578 2, /* number of current value */
579 0, /* current value string handle index */
580 1, /* current value string handle index */
581 };
582
583 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2);
584 EXPECT_EQ(length, enumEntry.size());
585 std::vector<uint8_t> encodeEntry(length, 0);
586 uint8_t handles[] = {0, 1};
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930587 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_enum_check(
588 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles),
589 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930590 EXPECT_EQ(encodeEntry, enumEntry);
591
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930592 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_enum_check(
593 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
594 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930595
596 auto rc = pldm_bios_table_attr_value_entry_encode_enum_check(
597 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2,
598 handles);
599 EXPECT_EQ(rc, PLDM_SUCCESS);
600 EXPECT_EQ(encodeEntry, enumEntry);
601 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
602 enumEntry.data());
603 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY;
604 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
605 encodeEntry.data(), encodeEntry.size(), 0,
606 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles);
607 EXPECT_EQ(rc, PLDM_SUCCESS);
608 EXPECT_EQ(encodeEntry, enumEntry);
609 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
610 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2,
611 handles);
612 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
613 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
614 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2,
615 handles);
616 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
617}
618
619TEST(AttrValTable, EnumEntryDecodeTest)
620{
621 std::vector<uint8_t> enumEntry{
622 0, 0, /* attr handle */
623 0, /* attr type */
624 2, /* number of current value */
625 0, /* current value string handle index */
626 1, /* current value string handle index */
627 };
628
629 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
630 enumEntry.data());
631 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
632 EXPECT_EQ(2, number);
633
634 std::vector<uint8_t> handles(2, 0);
635 auto rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
636 entry, handles.data(), handles.size());
637 EXPECT_EQ(rc, 2);
638 EXPECT_EQ(handles[0], 0);
639 EXPECT_EQ(handles[1], 1);
640}
641
642TEST(AttrValTable, stringEntryEncodeTest)
643{
644 std::vector<uint8_t> stringEntry{
645 0, 0, /* attr handle */
646 1, /* attr type */
647 3, 0, /* current string length */
648 'a', 'b', 'c', /* defaut value string handle index */
649 };
650
651 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
652 EXPECT_EQ(length, stringEntry.size());
653 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery46d07682023-07-14 15:51:51 +0930654 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_string_check(
655 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc"),
656 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930657 EXPECT_EQ(encodeEntry, stringEntry);
658
Andrew Jeffery46d07682023-07-14 15:51:51 +0930659 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_string_check(
660 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
661 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930662
663 auto rc = pldm_bios_table_attr_value_entry_encode_string_check(
664 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
665 EXPECT_EQ(rc, PLDM_SUCCESS);
666 EXPECT_EQ(encodeEntry, stringEntry);
667 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
668 stringEntry.data());
669 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
670 rc = pldm_bios_table_attr_value_entry_encode_string_check(
671 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
672 3, "abc");
673 EXPECT_EQ(rc, PLDM_SUCCESS);
674 EXPECT_EQ(encodeEntry, stringEntry);
675 rc = pldm_bios_table_attr_value_entry_encode_string_check(
676 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
677 "abc");
678 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
679 rc = pldm_bios_table_attr_value_entry_encode_string_check(
680 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
681 "abc");
682 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
683}
684
685TEST(AttrValTable, StringEntryDecodeTest)
686{
687 std::vector<uint8_t> stringEntry{
688 0, 0, /* attr handle */
689 1, /* attr type */
690 3, 0, /* current string length */
691 'a', 'b', 'c', /* defaut value string handle index */
692 };
693
694 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
695 stringEntry.data());
696 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
697 EXPECT_EQ(3, length);
698
699 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
700 EXPECT_EQ(0, handle);
701
702 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
703 EXPECT_EQ(stringEntry.size(), entryLength);
704
705 variable_field currentString{};
706 pldm_bios_table_attr_value_entry_string_decode_string(entry,
707 &currentString);
708 EXPECT_THAT(std::vector<uint8_t>(currentString.ptr,
709 currentString.ptr + currentString.length),
710 ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'}));
711}
712
713TEST(AttrValTable, integerEntryEncodeTest)
714{
715 std::vector<uint8_t> integerEntry{
716 0, 0, /* attr handle */
717 3, /* attr type */
718 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
719 };
720
721 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
722 EXPECT_EQ(length, integerEntry.size());
723 std::vector<uint8_t> encodeEntry(length, 0);
724 pldm_bios_table_attr_value_entry_encode_integer(
725 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
726 EXPECT_EQ(encodeEntry, integerEntry);
727
728 EXPECT_DEATH(pldm_bios_table_attr_value_entry_encode_integer(
729 encodeEntry.data(), encodeEntry.size() - 1, 0,
730 PLDM_BIOS_INTEGER, 10),
Andrew Jeffery0088a6a2023-06-27 15:06:45 +0930731 "rc == PLDM_SUCCESS");
Andrew Jeffery9c766792022-08-10 23:12:49 +0930732
733 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
734 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
735 EXPECT_EQ(rc, PLDM_SUCCESS);
736 EXPECT_EQ(encodeEntry, integerEntry);
737 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
738 integerEntry.data());
739 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
740 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
741 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
742 10);
743 EXPECT_EQ(rc, PLDM_SUCCESS);
744 EXPECT_EQ(encodeEntry, integerEntry);
745
746 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
747 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
748 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
749 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
750 encodeEntry.data(), encodeEntry.size() - 1, 0,
751 PLDM_BIOS_INTEGER_READ_ONLY, 10);
752 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
753}
754
755TEST(AttrValTable, integerEntryDecodeTest)
756{
757 std::vector<uint8_t> integerEntry{
758 0, 0, /* attr handle */
759 3, /* attr type */
760 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
761 };
762
763 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
764 integerEntry.data());
765 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
766 EXPECT_EQ(cv, 10u);
767}
768
769TEST(AttrValTable, IteratorTest)
770{
771 std::vector<uint8_t> enumEntry{
772 0, 0, /* attr handle */
773 0, /* attr type */
774 2, /* number of current value */
775 0, /* current value string handle index */
776 1, /* current value string handle index */
777 };
778 std::vector<uint8_t> stringEntry{
779 0, 0, /* attr handle */
780 1, /* attr type */
781 3, 0, /* current string length */
782 'a', 'b', 'c', /* defaut value string handle index */
783 };
784 std::vector<uint8_t> integerEntry{
785 0, 0, /* attr handle */
786 3, /* attr type */
787 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
788 };
789
790 Table table;
791 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
792
793 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
794 PLDM_BIOS_ATTR_VAL_TABLE);
795 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
796
797 auto p = reinterpret_cast<const uint8_t*>(entry);
798 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
799 ElementsAreArray(enumEntry));
800
801 pldm_bios_table_iter_next(iter);
802 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
803 p = reinterpret_cast<const uint8_t*>(entry);
804 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
805 ElementsAreArray(stringEntry));
806
807 pldm_bios_table_iter_next(iter);
808 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
809 p = reinterpret_cast<const uint8_t*>(entry);
810 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
811 ElementsAreArray(integerEntry));
812
813 pldm_bios_table_iter_next(iter);
814 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
815 p = reinterpret_cast<const uint8_t*>(entry);
816 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
817 ElementsAreArray(enumEntry));
818
819 pldm_bios_table_iter_next(iter);
820 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
821
822 pldm_bios_table_iter_free(iter);
823}
824
825TEST(AttrValTable, FindTest)
826{
827 std::vector<uint8_t> enumEntry{
828 0, 0, /* attr handle */
829 0, /* attr type */
830 2, /* number of current value */
831 0, /* current value string handle index */
832 1, /* current value string handle index */
833 };
834 std::vector<uint8_t> stringEntry{
835 1, 0, /* attr handle */
836 1, /* attr type */
837 3, 0, /* current string length */
838 'a', 'b', 'c', /* defaut value string handle index */
839 };
840 std::vector<uint8_t> integerEntry{
841 2, 0, /* attr handle */
842 3, /* attr type */
843 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
844 };
845
846 Table table;
847 buildTable(table, enumEntry, stringEntry, integerEntry);
848
849 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
850 table.size(), 1);
851 EXPECT_NE(entry, nullptr);
852 auto p = reinterpret_cast<const uint8_t*>(entry);
853 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
854 ElementsAreArray(stringEntry));
855
856 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
857 table.size(), 3);
858 EXPECT_EQ(entry, nullptr);
859
860 auto firstEntry =
861 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
862 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
863 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
864 table.size(), 1),
865 "entry_length != NULL");
866}
867
868TEST(AttrValTable, CopyAndUpdateTest)
869{
870 std::vector<uint8_t> enumEntry{
871 0, 0, /* attr handle */
872 0, /* attr type */
873 2, /* number of current value */
874 0, /* current value string handle index */
875 1, /* current value string handle index */
876 };
877 std::vector<uint8_t> stringEntry{
878 1, 0, /* attr handle */
879 1, /* attr type */
880 3, 0, /* current string length */
881 'a', 'b', 'c', /* defaut value string handle index */
882 };
883 std::vector<uint8_t> integerEntry{
884 2, 0, /* attr handle */
885 3, /* attr type */
886 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
887 };
888
889 Table srcTable;
890 buildTable(srcTable, enumEntry, stringEntry, integerEntry);
891
892 std::vector<uint8_t> stringEntry1{
893 1, 0, /* attr handle */
894 1, /* attr type */
895 3, 0, /* current string length */
896 'd', 'e', 'f', /* defaut value string handle index */
897 };
898
899 Table expectTable;
900 buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
901 Table destTable(expectTable.size() + 10);
902 auto destLength = destTable.size();
903 auto rc = pldm_bios_table_attr_value_copy_and_update(
904 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
905 stringEntry1.data(), stringEntry1.size());
906
907 EXPECT_EQ(rc, PLDM_SUCCESS);
908 EXPECT_EQ(destLength, expectTable.size());
909 destTable.resize(destLength);
910 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
911
912 std::vector<uint8_t> stringEntry2{
913 1, 0, /* attr handle */
914 1, /* attr type */
915 5, 0, /* current string length */
916 'd', 'e', 'f', 'a', 'b', /* defaut value string handle index */
917 };
918 expectTable.resize(0);
919 buildTable(expectTable, enumEntry, stringEntry2, integerEntry);
920 destTable.resize(expectTable.size() + 10);
921 destLength = destTable.size();
922 rc = pldm_bios_table_attr_value_copy_and_update(
923 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
924 stringEntry2.data(), stringEntry2.size());
925 EXPECT_EQ(rc, PLDM_SUCCESS);
926 EXPECT_EQ(destLength, expectTable.size());
927 destTable.resize(destLength);
928 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
929
930 std::vector<uint8_t> stringEntry3{
931 1, 0, /* attr handle */
932 1, /* attr type */
933 1, 0, /* current string length */
934 'd', /* defaut value string handle index */
935 };
936 expectTable.resize(0);
937 buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
938 destTable.resize(expectTable.size() + 10);
939 destLength = destTable.size();
940 rc = pldm_bios_table_attr_value_copy_and_update(
941 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
942 stringEntry3.data(), stringEntry3.size());
943 EXPECT_EQ(rc, PLDM_SUCCESS);
944 EXPECT_EQ(destLength, expectTable.size());
945 destTable.resize(destLength);
946 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
947
948 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer
949 rc = pldm_bios_table_attr_value_copy_and_update(
950 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
951 stringEntry3.data(), stringEntry3.size());
952 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
953 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string
954
955 destTable.resize(expectTable.size() - 1);
956 destLength = destTable.size();
957 rc = pldm_bios_table_attr_value_copy_and_update(
958 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
959 stringEntry3.data(), stringEntry3.size());
960 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
961}
962
963TEST(StringTable, EntryEncodeTest)
964{
965 std::vector<uint8_t> stringEntry{
966 0, 0, /* string handle*/
967 7, 0, /* string length */
968 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
969 };
970
971 const char* str = "Allowed";
972 auto str_length = std::strlen(str);
973 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
974 EXPECT_EQ(encodeLength, stringEntry.size());
975
976 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930977 ASSERT_EQ(pldm_bios_table_string_entry_encode_check(
978 encodeEntry.data(), encodeEntry.size(), str, str_length),
979 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930980 // set string handle = 0
981 encodeEntry[0] = 0;
982 encodeEntry[1] = 0;
983
984 EXPECT_EQ(stringEntry, encodeEntry);
985
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930986 EXPECT_NE(pldm_bios_table_string_entry_encode_check(
987 encodeEntry.data(), encodeEntry.size() - 1, str, str_length),
988 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930989 auto rc = pldm_bios_table_string_entry_encode_check(
990 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
991 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
992}
993
994TEST(StringTable, EntryDecodeTest)
995{
996 std::vector<uint8_t> stringEntry{
997 4, 0, /* string handle*/
998 7, 0, /* string length */
999 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
1000 };
1001 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
1002 stringEntry.data());
1003 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1004 EXPECT_EQ(handle, 4);
1005 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
1006 EXPECT_EQ(strLength, 7);
1007
1008 std::vector<char> buffer(strLength + 1, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301009 pldm_bios_table_string_entry_decode_string_check(entry, buffer.data(),
1010 buffer.size());
1011 EXPECT_EQ(strlen(buffer.data()), strLength);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301012 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301013 EXPECT_EQ(pldm_bios_table_string_entry_decode_string_check(
1014 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/),
1015 PLDM_SUCCESS);
1016 EXPECT_EQ(strlen(buffer.data()), 2);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301017 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
1018
1019 auto rc = pldm_bios_table_string_entry_decode_string_check(
1020 entry, buffer.data(), buffer.size());
1021 EXPECT_EQ(rc, PLDM_SUCCESS);
1022 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
1023
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301024 /* Ensure equivalence with the unchecked API */
1025 rc = pldm_bios_table_string_entry_decode_string_check(
1026 entry, buffer.data(), 2 + 1 /* sizeof '\0' */);
1027 EXPECT_EQ(rc, std::strcmp("Al", buffer.data()));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301028}
1029
1030TEST(StringTable, IteratorTest)
1031{
1032 std::vector<uint8_t> stringHello{
1033 0, 0, /* string handle*/
1034 5, 0, /* string length */
1035 'H', 'e', 'l', 'l', 'o', /* string */
1036 };
1037 std::vector<uint8_t> stringWorld{
1038 1, 0, /* string handle*/
1039 6, 0, /* string length */
1040 'W', 'o', 'r', 'l', 'd', '!', /* string */
1041 };
1042
1043 Table table;
1044 buildTable(table, stringHello, stringWorld);
1045
1046 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1047 PLDM_BIOS_STRING_TABLE);
1048 auto entry = pldm_bios_table_iter_string_entry_value(iter);
1049 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
1050 EXPECT_EQ(rc, 0);
1051 pldm_bios_table_iter_next(iter);
1052 entry = pldm_bios_table_iter_string_entry_value(iter);
1053 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
1054 EXPECT_EQ(rc, 0);
1055 pldm_bios_table_iter_next(iter);
1056 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
1057 pldm_bios_table_iter_free(iter);
1058}
1059
1060TEST(StringTable, FindTest)
1061{
1062 std::vector<uint8_t> stringHello{
1063 1, 0, /* string handle*/
1064 5, 0, /* string length */
1065 'H', 'e', 'l', 'l', 'o', /* string */
1066 };
1067 std::vector<uint8_t> stringWorld{
1068 2, 0, /* string handle*/
1069 6, 0, /* string length */
1070 'W', 'o', 'r', 'l', 'd', '!', /* string */
1071 };
1072 std::vector<uint8_t> stringHi{
1073 3, 0, /* string handle*/
1074 2, 0, /* string length */
1075 'H', 'i', /* string */
1076 };
1077
1078 Table table;
1079 buildTable(table, stringHello, stringWorld, stringHi);
1080
1081 auto entry = pldm_bios_table_string_find_by_string(table.data(),
1082 table.size(), "World!");
1083 EXPECT_NE(entry, nullptr);
1084 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1085 EXPECT_EQ(handle, 2);
1086
1087 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
1088 "Worl");
1089 EXPECT_EQ(entry, nullptr);
1090
1091 entry =
1092 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
1093 EXPECT_NE(entry, nullptr);
1094 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
1095 EXPECT_EQ(str_length, 2);
1096 std::vector<char> strBuf(str_length + 1, 0);
1097 auto rc = pldm_bios_table_string_entry_decode_string_check(
1098 entry, strBuf.data(), strBuf.size());
1099 EXPECT_EQ(rc, PLDM_SUCCESS);
1100 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
1101
1102 entry =
1103 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
1104 EXPECT_EQ(entry, nullptr);
1105}
1106
Andrew Jefferybf6699b2023-07-05 16:27:59 +09301107TEST(Iterator, DeathTest)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301108{
1109
1110 Table table(256, 0);
1111
1112 /* first entry */
1113 auto attr_entry =
1114 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
1115 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1116 PLDM_BIOS_ATTR_TABLE);
1117 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
1118 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
1119 pldm_bios_table_iter_free(iter);
1120}
1121
1122TEST(PadAndChecksum, PadAndChecksum)
1123{
1124 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0));
1125 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1));
1126 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2));
1127 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3));
1128 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4));
1129
1130 // The table is borrowed from
1131 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
1132 // refer to the commit message
1133 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
1134 auto sizeWithoutPad = attrValTable.size();
1135 attrValTable.resize(sizeWithoutPad +
1136 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
1137 pldm_bios_table_append_pad_checksum(attrValTable.data(),
1138 attrValTable.size(), sizeWithoutPad);
1139 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
1140 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
1141 EXPECT_EQ(attrValTable, expectedTable);
1142}
1143
1144TEST(BIOSTableChecksum, testBIOSTableChecksum)
1145{
1146 std::vector<uint8_t> stringTable{
1147 1, 0, /* string handle*/
1148 5, 0, /* string length */
1149 'T', 'a', 'b', 'l', 'e', /* string */
1150 };
1151
1152 buildTable(stringTable);
1153
1154 EXPECT_EQ(true,
1155 pldm_bios_table_checksum(stringTable.data(), stringTable.size()));
1156}