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