blob: 8a808a5f9a492a878f5c20000d4aa1fb58d44b90 [file] [log] [blame]
John Wang02700402019-10-06 16:34:29 +08001#include <string.h>
2
3#include <cstring>
4#include <vector>
5
6#include "libpldm/base.h"
7#include "libpldm/bios.h"
8#include "libpldm/bios_table.h"
9
10#include <gtest/gtest.h>
11
12using Table = std::vector<uint8_t>;
13
14void buildTable(Table& table)
15{
16 auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
17 table.insert(table.end(), padSize, 0);
18 table.insert(table.end(), sizeof(uint32_t) /*checksum*/, 0);
19}
20
21template <typename First, typename... Rest>
22void buildTable(Table& table, First& first, Rest&... rest)
23{
24 table.insert(table.end(), first.begin(), first.end());
25 buildTable(table, rest...);
26}
27
28TEST(AttrTable, EnumEntryDecodeTest)
29{
30 std::vector<uint8_t> enumEntry{
31 0, 0, /* attr handle */
32 0, /* attr type */
33 1, 0, /* attr name handle */
34 2, /* number of possible value */
35 2, 0, /* possible value handle */
36 3, 0, /* possible value handle */
37 1, /* number of default value */
38 0 /* defaut value string handle index */
39 };
40
41 auto entry =
42 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
43 uint8_t pvNumber = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
44 EXPECT_EQ(pvNumber, 2);
John Wang02700402019-10-06 16:34:29 +080045 pvNumber = 0;
46 auto rc =
47 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
48 EXPECT_EQ(rc, PLDM_SUCCESS);
49 EXPECT_EQ(pvNumber, 2);
John Wang3ad21752019-10-06 16:42:21 +080050
51 std::vector<uint16_t> pvHandles(pvNumber, 0);
52 pvNumber = pldm_bios_table_attr_entry_enum_decode_pv_hdls(
53 entry, pvHandles.data(), pvHandles.size());
54 EXPECT_EQ(pvNumber, 2);
55 EXPECT_EQ(pvHandles[0], 2);
56 EXPECT_EQ(pvHandles[1], 3);
57 pvHandles.resize(1);
58 pvNumber = pldm_bios_table_attr_entry_enum_decode_pv_hdls(
59 entry, pvHandles.data(), pvHandles.size());
60 EXPECT_EQ(pvNumber, 1);
61 EXPECT_EQ(pvHandles[0], 2);
62
63 pvHandles.resize(2);
64 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
65 entry, pvHandles.data(), pvHandles.size());
66 EXPECT_EQ(rc, PLDM_SUCCESS);
67 EXPECT_EQ(pvHandles[0], 2);
68 EXPECT_EQ(pvHandles[1], 3);
69 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
70 entry, pvHandles.data(), 1);
71 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
72
73 uint8_t defNumber = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
74 EXPECT_EQ(defNumber, 1);
John Wang02700402019-10-06 16:34:29 +080075 defNumber = 0;
76 rc =
77 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
78 EXPECT_EQ(rc, PLDM_SUCCESS);
79 EXPECT_EQ(defNumber, 1);
80
81 rc =
82 pldm_bios_table_attr_entry_enum_decode_pv_num_check(nullptr, &pvNumber);
83 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
84 rc = pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, nullptr);
85 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
86
87 entry->attr_type = PLDM_BIOS_STRING;
88 rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
89 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
90
91 rc =
92 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
93 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
John Wang3ad21752019-10-06 16:42:21 +080094 rc =
95 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(entry, nullptr, 0);
96 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
John Wang02700402019-10-06 16:34:29 +080097}
98
99TEST(AttrTable, StringEntryDecodeTest)
100{
101 std::vector<uint8_t> stringEntry{
102 1, 0, /* attr handle */
103 1, /* attr type */
104 12, 0, /* attr name handle */
105 1, /* string type */
106 1, 0, /* minimum length of the string in bytes */
107 100, 0, /* maximum length of the string in bytes */
108 3, 0, /* length of default string in length */
109 'a', 'b', 'c' /* default string */
110 };
111
112 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
113 stringEntry.data());
114 uint16_t def_string_length =
115 pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
116 EXPECT_EQ(def_string_length, 3);
117
118 def_string_length = 0;
119 auto rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
120 entry, &def_string_length);
121 EXPECT_EQ(rc, PLDM_SUCCESS);
122 EXPECT_EQ(def_string_length, 3);
123
124 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
125 entry, nullptr);
126 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
127 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
128 nullptr, &def_string_length);
129 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
130 entry->attr_type = PLDM_BIOS_INTEGER;
131 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
132 entry, &def_string_length);
133 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
134 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
135 nullptr, &def_string_length);
136 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
137}
138
139TEST(AttrTable, ItearatorTest)
140{
141 std::vector<uint8_t> enumEntry{
142 0, 0, /* attr handle */
143 0, /* attr type */
144 1, 0, /* attr name handle */
145 2, /* number of possible value */
146 2, 0, /* possible value handle */
147 3, 0, /* possible value handle */
148 1, /* number of default value */
149 0 /* defaut value string handle index */
150 };
151 std::vector<uint8_t> stringEntry{
152 1, 0, /* attr handle */
153 1, /* attr type */
154 12, 0, /* attr name handle */
155 1, /* string type */
156 1, 0, /* minimum length of the string in bytes */
157 100, 0, /* maximum length of the string in bytes */
158 3, 0, /* length of default string in length */
159 'a', 'b', 'c' /* default string */
160 };
161
162 Table table;
163 buildTable(table, enumEntry, stringEntry, enumEntry);
164 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
165 PLDM_BIOS_ATTR_TABLE);
166 auto entry = pldm_bios_table_iter_attr_entry_value(iter);
167 auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
168 EXPECT_EQ(rc, 0);
169
170 pldm_bios_table_iter_next(iter);
171 entry = pldm_bios_table_iter_attr_entry_value(iter);
172 rc = std::memcmp(entry, stringEntry.data(), stringEntry.size());
173 EXPECT_EQ(rc, 0);
174
175 pldm_bios_table_iter_next(iter);
176 entry = pldm_bios_table_iter_attr_entry_value(iter);
177 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
178 EXPECT_EQ(rc, 0);
179
180 pldm_bios_table_iter_next(iter);
181 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
182 pldm_bios_table_iter_free(iter);
183}
184
John Wang3ad21752019-10-06 16:42:21 +0800185TEST(AttrValTable, EnumEntryEncodeTest)
186{
187 std::vector<uint8_t> enumEntry{
188 0, 0, /* attr handle */
189 0, /* attr type */
190 2, /* number of current value */
191 0, /* current value string handle index */
192 1, /* current value string handle index */
193 };
194
195 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2);
196 EXPECT_EQ(length, enumEntry.size());
197 std::vector<uint8_t> encodeEntry(length, 0);
198 uint8_t handles[] = {0, 1};
199 pldm_bios_table_attr_value_entry_encode_enum(
200 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles);
201 EXPECT_EQ(encodeEntry, enumEntry);
202
203 EXPECT_DEATH(
204 pldm_bios_table_attr_value_entry_encode_enum(
205 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
206 "length <= entry_length");
207
208 auto rc = pldm_bios_table_attr_value_entry_encode_enum_check(
209 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2,
210 handles);
211 EXPECT_EQ(rc, PLDM_SUCCESS);
212 EXPECT_EQ(encodeEntry, enumEntry);
213 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
214 enumEntry.data());
215 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY;
216 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
217 encodeEntry.data(), encodeEntry.size(), 0,
218 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles);
219 EXPECT_EQ(rc, PLDM_SUCCESS);
220 EXPECT_EQ(encodeEntry, enumEntry);
221 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
222 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2,
223 handles);
224 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
225 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
226 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2,
227 handles);
228 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
229}
230
231TEST(AttrValTable, stringEntryEncodeTest)
232{
233 std::vector<uint8_t> stringEntry{
234 0, 0, /* attr handle */
235 1, /* attr type */
236 3, 0, /* current string length */
237 'a', 'b', 'c', /* defaut value string handle index */
238 };
239
240 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
241 EXPECT_EQ(length, stringEntry.size());
242 std::vector<uint8_t> encodeEntry(length, 0);
243 pldm_bios_table_attr_value_entry_encode_string(
244 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc");
245 EXPECT_EQ(encodeEntry, stringEntry);
246
247 EXPECT_DEATH(
248 pldm_bios_table_attr_value_entry_encode_string(
249 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
250 "length <= entry_length");
251
252 auto rc = pldm_bios_table_attr_value_entry_encode_string_check(
253 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
254 EXPECT_EQ(rc, PLDM_SUCCESS);
255 EXPECT_EQ(encodeEntry, stringEntry);
256 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
257 stringEntry.data());
258 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
259 rc = pldm_bios_table_attr_value_entry_encode_string_check(
260 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
261 3, "abc");
262 EXPECT_EQ(rc, PLDM_SUCCESS);
263 EXPECT_EQ(encodeEntry, stringEntry);
264 rc = pldm_bios_table_attr_value_entry_encode_string_check(
265 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
266 "abc");
267 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
268 rc = pldm_bios_table_attr_value_entry_encode_string_check(
269 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
270 "abc");
271 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
272}
273
John Wangdd9a6282019-10-11 18:52:46 +0800274TEST(StringTable, EntryEncodeTest)
275{
276 std::vector<uint8_t> stringEntry{
277 0, 0, /* string handle*/
278 7, 0, /* string length */
279 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
280 };
281
282 const char* str = "Allowed";
283 auto str_length = std::strlen(str);
284 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
285 EXPECT_EQ(encodeLength, stringEntry.size());
286
287 std::vector<uint8_t> encodeEntry(encodeLength, 0);
288 pldm_bios_table_string_entry_encode(encodeEntry.data(), encodeEntry.size(),
289 str, str_length);
290 // set string handle = 0
291 encodeEntry[0] = 0;
292 encodeEntry[1] = 0;
293
294 EXPECT_EQ(stringEntry, encodeEntry);
295
296 EXPECT_DEATH(pldm_bios_table_string_entry_encode(encodeEntry.data(),
297 encodeEntry.size() - 1,
298 str, str_length),
299 "length <= entry_length");
300 auto rc = pldm_bios_table_string_entry_encode_check(
301 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
302 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
303}
304
305TEST(StringTable, EntryDecodeTest)
306{
307 std::vector<uint8_t> stringEntry{
308 4, 0, /* string handle*/
309 7, 0, /* string length */
310 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
311 };
312 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
313 stringEntry.data());
314 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
315 EXPECT_EQ(handle, 4);
316 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
317 EXPECT_EQ(strLength, 7);
318
319 std::vector<char> buffer(strLength + 1, 0);
320 auto decodedLength = pldm_bios_table_string_entry_decode_string(
321 entry, buffer.data(), buffer.size());
322 EXPECT_EQ(decodedLength, strLength);
323 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
324 decodedLength =
325 pldm_bios_table_string_entry_decode_string(entry, buffer.data(), 2);
326 EXPECT_EQ(decodedLength, 2);
327 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
328
329 auto rc = pldm_bios_table_string_entry_decode_string_check(
330 entry, buffer.data(), buffer.size());
331 EXPECT_EQ(rc, PLDM_SUCCESS);
332 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
333
334 rc = pldm_bios_table_string_entry_decode_string_check(entry, buffer.data(),
335 buffer.size() - 1);
336 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
337}
338
339TEST(StringTable, IteratorTest)
340{
341 std::vector<uint8_t> stringHello{
342 0, 0, /* string handle*/
343 5, 0, /* string length */
344 'H', 'e', 'l', 'l', 'o', /* string */
345 };
346 std::vector<uint8_t> stringWorld{
347 1, 0, /* string handle*/
348 6, 0, /* string length */
349 'W', 'o', 'r', 'l', 'd', '!', /* string */
350 };
351
352 Table table;
353 buildTable(table, stringHello, stringWorld);
354
355 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
356 PLDM_BIOS_STRING_TABLE);
357 auto entry = pldm_bios_table_iter_string_entry_value(iter);
358 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
359 EXPECT_EQ(rc, 0);
360 pldm_bios_table_iter_next(iter);
361 entry = pldm_bios_table_iter_string_entry_value(iter);
362 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
363 EXPECT_EQ(rc, 0);
364 pldm_bios_table_iter_next(iter);
365 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
366 pldm_bios_table_iter_free(iter);
367}
368
369TEST(StringTable, FindTest)
370{
371 std::vector<uint8_t> stringHello{
372 1, 0, /* string handle*/
373 5, 0, /* string length */
374 'H', 'e', 'l', 'l', 'o', /* string */
375 };
376 std::vector<uint8_t> stringWorld{
377 2, 0, /* string handle*/
378 6, 0, /* string length */
379 'W', 'o', 'r', 'l', 'd', '!', /* string */
380 };
381 std::vector<uint8_t> stringHi{
382 3, 0, /* string handle*/
383 2, 0, /* string length */
384 'H', 'i', /* string */
385 };
386
387 Table table;
388 buildTable(table, stringHello, stringWorld, stringHi);
389
390 auto entry = pldm_bios_table_string_find_by_string(table.data(),
391 table.size(), "World!");
392 EXPECT_NE(entry, nullptr);
393 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
394 EXPECT_EQ(handle, 2);
395
396 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
397 "Worl");
398 EXPECT_EQ(entry, nullptr);
399
400 entry =
401 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
402 EXPECT_NE(entry, nullptr);
403 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
404 EXPECT_EQ(str_length, 2);
405 std::vector<char> strBuf(str_length + 1, 0);
406 auto rc = pldm_bios_table_string_entry_decode_string_check(
407 entry, strBuf.data(), strBuf.size());
408 EXPECT_EQ(rc, PLDM_SUCCESS);
409 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
410
411 entry =
412 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
413 EXPECT_EQ(entry, nullptr);
414}
415
John Wang02700402019-10-06 16:34:29 +0800416TEST(Itearator, DeathTest)
417{
418
419 Table table(256, 0);
420
421 /* first entry */
422 auto attr_entry =
423 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
424 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
425 PLDM_BIOS_ATTR_TABLE);
426 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
427 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
428 attr_entry->attr_type = PLDM_BIOS_INTEGER;
429 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
430 pldm_bios_table_iter_free(iter);
431}