blob: 83e7fd97b5b03d8045018570a77d8ac4e525d6eb [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);
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930724 ASSERT_EQ(
725 pldm_bios_table_attr_value_entry_encode_integer_check(
726 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10),
727 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930728 EXPECT_EQ(encodeEntry, integerEntry);
729
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930730 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_integer_check(
731 encodeEntry.data(), encodeEntry.size() - 1, 0,
732 PLDM_BIOS_INTEGER, 10),
733 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930734
735 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
736 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
737 EXPECT_EQ(rc, PLDM_SUCCESS);
738 EXPECT_EQ(encodeEntry, integerEntry);
739 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
740 integerEntry.data());
741 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
742 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
743 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
744 10);
745 EXPECT_EQ(rc, PLDM_SUCCESS);
746 EXPECT_EQ(encodeEntry, integerEntry);
747
748 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
749 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
750 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
751 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
752 encodeEntry.data(), encodeEntry.size() - 1, 0,
753 PLDM_BIOS_INTEGER_READ_ONLY, 10);
754 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
755}
756
757TEST(AttrValTable, integerEntryDecodeTest)
758{
759 std::vector<uint8_t> integerEntry{
760 0, 0, /* attr handle */
761 3, /* attr type */
762 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
763 };
764
765 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
766 integerEntry.data());
767 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
768 EXPECT_EQ(cv, 10u);
769}
770
771TEST(AttrValTable, IteratorTest)
772{
773 std::vector<uint8_t> enumEntry{
774 0, 0, /* attr handle */
775 0, /* attr type */
776 2, /* number of current value */
777 0, /* current value string handle index */
778 1, /* current value string handle index */
779 };
780 std::vector<uint8_t> stringEntry{
781 0, 0, /* attr handle */
782 1, /* attr type */
783 3, 0, /* current string length */
784 'a', 'b', 'c', /* defaut value string handle index */
785 };
786 std::vector<uint8_t> integerEntry{
787 0, 0, /* attr handle */
788 3, /* attr type */
789 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
790 };
791
792 Table table;
793 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
794
795 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
796 PLDM_BIOS_ATTR_VAL_TABLE);
797 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
798
799 auto p = reinterpret_cast<const uint8_t*>(entry);
800 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
801 ElementsAreArray(enumEntry));
802
803 pldm_bios_table_iter_next(iter);
804 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
805 p = reinterpret_cast<const uint8_t*>(entry);
806 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
807 ElementsAreArray(stringEntry));
808
809 pldm_bios_table_iter_next(iter);
810 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
811 p = reinterpret_cast<const uint8_t*>(entry);
812 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
813 ElementsAreArray(integerEntry));
814
815 pldm_bios_table_iter_next(iter);
816 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
817 p = reinterpret_cast<const uint8_t*>(entry);
818 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
819 ElementsAreArray(enumEntry));
820
821 pldm_bios_table_iter_next(iter);
822 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
823
824 pldm_bios_table_iter_free(iter);
825}
826
827TEST(AttrValTable, FindTest)
828{
829 std::vector<uint8_t> enumEntry{
830 0, 0, /* attr handle */
831 0, /* attr type */
832 2, /* number of current value */
833 0, /* current value string handle index */
834 1, /* current value string handle index */
835 };
836 std::vector<uint8_t> stringEntry{
837 1, 0, /* attr handle */
838 1, /* attr type */
839 3, 0, /* current string length */
840 'a', 'b', 'c', /* defaut value string handle index */
841 };
842 std::vector<uint8_t> integerEntry{
843 2, 0, /* attr handle */
844 3, /* attr type */
845 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
846 };
847
848 Table table;
849 buildTable(table, enumEntry, stringEntry, integerEntry);
850
851 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
852 table.size(), 1);
853 EXPECT_NE(entry, nullptr);
854 auto p = reinterpret_cast<const uint8_t*>(entry);
855 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
856 ElementsAreArray(stringEntry));
857
858 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
859 table.size(), 3);
860 EXPECT_EQ(entry, nullptr);
861
862 auto firstEntry =
863 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
864 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
865 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
866 table.size(), 1),
867 "entry_length != NULL");
868}
869
870TEST(AttrValTable, CopyAndUpdateTest)
871{
872 std::vector<uint8_t> enumEntry{
873 0, 0, /* attr handle */
874 0, /* attr type */
875 2, /* number of current value */
876 0, /* current value string handle index */
877 1, /* current value string handle index */
878 };
879 std::vector<uint8_t> stringEntry{
880 1, 0, /* attr handle */
881 1, /* attr type */
882 3, 0, /* current string length */
883 'a', 'b', 'c', /* defaut value string handle index */
884 };
885 std::vector<uint8_t> integerEntry{
886 2, 0, /* attr handle */
887 3, /* attr type */
888 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
889 };
890
891 Table srcTable;
892 buildTable(srcTable, enumEntry, stringEntry, integerEntry);
893
894 std::vector<uint8_t> stringEntry1{
895 1, 0, /* attr handle */
896 1, /* attr type */
897 3, 0, /* current string length */
898 'd', 'e', 'f', /* defaut value string handle index */
899 };
900
901 Table expectTable;
902 buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
903 Table destTable(expectTable.size() + 10);
904 auto destLength = destTable.size();
905 auto rc = pldm_bios_table_attr_value_copy_and_update(
906 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
907 stringEntry1.data(), stringEntry1.size());
908
909 EXPECT_EQ(rc, PLDM_SUCCESS);
910 EXPECT_EQ(destLength, expectTable.size());
911 destTable.resize(destLength);
912 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
913
914 std::vector<uint8_t> stringEntry2{
915 1, 0, /* attr handle */
916 1, /* attr type */
917 5, 0, /* current string length */
918 'd', 'e', 'f', 'a', 'b', /* defaut value string handle index */
919 };
920 expectTable.resize(0);
921 buildTable(expectTable, enumEntry, stringEntry2, integerEntry);
922 destTable.resize(expectTable.size() + 10);
923 destLength = destTable.size();
924 rc = pldm_bios_table_attr_value_copy_and_update(
925 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
926 stringEntry2.data(), stringEntry2.size());
927 EXPECT_EQ(rc, PLDM_SUCCESS);
928 EXPECT_EQ(destLength, expectTable.size());
929 destTable.resize(destLength);
930 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
931
932 std::vector<uint8_t> stringEntry3{
933 1, 0, /* attr handle */
934 1, /* attr type */
935 1, 0, /* current string length */
936 'd', /* defaut value string handle index */
937 };
938 expectTable.resize(0);
939 buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
940 destTable.resize(expectTable.size() + 10);
941 destLength = destTable.size();
942 rc = pldm_bios_table_attr_value_copy_and_update(
943 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
944 stringEntry3.data(), stringEntry3.size());
945 EXPECT_EQ(rc, PLDM_SUCCESS);
946 EXPECT_EQ(destLength, expectTable.size());
947 destTable.resize(destLength);
948 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
949
950 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer
951 rc = pldm_bios_table_attr_value_copy_and_update(
952 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
953 stringEntry3.data(), stringEntry3.size());
954 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
955 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string
956
957 destTable.resize(expectTable.size() - 1);
958 destLength = destTable.size();
959 rc = pldm_bios_table_attr_value_copy_and_update(
960 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
961 stringEntry3.data(), stringEntry3.size());
962 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
963}
964
965TEST(StringTable, EntryEncodeTest)
966{
967 std::vector<uint8_t> stringEntry{
968 0, 0, /* string handle*/
969 7, 0, /* string length */
970 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
971 };
972
973 const char* str = "Allowed";
974 auto str_length = std::strlen(str);
975 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
976 EXPECT_EQ(encodeLength, stringEntry.size());
977
978 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930979 ASSERT_EQ(pldm_bios_table_string_entry_encode_check(
980 encodeEntry.data(), encodeEntry.size(), str, str_length),
981 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930982 // set string handle = 0
983 encodeEntry[0] = 0;
984 encodeEntry[1] = 0;
985
986 EXPECT_EQ(stringEntry, encodeEntry);
987
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930988 EXPECT_NE(pldm_bios_table_string_entry_encode_check(
989 encodeEntry.data(), encodeEntry.size() - 1, str, str_length),
990 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930991 auto rc = pldm_bios_table_string_entry_encode_check(
992 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
993 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
994}
995
996TEST(StringTable, EntryDecodeTest)
997{
998 std::vector<uint8_t> stringEntry{
999 4, 0, /* string handle*/
1000 7, 0, /* string length */
1001 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
1002 };
1003 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
1004 stringEntry.data());
1005 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1006 EXPECT_EQ(handle, 4);
1007 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
1008 EXPECT_EQ(strLength, 7);
1009
1010 std::vector<char> buffer(strLength + 1, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301011 pldm_bios_table_string_entry_decode_string_check(entry, buffer.data(),
1012 buffer.size());
1013 EXPECT_EQ(strlen(buffer.data()), strLength);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301014 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301015 EXPECT_EQ(pldm_bios_table_string_entry_decode_string_check(
1016 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/),
1017 PLDM_SUCCESS);
1018 EXPECT_EQ(strlen(buffer.data()), 2);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301019 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
1020
1021 auto rc = pldm_bios_table_string_entry_decode_string_check(
1022 entry, buffer.data(), buffer.size());
1023 EXPECT_EQ(rc, PLDM_SUCCESS);
1024 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
1025
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301026 /* Ensure equivalence with the unchecked API */
1027 rc = pldm_bios_table_string_entry_decode_string_check(
1028 entry, buffer.data(), 2 + 1 /* sizeof '\0' */);
1029 EXPECT_EQ(rc, std::strcmp("Al", buffer.data()));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301030}
1031
1032TEST(StringTable, IteratorTest)
1033{
1034 std::vector<uint8_t> stringHello{
1035 0, 0, /* string handle*/
1036 5, 0, /* string length */
1037 'H', 'e', 'l', 'l', 'o', /* string */
1038 };
1039 std::vector<uint8_t> stringWorld{
1040 1, 0, /* string handle*/
1041 6, 0, /* string length */
1042 'W', 'o', 'r', 'l', 'd', '!', /* string */
1043 };
1044
1045 Table table;
1046 buildTable(table, stringHello, stringWorld);
1047
1048 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1049 PLDM_BIOS_STRING_TABLE);
1050 auto entry = pldm_bios_table_iter_string_entry_value(iter);
1051 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
1052 EXPECT_EQ(rc, 0);
1053 pldm_bios_table_iter_next(iter);
1054 entry = pldm_bios_table_iter_string_entry_value(iter);
1055 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
1056 EXPECT_EQ(rc, 0);
1057 pldm_bios_table_iter_next(iter);
1058 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
1059 pldm_bios_table_iter_free(iter);
1060}
1061
1062TEST(StringTable, FindTest)
1063{
1064 std::vector<uint8_t> stringHello{
1065 1, 0, /* string handle*/
1066 5, 0, /* string length */
1067 'H', 'e', 'l', 'l', 'o', /* string */
1068 };
1069 std::vector<uint8_t> stringWorld{
1070 2, 0, /* string handle*/
1071 6, 0, /* string length */
1072 'W', 'o', 'r', 'l', 'd', '!', /* string */
1073 };
1074 std::vector<uint8_t> stringHi{
1075 3, 0, /* string handle*/
1076 2, 0, /* string length */
1077 'H', 'i', /* string */
1078 };
1079
1080 Table table;
1081 buildTable(table, stringHello, stringWorld, stringHi);
1082
1083 auto entry = pldm_bios_table_string_find_by_string(table.data(),
1084 table.size(), "World!");
1085 EXPECT_NE(entry, nullptr);
1086 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1087 EXPECT_EQ(handle, 2);
1088
1089 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
1090 "Worl");
1091 EXPECT_EQ(entry, nullptr);
1092
1093 entry =
1094 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
1095 EXPECT_NE(entry, nullptr);
1096 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
1097 EXPECT_EQ(str_length, 2);
1098 std::vector<char> strBuf(str_length + 1, 0);
1099 auto rc = pldm_bios_table_string_entry_decode_string_check(
1100 entry, strBuf.data(), strBuf.size());
1101 EXPECT_EQ(rc, PLDM_SUCCESS);
1102 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
1103
1104 entry =
1105 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
1106 EXPECT_EQ(entry, nullptr);
1107}
1108
Andrew Jefferybf6699b2023-07-05 16:27:59 +09301109TEST(Iterator, DeathTest)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301110{
1111
1112 Table table(256, 0);
1113
1114 /* first entry */
1115 auto attr_entry =
1116 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
1117 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1118 PLDM_BIOS_ATTR_TABLE);
1119 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
1120 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
1121 pldm_bios_table_iter_free(iter);
1122}
1123
1124TEST(PadAndChecksum, PadAndChecksum)
1125{
1126 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0));
1127 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1));
1128 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2));
1129 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3));
1130 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4));
1131
1132 // The table is borrowed from
1133 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
1134 // refer to the commit message
1135 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
1136 auto sizeWithoutPad = attrValTable.size();
1137 attrValTable.resize(sizeWithoutPad +
1138 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
Andrew Jeffery50dd1592023-07-14 16:02:05 +09301139 ASSERT_EQ(pldm_bios_table_append_pad_checksum_check(
1140 attrValTable.data(), attrValTable.size(), &sizeWithoutPad),
1141 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301142 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
1143 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
1144 EXPECT_EQ(attrValTable, expectedTable);
1145}
1146
1147TEST(BIOSTableChecksum, testBIOSTableChecksum)
1148{
1149 std::vector<uint8_t> stringTable{
1150 1, 0, /* string handle*/
1151 5, 0, /* string length */
1152 'T', 'a', 'b', 'l', 'e', /* string */
1153 };
1154
1155 buildTable(stringTable);
1156
1157 EXPECT_EQ(true,
1158 pldm_bios_table_checksum(stringTable.data(), stringTable.size()));
1159}