blob: 4d81a0376b1471bb98dcd47508dba29f21b58aab [file] [log] [blame]
Andrew Jeffery9c766792022-08-10 23:12:49 +09301#include <endian.h>
Andrew Jefferyefb40062023-11-10 13:48:39 +10302#include <libpldm/base.h>
3#include <libpldm/bios.h>
4#include <libpldm/bios_table.h>
5#include <libpldm/utils.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +09306
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05307#include <algorithm>
8#include <cstdint>
Andrew Jeffery9c766792022-08-10 23:12:49 +09309#include <cstring>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053010#include <iterator>
Andrew Jeffery9c766792022-08-10 23:12:49 +093011#include <string>
12#include <utility>
13#include <vector>
14
Andrew Jeffery9c766792022-08-10 23:12:49 +093015#include <gmock/gmock.h>
16#include <gtest/gtest.h>
17
18using testing::ElementsAreArray;
19using Table = std::vector<uint8_t>;
20
21void buildTable(Table& table)
22{
23 auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
24 table.insert(table.end(), padSize, 0);
25 uint32_t checksum = crc32(table.data(), table.size());
26 checksum = htole32(checksum);
27 uint8_t a[4];
28 std::memcpy(a, &checksum, sizeof(checksum));
29 table.insert(table.end(), std::begin(a), std::end(a));
30}
31
32template <typename First, typename... Rest>
33void buildTable(Table& table, First& first, Rest&... rest)
34{
35 table.insert(table.end(), first.begin(), first.end());
36 buildTable(table, rest...);
37}
38
39TEST(AttrTable, HeaderDecodeTest)
40{
41 std::vector<uint8_t> enumEntry{
42 2, 0, /* attr handle */
43 0, /* attr type */
44 1, 0, /* attr name handle (string handle) */
45 2, /* number of possible value */
46 2, 0, /* possible value handle */
47 3, 0, /* possible value handle */
48 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +053049 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +093050 };
51 auto entry =
52 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
53 auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
54 EXPECT_EQ(attrHandle, 2);
55 auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
56 EXPECT_EQ(attrType, 0);
57 auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
58 EXPECT_EQ(stringHandle, 1);
59}
60
61TEST(AttrTable, EnumEntryDecodeTest)
62{
63 std::vector<uint8_t> enumEntry{
64 0, 0, /* attr handle */
65 0, /* attr type */
66 1, 0, /* attr name handle */
67 2, /* number of possible value */
68 2, 0, /* possible value handle */
69 3, 0, /* possible value handle */
70 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +053071 1 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +093072 };
73
74 auto entry =
75 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093076 uint8_t pvNumber;
77 ASSERT_EQ(
78 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber),
79 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093080 EXPECT_EQ(pvNumber, 2);
81 pvNumber = 0;
82 auto rc =
83 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
84 EXPECT_EQ(rc, PLDM_SUCCESS);
85 EXPECT_EQ(pvNumber, 2);
86
87 std::vector<uint16_t> pvHandles(pvNumber, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093088 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
89 entry, pvHandles.data(), pvHandles.size()),
90 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093091 EXPECT_EQ(pvNumber, 2);
92 EXPECT_EQ(pvHandles[0], 2);
93 EXPECT_EQ(pvHandles[1], 3);
94 pvHandles.resize(1);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093095 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
96 entry, pvHandles.data(), pvHandles.size()),
97 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093098 EXPECT_EQ(pvHandles[0], 2);
99
100 pvHandles.resize(2);
101 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
102 entry, pvHandles.data(), pvHandles.size());
103 EXPECT_EQ(rc, PLDM_SUCCESS);
104 EXPECT_EQ(pvHandles[0], 2);
105 EXPECT_EQ(pvHandles[1], 3);
106 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
107 entry, pvHandles.data(), 1);
Andrew Jeffery0c9f5a82023-06-14 15:01:06 +0930108 EXPECT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930109
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930110 uint8_t defNumber;
111 ASSERT_EQ(
112 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber),
113 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930114 EXPECT_EQ(defNumber, 1);
115 std::vector<uint8_t> defIndices(defNumber);
116 rc = pldm_bios_table_attr_entry_enum_decode_def_indices(
117 entry, defIndices.data(), defIndices.size());
118 EXPECT_EQ(rc, defNumber);
119 EXPECT_THAT(defIndices, ElementsAreArray({1}));
120
121 defNumber = 0;
122 rc =
123 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
124 EXPECT_EQ(rc, PLDM_SUCCESS);
125 EXPECT_EQ(defNumber, 1);
126
127 rc =
128 pldm_bios_table_attr_entry_enum_decode_pv_num_check(nullptr, &pvNumber);
129 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
130 rc = pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, nullptr);
131 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
132
133 entry->attr_type = PLDM_BIOS_STRING;
134 rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
135 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
136
137 rc =
138 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
139 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
140 rc =
141 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(entry, nullptr, 0);
142 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
143}
144
145TEST(AttrTable, EnumEntryEncodeTest)
146{
147 std::vector<uint8_t> enumEntry{
148 0, 0, /* attr handle */
149 0, /* attr type */
150 1, 0, /* attr name handle */
151 2, /* number of possible value */
152 2, 0, /* possible value handle */
153 3, 0, /* possible value handle */
154 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530155 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930156 };
157
158 std::vector<uint16_t> pv_hdls{2, 3};
159 std::vector<uint8_t> defs{0};
160
161 struct pldm_bios_table_attr_entry_enum_info info = {
162 1, /* name handle */
163 false, /* read only */
164 2, /* pv number */
165 pv_hdls.data(), /* pv handle */
166 1, /*def number */
167 defs.data() /*def index*/
168 };
169 auto encodeLength = pldm_bios_table_attr_entry_enum_encode_length(2, 1);
170 EXPECT_EQ(encodeLength, enumEntry.size());
171
172 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930173 ASSERT_EQ(pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
174 encodeEntry.size(), &info),
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930175 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930176 // set attr handle = 0
177 encodeEntry[0] = 0;
178 encodeEntry[1] = 0;
179
180 EXPECT_EQ(enumEntry, encodeEntry);
181
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930182 EXPECT_NE(pldm_bios_table_attr_entry_enum_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930183 encodeEntry.data(), encodeEntry.size() - 1, &info),
184 PLDM_SUCCESS);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930185 auto rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
186 encodeEntry.size(), &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930187 EXPECT_EQ(rc, PLDM_SUCCESS);
188 // set attr handle = 0
189 encodeEntry[0] = 0;
190 encodeEntry[1] = 0;
191
192 EXPECT_EQ(enumEntry, encodeEntry);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930193 rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
194 encodeEntry.size() - 1, &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930195 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
196}
197
198TEST(AttrTable, StringEntryDecodeTest)
199{
200 std::vector<uint8_t> stringEntry{
201 1, 0, /* attr handle */
202 1, /* attr type */
203 12, 0, /* attr name handle */
204 1, /* string type */
205 1, 0, /* minimum length of the string in bytes */
206 100, 0, /* maximum length of the string in bytes */
207 3, 0, /* length of default string in length */
208 'a', 'b', 'c' /* default string */
209 };
210
211 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
212 stringEntry.data());
213 auto stringType =
214 pldm_bios_table_attr_entry_string_decode_string_type(entry);
215 EXPECT_EQ(stringType, 1);
216 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
217 EXPECT_EQ(minLength, 1);
218 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
219 EXPECT_EQ(maxLength, 100);
220
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930221 uint16_t defStringLength;
222 ASSERT_EQ(pldm_bios_table_attr_entry_string_decode_def_string_length_check(
223 entry, &defStringLength),
224 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930225 EXPECT_EQ(defStringLength, 3);
226 std::vector<char> defString(defStringLength + 1);
227 auto rc = pldm_bios_table_attr_entry_string_decode_def_string(
228 entry, defString.data(), defString.size());
229 EXPECT_EQ(rc, 3);
230 EXPECT_STREQ(defString.data(), "abc");
231 rc = pldm_bios_table_attr_entry_string_decode_def_string(
232 entry, defString.data(), defString.size() - 1);
233 EXPECT_EQ(rc, 2);
234 EXPECT_STREQ(defString.data(), "ab");
235
236 defStringLength = 0;
237 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
238 entry, &defStringLength);
239 EXPECT_EQ(rc, PLDM_SUCCESS);
240 EXPECT_EQ(defStringLength, 3);
241
242 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
243 entry, nullptr);
244 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
245 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
246 nullptr, &defStringLength);
247 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
248 entry->attr_type = PLDM_BIOS_INTEGER;
249 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
250 entry, &defStringLength);
251 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
252 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
253 nullptr, &defStringLength);
254 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
255}
256
257TEST(AttrTable, StringEntryEncodeTest)
258{
259 std::vector<uint8_t> stringEntry{
260 0, 0, /* attr handle */
261 1, /* attr type */
262 3, 0, /* attr name handle */
263 1, /* string type */
264 1, 0, /* min string length */
265 100, 0, /* max string length */
266 3, 0, /* default string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530267 'a', 'b', 'c', /* default string */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930268 };
269
270 struct pldm_bios_table_attr_entry_string_info info = {
271 3, /* name handle */
272 false, /* read only */
273 1, /* string type ascii */
274 1, /* min length */
275 100, /* max length */
276 3, /* def length */
277 "abc", /* def string */
278 };
279 auto encodeLength = pldm_bios_table_attr_entry_string_encode_length(3);
280 EXPECT_EQ(encodeLength, stringEntry.size());
281
282 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930283 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check(
284 encodeEntry.data(), encodeEntry.size(), &info),
285 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930286 // set attr handle = 0
287 encodeEntry[0] = 0;
288 encodeEntry[1] = 0;
289
290 EXPECT_EQ(stringEntry, encodeEntry);
291
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930292 EXPECT_NE(pldm_bios_table_attr_entry_string_encode_check(
293 encodeEntry.data(), encodeEntry.size() - 1, &info),
294 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930295 auto rc = pldm_bios_table_attr_entry_string_encode_check(
296 encodeEntry.data(), encodeEntry.size(), &info);
297 EXPECT_EQ(rc, PLDM_SUCCESS);
298 // set attr handle = 0
299 encodeEntry[0] = 0;
300 encodeEntry[1] = 0;
301
302 EXPECT_EQ(stringEntry, encodeEntry);
303 rc = pldm_bios_table_attr_entry_string_encode_check(
304 encodeEntry.data(), encodeEntry.size() - 1, &info);
305 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
306 std::swap(info.max_length, info.min_length);
307 const char* errmsg;
308 rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
309 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
310 EXPECT_STREQ(
311 "MinimumStingLength should not be greater than MaximumStringLength",
312 errmsg);
313 rc = pldm_bios_table_attr_entry_string_encode_check(
314 encodeEntry.data(), encodeEntry.size(), &info);
315 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
316 std::swap(info.max_length, info.min_length);
317
318 std::vector<uint8_t> stringEntryLength0{
319 0, 0, /* attr handle */
320 1, /* attr type */
321 3, 0, /* attr name handle */
322 1, /* string type */
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930323 0, 0, /* min string length */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930324 100, 0, /* max string length */
325 0, 0, /* default string length */
326 };
327
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930328 info.min_length = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930329 info.def_length = 0;
330 info.def_string = nullptr;
331
332 encodeLength = pldm_bios_table_attr_entry_string_encode_length(0);
333 EXPECT_EQ(encodeLength, stringEntryLength0.size());
334
335 encodeEntry.resize(encodeLength);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930336 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check(
337 encodeEntry.data(), encodeEntry.size(), &info),
338 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930339 // set attr handle = 0
340 encodeEntry[0] = 0;
341 encodeEntry[1] = 0;
342
343 EXPECT_EQ(stringEntryLength0, encodeEntry);
344}
345
346TEST(AttrTable, integerEntryEncodeTest)
347{
348 std::vector<uint8_t> integerEntry{
349 0, 0, /* attr handle */
350 3, /* attr type */
351 1, 0, /* attr name handle */
352 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
353 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
354 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530355 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930356 };
357
358 std::vector<uint16_t> pv_hdls{2, 3};
359 std::vector<uint8_t> defs{0};
360
361 struct pldm_bios_table_attr_entry_integer_info info = {
362 1, /* name handle */
363 false, /* read only */
364 1, /* lower bound */
365 10, /* upper bound */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530366 2, /* scalar increment */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930367 3 /* default value */
368 };
369 auto encodeLength = pldm_bios_table_attr_entry_integer_encode_length();
370 EXPECT_EQ(encodeLength, integerEntry.size());
371
372 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930373 ASSERT_EQ(pldm_bios_table_attr_entry_integer_encode_check(
374 encodeEntry.data(), encodeEntry.size(), &info),
375 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930376 // set attr handle = 0
377 encodeEntry[0] = 0;
378 encodeEntry[1] = 0;
379
380 EXPECT_EQ(integerEntry, encodeEntry);
381
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930382 EXPECT_NE(pldm_bios_table_attr_entry_integer_encode_check(
383 encodeEntry.data(), encodeEntry.size() - 1, &info),
384 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930385
386 auto rc = pldm_bios_table_attr_entry_integer_encode_check(
387 encodeEntry.data(), encodeEntry.size(), &info);
388 EXPECT_EQ(rc, PLDM_SUCCESS);
389 // set attr handle = 0
390 encodeEntry[0] = 0;
391 encodeEntry[1] = 0;
392
393 EXPECT_EQ(integerEntry, encodeEntry);
394
395 rc = pldm_bios_table_attr_entry_integer_encode_check(
396 encodeEntry.data(), encodeEntry.size() - 1, &info);
397 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
398
399 info.lower_bound = 100;
400 info.upper_bound = 50;
401 const char* errmsg;
402 rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
403 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
404 EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg);
405 rc = pldm_bios_table_attr_entry_integer_encode_check(
406 encodeEntry.data(), encodeEntry.size(), &info);
407 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
408}
409
410TEST(AttrTable, integerEntryDecodeTest)
411{
412 std::vector<uint8_t> integerEntry{
413 0, 0, /* attr handle */
414 3, /* attr type */
415 1, 0, /* attr name handle */
416 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
417 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
418 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530419 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930420 };
421
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930422 uint64_t lower;
423 uint64_t upper;
424 uint64_t def;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930425 uint32_t scalar;
426 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
427 integerEntry.data());
428 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
429 &def);
430 EXPECT_EQ(lower, 1u);
431 EXPECT_EQ(upper, 10u);
432 EXPECT_EQ(scalar, 2u);
433 EXPECT_EQ(def, 3u);
434}
435
436TEST(AttrTable, ItearatorTest)
437{
438 std::vector<uint8_t> enumEntry{
439 0, 0, /* attr handle */
440 0, /* attr type */
441 1, 0, /* attr name handle */
442 2, /* number of possible value */
443 2, 0, /* possible value handle */
444 3, 0, /* possible value handle */
445 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530446 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930447 };
448 std::vector<uint8_t> stringEntry{
449 1, 0, /* attr handle */
450 1, /* attr type */
451 12, 0, /* attr name handle */
452 1, /* string type */
453 1, 0, /* minimum length of the string in bytes */
454 100, 0, /* maximum length of the string in bytes */
455 3, 0, /* length of default string in length */
456 'a', 'b', 'c' /* default string */
457 };
458 std::vector<uint8_t> integerEntry{
459 0, 0, /* attr handle */
460 3, /* attr type */
461 1, 0, /* attr name handle */
462 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
463 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
464 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530465 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930466 };
467
468 Table table;
469 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
470 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
471 PLDM_BIOS_ATTR_TABLE);
472 auto entry = pldm_bios_table_iter_attr_entry_value(iter);
473 auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
474 EXPECT_EQ(rc, 0);
475
476 pldm_bios_table_iter_next(iter);
477 entry = pldm_bios_table_iter_attr_entry_value(iter);
478 rc = std::memcmp(entry, stringEntry.data(), stringEntry.size());
479 EXPECT_EQ(rc, 0);
480
481 pldm_bios_table_iter_next(iter);
482 entry = pldm_bios_table_iter_attr_entry_value(iter);
483 rc = std::memcmp(entry, integerEntry.data(), integerEntry.size());
484 EXPECT_EQ(rc, 0);
485
486 pldm_bios_table_iter_next(iter);
487 entry = pldm_bios_table_iter_attr_entry_value(iter);
488 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
489 EXPECT_EQ(rc, 0);
490
491 pldm_bios_table_iter_next(iter);
492 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
493 pldm_bios_table_iter_free(iter);
494}
495
496TEST(AttrTable, FindTest)
497{
498 std::vector<uint8_t> enumEntry{
499 0, 0, /* attr handle */
500 0, /* attr type */
501 1, 0, /* attr name handle */
502 2, /* number of possible value */
503 2, 0, /* possible value handle */
504 3, 0, /* possible value handle */
505 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530506 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930507 };
508 std::vector<uint8_t> stringEntry{
509 1, 0, /* attr handle */
510 1, /* attr type */
511 2, 0, /* attr name handle */
512 1, /* string type */
513 1, 0, /* minimum length of the string in bytes */
514 100, 0, /* maximum length of the string in bytes */
515 3, 0, /* length of default string in length */
516 'a', 'b', 'c' /* default string */
517 };
518 std::vector<uint8_t> integerEntry{
519 0, 0, /* attr handle */
520 3, /* attr type */
521 3, 0, /* attr name handle */
522 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
523 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
524 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530525 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930526 };
527
528 Table table;
529 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
530
531 auto entry =
532 pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 1);
533 EXPECT_NE(entry, nullptr);
534 auto p = reinterpret_cast<const uint8_t*>(entry);
535 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
536 ElementsAreArray(stringEntry));
537
538 entry = pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 3);
539 EXPECT_EQ(entry, nullptr);
540
541 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
542 table.size(), 2);
543 EXPECT_NE(entry, nullptr);
544 p = reinterpret_cast<const uint8_t*>(entry);
545 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
546 ElementsAreArray(stringEntry));
547
548 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
549 table.size(), 4);
550 EXPECT_EQ(entry, nullptr);
551}
552
553TEST(AttrValTable, HeaderDecodeTest)
554{
555 std::vector<uint8_t> enumEntry{
556 1, 0, /* attr handle */
557 0, /* attr type */
558 2, /* number of current value */
559 0, /* current value string handle index */
560 1, /* current value string handle index */
561 };
562 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
563 enumEntry.data());
564 auto attrHandle =
565 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
566 EXPECT_EQ(attrHandle, 1);
567 auto attrType =
568 pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
569 EXPECT_EQ(attrType, 0);
570}
571
572TEST(AttrValTable, EnumEntryEncodeTest)
573{
574 std::vector<uint8_t> enumEntry{
575 0, 0, /* attr handle */
576 0, /* attr type */
577 2, /* number of current value */
578 0, /* current value string handle index */
579 1, /* current value string handle index */
580 };
581
582 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2);
583 EXPECT_EQ(length, enumEntry.size());
584 std::vector<uint8_t> encodeEntry(length, 0);
585 uint8_t handles[] = {0, 1};
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930586 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_enum_check(
587 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles),
588 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930589 EXPECT_EQ(encodeEntry, enumEntry);
590
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930591 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_enum_check(
592 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
593 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930594
595 auto rc = pldm_bios_table_attr_value_entry_encode_enum_check(
596 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2,
597 handles);
598 EXPECT_EQ(rc, PLDM_SUCCESS);
599 EXPECT_EQ(encodeEntry, enumEntry);
600 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
601 enumEntry.data());
602 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY;
603 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
604 encodeEntry.data(), encodeEntry.size(), 0,
605 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles);
606 EXPECT_EQ(rc, PLDM_SUCCESS);
607 EXPECT_EQ(encodeEntry, enumEntry);
608 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
609 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2,
610 handles);
611 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
612 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
613 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2,
614 handles);
615 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
616}
617
618TEST(AttrValTable, EnumEntryDecodeTest)
619{
620 std::vector<uint8_t> enumEntry{
621 0, 0, /* attr handle */
622 0, /* attr type */
623 2, /* number of current value */
624 0, /* current value string handle index */
625 1, /* current value string handle index */
626 };
627
628 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
629 enumEntry.data());
630 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
631 EXPECT_EQ(2, number);
632
633 std::vector<uint8_t> handles(2, 0);
634 auto rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
635 entry, handles.data(), handles.size());
636 EXPECT_EQ(rc, 2);
637 EXPECT_EQ(handles[0], 0);
638 EXPECT_EQ(handles[1], 1);
Archana Kakanib9d951f2023-10-17 05:47:58 -0500639
640 /* Buffer size is more than the number of current string handles */
641 std::vector<uint8_t> handleIndexes(3, 0);
642 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
643 entry, handleIndexes.data(), handleIndexes.size());
644 EXPECT_EQ(rc, 2);
645 EXPECT_EQ(handleIndexes[0], 0);
646 EXPECT_EQ(handleIndexes[1], 1);
647
648 /* Buffersize is less than the number of current string handles */
649 std::vector<uint8_t> strHandles(1, 0);
650 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
651 entry, strHandles.data(), strHandles.size());
652 EXPECT_EQ(rc, 1);
653 EXPECT_EQ(strHandles[0], 0);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930654}
655
656TEST(AttrValTable, stringEntryEncodeTest)
657{
658 std::vector<uint8_t> stringEntry{
659 0, 0, /* attr handle */
660 1, /* attr type */
661 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530662 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930663 };
664
665 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
666 EXPECT_EQ(length, stringEntry.size());
667 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery46d07682023-07-14 15:51:51 +0930668 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_string_check(
669 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc"),
670 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930671 EXPECT_EQ(encodeEntry, stringEntry);
672
Andrew Jeffery46d07682023-07-14 15:51:51 +0930673 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_string_check(
674 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
675 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930676
677 auto rc = pldm_bios_table_attr_value_entry_encode_string_check(
678 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
679 EXPECT_EQ(rc, PLDM_SUCCESS);
680 EXPECT_EQ(encodeEntry, stringEntry);
681 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
682 stringEntry.data());
683 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
684 rc = pldm_bios_table_attr_value_entry_encode_string_check(
685 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
686 3, "abc");
687 EXPECT_EQ(rc, PLDM_SUCCESS);
688 EXPECT_EQ(encodeEntry, stringEntry);
689 rc = pldm_bios_table_attr_value_entry_encode_string_check(
690 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
691 "abc");
692 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
693 rc = pldm_bios_table_attr_value_entry_encode_string_check(
694 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
695 "abc");
696 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
697}
698
699TEST(AttrValTable, StringEntryDecodeTest)
700{
701 std::vector<uint8_t> stringEntry{
702 0, 0, /* attr handle */
703 1, /* attr type */
704 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530705 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930706 };
707
708 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
709 stringEntry.data());
710 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
711 EXPECT_EQ(3, length);
712
713 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
714 EXPECT_EQ(0, handle);
715
716 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
717 EXPECT_EQ(stringEntry.size(), entryLength);
718
719 variable_field currentString{};
720 pldm_bios_table_attr_value_entry_string_decode_string(entry,
721 &currentString);
722 EXPECT_THAT(std::vector<uint8_t>(currentString.ptr,
723 currentString.ptr + currentString.length),
724 ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'}));
725}
726
727TEST(AttrValTable, integerEntryEncodeTest)
728{
729 std::vector<uint8_t> integerEntry{
730 0, 0, /* attr handle */
731 3, /* attr type */
732 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
733 };
734
735 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
736 EXPECT_EQ(length, integerEntry.size());
737 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930738 ASSERT_EQ(
739 pldm_bios_table_attr_value_entry_encode_integer_check(
740 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10),
741 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930742 EXPECT_EQ(encodeEntry, integerEntry);
743
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930744 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_integer_check(
745 encodeEntry.data(), encodeEntry.size() - 1, 0,
746 PLDM_BIOS_INTEGER, 10),
747 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930748
749 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
750 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
751 EXPECT_EQ(rc, PLDM_SUCCESS);
752 EXPECT_EQ(encodeEntry, integerEntry);
753 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
754 integerEntry.data());
755 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
756 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
757 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
758 10);
759 EXPECT_EQ(rc, PLDM_SUCCESS);
760 EXPECT_EQ(encodeEntry, integerEntry);
761
762 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
763 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
764 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
765 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
766 encodeEntry.data(), encodeEntry.size() - 1, 0,
767 PLDM_BIOS_INTEGER_READ_ONLY, 10);
768 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
769}
770
771TEST(AttrValTable, integerEntryDecodeTest)
772{
773 std::vector<uint8_t> integerEntry{
774 0, 0, /* attr handle */
775 3, /* attr type */
776 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
777 };
778
779 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
780 integerEntry.data());
781 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
782 EXPECT_EQ(cv, 10u);
783}
784
785TEST(AttrValTable, IteratorTest)
786{
787 std::vector<uint8_t> enumEntry{
788 0, 0, /* attr handle */
789 0, /* attr type */
790 2, /* number of current value */
791 0, /* current value string handle index */
792 1, /* current value string handle index */
793 };
794 std::vector<uint8_t> stringEntry{
795 0, 0, /* attr handle */
796 1, /* attr type */
797 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530798 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930799 };
800 std::vector<uint8_t> integerEntry{
801 0, 0, /* attr handle */
802 3, /* attr type */
803 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
804 };
805
806 Table table;
807 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
808
809 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
810 PLDM_BIOS_ATTR_VAL_TABLE);
811 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
812
813 auto p = reinterpret_cast<const uint8_t*>(entry);
814 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
815 ElementsAreArray(enumEntry));
816
817 pldm_bios_table_iter_next(iter);
818 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
819 p = reinterpret_cast<const uint8_t*>(entry);
820 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
821 ElementsAreArray(stringEntry));
822
823 pldm_bios_table_iter_next(iter);
824 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
825 p = reinterpret_cast<const uint8_t*>(entry);
826 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
827 ElementsAreArray(integerEntry));
828
829 pldm_bios_table_iter_next(iter);
830 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
831 p = reinterpret_cast<const uint8_t*>(entry);
832 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
833 ElementsAreArray(enumEntry));
834
835 pldm_bios_table_iter_next(iter);
836 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
837
838 pldm_bios_table_iter_free(iter);
839}
840
841TEST(AttrValTable, FindTest)
842{
843 std::vector<uint8_t> enumEntry{
844 0, 0, /* attr handle */
845 0, /* attr type */
846 2, /* number of current value */
847 0, /* current value string handle index */
848 1, /* current value string handle index */
849 };
850 std::vector<uint8_t> stringEntry{
851 1, 0, /* attr handle */
852 1, /* attr type */
853 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530854 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930855 };
856 std::vector<uint8_t> integerEntry{
857 2, 0, /* attr handle */
858 3, /* attr type */
859 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
860 };
861
862 Table table;
863 buildTable(table, enumEntry, stringEntry, integerEntry);
864
865 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
866 table.size(), 1);
867 EXPECT_NE(entry, nullptr);
868 auto p = reinterpret_cast<const uint8_t*>(entry);
869 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
870 ElementsAreArray(stringEntry));
871
872 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
873 table.size(), 3);
874 EXPECT_EQ(entry, nullptr);
875
876 auto firstEntry =
877 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
878 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
Andrew Jefferyfbaea232024-05-23 10:58:29 +0930879#ifdef NDEBUG
880 EXPECT_EQ(pldm_bios_table_attr_value_find_by_handle(table.data(),
881 table.size(), 1),
882 nullptr);
883#else
Andrew Jeffery9c766792022-08-10 23:12:49 +0930884 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
885 table.size(), 1),
886 "entry_length != NULL");
Andrew Jefferyfbaea232024-05-23 10:58:29 +0930887#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +0930888}
889
890TEST(AttrValTable, CopyAndUpdateTest)
891{
892 std::vector<uint8_t> enumEntry{
893 0, 0, /* attr handle */
894 0, /* attr type */
895 2, /* number of current value */
896 0, /* current value string handle index */
897 1, /* current value string handle index */
898 };
899 std::vector<uint8_t> stringEntry{
900 1, 0, /* attr handle */
901 1, /* attr type */
902 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530903 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930904 };
905 std::vector<uint8_t> integerEntry{
906 2, 0, /* attr handle */
907 3, /* attr type */
908 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
909 };
910
911 Table srcTable;
912 buildTable(srcTable, enumEntry, stringEntry, integerEntry);
913
914 std::vector<uint8_t> stringEntry1{
915 1, 0, /* attr handle */
916 1, /* attr type */
917 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530918 'd', 'e', 'f', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930919 };
920
921 Table expectTable;
922 buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
923 Table destTable(expectTable.size() + 10);
924 auto destLength = destTable.size();
925 auto rc = pldm_bios_table_attr_value_copy_and_update(
926 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
927 stringEntry1.data(), stringEntry1.size());
928
929 EXPECT_EQ(rc, PLDM_SUCCESS);
930 EXPECT_EQ(destLength, expectTable.size());
931 destTable.resize(destLength);
932 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
933
934 std::vector<uint8_t> stringEntry2{
935 1, 0, /* attr handle */
936 1, /* attr type */
937 5, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530938 'd', 'e', 'f', 'a', 'b', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930939 };
940 expectTable.resize(0);
941 buildTable(expectTable, enumEntry, stringEntry2, integerEntry);
942 destTable.resize(expectTable.size() + 10);
943 destLength = destTable.size();
944 rc = pldm_bios_table_attr_value_copy_and_update(
945 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
946 stringEntry2.data(), stringEntry2.size());
947 EXPECT_EQ(rc, PLDM_SUCCESS);
948 EXPECT_EQ(destLength, expectTable.size());
949 destTable.resize(destLength);
950 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
951
952 std::vector<uint8_t> stringEntry3{
953 1, 0, /* attr handle */
954 1, /* attr type */
955 1, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530956 'd', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930957 };
958 expectTable.resize(0);
959 buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
960 destTable.resize(expectTable.size() + 10);
961 destLength = destTable.size();
962 rc = pldm_bios_table_attr_value_copy_and_update(
963 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
964 stringEntry3.data(), stringEntry3.size());
965 EXPECT_EQ(rc, PLDM_SUCCESS);
966 EXPECT_EQ(destLength, expectTable.size());
967 destTable.resize(destLength);
968 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
969
970 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer
971 rc = pldm_bios_table_attr_value_copy_and_update(
972 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
973 stringEntry3.data(), stringEntry3.size());
974 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
975 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string
976
977 destTable.resize(expectTable.size() - 1);
978 destLength = destTable.size();
979 rc = pldm_bios_table_attr_value_copy_and_update(
980 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
981 stringEntry3.data(), stringEntry3.size());
982 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
983}
984
985TEST(StringTable, EntryEncodeTest)
986{
987 std::vector<uint8_t> stringEntry{
988 0, 0, /* string handle*/
989 7, 0, /* string length */
990 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
991 };
992
993 const char* str = "Allowed";
994 auto str_length = std::strlen(str);
995 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
996 EXPECT_EQ(encodeLength, stringEntry.size());
997
998 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jefferye48fdd62024-06-25 00:36:20 +0930999 ASSERT_EQ(pldm_bios_table_string_entry_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301000 encodeEntry.data(), encodeEntry.size(), str, str_length),
1001 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301002 // set string handle = 0
1003 encodeEntry[0] = 0;
1004 encodeEntry[1] = 0;
1005
1006 EXPECT_EQ(stringEntry, encodeEntry);
1007
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301008 EXPECT_NE(pldm_bios_table_string_entry_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301009 encodeEntry.data(), encodeEntry.size() - 1, str, str_length),
1010 PLDM_SUCCESS);
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301011 auto rc = pldm_bios_table_string_entry_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +09301012 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
1013 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1014}
1015
1016TEST(StringTable, EntryDecodeTest)
1017{
1018 std::vector<uint8_t> stringEntry{
1019 4, 0, /* string handle*/
1020 7, 0, /* string length */
1021 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
1022 };
1023 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
1024 stringEntry.data());
1025 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1026 EXPECT_EQ(handle, 4);
1027 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
1028 EXPECT_EQ(strLength, 7);
1029
1030 std::vector<char> buffer(strLength + 1, 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301031 pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1032 buffer.size());
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301033 EXPECT_EQ(strlen(buffer.data()), strLength);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301034 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301035 EXPECT_EQ(pldm_bios_table_string_entry_decode_string(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301036 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/),
1037 PLDM_SUCCESS);
1038 EXPECT_EQ(strlen(buffer.data()), 2);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301039 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
1040
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301041 auto rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1042 buffer.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +09301043 EXPECT_EQ(rc, PLDM_SUCCESS);
1044 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
1045
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301046 /* Ensure equivalence with the unchecked API */
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301047 rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1048 2 + 1 /* sizeof '\0' */);
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301049 EXPECT_EQ(rc, std::strcmp("Al", buffer.data()));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301050}
1051
1052TEST(StringTable, IteratorTest)
1053{
1054 std::vector<uint8_t> stringHello{
1055 0, 0, /* string handle*/
1056 5, 0, /* string length */
1057 'H', 'e', 'l', 'l', 'o', /* string */
1058 };
1059 std::vector<uint8_t> stringWorld{
1060 1, 0, /* string handle*/
1061 6, 0, /* string length */
1062 'W', 'o', 'r', 'l', 'd', '!', /* string */
1063 };
1064
1065 Table table;
1066 buildTable(table, stringHello, stringWorld);
1067
1068 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1069 PLDM_BIOS_STRING_TABLE);
1070 auto entry = pldm_bios_table_iter_string_entry_value(iter);
1071 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
1072 EXPECT_EQ(rc, 0);
1073 pldm_bios_table_iter_next(iter);
1074 entry = pldm_bios_table_iter_string_entry_value(iter);
1075 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
1076 EXPECT_EQ(rc, 0);
1077 pldm_bios_table_iter_next(iter);
1078 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
1079 pldm_bios_table_iter_free(iter);
1080}
1081
1082TEST(StringTable, FindTest)
1083{
1084 std::vector<uint8_t> stringHello{
1085 1, 0, /* string handle*/
1086 5, 0, /* string length */
1087 'H', 'e', 'l', 'l', 'o', /* string */
1088 };
1089 std::vector<uint8_t> stringWorld{
1090 2, 0, /* string handle*/
1091 6, 0, /* string length */
1092 'W', 'o', 'r', 'l', 'd', '!', /* string */
1093 };
1094 std::vector<uint8_t> stringHi{
1095 3, 0, /* string handle*/
1096 2, 0, /* string length */
1097 'H', 'i', /* string */
1098 };
1099
1100 Table table;
1101 buildTable(table, stringHello, stringWorld, stringHi);
1102
1103 auto entry = pldm_bios_table_string_find_by_string(table.data(),
1104 table.size(), "World!");
1105 EXPECT_NE(entry, nullptr);
1106 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1107 EXPECT_EQ(handle, 2);
1108
1109 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
1110 "Worl");
1111 EXPECT_EQ(entry, nullptr);
1112
1113 entry =
1114 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
1115 EXPECT_NE(entry, nullptr);
1116 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
1117 EXPECT_EQ(str_length, 2);
1118 std::vector<char> strBuf(str_length + 1, 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301119 auto rc = pldm_bios_table_string_entry_decode_string(entry, strBuf.data(),
1120 strBuf.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +09301121 EXPECT_EQ(rc, PLDM_SUCCESS);
1122 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
1123
1124 entry =
1125 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
1126 EXPECT_EQ(entry, nullptr);
1127}
1128
Andrew Jefferybf6699b2023-07-05 16:27:59 +09301129TEST(Iterator, DeathTest)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301130{
1131
1132 Table table(256, 0);
1133
1134 /* first entry */
1135 auto attr_entry =
1136 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
1137 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1138 PLDM_BIOS_ATTR_TABLE);
1139 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
Andrew Jefferyfbaea232024-05-23 10:58:29 +09301140#ifndef NDEBUG
Andrew Jeffery9c766792022-08-10 23:12:49 +09301141 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
Andrew Jefferyfbaea232024-05-23 10:58:29 +09301142#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301143 pldm_bios_table_iter_free(iter);
1144}
1145
1146TEST(PadAndChecksum, PadAndChecksum)
1147{
1148 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0));
1149 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1));
1150 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2));
1151 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3));
1152 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4));
1153
1154 // The table is borrowed from
1155 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
1156 // refer to the commit message
1157 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
1158 auto sizeWithoutPad = attrValTable.size();
1159 attrValTable.resize(sizeWithoutPad +
1160 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
Andrew Jeffery50dd1592023-07-14 16:02:05 +09301161 ASSERT_EQ(pldm_bios_table_append_pad_checksum_check(
1162 attrValTable.data(), attrValTable.size(), &sizeWithoutPad),
1163 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301164 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
1165 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
1166 EXPECT_EQ(attrValTable, expectedTable);
1167}
1168
1169TEST(BIOSTableChecksum, testBIOSTableChecksum)
1170{
1171 std::vector<uint8_t> stringTable{
1172 1, 0, /* string handle*/
1173 5, 0, /* string length */
1174 'T', 'a', 'b', 'l', 'e', /* string */
1175 };
1176
1177 buildTable(stringTable);
1178
1179 EXPECT_EQ(true,
1180 pldm_bios_table_checksum(stringTable.data(), stringTable.size()));
1181}