blob: b2f9fa250b37e94d620022218e999bcf4c92bec4 [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;
Andrew Jefferyb06882f2024-06-25 15:52:02 +093077 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNumber),
78 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093079 EXPECT_EQ(pvNumber, 2);
80 pvNumber = 0;
Andrew Jefferyb06882f2024-06-25 15:52:02 +093081 auto rc = pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +093082 EXPECT_EQ(rc, PLDM_SUCCESS);
83 EXPECT_EQ(pvNumber, 2);
84
85 std::vector<uint16_t> pvHandles(pvNumber, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093086 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
87 entry, pvHandles.data(), pvHandles.size()),
88 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093089 EXPECT_EQ(pvNumber, 2);
90 EXPECT_EQ(pvHandles[0], 2);
91 EXPECT_EQ(pvHandles[1], 3);
92 pvHandles.resize(1);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093093 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
94 entry, pvHandles.data(), pvHandles.size()),
95 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093096 EXPECT_EQ(pvHandles[0], 2);
97
98 pvHandles.resize(2);
99 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
100 entry, pvHandles.data(), pvHandles.size());
101 EXPECT_EQ(rc, PLDM_SUCCESS);
102 EXPECT_EQ(pvHandles[0], 2);
103 EXPECT_EQ(pvHandles[1], 3);
104 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
105 entry, pvHandles.data(), 1);
Andrew Jeffery0c9f5a82023-06-14 15:01:06 +0930106 EXPECT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930107
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930108 uint8_t defNumber;
109 ASSERT_EQ(
110 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber),
111 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930112 EXPECT_EQ(defNumber, 1);
113 std::vector<uint8_t> defIndices(defNumber);
114 rc = pldm_bios_table_attr_entry_enum_decode_def_indices(
115 entry, defIndices.data(), defIndices.size());
116 EXPECT_EQ(rc, defNumber);
117 EXPECT_THAT(defIndices, ElementsAreArray({1}));
118
119 defNumber = 0;
120 rc =
121 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
122 EXPECT_EQ(rc, PLDM_SUCCESS);
123 EXPECT_EQ(defNumber, 1);
124
Andrew Jefferyb06882f2024-06-25 15:52:02 +0930125 rc = pldm_bios_table_attr_entry_enum_decode_pv_num(nullptr, &pvNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930126 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
127 rc = pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, nullptr);
128 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
129
130 entry->attr_type = PLDM_BIOS_STRING;
Andrew Jefferyb06882f2024-06-25 15:52:02 +0930131 rc = pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930132 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
133
134 rc =
135 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
136 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
137 rc =
138 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(entry, nullptr, 0);
139 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
140}
141
142TEST(AttrTable, EnumEntryEncodeTest)
143{
144 std::vector<uint8_t> enumEntry{
145 0, 0, /* attr handle */
146 0, /* attr type */
147 1, 0, /* attr name handle */
148 2, /* number of possible value */
149 2, 0, /* possible value handle */
150 3, 0, /* possible value handle */
151 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530152 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930153 };
154
155 std::vector<uint16_t> pv_hdls{2, 3};
156 std::vector<uint8_t> defs{0};
157
158 struct pldm_bios_table_attr_entry_enum_info info = {
159 1, /* name handle */
160 false, /* read only */
161 2, /* pv number */
162 pv_hdls.data(), /* pv handle */
163 1, /*def number */
164 defs.data() /*def index*/
165 };
166 auto encodeLength = pldm_bios_table_attr_entry_enum_encode_length(2, 1);
167 EXPECT_EQ(encodeLength, enumEntry.size());
168
169 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930170 ASSERT_EQ(pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
171 encodeEntry.size(), &info),
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930172 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930173 // set attr handle = 0
174 encodeEntry[0] = 0;
175 encodeEntry[1] = 0;
176
177 EXPECT_EQ(enumEntry, encodeEntry);
178
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930179 EXPECT_NE(pldm_bios_table_attr_entry_enum_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930180 encodeEntry.data(), encodeEntry.size() - 1, &info),
181 PLDM_SUCCESS);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930182 auto rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
183 encodeEntry.size(), &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930184 EXPECT_EQ(rc, PLDM_SUCCESS);
185 // set attr handle = 0
186 encodeEntry[0] = 0;
187 encodeEntry[1] = 0;
188
189 EXPECT_EQ(enumEntry, encodeEntry);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930190 rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
191 encodeEntry.size() - 1, &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930192 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
193}
194
195TEST(AttrTable, StringEntryDecodeTest)
196{
197 std::vector<uint8_t> stringEntry{
198 1, 0, /* attr handle */
199 1, /* attr type */
200 12, 0, /* attr name handle */
201 1, /* string type */
202 1, 0, /* minimum length of the string in bytes */
203 100, 0, /* maximum length of the string in bytes */
204 3, 0, /* length of default string in length */
205 'a', 'b', 'c' /* default string */
206 };
207
208 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
209 stringEntry.data());
210 auto stringType =
211 pldm_bios_table_attr_entry_string_decode_string_type(entry);
212 EXPECT_EQ(stringType, 1);
213 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
214 EXPECT_EQ(minLength, 1);
215 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
216 EXPECT_EQ(maxLength, 100);
217
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930218 uint16_t defStringLength;
219 ASSERT_EQ(pldm_bios_table_attr_entry_string_decode_def_string_length_check(
220 entry, &defStringLength),
221 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930222 EXPECT_EQ(defStringLength, 3);
223 std::vector<char> defString(defStringLength + 1);
224 auto rc = pldm_bios_table_attr_entry_string_decode_def_string(
225 entry, defString.data(), defString.size());
226 EXPECT_EQ(rc, 3);
227 EXPECT_STREQ(defString.data(), "abc");
228 rc = pldm_bios_table_attr_entry_string_decode_def_string(
229 entry, defString.data(), defString.size() - 1);
230 EXPECT_EQ(rc, 2);
231 EXPECT_STREQ(defString.data(), "ab");
232
233 defStringLength = 0;
234 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
235 entry, &defStringLength);
236 EXPECT_EQ(rc, PLDM_SUCCESS);
237 EXPECT_EQ(defStringLength, 3);
238
239 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
240 entry, nullptr);
241 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
242 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
243 nullptr, &defStringLength);
244 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
245 entry->attr_type = PLDM_BIOS_INTEGER;
246 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
247 entry, &defStringLength);
248 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
249 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
250 nullptr, &defStringLength);
251 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
252}
253
254TEST(AttrTable, StringEntryEncodeTest)
255{
256 std::vector<uint8_t> stringEntry{
257 0, 0, /* attr handle */
258 1, /* attr type */
259 3, 0, /* attr name handle */
260 1, /* string type */
261 1, 0, /* min string length */
262 100, 0, /* max string length */
263 3, 0, /* default string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530264 'a', 'b', 'c', /* default string */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930265 };
266
267 struct pldm_bios_table_attr_entry_string_info info = {
268 3, /* name handle */
269 false, /* read only */
270 1, /* string type ascii */
271 1, /* min length */
272 100, /* max length */
273 3, /* def length */
274 "abc", /* def string */
275 };
276 auto encodeLength = pldm_bios_table_attr_entry_string_encode_length(3);
277 EXPECT_EQ(encodeLength, stringEntry.size());
278
279 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930280 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check(
281 encodeEntry.data(), encodeEntry.size(), &info),
282 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930283 // set attr handle = 0
284 encodeEntry[0] = 0;
285 encodeEntry[1] = 0;
286
287 EXPECT_EQ(stringEntry, encodeEntry);
288
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930289 EXPECT_NE(pldm_bios_table_attr_entry_string_encode_check(
290 encodeEntry.data(), encodeEntry.size() - 1, &info),
291 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930292 auto rc = pldm_bios_table_attr_entry_string_encode_check(
293 encodeEntry.data(), encodeEntry.size(), &info);
294 EXPECT_EQ(rc, PLDM_SUCCESS);
295 // set attr handle = 0
296 encodeEntry[0] = 0;
297 encodeEntry[1] = 0;
298
299 EXPECT_EQ(stringEntry, encodeEntry);
300 rc = pldm_bios_table_attr_entry_string_encode_check(
301 encodeEntry.data(), encodeEntry.size() - 1, &info);
302 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
303 std::swap(info.max_length, info.min_length);
304 const char* errmsg;
305 rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
306 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
307 EXPECT_STREQ(
308 "MinimumStingLength should not be greater than MaximumStringLength",
309 errmsg);
310 rc = pldm_bios_table_attr_entry_string_encode_check(
311 encodeEntry.data(), encodeEntry.size(), &info);
312 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
313 std::swap(info.max_length, info.min_length);
314
315 std::vector<uint8_t> stringEntryLength0{
316 0, 0, /* attr handle */
317 1, /* attr type */
318 3, 0, /* attr name handle */
319 1, /* string type */
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930320 0, 0, /* min string length */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930321 100, 0, /* max string length */
322 0, 0, /* default string length */
323 };
324
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930325 info.min_length = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930326 info.def_length = 0;
327 info.def_string = nullptr;
328
329 encodeLength = pldm_bios_table_attr_entry_string_encode_length(0);
330 EXPECT_EQ(encodeLength, stringEntryLength0.size());
331
332 encodeEntry.resize(encodeLength);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930333 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check(
334 encodeEntry.data(), encodeEntry.size(), &info),
335 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930336 // set attr handle = 0
337 encodeEntry[0] = 0;
338 encodeEntry[1] = 0;
339
340 EXPECT_EQ(stringEntryLength0, encodeEntry);
341}
342
343TEST(AttrTable, integerEntryEncodeTest)
344{
345 std::vector<uint8_t> integerEntry{
346 0, 0, /* attr handle */
347 3, /* attr type */
348 1, 0, /* attr name handle */
349 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
350 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
351 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530352 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930353 };
354
355 std::vector<uint16_t> pv_hdls{2, 3};
356 std::vector<uint8_t> defs{0};
357
358 struct pldm_bios_table_attr_entry_integer_info info = {
359 1, /* name handle */
360 false, /* read only */
361 1, /* lower bound */
362 10, /* upper bound */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530363 2, /* scalar increment */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930364 3 /* default value */
365 };
366 auto encodeLength = pldm_bios_table_attr_entry_integer_encode_length();
367 EXPECT_EQ(encodeLength, integerEntry.size());
368
369 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930370 ASSERT_EQ(pldm_bios_table_attr_entry_integer_encode_check(
371 encodeEntry.data(), encodeEntry.size(), &info),
372 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930373 // set attr handle = 0
374 encodeEntry[0] = 0;
375 encodeEntry[1] = 0;
376
377 EXPECT_EQ(integerEntry, encodeEntry);
378
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930379 EXPECT_NE(pldm_bios_table_attr_entry_integer_encode_check(
380 encodeEntry.data(), encodeEntry.size() - 1, &info),
381 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930382
383 auto rc = pldm_bios_table_attr_entry_integer_encode_check(
384 encodeEntry.data(), encodeEntry.size(), &info);
385 EXPECT_EQ(rc, PLDM_SUCCESS);
386 // set attr handle = 0
387 encodeEntry[0] = 0;
388 encodeEntry[1] = 0;
389
390 EXPECT_EQ(integerEntry, encodeEntry);
391
392 rc = pldm_bios_table_attr_entry_integer_encode_check(
393 encodeEntry.data(), encodeEntry.size() - 1, &info);
394 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
395
396 info.lower_bound = 100;
397 info.upper_bound = 50;
398 const char* errmsg;
399 rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
400 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
401 EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg);
402 rc = pldm_bios_table_attr_entry_integer_encode_check(
403 encodeEntry.data(), encodeEntry.size(), &info);
404 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
405}
406
407TEST(AttrTable, integerEntryDecodeTest)
408{
409 std::vector<uint8_t> integerEntry{
410 0, 0, /* attr handle */
411 3, /* attr type */
412 1, 0, /* attr name handle */
413 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
414 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
415 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530416 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930417 };
418
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930419 uint64_t lower;
420 uint64_t upper;
421 uint64_t def;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930422 uint32_t scalar;
423 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
424 integerEntry.data());
425 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
426 &def);
427 EXPECT_EQ(lower, 1u);
428 EXPECT_EQ(upper, 10u);
429 EXPECT_EQ(scalar, 2u);
430 EXPECT_EQ(def, 3u);
431}
432
433TEST(AttrTable, ItearatorTest)
434{
435 std::vector<uint8_t> enumEntry{
436 0, 0, /* attr handle */
437 0, /* attr type */
438 1, 0, /* attr name handle */
439 2, /* number of possible value */
440 2, 0, /* possible value handle */
441 3, 0, /* possible value handle */
442 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530443 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930444 };
445 std::vector<uint8_t> stringEntry{
446 1, 0, /* attr handle */
447 1, /* attr type */
448 12, 0, /* attr name handle */
449 1, /* string type */
450 1, 0, /* minimum length of the string in bytes */
451 100, 0, /* maximum length of the string in bytes */
452 3, 0, /* length of default string in length */
453 'a', 'b', 'c' /* default string */
454 };
455 std::vector<uint8_t> integerEntry{
456 0, 0, /* attr handle */
457 3, /* attr type */
458 1, 0, /* attr name handle */
459 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
460 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
461 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530462 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930463 };
464
465 Table table;
466 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
467 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
468 PLDM_BIOS_ATTR_TABLE);
469 auto entry = pldm_bios_table_iter_attr_entry_value(iter);
470 auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
471 EXPECT_EQ(rc, 0);
472
473 pldm_bios_table_iter_next(iter);
474 entry = pldm_bios_table_iter_attr_entry_value(iter);
475 rc = std::memcmp(entry, stringEntry.data(), stringEntry.size());
476 EXPECT_EQ(rc, 0);
477
478 pldm_bios_table_iter_next(iter);
479 entry = pldm_bios_table_iter_attr_entry_value(iter);
480 rc = std::memcmp(entry, integerEntry.data(), integerEntry.size());
481 EXPECT_EQ(rc, 0);
482
483 pldm_bios_table_iter_next(iter);
484 entry = pldm_bios_table_iter_attr_entry_value(iter);
485 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
486 EXPECT_EQ(rc, 0);
487
488 pldm_bios_table_iter_next(iter);
489 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
490 pldm_bios_table_iter_free(iter);
491}
492
493TEST(AttrTable, FindTest)
494{
495 std::vector<uint8_t> enumEntry{
496 0, 0, /* attr handle */
497 0, /* attr type */
498 1, 0, /* attr name handle */
499 2, /* number of possible value */
500 2, 0, /* possible value handle */
501 3, 0, /* possible value handle */
502 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530503 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930504 };
505 std::vector<uint8_t> stringEntry{
506 1, 0, /* attr handle */
507 1, /* attr type */
508 2, 0, /* attr name handle */
509 1, /* string type */
510 1, 0, /* minimum length of the string in bytes */
511 100, 0, /* maximum length of the string in bytes */
512 3, 0, /* length of default string in length */
513 'a', 'b', 'c' /* default string */
514 };
515 std::vector<uint8_t> integerEntry{
516 0, 0, /* attr handle */
517 3, /* attr type */
518 3, 0, /* attr name handle */
519 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
520 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
521 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530522 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930523 };
524
525 Table table;
526 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
527
528 auto entry =
529 pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 1);
530 EXPECT_NE(entry, nullptr);
531 auto p = reinterpret_cast<const uint8_t*>(entry);
532 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
533 ElementsAreArray(stringEntry));
534
535 entry = pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 3);
536 EXPECT_EQ(entry, nullptr);
537
538 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
539 table.size(), 2);
540 EXPECT_NE(entry, nullptr);
541 p = reinterpret_cast<const uint8_t*>(entry);
542 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
543 ElementsAreArray(stringEntry));
544
545 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
546 table.size(), 4);
547 EXPECT_EQ(entry, nullptr);
548}
549
550TEST(AttrValTable, HeaderDecodeTest)
551{
552 std::vector<uint8_t> enumEntry{
553 1, 0, /* attr handle */
554 0, /* attr type */
555 2, /* number of current value */
556 0, /* current value string handle index */
557 1, /* current value string handle index */
558 };
559 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
560 enumEntry.data());
561 auto attrHandle =
562 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
563 EXPECT_EQ(attrHandle, 1);
564 auto attrType =
565 pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
566 EXPECT_EQ(attrType, 0);
567}
568
569TEST(AttrValTable, EnumEntryEncodeTest)
570{
571 std::vector<uint8_t> enumEntry{
572 0, 0, /* attr handle */
573 0, /* attr type */
574 2, /* number of current value */
575 0, /* current value string handle index */
576 1, /* current value string handle index */
577 };
578
579 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2);
580 EXPECT_EQ(length, enumEntry.size());
581 std::vector<uint8_t> encodeEntry(length, 0);
582 uint8_t handles[] = {0, 1};
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930583 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_enum_check(
584 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles),
585 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930586 EXPECT_EQ(encodeEntry, enumEntry);
587
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930588 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_enum_check(
589 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
590 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930591
592 auto rc = pldm_bios_table_attr_value_entry_encode_enum_check(
593 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2,
594 handles);
595 EXPECT_EQ(rc, PLDM_SUCCESS);
596 EXPECT_EQ(encodeEntry, enumEntry);
597 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
598 enumEntry.data());
599 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY;
600 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
601 encodeEntry.data(), encodeEntry.size(), 0,
602 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles);
603 EXPECT_EQ(rc, PLDM_SUCCESS);
604 EXPECT_EQ(encodeEntry, enumEntry);
605 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
606 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2,
607 handles);
608 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
609 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
610 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2,
611 handles);
612 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
613}
614
615TEST(AttrValTable, EnumEntryDecodeTest)
616{
617 std::vector<uint8_t> enumEntry{
618 0, 0, /* attr handle */
619 0, /* attr type */
620 2, /* number of current value */
621 0, /* current value string handle index */
622 1, /* current value string handle index */
623 };
624
625 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
626 enumEntry.data());
627 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
628 EXPECT_EQ(2, number);
629
630 std::vector<uint8_t> handles(2, 0);
631 auto rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
632 entry, handles.data(), handles.size());
633 EXPECT_EQ(rc, 2);
634 EXPECT_EQ(handles[0], 0);
635 EXPECT_EQ(handles[1], 1);
Archana Kakanib9d951f2023-10-17 05:47:58 -0500636
637 /* Buffer size is more than the number of current string handles */
638 std::vector<uint8_t> handleIndexes(3, 0);
639 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
640 entry, handleIndexes.data(), handleIndexes.size());
641 EXPECT_EQ(rc, 2);
642 EXPECT_EQ(handleIndexes[0], 0);
643 EXPECT_EQ(handleIndexes[1], 1);
644
645 /* Buffersize is less than the number of current string handles */
646 std::vector<uint8_t> strHandles(1, 0);
647 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
648 entry, strHandles.data(), strHandles.size());
649 EXPECT_EQ(rc, 1);
650 EXPECT_EQ(strHandles[0], 0);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930651}
652
653TEST(AttrValTable, stringEntryEncodeTest)
654{
655 std::vector<uint8_t> stringEntry{
656 0, 0, /* attr handle */
657 1, /* attr type */
658 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530659 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930660 };
661
662 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
663 EXPECT_EQ(length, stringEntry.size());
664 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery46d07682023-07-14 15:51:51 +0930665 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_string_check(
666 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc"),
667 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930668 EXPECT_EQ(encodeEntry, stringEntry);
669
Andrew Jeffery46d07682023-07-14 15:51:51 +0930670 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_string_check(
671 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
672 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930673
674 auto rc = pldm_bios_table_attr_value_entry_encode_string_check(
675 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
676 EXPECT_EQ(rc, PLDM_SUCCESS);
677 EXPECT_EQ(encodeEntry, stringEntry);
678 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
679 stringEntry.data());
680 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
681 rc = pldm_bios_table_attr_value_entry_encode_string_check(
682 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
683 3, "abc");
684 EXPECT_EQ(rc, PLDM_SUCCESS);
685 EXPECT_EQ(encodeEntry, stringEntry);
686 rc = pldm_bios_table_attr_value_entry_encode_string_check(
687 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
688 "abc");
689 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
690 rc = pldm_bios_table_attr_value_entry_encode_string_check(
691 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
692 "abc");
693 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
694}
695
696TEST(AttrValTable, StringEntryDecodeTest)
697{
698 std::vector<uint8_t> stringEntry{
699 0, 0, /* attr handle */
700 1, /* attr type */
701 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530702 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930703 };
704
705 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
706 stringEntry.data());
707 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
708 EXPECT_EQ(3, length);
709
710 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
711 EXPECT_EQ(0, handle);
712
713 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
714 EXPECT_EQ(stringEntry.size(), entryLength);
715
716 variable_field currentString{};
717 pldm_bios_table_attr_value_entry_string_decode_string(entry,
718 &currentString);
719 EXPECT_THAT(std::vector<uint8_t>(currentString.ptr,
720 currentString.ptr + currentString.length),
721 ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'}));
722}
723
724TEST(AttrValTable, integerEntryEncodeTest)
725{
726 std::vector<uint8_t> integerEntry{
727 0, 0, /* attr handle */
728 3, /* attr type */
729 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
730 };
731
732 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
733 EXPECT_EQ(length, integerEntry.size());
734 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930735 ASSERT_EQ(
736 pldm_bios_table_attr_value_entry_encode_integer_check(
737 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10),
738 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930739 EXPECT_EQ(encodeEntry, integerEntry);
740
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930741 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_integer_check(
742 encodeEntry.data(), encodeEntry.size() - 1, 0,
743 PLDM_BIOS_INTEGER, 10),
744 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930745
746 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
747 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
748 EXPECT_EQ(rc, PLDM_SUCCESS);
749 EXPECT_EQ(encodeEntry, integerEntry);
750 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
751 integerEntry.data());
752 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
753 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
754 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
755 10);
756 EXPECT_EQ(rc, PLDM_SUCCESS);
757 EXPECT_EQ(encodeEntry, integerEntry);
758
759 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
760 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
761 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
762 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
763 encodeEntry.data(), encodeEntry.size() - 1, 0,
764 PLDM_BIOS_INTEGER_READ_ONLY, 10);
765 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
766}
767
768TEST(AttrValTable, integerEntryDecodeTest)
769{
770 std::vector<uint8_t> integerEntry{
771 0, 0, /* attr handle */
772 3, /* attr type */
773 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
774 };
775
776 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
777 integerEntry.data());
778 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
779 EXPECT_EQ(cv, 10u);
780}
781
782TEST(AttrValTable, IteratorTest)
783{
784 std::vector<uint8_t> enumEntry{
785 0, 0, /* attr handle */
786 0, /* attr type */
787 2, /* number of current value */
788 0, /* current value string handle index */
789 1, /* current value string handle index */
790 };
791 std::vector<uint8_t> stringEntry{
792 0, 0, /* attr handle */
793 1, /* attr type */
794 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530795 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930796 };
797 std::vector<uint8_t> integerEntry{
798 0, 0, /* attr handle */
799 3, /* attr type */
800 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
801 };
802
803 Table table;
804 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
805
806 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
807 PLDM_BIOS_ATTR_VAL_TABLE);
808 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
809
810 auto p = reinterpret_cast<const uint8_t*>(entry);
811 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
812 ElementsAreArray(enumEntry));
813
814 pldm_bios_table_iter_next(iter);
815 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
816 p = reinterpret_cast<const uint8_t*>(entry);
817 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
818 ElementsAreArray(stringEntry));
819
820 pldm_bios_table_iter_next(iter);
821 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
822 p = reinterpret_cast<const uint8_t*>(entry);
823 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
824 ElementsAreArray(integerEntry));
825
826 pldm_bios_table_iter_next(iter);
827 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
828 p = reinterpret_cast<const uint8_t*>(entry);
829 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
830 ElementsAreArray(enumEntry));
831
832 pldm_bios_table_iter_next(iter);
833 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
834
835 pldm_bios_table_iter_free(iter);
836}
837
838TEST(AttrValTable, FindTest)
839{
840 std::vector<uint8_t> enumEntry{
841 0, 0, /* attr handle */
842 0, /* attr type */
843 2, /* number of current value */
844 0, /* current value string handle index */
845 1, /* current value string handle index */
846 };
847 std::vector<uint8_t> stringEntry{
848 1, 0, /* attr handle */
849 1, /* attr type */
850 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530851 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930852 };
853 std::vector<uint8_t> integerEntry{
854 2, 0, /* attr handle */
855 3, /* attr type */
856 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
857 };
858
859 Table table;
860 buildTable(table, enumEntry, stringEntry, integerEntry);
861
862 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
863 table.size(), 1);
864 EXPECT_NE(entry, nullptr);
865 auto p = reinterpret_cast<const uint8_t*>(entry);
866 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
867 ElementsAreArray(stringEntry));
868
869 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
870 table.size(), 3);
871 EXPECT_EQ(entry, nullptr);
872
873 auto firstEntry =
874 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
875 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
Andrew Jefferyfbaea232024-05-23 10:58:29 +0930876#ifdef NDEBUG
877 EXPECT_EQ(pldm_bios_table_attr_value_find_by_handle(table.data(),
878 table.size(), 1),
879 nullptr);
880#else
Andrew Jeffery9c766792022-08-10 23:12:49 +0930881 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
882 table.size(), 1),
883 "entry_length != NULL");
Andrew Jefferyfbaea232024-05-23 10:58:29 +0930884#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +0930885}
886
887TEST(AttrValTable, CopyAndUpdateTest)
888{
889 std::vector<uint8_t> enumEntry{
890 0, 0, /* attr handle */
891 0, /* attr type */
892 2, /* number of current value */
893 0, /* current value string handle index */
894 1, /* current value string handle index */
895 };
896 std::vector<uint8_t> stringEntry{
897 1, 0, /* attr handle */
898 1, /* attr type */
899 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530900 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930901 };
902 std::vector<uint8_t> integerEntry{
903 2, 0, /* attr handle */
904 3, /* attr type */
905 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
906 };
907
908 Table srcTable;
909 buildTable(srcTable, enumEntry, stringEntry, integerEntry);
910
911 std::vector<uint8_t> stringEntry1{
912 1, 0, /* attr handle */
913 1, /* attr type */
914 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530915 'd', 'e', 'f', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930916 };
917
918 Table expectTable;
919 buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
920 Table destTable(expectTable.size() + 10);
921 auto destLength = destTable.size();
922 auto rc = pldm_bios_table_attr_value_copy_and_update(
923 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
924 stringEntry1.data(), stringEntry1.size());
925
926 EXPECT_EQ(rc, PLDM_SUCCESS);
927 EXPECT_EQ(destLength, expectTable.size());
928 destTable.resize(destLength);
929 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
930
931 std::vector<uint8_t> stringEntry2{
932 1, 0, /* attr handle */
933 1, /* attr type */
934 5, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530935 'd', 'e', 'f', 'a', 'b', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930936 };
937 expectTable.resize(0);
938 buildTable(expectTable, enumEntry, stringEntry2, integerEntry);
939 destTable.resize(expectTable.size() + 10);
940 destLength = destTable.size();
941 rc = pldm_bios_table_attr_value_copy_and_update(
942 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
943 stringEntry2.data(), stringEntry2.size());
944 EXPECT_EQ(rc, PLDM_SUCCESS);
945 EXPECT_EQ(destLength, expectTable.size());
946 destTable.resize(destLength);
947 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
948
949 std::vector<uint8_t> stringEntry3{
950 1, 0, /* attr handle */
951 1, /* attr type */
952 1, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530953 'd', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930954 };
955 expectTable.resize(0);
956 buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
957 destTable.resize(expectTable.size() + 10);
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_SUCCESS);
963 EXPECT_EQ(destLength, expectTable.size());
964 destTable.resize(destLength);
965 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
966
967 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer
968 rc = pldm_bios_table_attr_value_copy_and_update(
969 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
970 stringEntry3.data(), stringEntry3.size());
971 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
972 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string
973
974 destTable.resize(expectTable.size() - 1);
975 destLength = destTable.size();
976 rc = pldm_bios_table_attr_value_copy_and_update(
977 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
978 stringEntry3.data(), stringEntry3.size());
979 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
980}
981
982TEST(StringTable, EntryEncodeTest)
983{
984 std::vector<uint8_t> stringEntry{
985 0, 0, /* string handle*/
986 7, 0, /* string length */
987 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
988 };
989
990 const char* str = "Allowed";
991 auto str_length = std::strlen(str);
992 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
993 EXPECT_EQ(encodeLength, stringEntry.size());
994
995 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jefferye48fdd62024-06-25 00:36:20 +0930996 ASSERT_EQ(pldm_bios_table_string_entry_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930997 encodeEntry.data(), encodeEntry.size(), str, str_length),
998 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930999 // set string handle = 0
1000 encodeEntry[0] = 0;
1001 encodeEntry[1] = 0;
1002
1003 EXPECT_EQ(stringEntry, encodeEntry);
1004
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301005 EXPECT_NE(pldm_bios_table_string_entry_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301006 encodeEntry.data(), encodeEntry.size() - 1, str, str_length),
1007 PLDM_SUCCESS);
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301008 auto rc = pldm_bios_table_string_entry_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +09301009 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
1010 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1011}
1012
1013TEST(StringTable, EntryDecodeTest)
1014{
1015 std::vector<uint8_t> stringEntry{
1016 4, 0, /* string handle*/
1017 7, 0, /* string length */
1018 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
1019 };
1020 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
1021 stringEntry.data());
1022 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1023 EXPECT_EQ(handle, 4);
1024 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
1025 EXPECT_EQ(strLength, 7);
1026
1027 std::vector<char> buffer(strLength + 1, 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301028 pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1029 buffer.size());
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301030 EXPECT_EQ(strlen(buffer.data()), strLength);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301031 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301032 EXPECT_EQ(pldm_bios_table_string_entry_decode_string(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301033 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/),
1034 PLDM_SUCCESS);
1035 EXPECT_EQ(strlen(buffer.data()), 2);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301036 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
1037
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301038 auto rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1039 buffer.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +09301040 EXPECT_EQ(rc, PLDM_SUCCESS);
1041 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
1042
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301043 /* Ensure equivalence with the unchecked API */
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301044 rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1045 2 + 1 /* sizeof '\0' */);
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301046 EXPECT_EQ(rc, std::strcmp("Al", buffer.data()));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301047}
1048
1049TEST(StringTable, IteratorTest)
1050{
1051 std::vector<uint8_t> stringHello{
1052 0, 0, /* string handle*/
1053 5, 0, /* string length */
1054 'H', 'e', 'l', 'l', 'o', /* string */
1055 };
1056 std::vector<uint8_t> stringWorld{
1057 1, 0, /* string handle*/
1058 6, 0, /* string length */
1059 'W', 'o', 'r', 'l', 'd', '!', /* string */
1060 };
1061
1062 Table table;
1063 buildTable(table, stringHello, stringWorld);
1064
1065 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1066 PLDM_BIOS_STRING_TABLE);
1067 auto entry = pldm_bios_table_iter_string_entry_value(iter);
1068 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
1069 EXPECT_EQ(rc, 0);
1070 pldm_bios_table_iter_next(iter);
1071 entry = pldm_bios_table_iter_string_entry_value(iter);
1072 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
1073 EXPECT_EQ(rc, 0);
1074 pldm_bios_table_iter_next(iter);
1075 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
1076 pldm_bios_table_iter_free(iter);
1077}
1078
1079TEST(StringTable, FindTest)
1080{
1081 std::vector<uint8_t> stringHello{
1082 1, 0, /* string handle*/
1083 5, 0, /* string length */
1084 'H', 'e', 'l', 'l', 'o', /* string */
1085 };
1086 std::vector<uint8_t> stringWorld{
1087 2, 0, /* string handle*/
1088 6, 0, /* string length */
1089 'W', 'o', 'r', 'l', 'd', '!', /* string */
1090 };
1091 std::vector<uint8_t> stringHi{
1092 3, 0, /* string handle*/
1093 2, 0, /* string length */
1094 'H', 'i', /* string */
1095 };
1096
1097 Table table;
1098 buildTable(table, stringHello, stringWorld, stringHi);
1099
1100 auto entry = pldm_bios_table_string_find_by_string(table.data(),
1101 table.size(), "World!");
1102 EXPECT_NE(entry, nullptr);
1103 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1104 EXPECT_EQ(handle, 2);
1105
1106 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
1107 "Worl");
1108 EXPECT_EQ(entry, nullptr);
1109
1110 entry =
1111 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
1112 EXPECT_NE(entry, nullptr);
1113 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
1114 EXPECT_EQ(str_length, 2);
1115 std::vector<char> strBuf(str_length + 1, 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301116 auto rc = pldm_bios_table_string_entry_decode_string(entry, strBuf.data(),
1117 strBuf.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +09301118 EXPECT_EQ(rc, PLDM_SUCCESS);
1119 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
1120
1121 entry =
1122 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
1123 EXPECT_EQ(entry, nullptr);
1124}
1125
Andrew Jefferybf6699b2023-07-05 16:27:59 +09301126TEST(Iterator, DeathTest)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301127{
1128
1129 Table table(256, 0);
1130
1131 /* first entry */
1132 auto attr_entry =
1133 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
1134 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1135 PLDM_BIOS_ATTR_TABLE);
1136 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
Andrew Jefferyfbaea232024-05-23 10:58:29 +09301137#ifndef NDEBUG
Andrew Jeffery9c766792022-08-10 23:12:49 +09301138 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
Andrew Jefferyfbaea232024-05-23 10:58:29 +09301139#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301140 pldm_bios_table_iter_free(iter);
1141}
1142
1143TEST(PadAndChecksum, PadAndChecksum)
1144{
1145 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0));
1146 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1));
1147 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2));
1148 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3));
1149 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4));
1150
1151 // The table is borrowed from
1152 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
1153 // refer to the commit message
1154 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
1155 auto sizeWithoutPad = attrValTable.size();
1156 attrValTable.resize(sizeWithoutPad +
1157 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
Andrew Jeffery50dd1592023-07-14 16:02:05 +09301158 ASSERT_EQ(pldm_bios_table_append_pad_checksum_check(
1159 attrValTable.data(), attrValTable.size(), &sizeWithoutPad),
1160 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301161 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
1162 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
1163 EXPECT_EQ(attrValTable, expectedTable);
1164}
1165
1166TEST(BIOSTableChecksum, testBIOSTableChecksum)
1167{
1168 std::vector<uint8_t> stringTable{
1169 1, 0, /* string handle*/
1170 5, 0, /* string length */
1171 'T', 'a', 'b', 'l', 'e', /* string */
1172 };
1173
1174 buildTable(stringTable);
1175
1176 EXPECT_EQ(true,
1177 pldm_bios_table_checksum(stringTable.data(), stringTable.size()));
1178}