blob: 99e17ba0de391a6db32f85976d58681dfae16afd [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;
Andrew Jefferyc668ffc2024-06-25 16:50:08 +0930215 ASSERT_EQ(pldm_bios_table_attr_entry_string_decode_def_string_length(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930216 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;
Andrew Jefferyc668ffc2024-06-25 16:50:08 +0930230 rc = pldm_bios_table_attr_entry_string_decode_def_string_length(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930231 entry, &defStringLength);
232 EXPECT_EQ(rc, PLDM_SUCCESS);
233 EXPECT_EQ(defStringLength, 3);
234
Andrew Jefferyc668ffc2024-06-25 16:50:08 +0930235 rc = pldm_bios_table_attr_entry_string_decode_def_string_length(entry,
236 nullptr);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930237 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyc668ffc2024-06-25 16:50:08 +0930238 rc = pldm_bios_table_attr_entry_string_decode_def_string_length(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930239 nullptr, &defStringLength);
240 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
241 entry->attr_type = PLDM_BIOS_INTEGER;
Andrew Jefferyc668ffc2024-06-25 16:50:08 +0930242 rc = pldm_bios_table_attr_entry_string_decode_def_string_length(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930243 entry, &defStringLength);
244 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyc668ffc2024-06-25 16:50:08 +0930245 rc = pldm_bios_table_attr_entry_string_decode_def_string_length(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930246 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 Jeffery5347e272024-06-29 22:05:36 +0930366 ASSERT_EQ(pldm_bios_table_attr_entry_integer_encode(
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930367 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 Jeffery5347e272024-06-29 22:05:36 +0930375 EXPECT_NE(pldm_bios_table_attr_entry_integer_encode(
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930376 encodeEntry.data(), encodeEntry.size() - 1, &info),
377 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930378
Andrew Jeffery5347e272024-06-29 22:05:36 +0930379 auto rc = pldm_bios_table_attr_entry_integer_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930380 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
Andrew Jeffery5347e272024-06-29 22:05:36 +0930388 rc = pldm_bios_table_attr_entry_integer_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930389 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);
Andrew Jeffery5347e272024-06-29 22:05:36 +0930398 rc = pldm_bios_table_attr_entry_integer_encode(encodeEntry.data(),
399 encodeEntry.size(), &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930400 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);
Andrew Jeffery3b5ab922024-09-22 15:20:50 +0930487
488 EXPECT_TRUE(pldm_bios_table_iter_is_end(nullptr));
Andrew Jeffery9c766792022-08-10 23:12:49 +0930489}
490
491TEST(AttrTable, FindTest)
492{
493 std::vector<uint8_t> enumEntry{
494 0, 0, /* attr handle */
495 0, /* attr type */
496 1, 0, /* attr name handle */
497 2, /* number of possible value */
498 2, 0, /* possible value handle */
499 3, 0, /* possible value handle */
500 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530501 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930502 };
503 std::vector<uint8_t> stringEntry{
504 1, 0, /* attr handle */
505 1, /* attr type */
506 2, 0, /* attr name handle */
507 1, /* string type */
508 1, 0, /* minimum length of the string in bytes */
509 100, 0, /* maximum length of the string in bytes */
510 3, 0, /* length of default string in length */
511 'a', 'b', 'c' /* default string */
512 };
513 std::vector<uint8_t> integerEntry{
514 0, 0, /* attr handle */
515 3, /* attr type */
516 3, 0, /* attr name handle */
517 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
518 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
519 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530520 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930521 };
522
523 Table table;
524 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
525
526 auto entry =
527 pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 1);
528 EXPECT_NE(entry, nullptr);
529 auto p = reinterpret_cast<const uint8_t*>(entry);
530 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
531 ElementsAreArray(stringEntry));
532
533 entry = pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 3);
534 EXPECT_EQ(entry, nullptr);
535
536 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
537 table.size(), 2);
538 EXPECT_NE(entry, nullptr);
539 p = reinterpret_cast<const uint8_t*>(entry);
540 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
541 ElementsAreArray(stringEntry));
542
543 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
544 table.size(), 4);
545 EXPECT_EQ(entry, nullptr);
546}
547
548TEST(AttrValTable, HeaderDecodeTest)
549{
550 std::vector<uint8_t> enumEntry{
551 1, 0, /* attr handle */
552 0, /* attr type */
553 2, /* number of current value */
554 0, /* current value string handle index */
555 1, /* current value string handle index */
556 };
557 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
558 enumEntry.data());
559 auto attrHandle =
560 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
561 EXPECT_EQ(attrHandle, 1);
562 auto attrType =
563 pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
564 EXPECT_EQ(attrType, 0);
565}
566
567TEST(AttrValTable, EnumEntryEncodeTest)
568{
569 std::vector<uint8_t> enumEntry{
570 0, 0, /* attr handle */
571 0, /* attr type */
572 2, /* number of current value */
573 0, /* current value string handle index */
574 1, /* current value string handle index */
575 };
576
577 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2);
578 EXPECT_EQ(length, enumEntry.size());
579 std::vector<uint8_t> encodeEntry(length, 0);
580 uint8_t handles[] = {0, 1};
Andrew Jeffery09004d62024-06-29 22:12:15 +0930581 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_enum(
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930582 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles),
583 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930584 EXPECT_EQ(encodeEntry, enumEntry);
585
Andrew Jeffery09004d62024-06-29 22:12:15 +0930586 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_enum(
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930587 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
588 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930589
Andrew Jeffery09004d62024-06-29 22:12:15 +0930590 auto rc = pldm_bios_table_attr_value_entry_encode_enum(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930591 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2,
592 handles);
593 EXPECT_EQ(rc, PLDM_SUCCESS);
594 EXPECT_EQ(encodeEntry, enumEntry);
595 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
596 enumEntry.data());
597 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY;
Andrew Jeffery09004d62024-06-29 22:12:15 +0930598 rc = pldm_bios_table_attr_value_entry_encode_enum(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930599 encodeEntry.data(), encodeEntry.size(), 0,
600 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles);
601 EXPECT_EQ(rc, PLDM_SUCCESS);
602 EXPECT_EQ(encodeEntry, enumEntry);
Andrew Jeffery09004d62024-06-29 22:12:15 +0930603 rc = pldm_bios_table_attr_value_entry_encode_enum(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930604 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2,
605 handles);
606 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery09004d62024-06-29 22:12:15 +0930607 rc = pldm_bios_table_attr_value_entry_encode_enum(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930608 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2,
609 handles);
610 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
611}
612
613TEST(AttrValTable, EnumEntryDecodeTest)
614{
615 std::vector<uint8_t> enumEntry{
616 0, 0, /* attr handle */
617 0, /* attr type */
618 2, /* number of current value */
619 0, /* current value string handle index */
620 1, /* current value string handle index */
621 };
622
623 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
624 enumEntry.data());
625 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
626 EXPECT_EQ(2, number);
627
628 std::vector<uint8_t> handles(2, 0);
629 auto rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
630 entry, handles.data(), handles.size());
631 EXPECT_EQ(rc, 2);
632 EXPECT_EQ(handles[0], 0);
633 EXPECT_EQ(handles[1], 1);
Archana Kakanib9d951f2023-10-17 05:47:58 -0500634
635 /* Buffer size is more than the number of current string handles */
636 std::vector<uint8_t> handleIndexes(3, 0);
637 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
638 entry, handleIndexes.data(), handleIndexes.size());
639 EXPECT_EQ(rc, 2);
640 EXPECT_EQ(handleIndexes[0], 0);
641 EXPECT_EQ(handleIndexes[1], 1);
642
643 /* Buffersize is less than the number of current string handles */
644 std::vector<uint8_t> strHandles(1, 0);
645 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
646 entry, strHandles.data(), strHandles.size());
647 EXPECT_EQ(rc, 1);
648 EXPECT_EQ(strHandles[0], 0);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930649}
650
651TEST(AttrValTable, stringEntryEncodeTest)
652{
653 std::vector<uint8_t> stringEntry{
654 0, 0, /* attr handle */
655 1, /* attr type */
656 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530657 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930658 };
659
660 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
661 EXPECT_EQ(length, stringEntry.size());
662 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery1a3983c2024-06-29 22:17:58 +0930663 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_string(
Andrew Jeffery46d07682023-07-14 15:51:51 +0930664 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc"),
665 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930666 EXPECT_EQ(encodeEntry, stringEntry);
667
Andrew Jeffery1a3983c2024-06-29 22:17:58 +0930668 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_string(
Andrew Jeffery46d07682023-07-14 15:51:51 +0930669 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
670 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930671
Andrew Jeffery1a3983c2024-06-29 22:17:58 +0930672 auto rc = pldm_bios_table_attr_value_entry_encode_string(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930673 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
674 EXPECT_EQ(rc, PLDM_SUCCESS);
675 EXPECT_EQ(encodeEntry, stringEntry);
676 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
677 stringEntry.data());
678 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
Andrew Jeffery1a3983c2024-06-29 22:17:58 +0930679 rc = pldm_bios_table_attr_value_entry_encode_string(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930680 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
681 3, "abc");
682 EXPECT_EQ(rc, PLDM_SUCCESS);
683 EXPECT_EQ(encodeEntry, stringEntry);
Andrew Jeffery1a3983c2024-06-29 22:17:58 +0930684 rc = pldm_bios_table_attr_value_entry_encode_string(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930685 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
686 "abc");
687 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery1a3983c2024-06-29 22:17:58 +0930688 rc = pldm_bios_table_attr_value_entry_encode_string(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930689 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
690 "abc");
691 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
692}
693
694TEST(AttrValTable, StringEntryDecodeTest)
695{
696 std::vector<uint8_t> stringEntry{
697 0, 0, /* attr handle */
698 1, /* attr type */
699 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530700 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930701 };
702
703 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
704 stringEntry.data());
705 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
706 EXPECT_EQ(3, length);
707
708 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
709 EXPECT_EQ(0, handle);
710
711 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
712 EXPECT_EQ(stringEntry.size(), entryLength);
713
714 variable_field currentString{};
715 pldm_bios_table_attr_value_entry_string_decode_string(entry,
716 &currentString);
717 EXPECT_THAT(std::vector<uint8_t>(currentString.ptr,
718 currentString.ptr + currentString.length),
719 ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'}));
720}
721
722TEST(AttrValTable, integerEntryEncodeTest)
723{
724 std::vector<uint8_t> integerEntry{
725 0, 0, /* attr handle */
726 3, /* attr type */
727 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
728 };
729
730 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
731 EXPECT_EQ(length, integerEntry.size());
732 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930733 ASSERT_EQ(
Andrew Jeffery504dd172024-06-29 22:23:15 +0930734 pldm_bios_table_attr_value_entry_encode_integer(
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930735 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10),
736 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930737 EXPECT_EQ(encodeEntry, integerEntry);
738
Andrew Jeffery504dd172024-06-29 22:23:15 +0930739 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_integer(
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930740 encodeEntry.data(), encodeEntry.size() - 1, 0,
741 PLDM_BIOS_INTEGER, 10),
742 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930743
Andrew Jeffery504dd172024-06-29 22:23:15 +0930744 auto rc = pldm_bios_table_attr_value_entry_encode_integer(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930745 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
746 EXPECT_EQ(rc, PLDM_SUCCESS);
747 EXPECT_EQ(encodeEntry, integerEntry);
748 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
749 integerEntry.data());
750 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
Andrew Jeffery504dd172024-06-29 22:23:15 +0930751 rc = pldm_bios_table_attr_value_entry_encode_integer(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930752 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
753 10);
754 EXPECT_EQ(rc, PLDM_SUCCESS);
755 EXPECT_EQ(encodeEntry, integerEntry);
756
Andrew Jeffery504dd172024-06-29 22:23:15 +0930757 rc = pldm_bios_table_attr_value_entry_encode_integer(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930758 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
759 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery504dd172024-06-29 22:23:15 +0930760 rc = pldm_bios_table_attr_value_entry_encode_integer(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930761 encodeEntry.data(), encodeEntry.size() - 1, 0,
762 PLDM_BIOS_INTEGER_READ_ONLY, 10);
763 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
764}
765
766TEST(AttrValTable, integerEntryDecodeTest)
767{
768 std::vector<uint8_t> integerEntry{
769 0, 0, /* attr handle */
770 3, /* attr type */
771 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
772 };
773
774 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
775 integerEntry.data());
776 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
777 EXPECT_EQ(cv, 10u);
778}
779
780TEST(AttrValTable, IteratorTest)
781{
782 std::vector<uint8_t> enumEntry{
783 0, 0, /* attr handle */
784 0, /* attr type */
785 2, /* number of current value */
786 0, /* current value string handle index */
787 1, /* current value string handle index */
788 };
789 std::vector<uint8_t> stringEntry{
790 0, 0, /* attr handle */
791 1, /* attr type */
792 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530793 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930794 };
795 std::vector<uint8_t> integerEntry{
796 0, 0, /* attr handle */
797 3, /* attr type */
798 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
799 };
800
801 Table table;
802 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
803
804 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
805 PLDM_BIOS_ATTR_VAL_TABLE);
806 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
807
808 auto p = reinterpret_cast<const uint8_t*>(entry);
809 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
810 ElementsAreArray(enumEntry));
811
812 pldm_bios_table_iter_next(iter);
813 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
814 p = reinterpret_cast<const uint8_t*>(entry);
815 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
816 ElementsAreArray(stringEntry));
817
818 pldm_bios_table_iter_next(iter);
819 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
820 p = reinterpret_cast<const uint8_t*>(entry);
821 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
822 ElementsAreArray(integerEntry));
823
824 pldm_bios_table_iter_next(iter);
825 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
826 p = reinterpret_cast<const uint8_t*>(entry);
827 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
828 ElementsAreArray(enumEntry));
829
830 pldm_bios_table_iter_next(iter);
831 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
832
833 pldm_bios_table_iter_free(iter);
834}
835
836TEST(AttrValTable, FindTest)
837{
838 std::vector<uint8_t> enumEntry{
839 0, 0, /* attr handle */
840 0, /* attr type */
841 2, /* number of current value */
842 0, /* current value string handle index */
843 1, /* current value string handle index */
844 };
845 std::vector<uint8_t> stringEntry{
846 1, 0, /* attr handle */
847 1, /* attr type */
848 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530849 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930850 };
851 std::vector<uint8_t> integerEntry{
852 2, 0, /* attr handle */
853 3, /* attr type */
854 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
855 };
856
857 Table table;
858 buildTable(table, enumEntry, stringEntry, integerEntry);
859
860 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
861 table.size(), 1);
862 EXPECT_NE(entry, nullptr);
863 auto p = reinterpret_cast<const uint8_t*>(entry);
864 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
865 ElementsAreArray(stringEntry));
866
867 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
868 table.size(), 3);
869 EXPECT_EQ(entry, nullptr);
870
871 auto firstEntry =
872 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
873 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
Andrew Jefferyfbaea232024-05-23 10:58:29 +0930874#ifdef NDEBUG
875 EXPECT_EQ(pldm_bios_table_attr_value_find_by_handle(table.data(),
876 table.size(), 1),
877 nullptr);
878#else
Andrew Jeffery9c766792022-08-10 23:12:49 +0930879 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
880 table.size(), 1),
881 "entry_length != NULL");
Andrew Jefferyfbaea232024-05-23 10:58:29 +0930882#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +0930883}
884
885TEST(AttrValTable, CopyAndUpdateTest)
886{
887 std::vector<uint8_t> enumEntry{
888 0, 0, /* attr handle */
889 0, /* attr type */
890 2, /* number of current value */
891 0, /* current value string handle index */
892 1, /* current value string handle index */
893 };
894 std::vector<uint8_t> stringEntry{
895 1, 0, /* attr handle */
896 1, /* attr type */
897 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530898 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930899 };
900 std::vector<uint8_t> integerEntry{
901 2, 0, /* attr handle */
902 3, /* attr type */
903 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
904 };
905
906 Table srcTable;
907 buildTable(srcTable, enumEntry, stringEntry, integerEntry);
908
909 std::vector<uint8_t> stringEntry1{
910 1, 0, /* attr handle */
911 1, /* attr type */
912 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530913 'd', 'e', 'f', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930914 };
915
916 Table expectTable;
917 buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
918 Table destTable(expectTable.size() + 10);
919 auto destLength = destTable.size();
920 auto rc = pldm_bios_table_attr_value_copy_and_update(
921 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
922 stringEntry1.data(), stringEntry1.size());
923
924 EXPECT_EQ(rc, PLDM_SUCCESS);
925 EXPECT_EQ(destLength, expectTable.size());
926 destTable.resize(destLength);
927 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
928
929 std::vector<uint8_t> stringEntry2{
930 1, 0, /* attr handle */
931 1, /* attr type */
932 5, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530933 'd', 'e', 'f', 'a', 'b', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930934 };
935 expectTable.resize(0);
936 buildTable(expectTable, enumEntry, stringEntry2, integerEntry);
937 destTable.resize(expectTable.size() + 10);
938 destLength = destTable.size();
939 rc = pldm_bios_table_attr_value_copy_and_update(
940 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
941 stringEntry2.data(), stringEntry2.size());
942 EXPECT_EQ(rc, PLDM_SUCCESS);
943 EXPECT_EQ(destLength, expectTable.size());
944 destTable.resize(destLength);
945 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
946
947 std::vector<uint8_t> stringEntry3{
948 1, 0, /* attr handle */
949 1, /* attr type */
950 1, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530951 'd', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930952 };
953 expectTable.resize(0);
954 buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
955 destTable.resize(expectTable.size() + 10);
956 destLength = destTable.size();
957 rc = pldm_bios_table_attr_value_copy_and_update(
958 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
959 stringEntry3.data(), stringEntry3.size());
960 EXPECT_EQ(rc, PLDM_SUCCESS);
961 EXPECT_EQ(destLength, expectTable.size());
962 destTable.resize(destLength);
963 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
964
965 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer
966 rc = pldm_bios_table_attr_value_copy_and_update(
967 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
968 stringEntry3.data(), stringEntry3.size());
969 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
970 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string
971
972 destTable.resize(expectTable.size() - 1);
973 destLength = destTable.size();
974 rc = pldm_bios_table_attr_value_copy_and_update(
975 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
976 stringEntry3.data(), stringEntry3.size());
977 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
978}
979
980TEST(StringTable, EntryEncodeTest)
981{
982 std::vector<uint8_t> stringEntry{
983 0, 0, /* string handle*/
984 7, 0, /* string length */
985 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
986 };
987
988 const char* str = "Allowed";
989 auto str_length = std::strlen(str);
990 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
991 EXPECT_EQ(encodeLength, stringEntry.size());
992
993 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jefferye48fdd62024-06-25 00:36:20 +0930994 ASSERT_EQ(pldm_bios_table_string_entry_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930995 encodeEntry.data(), encodeEntry.size(), str, str_length),
996 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930997 // set string handle = 0
998 encodeEntry[0] = 0;
999 encodeEntry[1] = 0;
1000
1001 EXPECT_EQ(stringEntry, encodeEntry);
1002
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301003 EXPECT_NE(pldm_bios_table_string_entry_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301004 encodeEntry.data(), encodeEntry.size() - 1, str, str_length),
1005 PLDM_SUCCESS);
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301006 auto rc = pldm_bios_table_string_entry_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +09301007 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
1008 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1009}
1010
1011TEST(StringTable, EntryDecodeTest)
1012{
1013 std::vector<uint8_t> stringEntry{
1014 4, 0, /* string handle*/
1015 7, 0, /* string length */
1016 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
1017 };
1018 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
1019 stringEntry.data());
1020 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1021 EXPECT_EQ(handle, 4);
1022 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
1023 EXPECT_EQ(strLength, 7);
1024
1025 std::vector<char> buffer(strLength + 1, 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301026 pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1027 buffer.size());
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301028 EXPECT_EQ(strlen(buffer.data()), strLength);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301029 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301030 EXPECT_EQ(pldm_bios_table_string_entry_decode_string(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301031 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/),
1032 PLDM_SUCCESS);
1033 EXPECT_EQ(strlen(buffer.data()), 2);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301034 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
1035
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301036 auto rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1037 buffer.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +09301038 EXPECT_EQ(rc, PLDM_SUCCESS);
1039 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
1040
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301041 /* Ensure equivalence with the unchecked API */
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301042 rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1043 2 + 1 /* sizeof '\0' */);
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301044 EXPECT_EQ(rc, std::strcmp("Al", buffer.data()));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301045}
1046
1047TEST(StringTable, IteratorTest)
1048{
1049 std::vector<uint8_t> stringHello{
1050 0, 0, /* string handle*/
1051 5, 0, /* string length */
1052 'H', 'e', 'l', 'l', 'o', /* string */
1053 };
1054 std::vector<uint8_t> stringWorld{
1055 1, 0, /* string handle*/
1056 6, 0, /* string length */
1057 'W', 'o', 'r', 'l', 'd', '!', /* string */
1058 };
1059
1060 Table table;
1061 buildTable(table, stringHello, stringWorld);
1062
1063 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1064 PLDM_BIOS_STRING_TABLE);
1065 auto entry = pldm_bios_table_iter_string_entry_value(iter);
1066 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
1067 EXPECT_EQ(rc, 0);
1068 pldm_bios_table_iter_next(iter);
1069 entry = pldm_bios_table_iter_string_entry_value(iter);
1070 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
1071 EXPECT_EQ(rc, 0);
1072 pldm_bios_table_iter_next(iter);
1073 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
1074 pldm_bios_table_iter_free(iter);
1075}
1076
1077TEST(StringTable, FindTest)
1078{
1079 std::vector<uint8_t> stringHello{
1080 1, 0, /* string handle*/
1081 5, 0, /* string length */
1082 'H', 'e', 'l', 'l', 'o', /* string */
1083 };
1084 std::vector<uint8_t> stringWorld{
1085 2, 0, /* string handle*/
1086 6, 0, /* string length */
1087 'W', 'o', 'r', 'l', 'd', '!', /* string */
1088 };
1089 std::vector<uint8_t> stringHi{
1090 3, 0, /* string handle*/
1091 2, 0, /* string length */
1092 'H', 'i', /* string */
1093 };
1094
1095 Table table;
1096 buildTable(table, stringHello, stringWorld, stringHi);
1097
1098 auto entry = pldm_bios_table_string_find_by_string(table.data(),
1099 table.size(), "World!");
1100 EXPECT_NE(entry, nullptr);
1101 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1102 EXPECT_EQ(handle, 2);
1103
1104 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
1105 "Worl");
1106 EXPECT_EQ(entry, nullptr);
1107
1108 entry =
1109 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
1110 EXPECT_NE(entry, nullptr);
1111 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
1112 EXPECT_EQ(str_length, 2);
1113 std::vector<char> strBuf(str_length + 1, 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301114 auto rc = pldm_bios_table_string_entry_decode_string(entry, strBuf.data(),
1115 strBuf.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +09301116 EXPECT_EQ(rc, PLDM_SUCCESS);
1117 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
1118
1119 entry =
1120 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
1121 EXPECT_EQ(entry, nullptr);
1122}
1123
Andrew Jefferybf6699b2023-07-05 16:27:59 +09301124TEST(Iterator, DeathTest)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301125{
1126
1127 Table table(256, 0);
1128
1129 /* first entry */
1130 auto attr_entry =
1131 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
1132 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1133 PLDM_BIOS_ATTR_TABLE);
1134 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
Andrew Jefferyfbaea232024-05-23 10:58:29 +09301135#ifndef NDEBUG
Andrew Jeffery9c766792022-08-10 23:12:49 +09301136 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
Andrew Jefferyfbaea232024-05-23 10:58:29 +09301137#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301138 pldm_bios_table_iter_free(iter);
1139}
1140
1141TEST(PadAndChecksum, PadAndChecksum)
1142{
1143 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0));
1144 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1));
1145 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2));
1146 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3));
1147 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4));
1148
1149 // The table is borrowed from
1150 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
1151 // refer to the commit message
1152 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
1153 auto sizeWithoutPad = attrValTable.size();
1154 attrValTable.resize(sizeWithoutPad +
1155 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
Andrew Jefferyd8bb75c2024-06-29 22:29:02 +09301156 ASSERT_EQ(pldm_bios_table_append_pad_checksum(
Andrew Jeffery50dd1592023-07-14 16:02:05 +09301157 attrValTable.data(), attrValTable.size(), &sizeWithoutPad),
1158 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301159 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
1160 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
1161 EXPECT_EQ(attrValTable, expectedTable);
1162}
1163
1164TEST(BIOSTableChecksum, testBIOSTableChecksum)
1165{
1166 std::vector<uint8_t> stringTable{
1167 1, 0, /* string handle*/
1168 5, 0, /* string length */
1169 'T', 'a', 'b', 'l', 'e', /* string */
1170 };
1171
1172 buildTable(stringTable);
1173
1174 EXPECT_EQ(true,
1175 pldm_bios_table_checksum(stringTable.data(), stringTable.size()));
1176}