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