blob: 37c1a094cb13aa49d1d778f19e32ea2a16ce29c6 [file] [log] [blame]
Andrew Jeffery9c766792022-08-10 23:12:49 +09301#include <endian.h>
Andrew Jefferyefb40062023-11-10 13:48:39 +10302#include <libpldm/base.h>
3#include <libpldm/bios.h>
4#include <libpldm/bios_table.h>
5#include <libpldm/utils.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +09306
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05307#include <algorithm>
8#include <cstdint>
Andrew Jeffery9c766792022-08-10 23:12:49 +09309#include <cstring>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053010#include <iterator>
Andrew Jeffery9c766792022-08-10 23:12:49 +093011#include <string>
12#include <utility>
13#include <vector>
14
Andrew Jeffery9c766792022-08-10 23:12:49 +093015#include <gmock/gmock.h>
16#include <gtest/gtest.h>
17
18using testing::ElementsAreArray;
19using Table = std::vector<uint8_t>;
20
21void buildTable(Table& table)
22{
23 auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
24 table.insert(table.end(), padSize, 0);
25 uint32_t checksum = crc32(table.data(), table.size());
26 checksum = htole32(checksum);
27 uint8_t a[4];
28 std::memcpy(a, &checksum, sizeof(checksum));
29 table.insert(table.end(), std::begin(a), std::end(a));
30}
31
32template <typename First, typename... Rest>
33void buildTable(Table& table, First& first, Rest&... rest)
34{
35 table.insert(table.end(), first.begin(), first.end());
36 buildTable(table, rest...);
37}
38
39TEST(AttrTable, HeaderDecodeTest)
40{
41 std::vector<uint8_t> enumEntry{
42 2, 0, /* attr handle */
43 0, /* attr type */
44 1, 0, /* attr name handle (string handle) */
45 2, /* number of possible value */
46 2, 0, /* possible value handle */
47 3, 0, /* possible value handle */
48 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +053049 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +093050 };
51 auto entry =
52 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
53 auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
54 EXPECT_EQ(attrHandle, 2);
55 auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
56 EXPECT_EQ(attrType, 0);
57 auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
58 EXPECT_EQ(stringHandle, 1);
59}
60
61TEST(AttrTable, EnumEntryDecodeTest)
62{
63 std::vector<uint8_t> enumEntry{
64 0, 0, /* attr handle */
65 0, /* attr type */
66 1, 0, /* attr name handle */
67 2, /* number of possible value */
68 2, 0, /* possible value handle */
69 3, 0, /* possible value handle */
70 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +053071 1 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +093072 };
73
74 auto entry =
75 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093076 uint8_t pvNumber;
Andrew Jefferyb06882f2024-06-25 15:52:02 +093077 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNumber),
78 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093079 EXPECT_EQ(pvNumber, 2);
80 pvNumber = 0;
Andrew Jefferyb06882f2024-06-25 15:52:02 +093081 auto rc = pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +093082 EXPECT_EQ(rc, PLDM_SUCCESS);
83 EXPECT_EQ(pvNumber, 2);
84
85 std::vector<uint16_t> pvHandles(pvNumber, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093086 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
87 entry, pvHandles.data(), pvHandles.size()),
88 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093089 EXPECT_EQ(pvNumber, 2);
90 EXPECT_EQ(pvHandles[0], 2);
91 EXPECT_EQ(pvHandles[1], 3);
92 pvHandles.resize(1);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093093 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
94 entry, pvHandles.data(), pvHandles.size()),
95 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093096 EXPECT_EQ(pvHandles[0], 2);
97
98 pvHandles.resize(2);
99 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
100 entry, pvHandles.data(), pvHandles.size());
101 EXPECT_EQ(rc, PLDM_SUCCESS);
102 EXPECT_EQ(pvHandles[0], 2);
103 EXPECT_EQ(pvHandles[1], 3);
104 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
105 entry, pvHandles.data(), 1);
Andrew Jeffery0c9f5a82023-06-14 15:01:06 +0930106 EXPECT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930107
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930108 uint8_t defNumber;
Andrew Jeffery46673f42024-06-25 16:02:25 +0930109 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_def_num(entry, &defNumber),
110 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930111 EXPECT_EQ(defNumber, 1);
112 std::vector<uint8_t> defIndices(defNumber);
113 rc = pldm_bios_table_attr_entry_enum_decode_def_indices(
114 entry, defIndices.data(), defIndices.size());
115 EXPECT_EQ(rc, defNumber);
116 EXPECT_THAT(defIndices, ElementsAreArray({1}));
117
118 defNumber = 0;
Andrew Jeffery46673f42024-06-25 16:02:25 +0930119 rc = pldm_bios_table_attr_entry_enum_decode_def_num(entry, &defNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930120 EXPECT_EQ(rc, PLDM_SUCCESS);
121 EXPECT_EQ(defNumber, 1);
122
Andrew Jefferyb06882f2024-06-25 15:52:02 +0930123 rc = pldm_bios_table_attr_entry_enum_decode_pv_num(nullptr, &pvNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930124 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery46673f42024-06-25 16:02:25 +0930125 rc = pldm_bios_table_attr_entry_enum_decode_def_num(entry, nullptr);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930126 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
127
128 entry->attr_type = PLDM_BIOS_STRING;
Andrew Jefferyb06882f2024-06-25 15:52:02 +0930129 rc = pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930130 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
131
Andrew Jeffery46673f42024-06-25 16:02:25 +0930132 rc = pldm_bios_table_attr_entry_enum_decode_def_num(entry, &defNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930133 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
134 rc =
135 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(entry, nullptr, 0);
136 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
137}
138
139TEST(AttrTable, EnumEntryEncodeTest)
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 */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530149 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930150 };
151
152 std::vector<uint16_t> pv_hdls{2, 3};
153 std::vector<uint8_t> defs{0};
154
155 struct pldm_bios_table_attr_entry_enum_info info = {
156 1, /* name handle */
157 false, /* read only */
158 2, /* pv number */
159 pv_hdls.data(), /* pv handle */
160 1, /*def number */
161 defs.data() /*def index*/
162 };
163 auto encodeLength = pldm_bios_table_attr_entry_enum_encode_length(2, 1);
164 EXPECT_EQ(encodeLength, enumEntry.size());
165
166 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930167 ASSERT_EQ(pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
168 encodeEntry.size(), &info),
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930169 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930170 // set attr handle = 0
171 encodeEntry[0] = 0;
172 encodeEntry[1] = 0;
173
174 EXPECT_EQ(enumEntry, encodeEntry);
175
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930176 EXPECT_NE(pldm_bios_table_attr_entry_enum_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930177 encodeEntry.data(), encodeEntry.size() - 1, &info),
178 PLDM_SUCCESS);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930179 auto rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
180 encodeEntry.size(), &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930181 EXPECT_EQ(rc, PLDM_SUCCESS);
182 // set attr handle = 0
183 encodeEntry[0] = 0;
184 encodeEntry[1] = 0;
185
186 EXPECT_EQ(enumEntry, encodeEntry);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930187 rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
188 encodeEntry.size() - 1, &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930189 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
190}
191
192TEST(AttrTable, StringEntryDecodeTest)
193{
194 std::vector<uint8_t> stringEntry{
195 1, 0, /* attr handle */
196 1, /* attr type */
197 12, 0, /* attr name handle */
198 1, /* string type */
199 1, 0, /* minimum length of the string in bytes */
200 100, 0, /* maximum length of the string in bytes */
201 3, 0, /* length of default string in length */
202 'a', 'b', 'c' /* default string */
203 };
204
205 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
206 stringEntry.data());
207 auto stringType =
208 pldm_bios_table_attr_entry_string_decode_string_type(entry);
209 EXPECT_EQ(stringType, 1);
210 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
211 EXPECT_EQ(minLength, 1);
212 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
213 EXPECT_EQ(maxLength, 100);
214
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930215 uint16_t defStringLength;
216 ASSERT_EQ(pldm_bios_table_attr_entry_string_decode_def_string_length_check(
217 entry, &defStringLength),
218 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930219 EXPECT_EQ(defStringLength, 3);
220 std::vector<char> defString(defStringLength + 1);
221 auto rc = pldm_bios_table_attr_entry_string_decode_def_string(
222 entry, defString.data(), defString.size());
223 EXPECT_EQ(rc, 3);
224 EXPECT_STREQ(defString.data(), "abc");
225 rc = pldm_bios_table_attr_entry_string_decode_def_string(
226 entry, defString.data(), defString.size() - 1);
227 EXPECT_EQ(rc, 2);
228 EXPECT_STREQ(defString.data(), "ab");
229
230 defStringLength = 0;
231 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
232 entry, &defStringLength);
233 EXPECT_EQ(rc, PLDM_SUCCESS);
234 EXPECT_EQ(defStringLength, 3);
235
236 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
237 entry, nullptr);
238 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
239 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
240 nullptr, &defStringLength);
241 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
242 entry->attr_type = PLDM_BIOS_INTEGER;
243 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
244 entry, &defStringLength);
245 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
246 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
247 nullptr, &defStringLength);
248 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
249}
250
251TEST(AttrTable, StringEntryEncodeTest)
252{
253 std::vector<uint8_t> stringEntry{
254 0, 0, /* attr handle */
255 1, /* attr type */
256 3, 0, /* attr name handle */
257 1, /* string type */
258 1, 0, /* min string length */
259 100, 0, /* max string length */
260 3, 0, /* default string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530261 'a', 'b', 'c', /* default string */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930262 };
263
264 struct pldm_bios_table_attr_entry_string_info info = {
265 3, /* name handle */
266 false, /* read only */
267 1, /* string type ascii */
268 1, /* min length */
269 100, /* max length */
270 3, /* def length */
271 "abc", /* def string */
272 };
273 auto encodeLength = pldm_bios_table_attr_entry_string_encode_length(3);
274 EXPECT_EQ(encodeLength, stringEntry.size());
275
276 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930277 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check(
278 encodeEntry.data(), encodeEntry.size(), &info),
279 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930280 // set attr handle = 0
281 encodeEntry[0] = 0;
282 encodeEntry[1] = 0;
283
284 EXPECT_EQ(stringEntry, encodeEntry);
285
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930286 EXPECT_NE(pldm_bios_table_attr_entry_string_encode_check(
287 encodeEntry.data(), encodeEntry.size() - 1, &info),
288 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930289 auto rc = pldm_bios_table_attr_entry_string_encode_check(
290 encodeEntry.data(), encodeEntry.size(), &info);
291 EXPECT_EQ(rc, PLDM_SUCCESS);
292 // set attr handle = 0
293 encodeEntry[0] = 0;
294 encodeEntry[1] = 0;
295
296 EXPECT_EQ(stringEntry, encodeEntry);
297 rc = pldm_bios_table_attr_entry_string_encode_check(
298 encodeEntry.data(), encodeEntry.size() - 1, &info);
299 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
300 std::swap(info.max_length, info.min_length);
301 const char* errmsg;
302 rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
303 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
304 EXPECT_STREQ(
305 "MinimumStingLength should not be greater than MaximumStringLength",
306 errmsg);
307 rc = pldm_bios_table_attr_entry_string_encode_check(
308 encodeEntry.data(), encodeEntry.size(), &info);
309 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
310 std::swap(info.max_length, info.min_length);
311
312 std::vector<uint8_t> stringEntryLength0{
313 0, 0, /* attr handle */
314 1, /* attr type */
315 3, 0, /* attr name handle */
316 1, /* string type */
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930317 0, 0, /* min string length */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930318 100, 0, /* max string length */
319 0, 0, /* default string length */
320 };
321
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930322 info.min_length = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930323 info.def_length = 0;
324 info.def_string = nullptr;
325
326 encodeLength = pldm_bios_table_attr_entry_string_encode_length(0);
327 EXPECT_EQ(encodeLength, stringEntryLength0.size());
328
329 encodeEntry.resize(encodeLength);
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930330 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check(
331 encodeEntry.data(), encodeEntry.size(), &info),
332 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930333 // set attr handle = 0
334 encodeEntry[0] = 0;
335 encodeEntry[1] = 0;
336
337 EXPECT_EQ(stringEntryLength0, encodeEntry);
338}
339
340TEST(AttrTable, integerEntryEncodeTest)
341{
342 std::vector<uint8_t> integerEntry{
343 0, 0, /* attr handle */
344 3, /* attr type */
345 1, 0, /* attr name handle */
346 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
347 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
348 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530349 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930350 };
351
352 std::vector<uint16_t> pv_hdls{2, 3};
353 std::vector<uint8_t> defs{0};
354
355 struct pldm_bios_table_attr_entry_integer_info info = {
356 1, /* name handle */
357 false, /* read only */
358 1, /* lower bound */
359 10, /* upper bound */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530360 2, /* scalar increment */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930361 3 /* default value */
362 };
363 auto encodeLength = pldm_bios_table_attr_entry_integer_encode_length();
364 EXPECT_EQ(encodeLength, integerEntry.size());
365
366 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930367 ASSERT_EQ(pldm_bios_table_attr_entry_integer_encode_check(
368 encodeEntry.data(), encodeEntry.size(), &info),
369 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930370 // set attr handle = 0
371 encodeEntry[0] = 0;
372 encodeEntry[1] = 0;
373
374 EXPECT_EQ(integerEntry, encodeEntry);
375
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930376 EXPECT_NE(pldm_bios_table_attr_entry_integer_encode_check(
377 encodeEntry.data(), encodeEntry.size() - 1, &info),
378 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930379
380 auto rc = pldm_bios_table_attr_entry_integer_encode_check(
381 encodeEntry.data(), encodeEntry.size(), &info);
382 EXPECT_EQ(rc, PLDM_SUCCESS);
383 // set attr handle = 0
384 encodeEntry[0] = 0;
385 encodeEntry[1] = 0;
386
387 EXPECT_EQ(integerEntry, encodeEntry);
388
389 rc = pldm_bios_table_attr_entry_integer_encode_check(
390 encodeEntry.data(), encodeEntry.size() - 1, &info);
391 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
392
393 info.lower_bound = 100;
394 info.upper_bound = 50;
395 const char* errmsg;
396 rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
397 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
398 EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg);
399 rc = pldm_bios_table_attr_entry_integer_encode_check(
400 encodeEntry.data(), encodeEntry.size(), &info);
401 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
402}
403
404TEST(AttrTable, integerEntryDecodeTest)
405{
406 std::vector<uint8_t> integerEntry{
407 0, 0, /* attr handle */
408 3, /* attr type */
409 1, 0, /* attr name handle */
410 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
411 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
412 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530413 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930414 };
415
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930416 uint64_t lower;
417 uint64_t upper;
418 uint64_t def;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930419 uint32_t scalar;
420 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
421 integerEntry.data());
422 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
423 &def);
424 EXPECT_EQ(lower, 1u);
425 EXPECT_EQ(upper, 10u);
426 EXPECT_EQ(scalar, 2u);
427 EXPECT_EQ(def, 3u);
428}
429
430TEST(AttrTable, ItearatorTest)
431{
432 std::vector<uint8_t> enumEntry{
433 0, 0, /* attr handle */
434 0, /* attr type */
435 1, 0, /* attr name handle */
436 2, /* number of possible value */
437 2, 0, /* possible value handle */
438 3, 0, /* possible value handle */
439 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530440 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930441 };
442 std::vector<uint8_t> stringEntry{
443 1, 0, /* attr handle */
444 1, /* attr type */
445 12, 0, /* attr name handle */
446 1, /* string type */
447 1, 0, /* minimum length of the string in bytes */
448 100, 0, /* maximum length of the string in bytes */
449 3, 0, /* length of default string in length */
450 'a', 'b', 'c' /* default string */
451 };
452 std::vector<uint8_t> integerEntry{
453 0, 0, /* attr handle */
454 3, /* attr type */
455 1, 0, /* attr name handle */
456 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
457 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
458 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530459 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930460 };
461
462 Table table;
463 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
464 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
465 PLDM_BIOS_ATTR_TABLE);
466 auto entry = pldm_bios_table_iter_attr_entry_value(iter);
467 auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
468 EXPECT_EQ(rc, 0);
469
470 pldm_bios_table_iter_next(iter);
471 entry = pldm_bios_table_iter_attr_entry_value(iter);
472 rc = std::memcmp(entry, stringEntry.data(), stringEntry.size());
473 EXPECT_EQ(rc, 0);
474
475 pldm_bios_table_iter_next(iter);
476 entry = pldm_bios_table_iter_attr_entry_value(iter);
477 rc = std::memcmp(entry, integerEntry.data(), integerEntry.size());
478 EXPECT_EQ(rc, 0);
479
480 pldm_bios_table_iter_next(iter);
481 entry = pldm_bios_table_iter_attr_entry_value(iter);
482 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
483 EXPECT_EQ(rc, 0);
484
485 pldm_bios_table_iter_next(iter);
486 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
487 pldm_bios_table_iter_free(iter);
488}
489
490TEST(AttrTable, FindTest)
491{
492 std::vector<uint8_t> enumEntry{
493 0, 0, /* attr handle */
494 0, /* attr type */
495 1, 0, /* attr name handle */
496 2, /* number of possible value */
497 2, 0, /* possible value handle */
498 3, 0, /* possible value handle */
499 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530500 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930501 };
502 std::vector<uint8_t> stringEntry{
503 1, 0, /* attr handle */
504 1, /* attr type */
505 2, 0, /* attr name handle */
506 1, /* string type */
507 1, 0, /* minimum length of the string in bytes */
508 100, 0, /* maximum length of the string in bytes */
509 3, 0, /* length of default string in length */
510 'a', 'b', 'c' /* default string */
511 };
512 std::vector<uint8_t> integerEntry{
513 0, 0, /* attr handle */
514 3, /* attr type */
515 3, 0, /* attr name handle */
516 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
517 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
518 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530519 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930520 };
521
522 Table table;
523 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
524
525 auto entry =
526 pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 1);
527 EXPECT_NE(entry, nullptr);
528 auto p = reinterpret_cast<const uint8_t*>(entry);
529 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
530 ElementsAreArray(stringEntry));
531
532 entry = pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 3);
533 EXPECT_EQ(entry, nullptr);
534
535 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
536 table.size(), 2);
537 EXPECT_NE(entry, nullptr);
538 p = reinterpret_cast<const uint8_t*>(entry);
539 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
540 ElementsAreArray(stringEntry));
541
542 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
543 table.size(), 4);
544 EXPECT_EQ(entry, nullptr);
545}
546
547TEST(AttrValTable, HeaderDecodeTest)
548{
549 std::vector<uint8_t> enumEntry{
550 1, 0, /* attr handle */
551 0, /* attr type */
552 2, /* number of current value */
553 0, /* current value string handle index */
554 1, /* current value string handle index */
555 };
556 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
557 enumEntry.data());
558 auto attrHandle =
559 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
560 EXPECT_EQ(attrHandle, 1);
561 auto attrType =
562 pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
563 EXPECT_EQ(attrType, 0);
564}
565
566TEST(AttrValTable, EnumEntryEncodeTest)
567{
568 std::vector<uint8_t> enumEntry{
569 0, 0, /* attr handle */
570 0, /* attr type */
571 2, /* number of current value */
572 0, /* current value string handle index */
573 1, /* current value string handle index */
574 };
575
576 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2);
577 EXPECT_EQ(length, enumEntry.size());
578 std::vector<uint8_t> encodeEntry(length, 0);
579 uint8_t handles[] = {0, 1};
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930580 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_enum_check(
581 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles),
582 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930583 EXPECT_EQ(encodeEntry, enumEntry);
584
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930585 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_enum_check(
586 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
587 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930588
589 auto rc = pldm_bios_table_attr_value_entry_encode_enum_check(
590 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2,
591 handles);
592 EXPECT_EQ(rc, PLDM_SUCCESS);
593 EXPECT_EQ(encodeEntry, enumEntry);
594 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
595 enumEntry.data());
596 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY;
597 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
598 encodeEntry.data(), encodeEntry.size(), 0,
599 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles);
600 EXPECT_EQ(rc, PLDM_SUCCESS);
601 EXPECT_EQ(encodeEntry, enumEntry);
602 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
603 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2,
604 handles);
605 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
606 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
607 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2,
608 handles);
609 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
610}
611
612TEST(AttrValTable, EnumEntryDecodeTest)
613{
614 std::vector<uint8_t> enumEntry{
615 0, 0, /* attr handle */
616 0, /* attr type */
617 2, /* number of current value */
618 0, /* current value string handle index */
619 1, /* current value string handle index */
620 };
621
622 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
623 enumEntry.data());
624 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
625 EXPECT_EQ(2, number);
626
627 std::vector<uint8_t> handles(2, 0);
628 auto rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
629 entry, handles.data(), handles.size());
630 EXPECT_EQ(rc, 2);
631 EXPECT_EQ(handles[0], 0);
632 EXPECT_EQ(handles[1], 1);
Archana Kakanib9d951f2023-10-17 05:47:58 -0500633
634 /* Buffer size is more than the number of current string handles */
635 std::vector<uint8_t> handleIndexes(3, 0);
636 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
637 entry, handleIndexes.data(), handleIndexes.size());
638 EXPECT_EQ(rc, 2);
639 EXPECT_EQ(handleIndexes[0], 0);
640 EXPECT_EQ(handleIndexes[1], 1);
641
642 /* Buffersize is less than the number of current string handles */
643 std::vector<uint8_t> strHandles(1, 0);
644 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
645 entry, strHandles.data(), strHandles.size());
646 EXPECT_EQ(rc, 1);
647 EXPECT_EQ(strHandles[0], 0);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930648}
649
650TEST(AttrValTable, stringEntryEncodeTest)
651{
652 std::vector<uint8_t> stringEntry{
653 0, 0, /* attr handle */
654 1, /* attr type */
655 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530656 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930657 };
658
659 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
660 EXPECT_EQ(length, stringEntry.size());
661 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery46d07682023-07-14 15:51:51 +0930662 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_string_check(
663 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc"),
664 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930665 EXPECT_EQ(encodeEntry, stringEntry);
666
Andrew Jeffery46d07682023-07-14 15:51:51 +0930667 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_string_check(
668 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
669 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930670
671 auto rc = pldm_bios_table_attr_value_entry_encode_string_check(
672 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
673 EXPECT_EQ(rc, PLDM_SUCCESS);
674 EXPECT_EQ(encodeEntry, stringEntry);
675 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
676 stringEntry.data());
677 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
678 rc = pldm_bios_table_attr_value_entry_encode_string_check(
679 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
680 3, "abc");
681 EXPECT_EQ(rc, PLDM_SUCCESS);
682 EXPECT_EQ(encodeEntry, stringEntry);
683 rc = pldm_bios_table_attr_value_entry_encode_string_check(
684 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
685 "abc");
686 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
687 rc = pldm_bios_table_attr_value_entry_encode_string_check(
688 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
689 "abc");
690 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
691}
692
693TEST(AttrValTable, StringEntryDecodeTest)
694{
695 std::vector<uint8_t> stringEntry{
696 0, 0, /* attr handle */
697 1, /* attr type */
698 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530699 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930700 };
701
702 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
703 stringEntry.data());
704 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
705 EXPECT_EQ(3, length);
706
707 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
708 EXPECT_EQ(0, handle);
709
710 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
711 EXPECT_EQ(stringEntry.size(), entryLength);
712
713 variable_field currentString{};
714 pldm_bios_table_attr_value_entry_string_decode_string(entry,
715 &currentString);
716 EXPECT_THAT(std::vector<uint8_t>(currentString.ptr,
717 currentString.ptr + currentString.length),
718 ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'}));
719}
720
721TEST(AttrValTable, integerEntryEncodeTest)
722{
723 std::vector<uint8_t> integerEntry{
724 0, 0, /* attr handle */
725 3, /* attr type */
726 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
727 };
728
729 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
730 EXPECT_EQ(length, integerEntry.size());
731 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930732 ASSERT_EQ(
733 pldm_bios_table_attr_value_entry_encode_integer_check(
734 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10),
735 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930736 EXPECT_EQ(encodeEntry, integerEntry);
737
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930738 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_integer_check(
739 encodeEntry.data(), encodeEntry.size() - 1, 0,
740 PLDM_BIOS_INTEGER, 10),
741 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930742
743 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
744 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
745 EXPECT_EQ(rc, PLDM_SUCCESS);
746 EXPECT_EQ(encodeEntry, integerEntry);
747 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
748 integerEntry.data());
749 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
750 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
751 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
752 10);
753 EXPECT_EQ(rc, PLDM_SUCCESS);
754 EXPECT_EQ(encodeEntry, integerEntry);
755
756 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
757 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
758 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
759 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
760 encodeEntry.data(), encodeEntry.size() - 1, 0,
761 PLDM_BIOS_INTEGER_READ_ONLY, 10);
762 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
763}
764
765TEST(AttrValTable, integerEntryDecodeTest)
766{
767 std::vector<uint8_t> integerEntry{
768 0, 0, /* attr handle */
769 3, /* attr type */
770 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
771 };
772
773 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
774 integerEntry.data());
775 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
776 EXPECT_EQ(cv, 10u);
777}
778
779TEST(AttrValTable, IteratorTest)
780{
781 std::vector<uint8_t> enumEntry{
782 0, 0, /* attr handle */
783 0, /* attr type */
784 2, /* number of current value */
785 0, /* current value string handle index */
786 1, /* current value string handle index */
787 };
788 std::vector<uint8_t> stringEntry{
789 0, 0, /* attr handle */
790 1, /* attr type */
791 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530792 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930793 };
794 std::vector<uint8_t> integerEntry{
795 0, 0, /* attr handle */
796 3, /* attr type */
797 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
798 };
799
800 Table table;
801 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
802
803 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
804 PLDM_BIOS_ATTR_VAL_TABLE);
805 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
806
807 auto p = reinterpret_cast<const uint8_t*>(entry);
808 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
809 ElementsAreArray(enumEntry));
810
811 pldm_bios_table_iter_next(iter);
812 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
813 p = reinterpret_cast<const uint8_t*>(entry);
814 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
815 ElementsAreArray(stringEntry));
816
817 pldm_bios_table_iter_next(iter);
818 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
819 p = reinterpret_cast<const uint8_t*>(entry);
820 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
821 ElementsAreArray(integerEntry));
822
823 pldm_bios_table_iter_next(iter);
824 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
825 p = reinterpret_cast<const uint8_t*>(entry);
826 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
827 ElementsAreArray(enumEntry));
828
829 pldm_bios_table_iter_next(iter);
830 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
831
832 pldm_bios_table_iter_free(iter);
833}
834
835TEST(AttrValTable, FindTest)
836{
837 std::vector<uint8_t> enumEntry{
838 0, 0, /* attr handle */
839 0, /* attr type */
840 2, /* number of current value */
841 0, /* current value string handle index */
842 1, /* current value string handle index */
843 };
844 std::vector<uint8_t> stringEntry{
845 1, 0, /* attr handle */
846 1, /* attr type */
847 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530848 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930849 };
850 std::vector<uint8_t> integerEntry{
851 2, 0, /* attr handle */
852 3, /* attr type */
853 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
854 };
855
856 Table table;
857 buildTable(table, enumEntry, stringEntry, integerEntry);
858
859 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
860 table.size(), 1);
861 EXPECT_NE(entry, nullptr);
862 auto p = reinterpret_cast<const uint8_t*>(entry);
863 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
864 ElementsAreArray(stringEntry));
865
866 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
867 table.size(), 3);
868 EXPECT_EQ(entry, nullptr);
869
870 auto firstEntry =
871 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
872 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
Andrew Jefferyfbaea232024-05-23 10:58:29 +0930873#ifdef NDEBUG
874 EXPECT_EQ(pldm_bios_table_attr_value_find_by_handle(table.data(),
875 table.size(), 1),
876 nullptr);
877#else
Andrew Jeffery9c766792022-08-10 23:12:49 +0930878 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
879 table.size(), 1),
880 "entry_length != NULL");
Andrew Jefferyfbaea232024-05-23 10:58:29 +0930881#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +0930882}
883
884TEST(AttrValTable, CopyAndUpdateTest)
885{
886 std::vector<uint8_t> enumEntry{
887 0, 0, /* attr handle */
888 0, /* attr type */
889 2, /* number of current value */
890 0, /* current value string handle index */
891 1, /* current value string handle index */
892 };
893 std::vector<uint8_t> stringEntry{
894 1, 0, /* attr handle */
895 1, /* attr type */
896 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530897 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930898 };
899 std::vector<uint8_t> integerEntry{
900 2, 0, /* attr handle */
901 3, /* attr type */
902 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
903 };
904
905 Table srcTable;
906 buildTable(srcTable, enumEntry, stringEntry, integerEntry);
907
908 std::vector<uint8_t> stringEntry1{
909 1, 0, /* attr handle */
910 1, /* attr type */
911 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530912 'd', 'e', 'f', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930913 };
914
915 Table expectTable;
916 buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
917 Table destTable(expectTable.size() + 10);
918 auto destLength = destTable.size();
919 auto rc = pldm_bios_table_attr_value_copy_and_update(
920 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
921 stringEntry1.data(), stringEntry1.size());
922
923 EXPECT_EQ(rc, PLDM_SUCCESS);
924 EXPECT_EQ(destLength, expectTable.size());
925 destTable.resize(destLength);
926 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
927
928 std::vector<uint8_t> stringEntry2{
929 1, 0, /* attr handle */
930 1, /* attr type */
931 5, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530932 'd', 'e', 'f', 'a', 'b', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930933 };
934 expectTable.resize(0);
935 buildTable(expectTable, enumEntry, stringEntry2, integerEntry);
936 destTable.resize(expectTable.size() + 10);
937 destLength = destTable.size();
938 rc = pldm_bios_table_attr_value_copy_and_update(
939 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
940 stringEntry2.data(), stringEntry2.size());
941 EXPECT_EQ(rc, PLDM_SUCCESS);
942 EXPECT_EQ(destLength, expectTable.size());
943 destTable.resize(destLength);
944 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
945
946 std::vector<uint8_t> stringEntry3{
947 1, 0, /* attr handle */
948 1, /* attr type */
949 1, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530950 'd', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930951 };
952 expectTable.resize(0);
953 buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
954 destTable.resize(expectTable.size() + 10);
955 destLength = destTable.size();
956 rc = pldm_bios_table_attr_value_copy_and_update(
957 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
958 stringEntry3.data(), stringEntry3.size());
959 EXPECT_EQ(rc, PLDM_SUCCESS);
960 EXPECT_EQ(destLength, expectTable.size());
961 destTable.resize(destLength);
962 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
963
964 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer
965 rc = pldm_bios_table_attr_value_copy_and_update(
966 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
967 stringEntry3.data(), stringEntry3.size());
968 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
969 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string
970
971 destTable.resize(expectTable.size() - 1);
972 destLength = destTable.size();
973 rc = pldm_bios_table_attr_value_copy_and_update(
974 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
975 stringEntry3.data(), stringEntry3.size());
976 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
977}
978
979TEST(StringTable, EntryEncodeTest)
980{
981 std::vector<uint8_t> stringEntry{
982 0, 0, /* string handle*/
983 7, 0, /* string length */
984 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
985 };
986
987 const char* str = "Allowed";
988 auto str_length = std::strlen(str);
989 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
990 EXPECT_EQ(encodeLength, stringEntry.size());
991
992 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jefferye48fdd62024-06-25 00:36:20 +0930993 ASSERT_EQ(pldm_bios_table_string_entry_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930994 encodeEntry.data(), encodeEntry.size(), str, str_length),
995 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930996 // set string handle = 0
997 encodeEntry[0] = 0;
998 encodeEntry[1] = 0;
999
1000 EXPECT_EQ(stringEntry, encodeEntry);
1001
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301002 EXPECT_NE(pldm_bios_table_string_entry_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301003 encodeEntry.data(), encodeEntry.size() - 1, str, str_length),
1004 PLDM_SUCCESS);
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301005 auto rc = pldm_bios_table_string_entry_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +09301006 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
1007 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1008}
1009
1010TEST(StringTable, EntryDecodeTest)
1011{
1012 std::vector<uint8_t> stringEntry{
1013 4, 0, /* string handle*/
1014 7, 0, /* string length */
1015 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
1016 };
1017 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
1018 stringEntry.data());
1019 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1020 EXPECT_EQ(handle, 4);
1021 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
1022 EXPECT_EQ(strLength, 7);
1023
1024 std::vector<char> buffer(strLength + 1, 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301025 pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1026 buffer.size());
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301027 EXPECT_EQ(strlen(buffer.data()), strLength);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301028 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301029 EXPECT_EQ(pldm_bios_table_string_entry_decode_string(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301030 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/),
1031 PLDM_SUCCESS);
1032 EXPECT_EQ(strlen(buffer.data()), 2);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301033 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
1034
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301035 auto rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1036 buffer.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +09301037 EXPECT_EQ(rc, PLDM_SUCCESS);
1038 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
1039
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301040 /* Ensure equivalence with the unchecked API */
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301041 rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1042 2 + 1 /* sizeof '\0' */);
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301043 EXPECT_EQ(rc, std::strcmp("Al", buffer.data()));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301044}
1045
1046TEST(StringTable, IteratorTest)
1047{
1048 std::vector<uint8_t> stringHello{
1049 0, 0, /* string handle*/
1050 5, 0, /* string length */
1051 'H', 'e', 'l', 'l', 'o', /* string */
1052 };
1053 std::vector<uint8_t> stringWorld{
1054 1, 0, /* string handle*/
1055 6, 0, /* string length */
1056 'W', 'o', 'r', 'l', 'd', '!', /* string */
1057 };
1058
1059 Table table;
1060 buildTable(table, stringHello, stringWorld);
1061
1062 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1063 PLDM_BIOS_STRING_TABLE);
1064 auto entry = pldm_bios_table_iter_string_entry_value(iter);
1065 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
1066 EXPECT_EQ(rc, 0);
1067 pldm_bios_table_iter_next(iter);
1068 entry = pldm_bios_table_iter_string_entry_value(iter);
1069 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
1070 EXPECT_EQ(rc, 0);
1071 pldm_bios_table_iter_next(iter);
1072 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
1073 pldm_bios_table_iter_free(iter);
1074}
1075
1076TEST(StringTable, FindTest)
1077{
1078 std::vector<uint8_t> stringHello{
1079 1, 0, /* string handle*/
1080 5, 0, /* string length */
1081 'H', 'e', 'l', 'l', 'o', /* string */
1082 };
1083 std::vector<uint8_t> stringWorld{
1084 2, 0, /* string handle*/
1085 6, 0, /* string length */
1086 'W', 'o', 'r', 'l', 'd', '!', /* string */
1087 };
1088 std::vector<uint8_t> stringHi{
1089 3, 0, /* string handle*/
1090 2, 0, /* string length */
1091 'H', 'i', /* string */
1092 };
1093
1094 Table table;
1095 buildTable(table, stringHello, stringWorld, stringHi);
1096
1097 auto entry = pldm_bios_table_string_find_by_string(table.data(),
1098 table.size(), "World!");
1099 EXPECT_NE(entry, nullptr);
1100 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1101 EXPECT_EQ(handle, 2);
1102
1103 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
1104 "Worl");
1105 EXPECT_EQ(entry, nullptr);
1106
1107 entry =
1108 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
1109 EXPECT_NE(entry, nullptr);
1110 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
1111 EXPECT_EQ(str_length, 2);
1112 std::vector<char> strBuf(str_length + 1, 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301113 auto rc = pldm_bios_table_string_entry_decode_string(entry, strBuf.data(),
1114 strBuf.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +09301115 EXPECT_EQ(rc, PLDM_SUCCESS);
1116 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
1117
1118 entry =
1119 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
1120 EXPECT_EQ(entry, nullptr);
1121}
1122
Andrew Jefferybf6699b2023-07-05 16:27:59 +09301123TEST(Iterator, DeathTest)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301124{
1125
1126 Table table(256, 0);
1127
1128 /* first entry */
1129 auto attr_entry =
1130 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
1131 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1132 PLDM_BIOS_ATTR_TABLE);
1133 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
Andrew Jefferyfbaea232024-05-23 10:58:29 +09301134#ifndef NDEBUG
Andrew Jeffery9c766792022-08-10 23:12:49 +09301135 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
Andrew Jefferyfbaea232024-05-23 10:58:29 +09301136#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301137 pldm_bios_table_iter_free(iter);
1138}
1139
1140TEST(PadAndChecksum, PadAndChecksum)
1141{
1142 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0));
1143 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1));
1144 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2));
1145 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3));
1146 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4));
1147
1148 // The table is borrowed from
1149 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
1150 // refer to the commit message
1151 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
1152 auto sizeWithoutPad = attrValTable.size();
1153 attrValTable.resize(sizeWithoutPad +
1154 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
Andrew Jeffery50dd1592023-07-14 16:02:05 +09301155 ASSERT_EQ(pldm_bios_table_append_pad_checksum_check(
1156 attrValTable.data(), attrValTable.size(), &sizeWithoutPad),
1157 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301158 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
1159 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
1160 EXPECT_EQ(attrValTable, expectedTable);
1161}
1162
1163TEST(BIOSTableChecksum, testBIOSTableChecksum)
1164{
1165 std::vector<uint8_t> stringTable{
1166 1, 0, /* string handle*/
1167 5, 0, /* string length */
1168 'T', 'a', 'b', 'l', 'e', /* string */
1169 };
1170
1171 buildTable(stringTable);
1172
1173 EXPECT_EQ(true,
1174 pldm_bios_table_checksum(stringTable.data(), stringTable.size()));
1175}