blob: 5ab1dfe037d9fb453038c848eef363ad2cc4dcd3 [file] [log] [blame]
John Wang871c9272019-12-09 18:02:15 +08001#include <endian.h>
John Wang02700402019-10-06 16:34:29 +08002#include <string.h>
3
4#include <cstring>
John Wangccc04552019-10-14 14:28:25 +08005#include <utility>
John Wang02700402019-10-06 16:34:29 +08006#include <vector>
7
8#include "libpldm/base.h"
9#include "libpldm/bios.h"
10#include "libpldm/bios_table.h"
John Wang871c9272019-12-09 18:02:15 +080011#include "libpldm/utils.h"
John Wang02700402019-10-06 16:34:29 +080012
John Wang49484a12019-12-02 14:21:53 +080013#include <gmock/gmock.h>
John Wang02700402019-10-06 16:34:29 +080014#include <gtest/gtest.h>
15
John Wang49484a12019-12-02 14:21:53 +080016using testing::ElementsAreArray;
John Wang02700402019-10-06 16:34:29 +080017using Table = std::vector<uint8_t>;
18
19void buildTable(Table& table)
20{
21 auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
22 table.insert(table.end(), padSize, 0);
John Wang871c9272019-12-09 18:02:15 +080023 uint32_t checksum = crc32(table.data(), table.size());
24 checksum = htole32(checksum);
25 uint8_t a[4];
26 std::memcpy(a, &checksum, sizeof(checksum));
27 table.insert(table.end(), std::begin(a), std::end(a));
John Wang02700402019-10-06 16:34:29 +080028}
29
30template <typename First, typename... Rest>
31void buildTable(Table& table, First& first, Rest&... rest)
32{
33 table.insert(table.end(), first.begin(), first.end());
34 buildTable(table, rest...);
35}
36
37TEST(AttrTable, EnumEntryDecodeTest)
38{
39 std::vector<uint8_t> enumEntry{
40 0, 0, /* attr handle */
41 0, /* attr type */
42 1, 0, /* attr name handle */
43 2, /* number of possible value */
44 2, 0, /* possible value handle */
45 3, 0, /* possible value handle */
46 1, /* number of default value */
47 0 /* defaut value string handle index */
48 };
49
50 auto entry =
51 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
52 uint8_t pvNumber = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
53 EXPECT_EQ(pvNumber, 2);
John Wang02700402019-10-06 16:34:29 +080054 pvNumber = 0;
55 auto rc =
56 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
57 EXPECT_EQ(rc, PLDM_SUCCESS);
58 EXPECT_EQ(pvNumber, 2);
John Wang3ad21752019-10-06 16:42:21 +080059
60 std::vector<uint16_t> pvHandles(pvNumber, 0);
61 pvNumber = pldm_bios_table_attr_entry_enum_decode_pv_hdls(
62 entry, pvHandles.data(), pvHandles.size());
63 EXPECT_EQ(pvNumber, 2);
64 EXPECT_EQ(pvHandles[0], 2);
65 EXPECT_EQ(pvHandles[1], 3);
66 pvHandles.resize(1);
67 pvNumber = pldm_bios_table_attr_entry_enum_decode_pv_hdls(
68 entry, pvHandles.data(), pvHandles.size());
69 EXPECT_EQ(pvNumber, 1);
70 EXPECT_EQ(pvHandles[0], 2);
71
72 pvHandles.resize(2);
73 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
74 entry, pvHandles.data(), pvHandles.size());
75 EXPECT_EQ(rc, PLDM_SUCCESS);
76 EXPECT_EQ(pvHandles[0], 2);
77 EXPECT_EQ(pvHandles[1], 3);
78 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
79 entry, pvHandles.data(), 1);
80 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
81
82 uint8_t defNumber = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
83 EXPECT_EQ(defNumber, 1);
John Wang02700402019-10-06 16:34:29 +080084 defNumber = 0;
85 rc =
86 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
87 EXPECT_EQ(rc, PLDM_SUCCESS);
88 EXPECT_EQ(defNumber, 1);
89
90 rc =
91 pldm_bios_table_attr_entry_enum_decode_pv_num_check(nullptr, &pvNumber);
92 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
93 rc = pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, nullptr);
94 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
95
96 entry->attr_type = PLDM_BIOS_STRING;
97 rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
98 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
99
100 rc =
101 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
102 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
John Wang3ad21752019-10-06 16:42:21 +0800103 rc =
104 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(entry, nullptr, 0);
105 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
John Wang02700402019-10-06 16:34:29 +0800106}
107
John Wangccc04552019-10-14 14:28:25 +0800108TEST(AttrTable, EnumEntryEncodeTest)
109{
110 std::vector<uint8_t> enumEntry{
111 0, 0, /* attr handle */
112 0, /* attr type */
113 1, 0, /* attr name handle */
114 2, /* number of possible value */
115 2, 0, /* possible value handle */
116 3, 0, /* possible value handle */
117 1, /* number of default value */
118 0 /* defaut value string handle index */
119 };
120
121 std::vector<uint16_t> pv_hdls{2, 3};
122 std::vector<uint8_t> defs{0};
123
124 struct pldm_bios_table_attr_entry_enum_info info = {
125 1, /* name handle */
126 false, /* read only */
127 2, /* pv number */
128 pv_hdls.data(), /* pv handle */
129 1, /*def number */
130 defs.data() /*def index*/
131 };
132 auto encodeLength = pldm_bios_table_attr_entry_enum_encode_length(2, 1);
133 EXPECT_EQ(encodeLength, enumEntry.size());
134
135 std::vector<uint8_t> encodeEntry(encodeLength, 0);
136 pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
137 encodeEntry.size(), &info);
138 // set attr handle = 0
139 encodeEntry[0] = 0;
140 encodeEntry[1] = 0;
141
142 EXPECT_EQ(enumEntry, encodeEntry);
143
144 EXPECT_DEATH(pldm_bios_table_attr_entry_enum_encode(
145 encodeEntry.data(), encodeEntry.size() - 1, &info),
146 "length <= entry_length");
147 auto rc = pldm_bios_table_attr_entry_enum_encode_check(
148 encodeEntry.data(), encodeEntry.size(), &info);
149 EXPECT_EQ(rc, PLDM_SUCCESS);
150 // set attr handle = 0
151 encodeEntry[0] = 0;
152 encodeEntry[1] = 0;
153
154 EXPECT_EQ(enumEntry, encodeEntry);
155 rc = pldm_bios_table_attr_entry_enum_encode_check(
156 encodeEntry.data(), encodeEntry.size() - 1, &info);
157 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
158}
159
John Wang02700402019-10-06 16:34:29 +0800160TEST(AttrTable, StringEntryDecodeTest)
161{
162 std::vector<uint8_t> stringEntry{
163 1, 0, /* attr handle */
164 1, /* attr type */
165 12, 0, /* attr name handle */
166 1, /* string type */
167 1, 0, /* minimum length of the string in bytes */
168 100, 0, /* maximum length of the string in bytes */
169 3, 0, /* length of default string in length */
170 'a', 'b', 'c' /* default string */
171 };
172
173 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
174 stringEntry.data());
175 uint16_t def_string_length =
176 pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
177 EXPECT_EQ(def_string_length, 3);
178
179 def_string_length = 0;
180 auto rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
181 entry, &def_string_length);
182 EXPECT_EQ(rc, PLDM_SUCCESS);
183 EXPECT_EQ(def_string_length, 3);
184
185 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
186 entry, nullptr);
187 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
188 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
189 nullptr, &def_string_length);
190 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
191 entry->attr_type = PLDM_BIOS_INTEGER;
192 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
193 entry, &def_string_length);
194 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
195 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
196 nullptr, &def_string_length);
197 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
198}
199
John Wangccc04552019-10-14 14:28:25 +0800200TEST(AttrTable, StringEntryEncodeTest)
201{
202 std::vector<uint8_t> stringEntry{
203 0, 0, /* attr handle */
204 1, /* attr type */
205 3, 0, /* attr name handle */
206 1, /* string type */
207 1, 0, /* min string length */
208 100, 0, /* max string length */
209 3, 0, /* default string length */
210 'a', 'b', 'c', /* defaul string */
211 };
212
213 struct pldm_bios_table_attr_entry_string_info info = {
214 3, /* name handle */
215 false, /* read only */
216 1, /* string type ascii */
217 1, /* min length */
218 100, /* max length */
219 3, /* def length */
220 "abc", /* def string */
221 };
222 auto encodeLength = pldm_bios_table_attr_entry_string_encode_length(3);
223 EXPECT_EQ(encodeLength, stringEntry.size());
224
225 std::vector<uint8_t> encodeEntry(encodeLength, 0);
226 pldm_bios_table_attr_entry_string_encode(encodeEntry.data(),
227 encodeEntry.size(), &info);
228 // set attr handle = 0
229 encodeEntry[0] = 0;
230 encodeEntry[1] = 0;
231
232 EXPECT_EQ(stringEntry, encodeEntry);
233
234 EXPECT_DEATH(pldm_bios_table_attr_entry_string_encode(
235 encodeEntry.data(), encodeEntry.size() - 1, &info),
236 "length <= entry_length");
237 auto rc = pldm_bios_table_attr_entry_string_encode_check(
238 encodeEntry.data(), encodeEntry.size(), &info);
239 EXPECT_EQ(rc, PLDM_SUCCESS);
240 // set attr handle = 0
241 encodeEntry[0] = 0;
242 encodeEntry[1] = 0;
243
244 EXPECT_EQ(stringEntry, encodeEntry);
245 rc = pldm_bios_table_attr_entry_string_encode_check(
246 encodeEntry.data(), encodeEntry.size() - 1, &info);
247 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
248 std::swap(info.max_length, info.min_length);
John Wang827c5de2019-11-07 18:27:27 +0800249 const char* errmsg;
250 rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
251 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
252 EXPECT_STREQ(
253 "MinimumStingLength should not be greater than MaximumStringLength",
254 errmsg);
John Wangccc04552019-10-14 14:28:25 +0800255 rc = pldm_bios_table_attr_entry_string_encode_check(
256 encodeEntry.data(), encodeEntry.size(), &info);
257 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
258 std::swap(info.max_length, info.min_length);
259
260 std::vector<uint8_t> stringEntryLength0{
261 0, 0, /* attr handle */
262 1, /* attr type */
263 3, 0, /* attr name handle */
264 1, /* string type */
265 1, 0, /* min string length */
266 100, 0, /* max string length */
267 0, 0, /* default string length */
268 };
269
270 info.def_length = 0;
271 info.def_string = nullptr;
272
273 encodeLength = pldm_bios_table_attr_entry_string_encode_length(0);
274 EXPECT_EQ(encodeLength, stringEntryLength0.size());
275
276 encodeEntry.resize(encodeLength);
277 pldm_bios_table_attr_entry_string_encode(encodeEntry.data(),
278 encodeEntry.size(), &info);
279 // set attr handle = 0
280 encodeEntry[0] = 0;
281 encodeEntry[1] = 0;
282
283 EXPECT_EQ(stringEntryLength0, encodeEntry);
284}
285
John Wangca230822019-10-16 11:39:27 +0800286TEST(AttrTable, integerEntryEncodeTest)
287{
288 std::vector<uint8_t> integerEntry{
289 0, 0, /* attr handle */
290 3, /* attr type */
291 1, 0, /* attr name handle */
292 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
293 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
294 2, 0, 0, 0, /* scalar increment */
295 3, 0, 0, 0, 0, 0, 0, 0, /* defaut value */
296 };
297
298 std::vector<uint16_t> pv_hdls{2, 3};
299 std::vector<uint8_t> defs{0};
300
301 struct pldm_bios_table_attr_entry_integer_info info = {
302 1, /* name handle */
303 false, /* read only */
304 1, /* lower bound */
305 10, /* upper bound */
306 2, /* sacalar increment */
307 3 /* default value */
308 };
309 auto encodeLength = pldm_bios_table_attr_entry_integer_encode_length();
310 EXPECT_EQ(encodeLength, integerEntry.size());
311
312 std::vector<uint8_t> encodeEntry(encodeLength, 0);
313 pldm_bios_table_attr_entry_integer_encode(encodeEntry.data(),
314 encodeEntry.size(), &info);
315 // set attr handle = 0
316 encodeEntry[0] = 0;
317 encodeEntry[1] = 0;
318
319 EXPECT_EQ(integerEntry, encodeEntry);
320
321 EXPECT_DEATH(pldm_bios_table_attr_entry_integer_encode(
322 encodeEntry.data(), encodeEntry.size() - 1, &info),
323 "length <= entry_length");
324
325 auto rc = pldm_bios_table_attr_entry_integer_encode_check(
326 encodeEntry.data(), encodeEntry.size(), &info);
327 EXPECT_EQ(rc, PLDM_SUCCESS);
328 // set attr handle = 0
329 encodeEntry[0] = 0;
330 encodeEntry[1] = 0;
331
332 EXPECT_EQ(integerEntry, encodeEntry);
333
334 rc = pldm_bios_table_attr_entry_integer_encode_check(
335 encodeEntry.data(), encodeEntry.size() - 1, &info);
336 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
337
338 info.lower_bound = 100;
339 info.upper_bound = 50;
John Wang827c5de2019-11-07 18:27:27 +0800340 const char* errmsg;
341 rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
342 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
343 EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg);
John Wangca230822019-10-16 11:39:27 +0800344 rc = pldm_bios_table_attr_entry_integer_encode_check(
345 encodeEntry.data(), encodeEntry.size(), &info);
346 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
347}
348
John Wang02700402019-10-06 16:34:29 +0800349TEST(AttrTable, ItearatorTest)
350{
351 std::vector<uint8_t> enumEntry{
352 0, 0, /* attr handle */
353 0, /* attr type */
354 1, 0, /* attr name handle */
355 2, /* number of possible value */
356 2, 0, /* possible value handle */
357 3, 0, /* possible value handle */
358 1, /* number of default value */
359 0 /* defaut value string handle index */
360 };
361 std::vector<uint8_t> stringEntry{
362 1, 0, /* attr handle */
363 1, /* attr type */
364 12, 0, /* attr name handle */
365 1, /* string type */
366 1, 0, /* minimum length of the string in bytes */
367 100, 0, /* maximum length of the string in bytes */
368 3, 0, /* length of default string in length */
369 'a', 'b', 'c' /* default string */
370 };
John Wangca230822019-10-16 11:39:27 +0800371 std::vector<uint8_t> integerEntry{
372 0, 0, /* attr handle */
373 3, /* attr type */
374 1, 0, /* attr name handle */
375 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
376 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
377 2, 0, 0, 0, /* scalar increment */
378 3, 0, 0, 0, 0, 0, 0, 0, /* defaut value */
379 };
John Wang02700402019-10-06 16:34:29 +0800380
381 Table table;
John Wangca230822019-10-16 11:39:27 +0800382 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
John Wang02700402019-10-06 16:34:29 +0800383 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
384 PLDM_BIOS_ATTR_TABLE);
385 auto entry = pldm_bios_table_iter_attr_entry_value(iter);
386 auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
387 EXPECT_EQ(rc, 0);
388
389 pldm_bios_table_iter_next(iter);
390 entry = pldm_bios_table_iter_attr_entry_value(iter);
391 rc = std::memcmp(entry, stringEntry.data(), stringEntry.size());
392 EXPECT_EQ(rc, 0);
393
394 pldm_bios_table_iter_next(iter);
395 entry = pldm_bios_table_iter_attr_entry_value(iter);
John Wangca230822019-10-16 11:39:27 +0800396 rc = std::memcmp(entry, integerEntry.data(), integerEntry.size());
397 EXPECT_EQ(rc, 0);
398
399 pldm_bios_table_iter_next(iter);
400 entry = pldm_bios_table_iter_attr_entry_value(iter);
John Wang02700402019-10-06 16:34:29 +0800401 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
402 EXPECT_EQ(rc, 0);
403
404 pldm_bios_table_iter_next(iter);
405 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
406 pldm_bios_table_iter_free(iter);
407}
408
John Wang3ad21752019-10-06 16:42:21 +0800409TEST(AttrValTable, EnumEntryEncodeTest)
410{
411 std::vector<uint8_t> enumEntry{
412 0, 0, /* attr handle */
413 0, /* attr type */
414 2, /* number of current value */
415 0, /* current value string handle index */
416 1, /* current value string handle index */
417 };
418
419 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2);
420 EXPECT_EQ(length, enumEntry.size());
421 std::vector<uint8_t> encodeEntry(length, 0);
422 uint8_t handles[] = {0, 1};
423 pldm_bios_table_attr_value_entry_encode_enum(
424 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles);
425 EXPECT_EQ(encodeEntry, enumEntry);
426
427 EXPECT_DEATH(
428 pldm_bios_table_attr_value_entry_encode_enum(
429 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
430 "length <= entry_length");
431
432 auto rc = pldm_bios_table_attr_value_entry_encode_enum_check(
433 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2,
434 handles);
435 EXPECT_EQ(rc, PLDM_SUCCESS);
436 EXPECT_EQ(encodeEntry, enumEntry);
437 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
438 enumEntry.data());
439 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY;
440 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
441 encodeEntry.data(), encodeEntry.size(), 0,
442 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles);
443 EXPECT_EQ(rc, PLDM_SUCCESS);
444 EXPECT_EQ(encodeEntry, enumEntry);
445 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
446 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2,
447 handles);
448 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
449 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
450 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2,
451 handles);
452 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
453}
454
John Wang49484a12019-12-02 14:21:53 +0800455TEST(AttrValTable, EnumEntryDecodeTest)
456{
457 std::vector<uint8_t> enumEntry{
458 0, 0, /* attr handle */
459 0, /* attr type */
460 2, /* number of current value */
461 0, /* current value string handle index */
462 1, /* current value string handle index */
463 };
464
465 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
466 enumEntry.data());
467 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
468 EXPECT_EQ(2, number);
469}
470
John Wang3ad21752019-10-06 16:42:21 +0800471TEST(AttrValTable, stringEntryEncodeTest)
472{
473 std::vector<uint8_t> stringEntry{
474 0, 0, /* attr handle */
475 1, /* attr type */
476 3, 0, /* current string length */
477 'a', 'b', 'c', /* defaut value string handle index */
478 };
479
480 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
481 EXPECT_EQ(length, stringEntry.size());
482 std::vector<uint8_t> encodeEntry(length, 0);
483 pldm_bios_table_attr_value_entry_encode_string(
484 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc");
485 EXPECT_EQ(encodeEntry, stringEntry);
486
487 EXPECT_DEATH(
488 pldm_bios_table_attr_value_entry_encode_string(
489 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
490 "length <= entry_length");
491
492 auto rc = pldm_bios_table_attr_value_entry_encode_string_check(
493 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
494 EXPECT_EQ(rc, PLDM_SUCCESS);
495 EXPECT_EQ(encodeEntry, stringEntry);
496 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
497 stringEntry.data());
498 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
499 rc = pldm_bios_table_attr_value_entry_encode_string_check(
500 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
501 3, "abc");
502 EXPECT_EQ(rc, PLDM_SUCCESS);
503 EXPECT_EQ(encodeEntry, stringEntry);
504 rc = pldm_bios_table_attr_value_entry_encode_string_check(
505 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
506 "abc");
507 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
508 rc = pldm_bios_table_attr_value_entry_encode_string_check(
509 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
510 "abc");
511 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
512}
513
John Wang49484a12019-12-02 14:21:53 +0800514TEST(AttrValTable, StringEntryDecodeTest)
515{
516 std::vector<uint8_t> stringEntry{
517 0, 0, /* attr handle */
518 1, /* attr type */
519 3, 0, /* current string length */
520 'a', 'b', 'c', /* defaut value string handle index */
521 };
522
523 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
524 stringEntry.data());
525 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
526 EXPECT_EQ(3, length);
John Wang3342adb2019-11-29 16:03:58 +0800527
528 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
529 EXPECT_EQ(0, handle);
530
John Wang8e877e02020-02-03 16:06:55 +0800531 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
532 EXPECT_EQ(stringEntry.size(), entryLength);
John Wang49484a12019-12-02 14:21:53 +0800533}
534
John Wangca230822019-10-16 11:39:27 +0800535TEST(AttrValTable, integerEntryEncodeTest)
536{
537 std::vector<uint8_t> integerEntry{
538 0, 0, /* attr handle */
539 3, /* attr type */
540 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
541 };
542
543 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
544 EXPECT_EQ(length, integerEntry.size());
545 std::vector<uint8_t> encodeEntry(length, 0);
546 pldm_bios_table_attr_value_entry_encode_integer(
547 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
548 EXPECT_EQ(encodeEntry, integerEntry);
549
550 EXPECT_DEATH(pldm_bios_table_attr_value_entry_encode_integer(
551 encodeEntry.data(), encodeEntry.size() - 1, 0,
552 PLDM_BIOS_INTEGER, 10),
553 "length <= entry_length");
554
555 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
556 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
557 EXPECT_EQ(rc, PLDM_SUCCESS);
558 EXPECT_EQ(encodeEntry, integerEntry);
559 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
560 integerEntry.data());
561 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
562 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
563 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
564 10);
565 EXPECT_EQ(rc, PLDM_SUCCESS);
566 EXPECT_EQ(encodeEntry, integerEntry);
567
568 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
569 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
570 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
571 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
572 encodeEntry.data(), encodeEntry.size() - 1, 0,
573 PLDM_BIOS_INTEGER_READ_ONLY, 10);
574 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
575}
576
John Wang49484a12019-12-02 14:21:53 +0800577TEST(AttrValTable, IteratorTest)
578{
579 std::vector<uint8_t> enumEntry{
580 0, 0, /* attr handle */
581 0, /* attr type */
582 2, /* number of current value */
583 0, /* current value string handle index */
584 1, /* current value string handle index */
585 };
586 std::vector<uint8_t> stringEntry{
587 0, 0, /* attr handle */
588 1, /* attr type */
589 3, 0, /* current string length */
590 'a', 'b', 'c', /* defaut value string handle index */
591 };
592 std::vector<uint8_t> integerEntry{
593 0, 0, /* attr handle */
594 3, /* attr type */
595 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
596 };
597
598 Table table;
599 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
600
601 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
602 PLDM_BIOS_ATTR_VAL_TABLE);
603 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
604
605 auto p = reinterpret_cast<const uint8_t*>(entry);
606 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
607 ElementsAreArray(enumEntry));
608
609 pldm_bios_table_iter_next(iter);
610 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
611 p = reinterpret_cast<const uint8_t*>(entry);
612 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
613 ElementsAreArray(stringEntry));
614
615 pldm_bios_table_iter_next(iter);
616 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
617 p = reinterpret_cast<const uint8_t*>(entry);
618 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
619 ElementsAreArray(integerEntry));
620
621 pldm_bios_table_iter_next(iter);
622 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
623 p = reinterpret_cast<const uint8_t*>(entry);
624 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
625 ElementsAreArray(enumEntry));
626
627 pldm_bios_table_iter_next(iter);
628 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
629
630 pldm_bios_table_iter_free(iter);
631}
632
John Wang3342adb2019-11-29 16:03:58 +0800633TEST(AttrValTable, FindTest)
634{
635 std::vector<uint8_t> enumEntry{
636 0, 0, /* attr handle */
637 0, /* attr type */
638 2, /* number of current value */
639 0, /* current value string handle index */
640 1, /* current value string handle index */
641 };
642 std::vector<uint8_t> stringEntry{
643 1, 0, /* attr handle */
644 1, /* attr type */
645 3, 0, /* current string length */
646 'a', 'b', 'c', /* defaut value string handle index */
647 };
648 std::vector<uint8_t> integerEntry{
649 2, 0, /* attr handle */
650 3, /* attr type */
651 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
652 };
653
654 Table table;
655 buildTable(table, enumEntry, stringEntry, integerEntry);
656
657 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
658 table.size(), 1);
659 EXPECT_NE(entry, nullptr);
660 auto p = reinterpret_cast<const uint8_t*>(entry);
661 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
662 ElementsAreArray(stringEntry));
663
664 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
665 table.size(), 3);
666 EXPECT_EQ(entry, nullptr);
667
668 auto firstEntry =
669 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
670 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
671 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
672 table.size(), 1),
673 "entry_length != NULL");
674}
675
John Wang871c9272019-12-09 18:02:15 +0800676TEST(AttrValTable, CopyAndUpdateTest)
677{
678 std::vector<uint8_t> enumEntry{
679 0, 0, /* attr handle */
680 0, /* attr type */
681 2, /* number of current value */
682 0, /* current value string handle index */
683 1, /* current value string handle index */
684 };
685 std::vector<uint8_t> stringEntry{
686 1, 0, /* attr handle */
687 1, /* attr type */
688 3, 0, /* current string length */
689 'a', 'b', 'c', /* defaut value string handle index */
690 };
691 std::vector<uint8_t> integerEntry{
692 2, 0, /* attr handle */
693 3, /* attr type */
694 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
695 };
696
697 Table srcTable;
698 buildTable(srcTable, enumEntry, stringEntry, integerEntry);
699
700 std::vector<uint8_t> stringEntry1{
701 1, 0, /* attr handle */
702 1, /* attr type */
703 3, 0, /* current string length */
704 'd', 'e', 'f', /* defaut value string handle index */
705 };
706
707 Table expectTable;
708 buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
709 Table destTable(expectTable.size() + 10);
710 auto destLength = destTable.size();
711 auto rc = pldm_bios_table_attr_value_copy_and_update(
712 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
713 stringEntry1.data(), stringEntry1.size());
714
715 EXPECT_EQ(rc, PLDM_SUCCESS);
716 EXPECT_EQ(destLength, expectTable.size());
717 destTable.resize(destLength);
718 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
719
720 std::vector<uint8_t> stringEntry2{
721 1, 0, /* attr handle */
722 1, /* attr type */
723 5, 0, /* current string length */
724 'd', 'e', 'f', 'a', 'b', /* defaut value string handle index */
725 };
726 expectTable.resize(0);
727 buildTable(expectTable, enumEntry, stringEntry2, integerEntry);
728 destTable.resize(expectTable.size() + 10);
729 destLength = destTable.size();
730 rc = pldm_bios_table_attr_value_copy_and_update(
731 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
732 stringEntry2.data(), stringEntry2.size());
733 EXPECT_EQ(rc, PLDM_SUCCESS);
734 EXPECT_EQ(destLength, expectTable.size());
735 destTable.resize(destLength);
736 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
737
738 std::vector<uint8_t> stringEntry3{
739 1, 0, /* attr handle */
740 1, /* attr type */
741 1, 0, /* current string length */
742 'd', /* defaut value string handle index */
743 };
744 expectTable.resize(0);
745 buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
746 destTable.resize(expectTable.size() + 10);
747 destLength = destTable.size();
748 rc = pldm_bios_table_attr_value_copy_and_update(
749 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
750 stringEntry3.data(), stringEntry3.size());
751 EXPECT_EQ(rc, PLDM_SUCCESS);
752 EXPECT_EQ(destLength, expectTable.size());
753 destTable.resize(destLength);
754 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
755
756 destTable.resize(expectTable.size() - 1);
757 destLength = destTable.size();
758 rc = pldm_bios_table_attr_value_copy_and_update(
759 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
760 stringEntry3.data(), stringEntry3.size());
761 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
762}
763
John Wangdd9a6282019-10-11 18:52:46 +0800764TEST(StringTable, EntryEncodeTest)
765{
766 std::vector<uint8_t> stringEntry{
767 0, 0, /* string handle*/
768 7, 0, /* string length */
769 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
770 };
771
772 const char* str = "Allowed";
773 auto str_length = std::strlen(str);
774 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
775 EXPECT_EQ(encodeLength, stringEntry.size());
776
777 std::vector<uint8_t> encodeEntry(encodeLength, 0);
778 pldm_bios_table_string_entry_encode(encodeEntry.data(), encodeEntry.size(),
779 str, str_length);
780 // set string handle = 0
781 encodeEntry[0] = 0;
782 encodeEntry[1] = 0;
783
784 EXPECT_EQ(stringEntry, encodeEntry);
785
786 EXPECT_DEATH(pldm_bios_table_string_entry_encode(encodeEntry.data(),
787 encodeEntry.size() - 1,
788 str, str_length),
789 "length <= entry_length");
790 auto rc = pldm_bios_table_string_entry_encode_check(
791 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
792 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
793}
794
795TEST(StringTable, EntryDecodeTest)
796{
797 std::vector<uint8_t> stringEntry{
798 4, 0, /* string handle*/
799 7, 0, /* string length */
800 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
801 };
802 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
803 stringEntry.data());
804 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
805 EXPECT_EQ(handle, 4);
806 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
807 EXPECT_EQ(strLength, 7);
808
809 std::vector<char> buffer(strLength + 1, 0);
810 auto decodedLength = pldm_bios_table_string_entry_decode_string(
811 entry, buffer.data(), buffer.size());
812 EXPECT_EQ(decodedLength, strLength);
813 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
814 decodedLength =
815 pldm_bios_table_string_entry_decode_string(entry, buffer.data(), 2);
816 EXPECT_EQ(decodedLength, 2);
817 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
818
819 auto rc = pldm_bios_table_string_entry_decode_string_check(
820 entry, buffer.data(), buffer.size());
821 EXPECT_EQ(rc, PLDM_SUCCESS);
822 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
823
824 rc = pldm_bios_table_string_entry_decode_string_check(entry, buffer.data(),
825 buffer.size() - 1);
826 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
827}
828
829TEST(StringTable, IteratorTest)
830{
831 std::vector<uint8_t> stringHello{
832 0, 0, /* string handle*/
833 5, 0, /* string length */
834 'H', 'e', 'l', 'l', 'o', /* string */
835 };
836 std::vector<uint8_t> stringWorld{
837 1, 0, /* string handle*/
838 6, 0, /* string length */
839 'W', 'o', 'r', 'l', 'd', '!', /* string */
840 };
841
842 Table table;
843 buildTable(table, stringHello, stringWorld);
844
845 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
846 PLDM_BIOS_STRING_TABLE);
847 auto entry = pldm_bios_table_iter_string_entry_value(iter);
848 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
849 EXPECT_EQ(rc, 0);
850 pldm_bios_table_iter_next(iter);
851 entry = pldm_bios_table_iter_string_entry_value(iter);
852 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
853 EXPECT_EQ(rc, 0);
854 pldm_bios_table_iter_next(iter);
855 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
856 pldm_bios_table_iter_free(iter);
857}
858
859TEST(StringTable, FindTest)
860{
861 std::vector<uint8_t> stringHello{
862 1, 0, /* string handle*/
863 5, 0, /* string length */
864 'H', 'e', 'l', 'l', 'o', /* string */
865 };
866 std::vector<uint8_t> stringWorld{
867 2, 0, /* string handle*/
868 6, 0, /* string length */
869 'W', 'o', 'r', 'l', 'd', '!', /* string */
870 };
871 std::vector<uint8_t> stringHi{
872 3, 0, /* string handle*/
873 2, 0, /* string length */
874 'H', 'i', /* string */
875 };
876
877 Table table;
878 buildTable(table, stringHello, stringWorld, stringHi);
879
880 auto entry = pldm_bios_table_string_find_by_string(table.data(),
881 table.size(), "World!");
882 EXPECT_NE(entry, nullptr);
883 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
884 EXPECT_EQ(handle, 2);
885
886 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
887 "Worl");
888 EXPECT_EQ(entry, nullptr);
889
890 entry =
891 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
892 EXPECT_NE(entry, nullptr);
893 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
894 EXPECT_EQ(str_length, 2);
895 std::vector<char> strBuf(str_length + 1, 0);
896 auto rc = pldm_bios_table_string_entry_decode_string_check(
897 entry, strBuf.data(), strBuf.size());
898 EXPECT_EQ(rc, PLDM_SUCCESS);
899 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
900
901 entry =
902 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
903 EXPECT_EQ(entry, nullptr);
904}
905
John Wang02700402019-10-06 16:34:29 +0800906TEST(Itearator, DeathTest)
907{
908
909 Table table(256, 0);
910
911 /* first entry */
912 auto attr_entry =
913 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
914 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
915 PLDM_BIOS_ATTR_TABLE);
916 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
917 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
John Wang02700402019-10-06 16:34:29 +0800918 pldm_bios_table_iter_free(iter);
919}
John Wang79c37f12019-10-31 15:46:31 +0800920
921TEST(PadAndChecksum, PadAndChecksum)
922{
923 EXPECT_EQ(4, pldm_bios_table_pad_checksum_size(0));
924 EXPECT_EQ(7, pldm_bios_table_pad_checksum_size(1));
925 EXPECT_EQ(6, pldm_bios_table_pad_checksum_size(2));
926 EXPECT_EQ(5, pldm_bios_table_pad_checksum_size(3));
927 EXPECT_EQ(4, pldm_bios_table_pad_checksum_size(4));
928
929 // The table is borrowed from
930 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
931 // refer to the commit message
932 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
933 auto sizeWithoutPad = attrValTable.size();
934 attrValTable.resize(sizeWithoutPad +
935 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
936 pldm_bios_table_append_pad_checksum(attrValTable.data(),
937 attrValTable.size(), sizeWithoutPad);
938 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
939 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
940 EXPECT_EQ(attrValTable, expectedTable);
941}