blob: d42d1265671421fa29ad325dc2bf24d666b02e8a [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);
Archana Kakanib9d951f2023-10-17 05:47:58 -0500640
641 /* Buffer size is more than the number of current string handles */
642 std::vector<uint8_t> handleIndexes(3, 0);
643 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
644 entry, handleIndexes.data(), handleIndexes.size());
645 EXPECT_EQ(rc, 2);
646 EXPECT_EQ(handleIndexes[0], 0);
647 EXPECT_EQ(handleIndexes[1], 1);
648
649 /* Buffersize is less than the number of current string handles */
650 std::vector<uint8_t> strHandles(1, 0);
651 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
652 entry, strHandles.data(), strHandles.size());
653 EXPECT_EQ(rc, 1);
654 EXPECT_EQ(strHandles[0], 0);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930655}
656
657TEST(AttrValTable, stringEntryEncodeTest)
658{
659 std::vector<uint8_t> stringEntry{
660 0, 0, /* attr handle */
661 1, /* attr type */
662 3, 0, /* current string length */
663 'a', 'b', 'c', /* defaut value string handle index */
664 };
665
666 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
667 EXPECT_EQ(length, stringEntry.size());
668 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery46d07682023-07-14 15:51:51 +0930669 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_string_check(
670 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc"),
671 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930672 EXPECT_EQ(encodeEntry, stringEntry);
673
Andrew Jeffery46d07682023-07-14 15:51:51 +0930674 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_string_check(
675 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
676 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930677
678 auto rc = pldm_bios_table_attr_value_entry_encode_string_check(
679 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
680 EXPECT_EQ(rc, PLDM_SUCCESS);
681 EXPECT_EQ(encodeEntry, stringEntry);
682 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
683 stringEntry.data());
684 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
685 rc = pldm_bios_table_attr_value_entry_encode_string_check(
686 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
687 3, "abc");
688 EXPECT_EQ(rc, PLDM_SUCCESS);
689 EXPECT_EQ(encodeEntry, stringEntry);
690 rc = pldm_bios_table_attr_value_entry_encode_string_check(
691 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
692 "abc");
693 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
694 rc = pldm_bios_table_attr_value_entry_encode_string_check(
695 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
696 "abc");
697 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
698}
699
700TEST(AttrValTable, StringEntryDecodeTest)
701{
702 std::vector<uint8_t> stringEntry{
703 0, 0, /* attr handle */
704 1, /* attr type */
705 3, 0, /* current string length */
706 'a', 'b', 'c', /* defaut value string handle index */
707 };
708
709 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
710 stringEntry.data());
711 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
712 EXPECT_EQ(3, length);
713
714 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
715 EXPECT_EQ(0, handle);
716
717 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
718 EXPECT_EQ(stringEntry.size(), entryLength);
719
720 variable_field currentString{};
721 pldm_bios_table_attr_value_entry_string_decode_string(entry,
722 &currentString);
723 EXPECT_THAT(std::vector<uint8_t>(currentString.ptr,
724 currentString.ptr + currentString.length),
725 ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'}));
726}
727
728TEST(AttrValTable, integerEntryEncodeTest)
729{
730 std::vector<uint8_t> integerEntry{
731 0, 0, /* attr handle */
732 3, /* attr type */
733 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
734 };
735
736 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
737 EXPECT_EQ(length, integerEntry.size());
738 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930739 ASSERT_EQ(
740 pldm_bios_table_attr_value_entry_encode_integer_check(
741 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10),
742 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930743 EXPECT_EQ(encodeEntry, integerEntry);
744
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930745 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_integer_check(
746 encodeEntry.data(), encodeEntry.size() - 1, 0,
747 PLDM_BIOS_INTEGER, 10),
748 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930749
750 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
751 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
752 EXPECT_EQ(rc, PLDM_SUCCESS);
753 EXPECT_EQ(encodeEntry, integerEntry);
754 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
755 integerEntry.data());
756 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
757 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
758 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
759 10);
760 EXPECT_EQ(rc, PLDM_SUCCESS);
761 EXPECT_EQ(encodeEntry, integerEntry);
762
763 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
764 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
765 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
766 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
767 encodeEntry.data(), encodeEntry.size() - 1, 0,
768 PLDM_BIOS_INTEGER_READ_ONLY, 10);
769 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
770}
771
772TEST(AttrValTable, integerEntryDecodeTest)
773{
774 std::vector<uint8_t> integerEntry{
775 0, 0, /* attr handle */
776 3, /* attr type */
777 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
778 };
779
780 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
781 integerEntry.data());
782 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
783 EXPECT_EQ(cv, 10u);
784}
785
786TEST(AttrValTable, IteratorTest)
787{
788 std::vector<uint8_t> enumEntry{
789 0, 0, /* attr handle */
790 0, /* attr type */
791 2, /* number of current value */
792 0, /* current value string handle index */
793 1, /* current value string handle index */
794 };
795 std::vector<uint8_t> stringEntry{
796 0, 0, /* attr handle */
797 1, /* attr type */
798 3, 0, /* current string length */
799 'a', 'b', 'c', /* defaut value string handle index */
800 };
801 std::vector<uint8_t> integerEntry{
802 0, 0, /* attr handle */
803 3, /* attr type */
804 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
805 };
806
807 Table table;
808 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
809
810 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
811 PLDM_BIOS_ATTR_VAL_TABLE);
812 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
813
814 auto 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 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
820 p = reinterpret_cast<const uint8_t*>(entry);
821 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
822 ElementsAreArray(stringEntry));
823
824 pldm_bios_table_iter_next(iter);
825 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
826 p = reinterpret_cast<const uint8_t*>(entry);
827 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
828 ElementsAreArray(integerEntry));
829
830 pldm_bios_table_iter_next(iter);
831 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
832 p = reinterpret_cast<const uint8_t*>(entry);
833 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
834 ElementsAreArray(enumEntry));
835
836 pldm_bios_table_iter_next(iter);
837 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
838
839 pldm_bios_table_iter_free(iter);
840}
841
842TEST(AttrValTable, FindTest)
843{
844 std::vector<uint8_t> enumEntry{
845 0, 0, /* attr handle */
846 0, /* attr type */
847 2, /* number of current value */
848 0, /* current value string handle index */
849 1, /* current value string handle index */
850 };
851 std::vector<uint8_t> stringEntry{
852 1, 0, /* attr handle */
853 1, /* attr type */
854 3, 0, /* current string length */
855 'a', 'b', 'c', /* defaut value string handle index */
856 };
857 std::vector<uint8_t> integerEntry{
858 2, 0, /* attr handle */
859 3, /* attr type */
860 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
861 };
862
863 Table table;
864 buildTable(table, enumEntry, stringEntry, integerEntry);
865
866 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
867 table.size(), 1);
868 EXPECT_NE(entry, nullptr);
869 auto p = reinterpret_cast<const uint8_t*>(entry);
870 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
871 ElementsAreArray(stringEntry));
872
873 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
874 table.size(), 3);
875 EXPECT_EQ(entry, nullptr);
876
877 auto firstEntry =
878 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
879 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
880 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
881 table.size(), 1),
882 "entry_length != NULL");
883}
884
885TEST(AttrValTable, CopyAndUpdateTest)
886{
887 std::vector<uint8_t> enumEntry{
888 0, 0, /* attr handle */
889 0, /* attr type */
890 2, /* number of current value */
891 0, /* current value string handle index */
892 1, /* current value string handle index */
893 };
894 std::vector<uint8_t> stringEntry{
895 1, 0, /* attr handle */
896 1, /* attr type */
897 3, 0, /* current string length */
898 'a', 'b', 'c', /* defaut value string handle index */
899 };
900 std::vector<uint8_t> integerEntry{
901 2, 0, /* attr handle */
902 3, /* attr type */
903 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
904 };
905
906 Table srcTable;
907 buildTable(srcTable, enumEntry, stringEntry, integerEntry);
908
909 std::vector<uint8_t> stringEntry1{
910 1, 0, /* attr handle */
911 1, /* attr type */
912 3, 0, /* current string length */
913 'd', 'e', 'f', /* defaut value string handle index */
914 };
915
916 Table expectTable;
917 buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
918 Table destTable(expectTable.size() + 10);
919 auto destLength = destTable.size();
920 auto rc = pldm_bios_table_attr_value_copy_and_update(
921 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
922 stringEntry1.data(), stringEntry1.size());
923
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> stringEntry2{
930 1, 0, /* attr handle */
931 1, /* attr type */
932 5, 0, /* current string length */
933 'd', 'e', 'f', 'a', 'b', /* defaut value string handle index */
934 };
935 expectTable.resize(0);
936 buildTable(expectTable, enumEntry, stringEntry2, 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 stringEntry2.data(), stringEntry2.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 std::vector<uint8_t> stringEntry3{
948 1, 0, /* attr handle */
949 1, /* attr type */
950 1, 0, /* current string length */
951 'd', /* defaut value string handle index */
952 };
953 expectTable.resize(0);
954 buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
955 destTable.resize(expectTable.size() + 10);
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_SUCCESS);
961 EXPECT_EQ(destLength, expectTable.size());
962 destTable.resize(destLength);
963 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
964
965 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer
966 rc = pldm_bios_table_attr_value_copy_and_update(
967 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
968 stringEntry3.data(), stringEntry3.size());
969 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
970 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string
971
972 destTable.resize(expectTable.size() - 1);
973 destLength = destTable.size();
974 rc = pldm_bios_table_attr_value_copy_and_update(
975 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
976 stringEntry3.data(), stringEntry3.size());
977 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
978}
979
980TEST(StringTable, EntryEncodeTest)
981{
982 std::vector<uint8_t> stringEntry{
983 0, 0, /* string handle*/
984 7, 0, /* string length */
985 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
986 };
987
988 const char* str = "Allowed";
989 auto str_length = std::strlen(str);
990 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
991 EXPECT_EQ(encodeLength, stringEntry.size());
992
993 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930994 ASSERT_EQ(pldm_bios_table_string_entry_encode_check(
995 encodeEntry.data(), encodeEntry.size(), str, str_length),
996 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930997 // set string handle = 0
998 encodeEntry[0] = 0;
999 encodeEntry[1] = 0;
1000
1001 EXPECT_EQ(stringEntry, encodeEntry);
1002
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301003 EXPECT_NE(pldm_bios_table_string_entry_encode_check(
1004 encodeEntry.data(), encodeEntry.size() - 1, str, str_length),
1005 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301006 auto rc = pldm_bios_table_string_entry_encode_check(
1007 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
1008 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1009}
1010
1011TEST(StringTable, EntryDecodeTest)
1012{
1013 std::vector<uint8_t> stringEntry{
1014 4, 0, /* string handle*/
1015 7, 0, /* string length */
1016 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
1017 };
1018 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
1019 stringEntry.data());
1020 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1021 EXPECT_EQ(handle, 4);
1022 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
1023 EXPECT_EQ(strLength, 7);
1024
1025 std::vector<char> buffer(strLength + 1, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301026 pldm_bios_table_string_entry_decode_string_check(entry, buffer.data(),
1027 buffer.size());
1028 EXPECT_EQ(strlen(buffer.data()), strLength);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301029 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301030 EXPECT_EQ(pldm_bios_table_string_entry_decode_string_check(
1031 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/),
1032 PLDM_SUCCESS);
1033 EXPECT_EQ(strlen(buffer.data()), 2);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301034 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
1035
1036 auto rc = pldm_bios_table_string_entry_decode_string_check(
1037 entry, buffer.data(), buffer.size());
1038 EXPECT_EQ(rc, PLDM_SUCCESS);
1039 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
1040
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301041 /* Ensure equivalence with the unchecked API */
1042 rc = pldm_bios_table_string_entry_decode_string_check(
1043 entry, buffer.data(), 2 + 1 /* sizeof '\0' */);
1044 EXPECT_EQ(rc, std::strcmp("Al", buffer.data()));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301045}
1046
1047TEST(StringTable, IteratorTest)
1048{
1049 std::vector<uint8_t> stringHello{
1050 0, 0, /* string handle*/
1051 5, 0, /* string length */
1052 'H', 'e', 'l', 'l', 'o', /* string */
1053 };
1054 std::vector<uint8_t> stringWorld{
1055 1, 0, /* string handle*/
1056 6, 0, /* string length */
1057 'W', 'o', 'r', 'l', 'd', '!', /* string */
1058 };
1059
1060 Table table;
1061 buildTable(table, stringHello, stringWorld);
1062
1063 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1064 PLDM_BIOS_STRING_TABLE);
1065 auto entry = pldm_bios_table_iter_string_entry_value(iter);
1066 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
1067 EXPECT_EQ(rc, 0);
1068 pldm_bios_table_iter_next(iter);
1069 entry = pldm_bios_table_iter_string_entry_value(iter);
1070 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
1071 EXPECT_EQ(rc, 0);
1072 pldm_bios_table_iter_next(iter);
1073 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
1074 pldm_bios_table_iter_free(iter);
1075}
1076
1077TEST(StringTable, FindTest)
1078{
1079 std::vector<uint8_t> stringHello{
1080 1, 0, /* string handle*/
1081 5, 0, /* string length */
1082 'H', 'e', 'l', 'l', 'o', /* string */
1083 };
1084 std::vector<uint8_t> stringWorld{
1085 2, 0, /* string handle*/
1086 6, 0, /* string length */
1087 'W', 'o', 'r', 'l', 'd', '!', /* string */
1088 };
1089 std::vector<uint8_t> stringHi{
1090 3, 0, /* string handle*/
1091 2, 0, /* string length */
1092 'H', 'i', /* string */
1093 };
1094
1095 Table table;
1096 buildTable(table, stringHello, stringWorld, stringHi);
1097
1098 auto entry = pldm_bios_table_string_find_by_string(table.data(),
1099 table.size(), "World!");
1100 EXPECT_NE(entry, nullptr);
1101 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1102 EXPECT_EQ(handle, 2);
1103
1104 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
1105 "Worl");
1106 EXPECT_EQ(entry, nullptr);
1107
1108 entry =
1109 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
1110 EXPECT_NE(entry, nullptr);
1111 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
1112 EXPECT_EQ(str_length, 2);
1113 std::vector<char> strBuf(str_length + 1, 0);
1114 auto rc = pldm_bios_table_string_entry_decode_string_check(
1115 entry, strBuf.data(), strBuf.size());
1116 EXPECT_EQ(rc, PLDM_SUCCESS);
1117 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
1118
1119 entry =
1120 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
1121 EXPECT_EQ(entry, nullptr);
1122}
1123
Andrew Jefferybf6699b2023-07-05 16:27:59 +09301124TEST(Iterator, DeathTest)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301125{
1126
1127 Table table(256, 0);
1128
1129 /* first entry */
1130 auto attr_entry =
1131 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
1132 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1133 PLDM_BIOS_ATTR_TABLE);
1134 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
1135 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
1136 pldm_bios_table_iter_free(iter);
1137}
1138
1139TEST(PadAndChecksum, PadAndChecksum)
1140{
1141 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0));
1142 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1));
1143 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2));
1144 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3));
1145 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4));
1146
1147 // The table is borrowed from
1148 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
1149 // refer to the commit message
1150 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
1151 auto sizeWithoutPad = attrValTable.size();
1152 attrValTable.resize(sizeWithoutPad +
1153 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
Andrew Jeffery50dd1592023-07-14 16:02:05 +09301154 ASSERT_EQ(pldm_bios_table_append_pad_checksum_check(
1155 attrValTable.data(), attrValTable.size(), &sizeWithoutPad),
1156 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301157 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
1158 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
1159 EXPECT_EQ(attrValTable, expectedTable);
1160}
1161
1162TEST(BIOSTableChecksum, testBIOSTableChecksum)
1163{
1164 std::vector<uint8_t> stringTable{
1165 1, 0, /* string handle*/
1166 5, 0, /* string length */
1167 'T', 'a', 'b', 'l', 'e', /* string */
1168 };
1169
1170 buildTable(stringTable);
1171
1172 EXPECT_EQ(true,
1173 pldm_bios_table_checksum(stringTable.data(), stringTable.size()));
1174}