blob: 70ad1ae453de649dc8ba44cb8d80e4532f958247 [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 Jeffery82b4d3b2024-06-25 16:22:36 +093086 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093087 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 Jeffery82b4d3b2024-06-25 16:22:36 +093093 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093094 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);
Andrew Jeffery82b4d3b2024-06-25 16:22:36 +093099 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pvHandles.data(),
100 pvHandles.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +0930101 EXPECT_EQ(rc, PLDM_SUCCESS);
102 EXPECT_EQ(pvHandles[0], 2);
103 EXPECT_EQ(pvHandles[1], 3);
Andrew Jeffery82b4d3b2024-06-25 16:22:36 +0930104 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pvHandles.data(),
105 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);
Andrew Jeffery82b4d3b2024-06-25 16:22:36 +0930134 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, nullptr, 0);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930135 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
136}
137
138TEST(AttrTable, EnumEntryEncodeTest)
139{
140 std::vector<uint8_t> enumEntry{
141 0, 0, /* attr handle */
142 0, /* attr type */
143 1, 0, /* attr name handle */
144 2, /* number of possible value */
145 2, 0, /* possible value handle */
146 3, 0, /* possible value handle */
147 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530148 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930149 };
150
151 std::vector<uint16_t> pv_hdls{2, 3};
152 std::vector<uint8_t> defs{0};
153
154 struct pldm_bios_table_attr_entry_enum_info info = {
155 1, /* name handle */
156 false, /* read only */
157 2, /* pv number */
158 pv_hdls.data(), /* pv handle */
159 1, /*def number */
160 defs.data() /*def index*/
161 };
162 auto encodeLength = pldm_bios_table_attr_entry_enum_encode_length(2, 1);
163 EXPECT_EQ(encodeLength, enumEntry.size());
164
165 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930166 ASSERT_EQ(pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
167 encodeEntry.size(), &info),
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930168 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930169 // set attr handle = 0
170 encodeEntry[0] = 0;
171 encodeEntry[1] = 0;
172
173 EXPECT_EQ(enumEntry, encodeEntry);
174
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930175 EXPECT_NE(pldm_bios_table_attr_entry_enum_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930176 encodeEntry.data(), encodeEntry.size() - 1, &info),
177 PLDM_SUCCESS);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930178 auto rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
179 encodeEntry.size(), &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930180 EXPECT_EQ(rc, PLDM_SUCCESS);
181 // set attr handle = 0
182 encodeEntry[0] = 0;
183 encodeEntry[1] = 0;
184
185 EXPECT_EQ(enumEntry, encodeEntry);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930186 rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
187 encodeEntry.size() - 1, &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930188 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
189}
190
191TEST(AttrTable, StringEntryDecodeTest)
192{
193 std::vector<uint8_t> stringEntry{
194 1, 0, /* attr handle */
195 1, /* attr type */
196 12, 0, /* attr name handle */
197 1, /* string type */
198 1, 0, /* minimum length of the string in bytes */
199 100, 0, /* maximum length of the string in bytes */
200 3, 0, /* length of default string in length */
201 'a', 'b', 'c' /* default string */
202 };
203
204 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
205 stringEntry.data());
206 auto stringType =
207 pldm_bios_table_attr_entry_string_decode_string_type(entry);
208 EXPECT_EQ(stringType, 1);
209 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
210 EXPECT_EQ(minLength, 1);
211 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
212 EXPECT_EQ(maxLength, 100);
213
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930214 uint16_t defStringLength;
215 ASSERT_EQ(pldm_bios_table_attr_entry_string_decode_def_string_length_check(
216 entry, &defStringLength),
217 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930218 EXPECT_EQ(defStringLength, 3);
219 std::vector<char> defString(defStringLength + 1);
220 auto rc = pldm_bios_table_attr_entry_string_decode_def_string(
221 entry, defString.data(), defString.size());
222 EXPECT_EQ(rc, 3);
223 EXPECT_STREQ(defString.data(), "abc");
224 rc = pldm_bios_table_attr_entry_string_decode_def_string(
225 entry, defString.data(), defString.size() - 1);
226 EXPECT_EQ(rc, 2);
227 EXPECT_STREQ(defString.data(), "ab");
228
229 defStringLength = 0;
230 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
231 entry, &defStringLength);
232 EXPECT_EQ(rc, PLDM_SUCCESS);
233 EXPECT_EQ(defStringLength, 3);
234
235 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
236 entry, nullptr);
237 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
238 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
239 nullptr, &defStringLength);
240 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
241 entry->attr_type = PLDM_BIOS_INTEGER;
242 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
243 entry, &defStringLength);
244 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
245 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
246 nullptr, &defStringLength);
247 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
248}
249
250TEST(AttrTable, StringEntryEncodeTest)
251{
252 std::vector<uint8_t> stringEntry{
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 3, 0, /* default string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530260 'a', 'b', 'c', /* default string */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930261 };
262
263 struct pldm_bios_table_attr_entry_string_info info = {
264 3, /* name handle */
265 false, /* read only */
266 1, /* string type ascii */
267 1, /* min length */
268 100, /* max length */
269 3, /* def length */
270 "abc", /* def string */
271 };
272 auto encodeLength = pldm_bios_table_attr_entry_string_encode_length(3);
273 EXPECT_EQ(encodeLength, stringEntry.size());
274
275 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jefferyf6be4932024-06-25 16:44:06 +0930276 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930277 encodeEntry.data(), encodeEntry.size(), &info),
278 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930279 // set attr handle = 0
280 encodeEntry[0] = 0;
281 encodeEntry[1] = 0;
282
283 EXPECT_EQ(stringEntry, encodeEntry);
284
Andrew Jefferyf6be4932024-06-25 16:44:06 +0930285 EXPECT_NE(pldm_bios_table_attr_entry_string_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930286 encodeEntry.data(), encodeEntry.size() - 1, &info),
287 PLDM_SUCCESS);
Andrew Jefferyf6be4932024-06-25 16:44:06 +0930288 auto rc = pldm_bios_table_attr_entry_string_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930289 encodeEntry.data(), encodeEntry.size(), &info);
290 EXPECT_EQ(rc, PLDM_SUCCESS);
291 // set attr handle = 0
292 encodeEntry[0] = 0;
293 encodeEntry[1] = 0;
294
295 EXPECT_EQ(stringEntry, encodeEntry);
Andrew Jefferyf6be4932024-06-25 16:44:06 +0930296 rc = pldm_bios_table_attr_entry_string_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930297 encodeEntry.data(), encodeEntry.size() - 1, &info);
298 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
299 std::swap(info.max_length, info.min_length);
300 const char* errmsg;
301 rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
302 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
303 EXPECT_STREQ(
304 "MinimumStingLength should not be greater than MaximumStringLength",
305 errmsg);
Andrew Jefferyf6be4932024-06-25 16:44:06 +0930306 rc = pldm_bios_table_attr_entry_string_encode(encodeEntry.data(),
307 encodeEntry.size(), &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930308 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
309 std::swap(info.max_length, info.min_length);
310
311 std::vector<uint8_t> stringEntryLength0{
312 0, 0, /* attr handle */
313 1, /* attr type */
314 3, 0, /* attr name handle */
315 1, /* string type */
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930316 0, 0, /* min string length */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930317 100, 0, /* max string length */
318 0, 0, /* default string length */
319 };
320
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930321 info.min_length = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930322 info.def_length = 0;
323 info.def_string = nullptr;
324
325 encodeLength = pldm_bios_table_attr_entry_string_encode_length(0);
326 EXPECT_EQ(encodeLength, stringEntryLength0.size());
327
328 encodeEntry.resize(encodeLength);
Andrew Jefferyf6be4932024-06-25 16:44:06 +0930329 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930330 encodeEntry.data(), encodeEntry.size(), &info),
331 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930332 // set attr handle = 0
333 encodeEntry[0] = 0;
334 encodeEntry[1] = 0;
335
336 EXPECT_EQ(stringEntryLength0, encodeEntry);
337}
338
339TEST(AttrTable, integerEntryEncodeTest)
340{
341 std::vector<uint8_t> integerEntry{
342 0, 0, /* attr handle */
343 3, /* attr type */
344 1, 0, /* attr name handle */
345 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
346 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
347 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530348 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930349 };
350
351 std::vector<uint16_t> pv_hdls{2, 3};
352 std::vector<uint8_t> defs{0};
353
354 struct pldm_bios_table_attr_entry_integer_info info = {
355 1, /* name handle */
356 false, /* read only */
357 1, /* lower bound */
358 10, /* upper bound */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530359 2, /* scalar increment */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930360 3 /* default value */
361 };
362 auto encodeLength = pldm_bios_table_attr_entry_integer_encode_length();
363 EXPECT_EQ(encodeLength, integerEntry.size());
364
365 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930366 ASSERT_EQ(pldm_bios_table_attr_entry_integer_encode_check(
367 encodeEntry.data(), encodeEntry.size(), &info),
368 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930369 // set attr handle = 0
370 encodeEntry[0] = 0;
371 encodeEntry[1] = 0;
372
373 EXPECT_EQ(integerEntry, encodeEntry);
374
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930375 EXPECT_NE(pldm_bios_table_attr_entry_integer_encode_check(
376 encodeEntry.data(), encodeEntry.size() - 1, &info),
377 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930378
379 auto rc = pldm_bios_table_attr_entry_integer_encode_check(
380 encodeEntry.data(), encodeEntry.size(), &info);
381 EXPECT_EQ(rc, PLDM_SUCCESS);
382 // set attr handle = 0
383 encodeEntry[0] = 0;
384 encodeEntry[1] = 0;
385
386 EXPECT_EQ(integerEntry, encodeEntry);
387
388 rc = pldm_bios_table_attr_entry_integer_encode_check(
389 encodeEntry.data(), encodeEntry.size() - 1, &info);
390 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
391
392 info.lower_bound = 100;
393 info.upper_bound = 50;
394 const char* errmsg;
395 rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
396 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
397 EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg);
398 rc = pldm_bios_table_attr_entry_integer_encode_check(
399 encodeEntry.data(), encodeEntry.size(), &info);
400 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
401}
402
403TEST(AttrTable, integerEntryDecodeTest)
404{
405 std::vector<uint8_t> integerEntry{
406 0, 0, /* attr handle */
407 3, /* attr type */
408 1, 0, /* attr name handle */
409 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
410 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
411 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530412 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930413 };
414
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930415 uint64_t lower;
416 uint64_t upper;
417 uint64_t def;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930418 uint32_t scalar;
419 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
420 integerEntry.data());
421 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
422 &def);
423 EXPECT_EQ(lower, 1u);
424 EXPECT_EQ(upper, 10u);
425 EXPECT_EQ(scalar, 2u);
426 EXPECT_EQ(def, 3u);
427}
428
429TEST(AttrTable, ItearatorTest)
430{
431 std::vector<uint8_t> enumEntry{
432 0, 0, /* attr handle */
433 0, /* attr type */
434 1, 0, /* attr name handle */
435 2, /* number of possible value */
436 2, 0, /* possible value handle */
437 3, 0, /* possible value handle */
438 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530439 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930440 };
441 std::vector<uint8_t> stringEntry{
442 1, 0, /* attr handle */
443 1, /* attr type */
444 12, 0, /* attr name handle */
445 1, /* string type */
446 1, 0, /* minimum length of the string in bytes */
447 100, 0, /* maximum length of the string in bytes */
448 3, 0, /* length of default string in length */
449 'a', 'b', 'c' /* default string */
450 };
451 std::vector<uint8_t> integerEntry{
452 0, 0, /* attr handle */
453 3, /* attr type */
454 1, 0, /* attr name handle */
455 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
456 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
457 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530458 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930459 };
460
461 Table table;
462 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
463 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
464 PLDM_BIOS_ATTR_TABLE);
465 auto entry = pldm_bios_table_iter_attr_entry_value(iter);
466 auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
467 EXPECT_EQ(rc, 0);
468
469 pldm_bios_table_iter_next(iter);
470 entry = pldm_bios_table_iter_attr_entry_value(iter);
471 rc = std::memcmp(entry, stringEntry.data(), stringEntry.size());
472 EXPECT_EQ(rc, 0);
473
474 pldm_bios_table_iter_next(iter);
475 entry = pldm_bios_table_iter_attr_entry_value(iter);
476 rc = std::memcmp(entry, integerEntry.data(), integerEntry.size());
477 EXPECT_EQ(rc, 0);
478
479 pldm_bios_table_iter_next(iter);
480 entry = pldm_bios_table_iter_attr_entry_value(iter);
481 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
482 EXPECT_EQ(rc, 0);
483
484 pldm_bios_table_iter_next(iter);
485 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
486 pldm_bios_table_iter_free(iter);
487}
488
489TEST(AttrTable, FindTest)
490{
491 std::vector<uint8_t> enumEntry{
492 0, 0, /* attr handle */
493 0, /* attr type */
494 1, 0, /* attr name handle */
495 2, /* number of possible value */
496 2, 0, /* possible value handle */
497 3, 0, /* possible value handle */
498 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530499 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930500 };
501 std::vector<uint8_t> stringEntry{
502 1, 0, /* attr handle */
503 1, /* attr type */
504 2, 0, /* attr name handle */
505 1, /* string type */
506 1, 0, /* minimum length of the string in bytes */
507 100, 0, /* maximum length of the string in bytes */
508 3, 0, /* length of default string in length */
509 'a', 'b', 'c' /* default string */
510 };
511 std::vector<uint8_t> integerEntry{
512 0, 0, /* attr handle */
513 3, /* attr type */
514 3, 0, /* attr name handle */
515 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
516 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
517 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530518 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930519 };
520
521 Table table;
522 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
523
524 auto entry =
525 pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 1);
526 EXPECT_NE(entry, nullptr);
527 auto p = reinterpret_cast<const uint8_t*>(entry);
528 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
529 ElementsAreArray(stringEntry));
530
531 entry = pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 3);
532 EXPECT_EQ(entry, nullptr);
533
534 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
535 table.size(), 2);
536 EXPECT_NE(entry, nullptr);
537 p = reinterpret_cast<const uint8_t*>(entry);
538 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
539 ElementsAreArray(stringEntry));
540
541 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
542 table.size(), 4);
543 EXPECT_EQ(entry, nullptr);
544}
545
546TEST(AttrValTable, HeaderDecodeTest)
547{
548 std::vector<uint8_t> enumEntry{
549 1, 0, /* attr handle */
550 0, /* attr type */
551 2, /* number of current value */
552 0, /* current value string handle index */
553 1, /* current value string handle index */
554 };
555 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
556 enumEntry.data());
557 auto attrHandle =
558 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
559 EXPECT_EQ(attrHandle, 1);
560 auto attrType =
561 pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
562 EXPECT_EQ(attrType, 0);
563}
564
565TEST(AttrValTable, EnumEntryEncodeTest)
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
575 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2);
576 EXPECT_EQ(length, enumEntry.size());
577 std::vector<uint8_t> encodeEntry(length, 0);
578 uint8_t handles[] = {0, 1};
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930579 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_enum_check(
580 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles),
581 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930582 EXPECT_EQ(encodeEntry, enumEntry);
583
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930584 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_enum_check(
585 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
586 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930587
588 auto rc = pldm_bios_table_attr_value_entry_encode_enum_check(
589 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2,
590 handles);
591 EXPECT_EQ(rc, PLDM_SUCCESS);
592 EXPECT_EQ(encodeEntry, enumEntry);
593 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
594 enumEntry.data());
595 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY;
596 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
597 encodeEntry.data(), encodeEntry.size(), 0,
598 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles);
599 EXPECT_EQ(rc, PLDM_SUCCESS);
600 EXPECT_EQ(encodeEntry, enumEntry);
601 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
602 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2,
603 handles);
604 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
605 rc = pldm_bios_table_attr_value_entry_encode_enum_check(
606 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2,
607 handles);
608 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
609}
610
611TEST(AttrValTable, EnumEntryDecodeTest)
612{
613 std::vector<uint8_t> enumEntry{
614 0, 0, /* attr handle */
615 0, /* attr type */
616 2, /* number of current value */
617 0, /* current value string handle index */
618 1, /* current value string handle index */
619 };
620
621 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
622 enumEntry.data());
623 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
624 EXPECT_EQ(2, number);
625
626 std::vector<uint8_t> handles(2, 0);
627 auto rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
628 entry, handles.data(), handles.size());
629 EXPECT_EQ(rc, 2);
630 EXPECT_EQ(handles[0], 0);
631 EXPECT_EQ(handles[1], 1);
Archana Kakanib9d951f2023-10-17 05:47:58 -0500632
633 /* Buffer size is more than the number of current string handles */
634 std::vector<uint8_t> handleIndexes(3, 0);
635 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
636 entry, handleIndexes.data(), handleIndexes.size());
637 EXPECT_EQ(rc, 2);
638 EXPECT_EQ(handleIndexes[0], 0);
639 EXPECT_EQ(handleIndexes[1], 1);
640
641 /* Buffersize is less than the number of current string handles */
642 std::vector<uint8_t> strHandles(1, 0);
643 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
644 entry, strHandles.data(), strHandles.size());
645 EXPECT_EQ(rc, 1);
646 EXPECT_EQ(strHandles[0], 0);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930647}
648
649TEST(AttrValTable, stringEntryEncodeTest)
650{
651 std::vector<uint8_t> stringEntry{
652 0, 0, /* attr handle */
653 1, /* attr type */
654 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530655 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930656 };
657
658 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
659 EXPECT_EQ(length, stringEntry.size());
660 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery46d07682023-07-14 15:51:51 +0930661 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_string_check(
662 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc"),
663 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930664 EXPECT_EQ(encodeEntry, stringEntry);
665
Andrew Jeffery46d07682023-07-14 15:51:51 +0930666 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_string_check(
667 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
668 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930669
670 auto rc = pldm_bios_table_attr_value_entry_encode_string_check(
671 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
672 EXPECT_EQ(rc, PLDM_SUCCESS);
673 EXPECT_EQ(encodeEntry, stringEntry);
674 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
675 stringEntry.data());
676 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
677 rc = pldm_bios_table_attr_value_entry_encode_string_check(
678 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
679 3, "abc");
680 EXPECT_EQ(rc, PLDM_SUCCESS);
681 EXPECT_EQ(encodeEntry, stringEntry);
682 rc = pldm_bios_table_attr_value_entry_encode_string_check(
683 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
684 "abc");
685 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
686 rc = pldm_bios_table_attr_value_entry_encode_string_check(
687 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
688 "abc");
689 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
690}
691
692TEST(AttrValTable, StringEntryDecodeTest)
693{
694 std::vector<uint8_t> stringEntry{
695 0, 0, /* attr handle */
696 1, /* attr type */
697 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530698 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930699 };
700
701 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
702 stringEntry.data());
703 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
704 EXPECT_EQ(3, length);
705
706 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
707 EXPECT_EQ(0, handle);
708
709 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
710 EXPECT_EQ(stringEntry.size(), entryLength);
711
712 variable_field currentString{};
713 pldm_bios_table_attr_value_entry_string_decode_string(entry,
714 &currentString);
715 EXPECT_THAT(std::vector<uint8_t>(currentString.ptr,
716 currentString.ptr + currentString.length),
717 ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'}));
718}
719
720TEST(AttrValTable, integerEntryEncodeTest)
721{
722 std::vector<uint8_t> integerEntry{
723 0, 0, /* attr handle */
724 3, /* attr type */
725 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
726 };
727
728 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
729 EXPECT_EQ(length, integerEntry.size());
730 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930731 ASSERT_EQ(
732 pldm_bios_table_attr_value_entry_encode_integer_check(
733 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10),
734 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930735 EXPECT_EQ(encodeEntry, integerEntry);
736
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930737 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_integer_check(
738 encodeEntry.data(), encodeEntry.size() - 1, 0,
739 PLDM_BIOS_INTEGER, 10),
740 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930741
742 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
743 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
744 EXPECT_EQ(rc, PLDM_SUCCESS);
745 EXPECT_EQ(encodeEntry, integerEntry);
746 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
747 integerEntry.data());
748 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
749 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
750 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
751 10);
752 EXPECT_EQ(rc, PLDM_SUCCESS);
753 EXPECT_EQ(encodeEntry, integerEntry);
754
755 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
756 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
757 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
758 rc = pldm_bios_table_attr_value_entry_encode_integer_check(
759 encodeEntry.data(), encodeEntry.size() - 1, 0,
760 PLDM_BIOS_INTEGER_READ_ONLY, 10);
761 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
762}
763
764TEST(AttrValTable, integerEntryDecodeTest)
765{
766 std::vector<uint8_t> integerEntry{
767 0, 0, /* attr handle */
768 3, /* attr type */
769 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
770 };
771
772 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
773 integerEntry.data());
774 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
775 EXPECT_EQ(cv, 10u);
776}
777
778TEST(AttrValTable, IteratorTest)
779{
780 std::vector<uint8_t> enumEntry{
781 0, 0, /* attr handle */
782 0, /* attr type */
783 2, /* number of current value */
784 0, /* current value string handle index */
785 1, /* current value string handle index */
786 };
787 std::vector<uint8_t> stringEntry{
788 0, 0, /* attr handle */
789 1, /* attr type */
790 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530791 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930792 };
793 std::vector<uint8_t> integerEntry{
794 0, 0, /* attr handle */
795 3, /* attr type */
796 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
797 };
798
799 Table table;
800 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
801
802 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
803 PLDM_BIOS_ATTR_VAL_TABLE);
804 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
805
806 auto p = reinterpret_cast<const uint8_t*>(entry);
807 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
808 ElementsAreArray(enumEntry));
809
810 pldm_bios_table_iter_next(iter);
811 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
812 p = reinterpret_cast<const uint8_t*>(entry);
813 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
814 ElementsAreArray(stringEntry));
815
816 pldm_bios_table_iter_next(iter);
817 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
818 p = reinterpret_cast<const uint8_t*>(entry);
819 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
820 ElementsAreArray(integerEntry));
821
822 pldm_bios_table_iter_next(iter);
823 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
824 p = reinterpret_cast<const uint8_t*>(entry);
825 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
826 ElementsAreArray(enumEntry));
827
828 pldm_bios_table_iter_next(iter);
829 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
830
831 pldm_bios_table_iter_free(iter);
832}
833
834TEST(AttrValTable, FindTest)
835{
836 std::vector<uint8_t> enumEntry{
837 0, 0, /* attr handle */
838 0, /* attr type */
839 2, /* number of current value */
840 0, /* current value string handle index */
841 1, /* current value string handle index */
842 };
843 std::vector<uint8_t> stringEntry{
844 1, 0, /* attr handle */
845 1, /* attr type */
846 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530847 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930848 };
849 std::vector<uint8_t> integerEntry{
850 2, 0, /* attr handle */
851 3, /* attr type */
852 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
853 };
854
855 Table table;
856 buildTable(table, enumEntry, stringEntry, integerEntry);
857
858 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
859 table.size(), 1);
860 EXPECT_NE(entry, nullptr);
861 auto p = reinterpret_cast<const uint8_t*>(entry);
862 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
863 ElementsAreArray(stringEntry));
864
865 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
866 table.size(), 3);
867 EXPECT_EQ(entry, nullptr);
868
869 auto firstEntry =
870 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
871 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
Andrew Jefferyfbaea232024-05-23 10:58:29 +0930872#ifdef NDEBUG
873 EXPECT_EQ(pldm_bios_table_attr_value_find_by_handle(table.data(),
874 table.size(), 1),
875 nullptr);
876#else
Andrew Jeffery9c766792022-08-10 23:12:49 +0930877 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
878 table.size(), 1),
879 "entry_length != NULL");
Andrew Jefferyfbaea232024-05-23 10:58:29 +0930880#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +0930881}
882
883TEST(AttrValTable, CopyAndUpdateTest)
884{
885 std::vector<uint8_t> enumEntry{
886 0, 0, /* attr handle */
887 0, /* attr type */
888 2, /* number of current value */
889 0, /* current value string handle index */
890 1, /* current value string handle index */
891 };
892 std::vector<uint8_t> stringEntry{
893 1, 0, /* attr handle */
894 1, /* attr type */
895 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530896 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930897 };
898 std::vector<uint8_t> integerEntry{
899 2, 0, /* attr handle */
900 3, /* attr type */
901 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
902 };
903
904 Table srcTable;
905 buildTable(srcTable, enumEntry, stringEntry, integerEntry);
906
907 std::vector<uint8_t> stringEntry1{
908 1, 0, /* attr handle */
909 1, /* attr type */
910 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530911 'd', 'e', 'f', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930912 };
913
914 Table expectTable;
915 buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
916 Table destTable(expectTable.size() + 10);
917 auto destLength = destTable.size();
918 auto rc = pldm_bios_table_attr_value_copy_and_update(
919 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
920 stringEntry1.data(), stringEntry1.size());
921
922 EXPECT_EQ(rc, PLDM_SUCCESS);
923 EXPECT_EQ(destLength, expectTable.size());
924 destTable.resize(destLength);
925 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
926
927 std::vector<uint8_t> stringEntry2{
928 1, 0, /* attr handle */
929 1, /* attr type */
930 5, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530931 'd', 'e', 'f', 'a', 'b', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930932 };
933 expectTable.resize(0);
934 buildTable(expectTable, enumEntry, stringEntry2, integerEntry);
935 destTable.resize(expectTable.size() + 10);
936 destLength = destTable.size();
937 rc = pldm_bios_table_attr_value_copy_and_update(
938 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
939 stringEntry2.data(), stringEntry2.size());
940 EXPECT_EQ(rc, PLDM_SUCCESS);
941 EXPECT_EQ(destLength, expectTable.size());
942 destTable.resize(destLength);
943 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
944
945 std::vector<uint8_t> stringEntry3{
946 1, 0, /* attr handle */
947 1, /* attr type */
948 1, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530949 'd', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930950 };
951 expectTable.resize(0);
952 buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
953 destTable.resize(expectTable.size() + 10);
954 destLength = destTable.size();
955 rc = pldm_bios_table_attr_value_copy_and_update(
956 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
957 stringEntry3.data(), stringEntry3.size());
958 EXPECT_EQ(rc, PLDM_SUCCESS);
959 EXPECT_EQ(destLength, expectTable.size());
960 destTable.resize(destLength);
961 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
962
963 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer
964 rc = pldm_bios_table_attr_value_copy_and_update(
965 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
966 stringEntry3.data(), stringEntry3.size());
967 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
968 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string
969
970 destTable.resize(expectTable.size() - 1);
971 destLength = destTable.size();
972 rc = pldm_bios_table_attr_value_copy_and_update(
973 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
974 stringEntry3.data(), stringEntry3.size());
975 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
976}
977
978TEST(StringTable, EntryEncodeTest)
979{
980 std::vector<uint8_t> stringEntry{
981 0, 0, /* string handle*/
982 7, 0, /* string length */
983 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
984 };
985
986 const char* str = "Allowed";
987 auto str_length = std::strlen(str);
988 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
989 EXPECT_EQ(encodeLength, stringEntry.size());
990
991 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jefferye48fdd62024-06-25 00:36:20 +0930992 ASSERT_EQ(pldm_bios_table_string_entry_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930993 encodeEntry.data(), encodeEntry.size(), str, str_length),
994 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930995 // set string handle = 0
996 encodeEntry[0] = 0;
997 encodeEntry[1] = 0;
998
999 EXPECT_EQ(stringEntry, encodeEntry);
1000
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301001 EXPECT_NE(pldm_bios_table_string_entry_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301002 encodeEntry.data(), encodeEntry.size() - 1, str, str_length),
1003 PLDM_SUCCESS);
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301004 auto rc = pldm_bios_table_string_entry_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +09301005 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
1006 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1007}
1008
1009TEST(StringTable, EntryDecodeTest)
1010{
1011 std::vector<uint8_t> stringEntry{
1012 4, 0, /* string handle*/
1013 7, 0, /* string length */
1014 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
1015 };
1016 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
1017 stringEntry.data());
1018 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1019 EXPECT_EQ(handle, 4);
1020 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
1021 EXPECT_EQ(strLength, 7);
1022
1023 std::vector<char> buffer(strLength + 1, 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301024 pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1025 buffer.size());
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301026 EXPECT_EQ(strlen(buffer.data()), strLength);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301027 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301028 EXPECT_EQ(pldm_bios_table_string_entry_decode_string(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301029 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/),
1030 PLDM_SUCCESS);
1031 EXPECT_EQ(strlen(buffer.data()), 2);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301032 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
1033
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301034 auto rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1035 buffer.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +09301036 EXPECT_EQ(rc, PLDM_SUCCESS);
1037 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
1038
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301039 /* Ensure equivalence with the unchecked API */
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301040 rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1041 2 + 1 /* sizeof '\0' */);
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301042 EXPECT_EQ(rc, std::strcmp("Al", buffer.data()));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301043}
1044
1045TEST(StringTable, IteratorTest)
1046{
1047 std::vector<uint8_t> stringHello{
1048 0, 0, /* string handle*/
1049 5, 0, /* string length */
1050 'H', 'e', 'l', 'l', 'o', /* string */
1051 };
1052 std::vector<uint8_t> stringWorld{
1053 1, 0, /* string handle*/
1054 6, 0, /* string length */
1055 'W', 'o', 'r', 'l', 'd', '!', /* string */
1056 };
1057
1058 Table table;
1059 buildTable(table, stringHello, stringWorld);
1060
1061 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1062 PLDM_BIOS_STRING_TABLE);
1063 auto entry = pldm_bios_table_iter_string_entry_value(iter);
1064 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
1065 EXPECT_EQ(rc, 0);
1066 pldm_bios_table_iter_next(iter);
1067 entry = pldm_bios_table_iter_string_entry_value(iter);
1068 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
1069 EXPECT_EQ(rc, 0);
1070 pldm_bios_table_iter_next(iter);
1071 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
1072 pldm_bios_table_iter_free(iter);
1073}
1074
1075TEST(StringTable, FindTest)
1076{
1077 std::vector<uint8_t> stringHello{
1078 1, 0, /* string handle*/
1079 5, 0, /* string length */
1080 'H', 'e', 'l', 'l', 'o', /* string */
1081 };
1082 std::vector<uint8_t> stringWorld{
1083 2, 0, /* string handle*/
1084 6, 0, /* string length */
1085 'W', 'o', 'r', 'l', 'd', '!', /* string */
1086 };
1087 std::vector<uint8_t> stringHi{
1088 3, 0, /* string handle*/
1089 2, 0, /* string length */
1090 'H', 'i', /* string */
1091 };
1092
1093 Table table;
1094 buildTable(table, stringHello, stringWorld, stringHi);
1095
1096 auto entry = pldm_bios_table_string_find_by_string(table.data(),
1097 table.size(), "World!");
1098 EXPECT_NE(entry, nullptr);
1099 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1100 EXPECT_EQ(handle, 2);
1101
1102 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
1103 "Worl");
1104 EXPECT_EQ(entry, nullptr);
1105
1106 entry =
1107 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
1108 EXPECT_NE(entry, nullptr);
1109 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
1110 EXPECT_EQ(str_length, 2);
1111 std::vector<char> strBuf(str_length + 1, 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301112 auto rc = pldm_bios_table_string_entry_decode_string(entry, strBuf.data(),
1113 strBuf.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +09301114 EXPECT_EQ(rc, PLDM_SUCCESS);
1115 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
1116
1117 entry =
1118 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
1119 EXPECT_EQ(entry, nullptr);
1120}
1121
Andrew Jefferybf6699b2023-07-05 16:27:59 +09301122TEST(Iterator, DeathTest)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301123{
1124
1125 Table table(256, 0);
1126
1127 /* first entry */
1128 auto attr_entry =
1129 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
1130 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1131 PLDM_BIOS_ATTR_TABLE);
1132 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
Andrew Jefferyfbaea232024-05-23 10:58:29 +09301133#ifndef NDEBUG
Andrew Jeffery9c766792022-08-10 23:12:49 +09301134 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
Andrew Jefferyfbaea232024-05-23 10:58:29 +09301135#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301136 pldm_bios_table_iter_free(iter);
1137}
1138
1139TEST(PadAndChecksum, PadAndChecksum)
1140{
1141 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0));
1142 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1));
1143 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2));
1144 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3));
1145 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4));
1146
1147 // The table is borrowed from
1148 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
1149 // refer to the commit message
1150 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
1151 auto sizeWithoutPad = attrValTable.size();
1152 attrValTable.resize(sizeWithoutPad +
1153 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
Andrew Jeffery50dd1592023-07-14 16:02:05 +09301154 ASSERT_EQ(pldm_bios_table_append_pad_checksum_check(
1155 attrValTable.data(), attrValTable.size(), &sizeWithoutPad),
1156 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301157 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
1158 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
1159 EXPECT_EQ(attrValTable, expectedTable);
1160}
1161
1162TEST(BIOSTableChecksum, testBIOSTableChecksum)
1163{
1164 std::vector<uint8_t> stringTable{
1165 1, 0, /* string handle*/
1166 5, 0, /* string length */
1167 'T', 'a', 'b', 'l', 'e', /* string */
1168 };
1169
1170 buildTable(stringTable);
1171
1172 EXPECT_EQ(true,
1173 pldm_bios_table_checksum(stringTable.data(), stringTable.size()));
1174}