blob: f1e0e560220410edd4617807b7c171de90bc09e7 [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
John Wang8e877e02020-02-03 16:06:55 +0800525 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
526 EXPECT_EQ(stringEntry.size(), entryLength);
John Wang49484a12019-12-02 14:21:53 +0800527}
528
John Wangca230822019-10-16 11:39:27 +0800529TEST(AttrValTable, integerEntryEncodeTest)
530{
531 std::vector<uint8_t> integerEntry{
532 0, 0, /* attr handle */
533 3, /* attr type */
534 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
535 };
536
537 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
538 EXPECT_EQ(length, integerEntry.size());
539 std::vector<uint8_t> encodeEntry(length, 0);
540 pldm_bios_table_attr_value_entry_encode_integer(
541 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
542 EXPECT_EQ(encodeEntry, integerEntry);
543
544 EXPECT_DEATH(pldm_bios_table_attr_value_entry_encode_integer(
545 encodeEntry.data(), encodeEntry.size() - 1, 0,
546 PLDM_BIOS_INTEGER, 10),
547 "length <= entry_length");
548
549 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
550 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
551 EXPECT_EQ(rc, PLDM_SUCCESS);
552 EXPECT_EQ(encodeEntry, integerEntry);
553 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
554 integerEntry.data());
555 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
556 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
557 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
558 10);
559 EXPECT_EQ(rc, PLDM_SUCCESS);
560 EXPECT_EQ(encodeEntry, integerEntry);
561
562 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
563 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
564 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
565 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
566 encodeEntry.data(), encodeEntry.size() - 1, 0,
567 PLDM_BIOS_INTEGER_READ_ONLY, 10);
568 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
569}
570
John Wang49484a12019-12-02 14:21:53 +0800571TEST(AttrValTable, IteratorTest)
572{
573 std::vector<uint8_t> enumEntry{
574 0, 0, /* attr handle */
575 0, /* attr type */
576 2, /* number of current value */
577 0, /* current value string handle index */
578 1, /* current value string handle index */
579 };
580 std::vector<uint8_t> stringEntry{
581 0, 0, /* attr handle */
582 1, /* attr type */
583 3, 0, /* current string length */
584 'a', 'b', 'c', /* defaut value string handle index */
585 };
586 std::vector<uint8_t> integerEntry{
587 0, 0, /* attr handle */
588 3, /* attr type */
589 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
590 };
591
592 Table table;
593 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
594
595 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
596 PLDM_BIOS_ATTR_VAL_TABLE);
597 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
598
599 auto p = reinterpret_cast<const uint8_t*>(entry);
600 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
601 ElementsAreArray(enumEntry));
602
603 pldm_bios_table_iter_next(iter);
604 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
605 p = reinterpret_cast<const uint8_t*>(entry);
606 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
607 ElementsAreArray(stringEntry));
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 + integerEntry.size()),
613 ElementsAreArray(integerEntry));
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 + enumEntry.size()),
619 ElementsAreArray(enumEntry));
620
621 pldm_bios_table_iter_next(iter);
622 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
623
624 pldm_bios_table_iter_free(iter);
625}
626
John Wang3342adb2019-11-29 16:03:58 +0800627TEST(AttrValTable, FindTest)
628{
629 std::vector<uint8_t> enumEntry{
630 0, 0, /* attr handle */
631 0, /* attr type */
632 2, /* number of current value */
633 0, /* current value string handle index */
634 1, /* current value string handle index */
635 };
636 std::vector<uint8_t> stringEntry{
637 1, 0, /* attr handle */
638 1, /* attr type */
639 3, 0, /* current string length */
640 'a', 'b', 'c', /* defaut value string handle index */
641 };
642 std::vector<uint8_t> integerEntry{
643 2, 0, /* attr handle */
644 3, /* attr type */
645 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
646 };
647
648 Table table;
649 buildTable(table, enumEntry, stringEntry, integerEntry);
650
651 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
652 table.size(), 1);
653 EXPECT_NE(entry, nullptr);
654 auto p = reinterpret_cast<const uint8_t*>(entry);
655 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
656 ElementsAreArray(stringEntry));
657
658 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
659 table.size(), 3);
660 EXPECT_EQ(entry, nullptr);
661
662 auto firstEntry =
663 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
664 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
665 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
666 table.size(), 1),
667 "entry_length != NULL");
668}
669
John Wangdd9a6282019-10-11 18:52:46 +0800670TEST(StringTable, EntryEncodeTest)
671{
672 std::vector<uint8_t> stringEntry{
673 0, 0, /* string handle*/
674 7, 0, /* string length */
675 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
676 };
677
678 const char* str = "Allowed";
679 auto str_length = std::strlen(str);
680 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
681 EXPECT_EQ(encodeLength, stringEntry.size());
682
683 std::vector<uint8_t> encodeEntry(encodeLength, 0);
684 pldm_bios_table_string_entry_encode(encodeEntry.data(), encodeEntry.size(),
685 str, str_length);
686 // set string handle = 0
687 encodeEntry[0] = 0;
688 encodeEntry[1] = 0;
689
690 EXPECT_EQ(stringEntry, encodeEntry);
691
692 EXPECT_DEATH(pldm_bios_table_string_entry_encode(encodeEntry.data(),
693 encodeEntry.size() - 1,
694 str, str_length),
695 "length <= entry_length");
696 auto rc = pldm_bios_table_string_entry_encode_check(
697 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
698 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
699}
700
701TEST(StringTable, EntryDecodeTest)
702{
703 std::vector<uint8_t> stringEntry{
704 4, 0, /* string handle*/
705 7, 0, /* string length */
706 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
707 };
708 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
709 stringEntry.data());
710 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
711 EXPECT_EQ(handle, 4);
712 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
713 EXPECT_EQ(strLength, 7);
714
715 std::vector<char> buffer(strLength + 1, 0);
716 auto decodedLength = pldm_bios_table_string_entry_decode_string(
717 entry, buffer.data(), buffer.size());
718 EXPECT_EQ(decodedLength, strLength);
719 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
720 decodedLength =
721 pldm_bios_table_string_entry_decode_string(entry, buffer.data(), 2);
722 EXPECT_EQ(decodedLength, 2);
723 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
724
725 auto rc = pldm_bios_table_string_entry_decode_string_check(
726 entry, buffer.data(), buffer.size());
727 EXPECT_EQ(rc, PLDM_SUCCESS);
728 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
729
730 rc = pldm_bios_table_string_entry_decode_string_check(entry, buffer.data(),
731 buffer.size() - 1);
732 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
733}
734
735TEST(StringTable, IteratorTest)
736{
737 std::vector<uint8_t> stringHello{
738 0, 0, /* string handle*/
739 5, 0, /* string length */
740 'H', 'e', 'l', 'l', 'o', /* string */
741 };
742 std::vector<uint8_t> stringWorld{
743 1, 0, /* string handle*/
744 6, 0, /* string length */
745 'W', 'o', 'r', 'l', 'd', '!', /* string */
746 };
747
748 Table table;
749 buildTable(table, stringHello, stringWorld);
750
751 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
752 PLDM_BIOS_STRING_TABLE);
753 auto entry = pldm_bios_table_iter_string_entry_value(iter);
754 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
755 EXPECT_EQ(rc, 0);
756 pldm_bios_table_iter_next(iter);
757 entry = pldm_bios_table_iter_string_entry_value(iter);
758 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
759 EXPECT_EQ(rc, 0);
760 pldm_bios_table_iter_next(iter);
761 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
762 pldm_bios_table_iter_free(iter);
763}
764
765TEST(StringTable, FindTest)
766{
767 std::vector<uint8_t> stringHello{
768 1, 0, /* string handle*/
769 5, 0, /* string length */
770 'H', 'e', 'l', 'l', 'o', /* string */
771 };
772 std::vector<uint8_t> stringWorld{
773 2, 0, /* string handle*/
774 6, 0, /* string length */
775 'W', 'o', 'r', 'l', 'd', '!', /* string */
776 };
777 std::vector<uint8_t> stringHi{
778 3, 0, /* string handle*/
779 2, 0, /* string length */
780 'H', 'i', /* string */
781 };
782
783 Table table;
784 buildTable(table, stringHello, stringWorld, stringHi);
785
786 auto entry = pldm_bios_table_string_find_by_string(table.data(),
787 table.size(), "World!");
788 EXPECT_NE(entry, nullptr);
789 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
790 EXPECT_EQ(handle, 2);
791
792 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
793 "Worl");
794 EXPECT_EQ(entry, nullptr);
795
796 entry =
797 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
798 EXPECT_NE(entry, nullptr);
799 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
800 EXPECT_EQ(str_length, 2);
801 std::vector<char> strBuf(str_length + 1, 0);
802 auto rc = pldm_bios_table_string_entry_decode_string_check(
803 entry, strBuf.data(), strBuf.size());
804 EXPECT_EQ(rc, PLDM_SUCCESS);
805 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
806
807 entry =
808 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
809 EXPECT_EQ(entry, nullptr);
810}
811
John Wang02700402019-10-06 16:34:29 +0800812TEST(Itearator, DeathTest)
813{
814
815 Table table(256, 0);
816
817 /* first entry */
818 auto attr_entry =
819 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
820 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
821 PLDM_BIOS_ATTR_TABLE);
822 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
823 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
John Wang02700402019-10-06 16:34:29 +0800824 pldm_bios_table_iter_free(iter);
825}
John Wang79c37f12019-10-31 15:46:31 +0800826
827TEST(PadAndChecksum, PadAndChecksum)
828{
829 EXPECT_EQ(4, pldm_bios_table_pad_checksum_size(0));
830 EXPECT_EQ(7, pldm_bios_table_pad_checksum_size(1));
831 EXPECT_EQ(6, pldm_bios_table_pad_checksum_size(2));
832 EXPECT_EQ(5, pldm_bios_table_pad_checksum_size(3));
833 EXPECT_EQ(4, pldm_bios_table_pad_checksum_size(4));
834
835 // The table is borrowed from
836 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
837 // refer to the commit message
838 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
839 auto sizeWithoutPad = attrValTable.size();
840 attrValTable.resize(sizeWithoutPad +
841 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
842 pldm_bios_table_append_pad_checksum(attrValTable.data(),
843 attrValTable.size(), sizeWithoutPad);
844 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
845 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
846 EXPECT_EQ(attrValTable, expectedTable);
847}