blob: cbed6d6c3ad0f625c582a2b49e63236ef77aa632 [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
11#include <gtest/gtest.h>
12
13using Table = std::vector<uint8_t>;
14
15void buildTable(Table& table)
16{
17 auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
18 table.insert(table.end(), padSize, 0);
19 table.insert(table.end(), sizeof(uint32_t) /*checksum*/, 0);
20}
21
22template <typename First, typename... Rest>
23void buildTable(Table& table, First& first, Rest&... rest)
24{
25 table.insert(table.end(), first.begin(), first.end());
26 buildTable(table, rest...);
27}
28
29TEST(AttrTable, EnumEntryDecodeTest)
30{
31 std::vector<uint8_t> enumEntry{
32 0, 0, /* attr handle */
33 0, /* attr type */
34 1, 0, /* attr name handle */
35 2, /* number of possible value */
36 2, 0, /* possible value handle */
37 3, 0, /* possible value handle */
38 1, /* number of default value */
39 0 /* defaut value string handle index */
40 };
41
42 auto entry =
43 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
44 uint8_t pvNumber = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
45 EXPECT_EQ(pvNumber, 2);
John Wang02700402019-10-06 16:34:29 +080046 pvNumber = 0;
47 auto rc =
48 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
49 EXPECT_EQ(rc, PLDM_SUCCESS);
50 EXPECT_EQ(pvNumber, 2);
John Wang3ad21752019-10-06 16:42:21 +080051
52 std::vector<uint16_t> pvHandles(pvNumber, 0);
53 pvNumber = pldm_bios_table_attr_entry_enum_decode_pv_hdls(
54 entry, pvHandles.data(), pvHandles.size());
55 EXPECT_EQ(pvNumber, 2);
56 EXPECT_EQ(pvHandles[0], 2);
57 EXPECT_EQ(pvHandles[1], 3);
58 pvHandles.resize(1);
59 pvNumber = pldm_bios_table_attr_entry_enum_decode_pv_hdls(
60 entry, pvHandles.data(), pvHandles.size());
61 EXPECT_EQ(pvNumber, 1);
62 EXPECT_EQ(pvHandles[0], 2);
63
64 pvHandles.resize(2);
65 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
66 entry, pvHandles.data(), pvHandles.size());
67 EXPECT_EQ(rc, PLDM_SUCCESS);
68 EXPECT_EQ(pvHandles[0], 2);
69 EXPECT_EQ(pvHandles[1], 3);
70 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
71 entry, pvHandles.data(), 1);
72 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
73
74 uint8_t defNumber = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
75 EXPECT_EQ(defNumber, 1);
John Wang02700402019-10-06 16:34:29 +080076 defNumber = 0;
77 rc =
78 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
79 EXPECT_EQ(rc, PLDM_SUCCESS);
80 EXPECT_EQ(defNumber, 1);
81
82 rc =
83 pldm_bios_table_attr_entry_enum_decode_pv_num_check(nullptr, &pvNumber);
84 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
85 rc = pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, nullptr);
86 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
87
88 entry->attr_type = PLDM_BIOS_STRING;
89 rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
90 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
91
92 rc =
93 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
94 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
John Wang3ad21752019-10-06 16:42:21 +080095 rc =
96 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(entry, nullptr, 0);
97 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
John Wang02700402019-10-06 16:34:29 +080098}
99
John Wangccc04552019-10-14 14:28:25 +0800100TEST(AttrTable, EnumEntryEncodeTest)
101{
102 std::vector<uint8_t> enumEntry{
103 0, 0, /* attr handle */
104 0, /* attr type */
105 1, 0, /* attr name handle */
106 2, /* number of possible value */
107 2, 0, /* possible value handle */
108 3, 0, /* possible value handle */
109 1, /* number of default value */
110 0 /* defaut value string handle index */
111 };
112
113 std::vector<uint16_t> pv_hdls{2, 3};
114 std::vector<uint8_t> defs{0};
115
116 struct pldm_bios_table_attr_entry_enum_info info = {
117 1, /* name handle */
118 false, /* read only */
119 2, /* pv number */
120 pv_hdls.data(), /* pv handle */
121 1, /*def number */
122 defs.data() /*def index*/
123 };
124 auto encodeLength = pldm_bios_table_attr_entry_enum_encode_length(2, 1);
125 EXPECT_EQ(encodeLength, enumEntry.size());
126
127 std::vector<uint8_t> encodeEntry(encodeLength, 0);
128 pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
129 encodeEntry.size(), &info);
130 // set attr handle = 0
131 encodeEntry[0] = 0;
132 encodeEntry[1] = 0;
133
134 EXPECT_EQ(enumEntry, encodeEntry);
135
136 EXPECT_DEATH(pldm_bios_table_attr_entry_enum_encode(
137 encodeEntry.data(), encodeEntry.size() - 1, &info),
138 "length <= entry_length");
139 auto rc = pldm_bios_table_attr_entry_enum_encode_check(
140 encodeEntry.data(), encodeEntry.size(), &info);
141 EXPECT_EQ(rc, PLDM_SUCCESS);
142 // set attr handle = 0
143 encodeEntry[0] = 0;
144 encodeEntry[1] = 0;
145
146 EXPECT_EQ(enumEntry, encodeEntry);
147 rc = pldm_bios_table_attr_entry_enum_encode_check(
148 encodeEntry.data(), encodeEntry.size() - 1, &info);
149 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
150}
151
John Wang02700402019-10-06 16:34:29 +0800152TEST(AttrTable, StringEntryDecodeTest)
153{
154 std::vector<uint8_t> stringEntry{
155 1, 0, /* attr handle */
156 1, /* attr type */
157 12, 0, /* attr name handle */
158 1, /* string type */
159 1, 0, /* minimum length of the string in bytes */
160 100, 0, /* maximum length of the string in bytes */
161 3, 0, /* length of default string in length */
162 'a', 'b', 'c' /* default string */
163 };
164
165 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
166 stringEntry.data());
167 uint16_t def_string_length =
168 pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
169 EXPECT_EQ(def_string_length, 3);
170
171 def_string_length = 0;
172 auto rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
173 entry, &def_string_length);
174 EXPECT_EQ(rc, PLDM_SUCCESS);
175 EXPECT_EQ(def_string_length, 3);
176
177 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
178 entry, nullptr);
179 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
180 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
181 nullptr, &def_string_length);
182 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
183 entry->attr_type = PLDM_BIOS_INTEGER;
184 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
185 entry, &def_string_length);
186 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
187 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
188 nullptr, &def_string_length);
189 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
190}
191
John Wangccc04552019-10-14 14:28:25 +0800192TEST(AttrTable, StringEntryEncodeTest)
193{
194 std::vector<uint8_t> stringEntry{
195 0, 0, /* attr handle */
196 1, /* attr type */
197 3, 0, /* attr name handle */
198 1, /* string type */
199 1, 0, /* min string length */
200 100, 0, /* max string length */
201 3, 0, /* default string length */
202 'a', 'b', 'c', /* defaul string */
203 };
204
205 struct pldm_bios_table_attr_entry_string_info info = {
206 3, /* name handle */
207 false, /* read only */
208 1, /* string type ascii */
209 1, /* min length */
210 100, /* max length */
211 3, /* def length */
212 "abc", /* def string */
213 };
214 auto encodeLength = pldm_bios_table_attr_entry_string_encode_length(3);
215 EXPECT_EQ(encodeLength, stringEntry.size());
216
217 std::vector<uint8_t> encodeEntry(encodeLength, 0);
218 pldm_bios_table_attr_entry_string_encode(encodeEntry.data(),
219 encodeEntry.size(), &info);
220 // set attr handle = 0
221 encodeEntry[0] = 0;
222 encodeEntry[1] = 0;
223
224 EXPECT_EQ(stringEntry, encodeEntry);
225
226 EXPECT_DEATH(pldm_bios_table_attr_entry_string_encode(
227 encodeEntry.data(), encodeEntry.size() - 1, &info),
228 "length <= entry_length");
229 auto rc = pldm_bios_table_attr_entry_string_encode_check(
230 encodeEntry.data(), encodeEntry.size(), &info);
231 EXPECT_EQ(rc, PLDM_SUCCESS);
232 // set attr handle = 0
233 encodeEntry[0] = 0;
234 encodeEntry[1] = 0;
235
236 EXPECT_EQ(stringEntry, encodeEntry);
237 rc = pldm_bios_table_attr_entry_string_encode_check(
238 encodeEntry.data(), encodeEntry.size() - 1, &info);
239 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
240 std::swap(info.max_length, info.min_length);
John Wang827c5de2019-11-07 18:27:27 +0800241 const char* errmsg;
242 rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
243 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
244 EXPECT_STREQ(
245 "MinimumStingLength should not be greater than MaximumStringLength",
246 errmsg);
John Wangccc04552019-10-14 14:28:25 +0800247 rc = pldm_bios_table_attr_entry_string_encode_check(
248 encodeEntry.data(), encodeEntry.size(), &info);
249 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
250 std::swap(info.max_length, info.min_length);
251
252 std::vector<uint8_t> stringEntryLength0{
253 0, 0, /* attr handle */
254 1, /* attr type */
255 3, 0, /* attr name handle */
256 1, /* string type */
257 1, 0, /* min string length */
258 100, 0, /* max string length */
259 0, 0, /* default string length */
260 };
261
262 info.def_length = 0;
263 info.def_string = nullptr;
264
265 encodeLength = pldm_bios_table_attr_entry_string_encode_length(0);
266 EXPECT_EQ(encodeLength, stringEntryLength0.size());
267
268 encodeEntry.resize(encodeLength);
269 pldm_bios_table_attr_entry_string_encode(encodeEntry.data(),
270 encodeEntry.size(), &info);
271 // set attr handle = 0
272 encodeEntry[0] = 0;
273 encodeEntry[1] = 0;
274
275 EXPECT_EQ(stringEntryLength0, encodeEntry);
276}
277
John Wangca230822019-10-16 11:39:27 +0800278TEST(AttrTable, integerEntryEncodeTest)
279{
280 std::vector<uint8_t> integerEntry{
281 0, 0, /* attr handle */
282 3, /* attr type */
283 1, 0, /* attr name handle */
284 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
285 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
286 2, 0, 0, 0, /* scalar increment */
287 3, 0, 0, 0, 0, 0, 0, 0, /* defaut value */
288 };
289
290 std::vector<uint16_t> pv_hdls{2, 3};
291 std::vector<uint8_t> defs{0};
292
293 struct pldm_bios_table_attr_entry_integer_info info = {
294 1, /* name handle */
295 false, /* read only */
296 1, /* lower bound */
297 10, /* upper bound */
298 2, /* sacalar increment */
299 3 /* default value */
300 };
301 auto encodeLength = pldm_bios_table_attr_entry_integer_encode_length();
302 EXPECT_EQ(encodeLength, integerEntry.size());
303
304 std::vector<uint8_t> encodeEntry(encodeLength, 0);
305 pldm_bios_table_attr_entry_integer_encode(encodeEntry.data(),
306 encodeEntry.size(), &info);
307 // set attr handle = 0
308 encodeEntry[0] = 0;
309 encodeEntry[1] = 0;
310
311 EXPECT_EQ(integerEntry, encodeEntry);
312
313 EXPECT_DEATH(pldm_bios_table_attr_entry_integer_encode(
314 encodeEntry.data(), encodeEntry.size() - 1, &info),
315 "length <= entry_length");
316
317 auto rc = pldm_bios_table_attr_entry_integer_encode_check(
318 encodeEntry.data(), encodeEntry.size(), &info);
319 EXPECT_EQ(rc, PLDM_SUCCESS);
320 // set attr handle = 0
321 encodeEntry[0] = 0;
322 encodeEntry[1] = 0;
323
324 EXPECT_EQ(integerEntry, encodeEntry);
325
326 rc = pldm_bios_table_attr_entry_integer_encode_check(
327 encodeEntry.data(), encodeEntry.size() - 1, &info);
328 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
329
330 info.lower_bound = 100;
331 info.upper_bound = 50;
John Wang827c5de2019-11-07 18:27:27 +0800332 const char* errmsg;
333 rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
334 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
335 EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg);
John Wangca230822019-10-16 11:39:27 +0800336 rc = pldm_bios_table_attr_entry_integer_encode_check(
337 encodeEntry.data(), encodeEntry.size(), &info);
338 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
339}
340
John Wang02700402019-10-06 16:34:29 +0800341TEST(AttrTable, ItearatorTest)
342{
343 std::vector<uint8_t> enumEntry{
344 0, 0, /* attr handle */
345 0, /* attr type */
346 1, 0, /* attr name handle */
347 2, /* number of possible value */
348 2, 0, /* possible value handle */
349 3, 0, /* possible value handle */
350 1, /* number of default value */
351 0 /* defaut value string handle index */
352 };
353 std::vector<uint8_t> stringEntry{
354 1, 0, /* attr handle */
355 1, /* attr type */
356 12, 0, /* attr name handle */
357 1, /* string type */
358 1, 0, /* minimum length of the string in bytes */
359 100, 0, /* maximum length of the string in bytes */
360 3, 0, /* length of default string in length */
361 'a', 'b', 'c' /* default string */
362 };
John Wangca230822019-10-16 11:39:27 +0800363 std::vector<uint8_t> integerEntry{
364 0, 0, /* attr handle */
365 3, /* attr type */
366 1, 0, /* attr name handle */
367 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
368 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
369 2, 0, 0, 0, /* scalar increment */
370 3, 0, 0, 0, 0, 0, 0, 0, /* defaut value */
371 };
John Wang02700402019-10-06 16:34:29 +0800372
373 Table table;
John Wangca230822019-10-16 11:39:27 +0800374 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
John Wang02700402019-10-06 16:34:29 +0800375 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
376 PLDM_BIOS_ATTR_TABLE);
377 auto entry = pldm_bios_table_iter_attr_entry_value(iter);
378 auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
379 EXPECT_EQ(rc, 0);
380
381 pldm_bios_table_iter_next(iter);
382 entry = pldm_bios_table_iter_attr_entry_value(iter);
383 rc = std::memcmp(entry, stringEntry.data(), stringEntry.size());
384 EXPECT_EQ(rc, 0);
385
386 pldm_bios_table_iter_next(iter);
387 entry = pldm_bios_table_iter_attr_entry_value(iter);
John Wangca230822019-10-16 11:39:27 +0800388 rc = std::memcmp(entry, integerEntry.data(), integerEntry.size());
389 EXPECT_EQ(rc, 0);
390
391 pldm_bios_table_iter_next(iter);
392 entry = pldm_bios_table_iter_attr_entry_value(iter);
John Wang02700402019-10-06 16:34:29 +0800393 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
394 EXPECT_EQ(rc, 0);
395
396 pldm_bios_table_iter_next(iter);
397 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
398 pldm_bios_table_iter_free(iter);
399}
400
John Wang3ad21752019-10-06 16:42:21 +0800401TEST(AttrValTable, EnumEntryEncodeTest)
402{
403 std::vector<uint8_t> enumEntry{
404 0, 0, /* attr handle */
405 0, /* attr type */
406 2, /* number of current value */
407 0, /* current value string handle index */
408 1, /* current value string handle index */
409 };
410
411 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2);
412 EXPECT_EQ(length, enumEntry.size());
413 std::vector<uint8_t> encodeEntry(length, 0);
414 uint8_t handles[] = {0, 1};
415 pldm_bios_table_attr_value_entry_encode_enum(
416 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles);
417 EXPECT_EQ(encodeEntry, enumEntry);
418
419 EXPECT_DEATH(
420 pldm_bios_table_attr_value_entry_encode_enum(
421 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
422 "length <= entry_length");
423
424 auto rc = pldm_bios_table_attr_value_entry_encode_enum_check(
425 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2,
426 handles);
427 EXPECT_EQ(rc, PLDM_SUCCESS);
428 EXPECT_EQ(encodeEntry, enumEntry);
429 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
430 enumEntry.data());
431 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY;
432 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
433 encodeEntry.data(), encodeEntry.size(), 0,
434 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles);
435 EXPECT_EQ(rc, PLDM_SUCCESS);
436 EXPECT_EQ(encodeEntry, enumEntry);
437 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
438 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2,
439 handles);
440 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
441 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
442 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2,
443 handles);
444 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
445}
446
447TEST(AttrValTable, stringEntryEncodeTest)
448{
449 std::vector<uint8_t> stringEntry{
450 0, 0, /* attr handle */
451 1, /* attr type */
452 3, 0, /* current string length */
453 'a', 'b', 'c', /* defaut value string handle index */
454 };
455
456 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
457 EXPECT_EQ(length, stringEntry.size());
458 std::vector<uint8_t> encodeEntry(length, 0);
459 pldm_bios_table_attr_value_entry_encode_string(
460 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc");
461 EXPECT_EQ(encodeEntry, stringEntry);
462
463 EXPECT_DEATH(
464 pldm_bios_table_attr_value_entry_encode_string(
465 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
466 "length <= entry_length");
467
468 auto rc = pldm_bios_table_attr_value_entry_encode_string_check(
469 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
470 EXPECT_EQ(rc, PLDM_SUCCESS);
471 EXPECT_EQ(encodeEntry, stringEntry);
472 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
473 stringEntry.data());
474 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
475 rc = pldm_bios_table_attr_value_entry_encode_string_check(
476 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
477 3, "abc");
478 EXPECT_EQ(rc, PLDM_SUCCESS);
479 EXPECT_EQ(encodeEntry, stringEntry);
480 rc = pldm_bios_table_attr_value_entry_encode_string_check(
481 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
482 "abc");
483 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
484 rc = pldm_bios_table_attr_value_entry_encode_string_check(
485 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
486 "abc");
487 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
488}
489
John Wangca230822019-10-16 11:39:27 +0800490TEST(AttrValTable, integerEntryEncodeTest)
491{
492 std::vector<uint8_t> integerEntry{
493 0, 0, /* attr handle */
494 3, /* attr type */
495 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
496 };
497
498 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
499 EXPECT_EQ(length, integerEntry.size());
500 std::vector<uint8_t> encodeEntry(length, 0);
501 pldm_bios_table_attr_value_entry_encode_integer(
502 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
503 EXPECT_EQ(encodeEntry, integerEntry);
504
505 EXPECT_DEATH(pldm_bios_table_attr_value_entry_encode_integer(
506 encodeEntry.data(), encodeEntry.size() - 1, 0,
507 PLDM_BIOS_INTEGER, 10),
508 "length <= entry_length");
509
510 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
511 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
512 EXPECT_EQ(rc, PLDM_SUCCESS);
513 EXPECT_EQ(encodeEntry, integerEntry);
514 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
515 integerEntry.data());
516 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
517 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
518 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
519 10);
520 EXPECT_EQ(rc, PLDM_SUCCESS);
521 EXPECT_EQ(encodeEntry, integerEntry);
522
523 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
524 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
525 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
526 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
527 encodeEntry.data(), encodeEntry.size() - 1, 0,
528 PLDM_BIOS_INTEGER_READ_ONLY, 10);
529 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
530}
531
John Wangdd9a6282019-10-11 18:52:46 +0800532TEST(StringTable, EntryEncodeTest)
533{
534 std::vector<uint8_t> stringEntry{
535 0, 0, /* string handle*/
536 7, 0, /* string length */
537 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
538 };
539
540 const char* str = "Allowed";
541 auto str_length = std::strlen(str);
542 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
543 EXPECT_EQ(encodeLength, stringEntry.size());
544
545 std::vector<uint8_t> encodeEntry(encodeLength, 0);
546 pldm_bios_table_string_entry_encode(encodeEntry.data(), encodeEntry.size(),
547 str, str_length);
548 // set string handle = 0
549 encodeEntry[0] = 0;
550 encodeEntry[1] = 0;
551
552 EXPECT_EQ(stringEntry, encodeEntry);
553
554 EXPECT_DEATH(pldm_bios_table_string_entry_encode(encodeEntry.data(),
555 encodeEntry.size() - 1,
556 str, str_length),
557 "length <= entry_length");
558 auto rc = pldm_bios_table_string_entry_encode_check(
559 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
560 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
561}
562
563TEST(StringTable, EntryDecodeTest)
564{
565 std::vector<uint8_t> stringEntry{
566 4, 0, /* string handle*/
567 7, 0, /* string length */
568 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
569 };
570 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
571 stringEntry.data());
572 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
573 EXPECT_EQ(handle, 4);
574 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
575 EXPECT_EQ(strLength, 7);
576
577 std::vector<char> buffer(strLength + 1, 0);
578 auto decodedLength = pldm_bios_table_string_entry_decode_string(
579 entry, buffer.data(), buffer.size());
580 EXPECT_EQ(decodedLength, strLength);
581 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
582 decodedLength =
583 pldm_bios_table_string_entry_decode_string(entry, buffer.data(), 2);
584 EXPECT_EQ(decodedLength, 2);
585 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
586
587 auto rc = pldm_bios_table_string_entry_decode_string_check(
588 entry, buffer.data(), buffer.size());
589 EXPECT_EQ(rc, PLDM_SUCCESS);
590 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
591
592 rc = pldm_bios_table_string_entry_decode_string_check(entry, buffer.data(),
593 buffer.size() - 1);
594 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
595}
596
597TEST(StringTable, IteratorTest)
598{
599 std::vector<uint8_t> stringHello{
600 0, 0, /* string handle*/
601 5, 0, /* string length */
602 'H', 'e', 'l', 'l', 'o', /* string */
603 };
604 std::vector<uint8_t> stringWorld{
605 1, 0, /* string handle*/
606 6, 0, /* string length */
607 'W', 'o', 'r', 'l', 'd', '!', /* string */
608 };
609
610 Table table;
611 buildTable(table, stringHello, stringWorld);
612
613 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
614 PLDM_BIOS_STRING_TABLE);
615 auto entry = pldm_bios_table_iter_string_entry_value(iter);
616 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
617 EXPECT_EQ(rc, 0);
618 pldm_bios_table_iter_next(iter);
619 entry = pldm_bios_table_iter_string_entry_value(iter);
620 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
621 EXPECT_EQ(rc, 0);
622 pldm_bios_table_iter_next(iter);
623 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
624 pldm_bios_table_iter_free(iter);
625}
626
627TEST(StringTable, FindTest)
628{
629 std::vector<uint8_t> stringHello{
630 1, 0, /* string handle*/
631 5, 0, /* string length */
632 'H', 'e', 'l', 'l', 'o', /* string */
633 };
634 std::vector<uint8_t> stringWorld{
635 2, 0, /* string handle*/
636 6, 0, /* string length */
637 'W', 'o', 'r', 'l', 'd', '!', /* string */
638 };
639 std::vector<uint8_t> stringHi{
640 3, 0, /* string handle*/
641 2, 0, /* string length */
642 'H', 'i', /* string */
643 };
644
645 Table table;
646 buildTable(table, stringHello, stringWorld, stringHi);
647
648 auto entry = pldm_bios_table_string_find_by_string(table.data(),
649 table.size(), "World!");
650 EXPECT_NE(entry, nullptr);
651 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
652 EXPECT_EQ(handle, 2);
653
654 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
655 "Worl");
656 EXPECT_EQ(entry, nullptr);
657
658 entry =
659 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
660 EXPECT_NE(entry, nullptr);
661 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
662 EXPECT_EQ(str_length, 2);
663 std::vector<char> strBuf(str_length + 1, 0);
664 auto rc = pldm_bios_table_string_entry_decode_string_check(
665 entry, strBuf.data(), strBuf.size());
666 EXPECT_EQ(rc, PLDM_SUCCESS);
667 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
668
669 entry =
670 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
671 EXPECT_EQ(entry, nullptr);
672}
673
John Wang02700402019-10-06 16:34:29 +0800674TEST(Itearator, DeathTest)
675{
676
677 Table table(256, 0);
678
679 /* first entry */
680 auto attr_entry =
681 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
682 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
683 PLDM_BIOS_ATTR_TABLE);
684 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
685 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
John Wang02700402019-10-06 16:34:29 +0800686 pldm_bios_table_iter_free(iter);
687}
John Wang79c37f12019-10-31 15:46:31 +0800688
689TEST(PadAndChecksum, PadAndChecksum)
690{
691 EXPECT_EQ(4, pldm_bios_table_pad_checksum_size(0));
692 EXPECT_EQ(7, pldm_bios_table_pad_checksum_size(1));
693 EXPECT_EQ(6, pldm_bios_table_pad_checksum_size(2));
694 EXPECT_EQ(5, pldm_bios_table_pad_checksum_size(3));
695 EXPECT_EQ(4, pldm_bios_table_pad_checksum_size(4));
696
697 // The table is borrowed from
698 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
699 // refer to the commit message
700 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
701 auto sizeWithoutPad = attrValTable.size();
702 attrValTable.resize(sizeWithoutPad +
703 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
704 pldm_bios_table_append_pad_checksum(attrValTable.data(),
705 attrValTable.size(), sizeWithoutPad);
706 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
707 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
708 EXPECT_EQ(attrValTable, expectedTable);
709}