blob: 19fb9298008a6b0db1489d57fe9a0ed01fd2d7fd [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 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +093052 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +093053 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
54 auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
55 EXPECT_EQ(attrHandle, 2);
56 auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
57 EXPECT_EQ(attrType, 0);
58 auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
59 EXPECT_EQ(stringHandle, 1);
60}
61
62TEST(AttrTable, EnumEntryDecodeTest)
63{
64 std::vector<uint8_t> enumEntry{
65 0, 0, /* attr handle */
66 0, /* attr type */
67 1, 0, /* attr name handle */
68 2, /* number of possible value */
69 2, 0, /* possible value handle */
70 3, 0, /* possible value handle */
71 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +053072 1 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +093073 };
74
75 auto entry =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +093076 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +093077 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093078 uint8_t pvNumber;
Andrew Jefferyb06882f2024-06-25 15:52:02 +093079 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNumber),
80 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093081 EXPECT_EQ(pvNumber, 2);
82 pvNumber = 0;
Andrew Jefferyb06882f2024-06-25 15:52:02 +093083 auto rc = pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +093084 EXPECT_EQ(rc, PLDM_SUCCESS);
85 EXPECT_EQ(pvNumber, 2);
86
87 std::vector<uint16_t> pvHandles(pvNumber, 0);
Andrew Jeffery82b4d3b2024-06-25 16:22:36 +093088 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093089 entry, pvHandles.data(), pvHandles.size()),
90 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093091 EXPECT_EQ(pvNumber, 2);
92 EXPECT_EQ(pvHandles[0], 2);
93 EXPECT_EQ(pvHandles[1], 3);
94 pvHandles.resize(1);
Andrew Jeffery82b4d3b2024-06-25 16:22:36 +093095 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +093096 entry, pvHandles.data(), pvHandles.size()),
97 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093098 EXPECT_EQ(pvHandles[0], 2);
99
100 pvHandles.resize(2);
Andrew Jeffery82b4d3b2024-06-25 16:22:36 +0930101 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pvHandles.data(),
102 pvHandles.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +0930103 EXPECT_EQ(rc, PLDM_SUCCESS);
104 EXPECT_EQ(pvHandles[0], 2);
105 EXPECT_EQ(pvHandles[1], 3);
Andrew Jeffery82b4d3b2024-06-25 16:22:36 +0930106 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pvHandles.data(),
107 1);
Andrew Jeffery0c9f5a82023-06-14 15:01:06 +0930108 EXPECT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930109
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930110 uint8_t defNumber;
Andrew Jeffery46673f42024-06-25 16:02:25 +0930111 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_def_num(entry, &defNumber),
112 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930113 EXPECT_EQ(defNumber, 1);
114 std::vector<uint8_t> defIndices(defNumber);
115 rc = pldm_bios_table_attr_entry_enum_decode_def_indices(
116 entry, defIndices.data(), defIndices.size());
117 EXPECT_EQ(rc, defNumber);
118 EXPECT_THAT(defIndices, ElementsAreArray({1}));
119
120 defNumber = 0;
Andrew Jeffery46673f42024-06-25 16:02:25 +0930121 rc = pldm_bios_table_attr_entry_enum_decode_def_num(entry, &defNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930122 EXPECT_EQ(rc, PLDM_SUCCESS);
123 EXPECT_EQ(defNumber, 1);
124
Andrew Jefferyb06882f2024-06-25 15:52:02 +0930125 rc = pldm_bios_table_attr_entry_enum_decode_pv_num(nullptr, &pvNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930126 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery46673f42024-06-25 16:02:25 +0930127 rc = pldm_bios_table_attr_entry_enum_decode_def_num(entry, nullptr);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930128 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
129
130 entry->attr_type = PLDM_BIOS_STRING;
Andrew Jefferyb06882f2024-06-25 15:52:02 +0930131 rc = pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930132 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
133
Andrew Jeffery46673f42024-06-25 16:02:25 +0930134 rc = pldm_bios_table_attr_entry_enum_decode_def_num(entry, &defNumber);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930135 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery82b4d3b2024-06-25 16:22:36 +0930136 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, nullptr, 0);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930137 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
138}
139
140TEST(AttrTable, EnumEntryEncodeTest)
141{
142 std::vector<uint8_t> enumEntry{
143 0, 0, /* attr handle */
144 0, /* attr type */
145 1, 0, /* attr name handle */
146 2, /* number of possible value */
147 2, 0, /* possible value handle */
148 3, 0, /* possible value handle */
149 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530150 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930151 };
152
153 std::vector<uint16_t> pv_hdls{2, 3};
154 std::vector<uint8_t> defs{0};
155
156 struct pldm_bios_table_attr_entry_enum_info info = {
157 1, /* name handle */
158 false, /* read only */
159 2, /* pv number */
160 pv_hdls.data(), /* pv handle */
161 1, /*def number */
162 defs.data() /*def index*/
163 };
164 auto encodeLength = pldm_bios_table_attr_entry_enum_encode_length(2, 1);
165 EXPECT_EQ(encodeLength, enumEntry.size());
166
167 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930168 ASSERT_EQ(pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
169 encodeEntry.size(), &info),
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930170 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930171 // set attr handle = 0
172 encodeEntry[0] = 0;
173 encodeEntry[1] = 0;
174
175 EXPECT_EQ(enumEntry, encodeEntry);
176
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930177 EXPECT_NE(pldm_bios_table_attr_entry_enum_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930178 encodeEntry.data(), encodeEntry.size() - 1, &info),
179 PLDM_SUCCESS);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930180 auto rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
181 encodeEntry.size(), &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930182 EXPECT_EQ(rc, PLDM_SUCCESS);
183 // set attr handle = 0
184 encodeEntry[0] = 0;
185 encodeEntry[1] = 0;
186
187 EXPECT_EQ(enumEntry, encodeEntry);
Andrew Jeffery7126b1d2024-06-25 15:48:34 +0930188 rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(),
189 encodeEntry.size() - 1, &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930190 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
191}
192
193TEST(AttrTable, StringEntryDecodeTest)
194{
195 std::vector<uint8_t> stringEntry{
196 1, 0, /* attr handle */
197 1, /* attr type */
198 12, 0, /* attr name handle */
199 1, /* string type */
200 1, 0, /* minimum length of the string in bytes */
201 100, 0, /* maximum length of the string in bytes */
202 3, 0, /* length of default string in length */
203 'a', 'b', 'c' /* default string */
204 };
205
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930206 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930207 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
208 stringEntry.data());
209 auto stringType =
210 pldm_bios_table_attr_entry_string_decode_string_type(entry);
211 EXPECT_EQ(stringType, 1);
212 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
213 EXPECT_EQ(minLength, 1);
214 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
215 EXPECT_EQ(maxLength, 100);
216
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930217 uint16_t defStringLength;
Andrew Jefferyc668ffc2024-06-25 16:50:08 +0930218 ASSERT_EQ(pldm_bios_table_attr_entry_string_decode_def_string_length(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930219 entry, &defStringLength),
220 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930221 EXPECT_EQ(defStringLength, 3);
222 std::vector<char> defString(defStringLength + 1);
223 auto rc = pldm_bios_table_attr_entry_string_decode_def_string(
224 entry, defString.data(), defString.size());
225 EXPECT_EQ(rc, 3);
226 EXPECT_STREQ(defString.data(), "abc");
227 rc = pldm_bios_table_attr_entry_string_decode_def_string(
228 entry, defString.data(), defString.size() - 1);
229 EXPECT_EQ(rc, 2);
230 EXPECT_STREQ(defString.data(), "ab");
231
232 defStringLength = 0;
Andrew Jefferyc668ffc2024-06-25 16:50:08 +0930233 rc = pldm_bios_table_attr_entry_string_decode_def_string_length(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930234 entry, &defStringLength);
235 EXPECT_EQ(rc, PLDM_SUCCESS);
236 EXPECT_EQ(defStringLength, 3);
237
Andrew Jefferyc668ffc2024-06-25 16:50:08 +0930238 rc = pldm_bios_table_attr_entry_string_decode_def_string_length(entry,
239 nullptr);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930240 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyc668ffc2024-06-25 16:50:08 +0930241 rc = pldm_bios_table_attr_entry_string_decode_def_string_length(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930242 nullptr, &defStringLength);
243 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
244 entry->attr_type = PLDM_BIOS_INTEGER;
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 entry, &defStringLength);
247 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyc668ffc2024-06-25 16:50:08 +0930248 rc = pldm_bios_table_attr_entry_string_decode_def_string_length(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930249 nullptr, &defStringLength);
250 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
251}
252
253TEST(AttrTable, StringEntryEncodeTest)
254{
255 std::vector<uint8_t> stringEntry{
256 0, 0, /* attr handle */
257 1, /* attr type */
258 3, 0, /* attr name handle */
259 1, /* string type */
260 1, 0, /* min string length */
261 100, 0, /* max string length */
262 3, 0, /* default string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530263 'a', 'b', 'c', /* default string */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930264 };
265
266 struct pldm_bios_table_attr_entry_string_info info = {
267 3, /* name handle */
268 false, /* read only */
269 1, /* string type ascii */
270 1, /* min length */
271 100, /* max length */
272 3, /* def length */
273 "abc", /* def string */
274 };
275 auto encodeLength = pldm_bios_table_attr_entry_string_encode_length(3);
276 EXPECT_EQ(encodeLength, stringEntry.size());
277
278 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jefferyf6be4932024-06-25 16:44:06 +0930279 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930280 encodeEntry.data(), encodeEntry.size(), &info),
281 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930282 // set attr handle = 0
283 encodeEntry[0] = 0;
284 encodeEntry[1] = 0;
285
286 EXPECT_EQ(stringEntry, encodeEntry);
287
Andrew Jefferyf6be4932024-06-25 16:44:06 +0930288 EXPECT_NE(pldm_bios_table_attr_entry_string_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930289 encodeEntry.data(), encodeEntry.size() - 1, &info),
290 PLDM_SUCCESS);
Andrew Jefferyf6be4932024-06-25 16:44:06 +0930291 auto rc = pldm_bios_table_attr_entry_string_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930292 encodeEntry.data(), encodeEntry.size(), &info);
293 EXPECT_EQ(rc, PLDM_SUCCESS);
294 // set attr handle = 0
295 encodeEntry[0] = 0;
296 encodeEntry[1] = 0;
297
298 EXPECT_EQ(stringEntry, encodeEntry);
Andrew Jefferyf6be4932024-06-25 16:44:06 +0930299 rc = pldm_bios_table_attr_entry_string_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930300 encodeEntry.data(), encodeEntry.size() - 1, &info);
301 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
302 std::swap(info.max_length, info.min_length);
303 const char* errmsg;
304 rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
305 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
306 EXPECT_STREQ(
307 "MinimumStingLength should not be greater than MaximumStringLength",
308 errmsg);
Andrew Jefferyf6be4932024-06-25 16:44:06 +0930309 rc = pldm_bios_table_attr_entry_string_encode(encodeEntry.data(),
310 encodeEntry.size(), &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930311 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
312 std::swap(info.max_length, info.min_length);
313
314 std::vector<uint8_t> stringEntryLength0{
315 0, 0, /* attr handle */
316 1, /* attr type */
317 3, 0, /* attr name handle */
318 1, /* string type */
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930319 0, 0, /* min string length */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930320 100, 0, /* max string length */
321 0, 0, /* default string length */
322 };
323
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930324 info.min_length = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930325 info.def_length = 0;
326 info.def_string = nullptr;
327
328 encodeLength = pldm_bios_table_attr_entry_string_encode_length(0);
329 EXPECT_EQ(encodeLength, stringEntryLength0.size());
330
331 encodeEntry.resize(encodeLength);
Andrew Jefferyf6be4932024-06-25 16:44:06 +0930332 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +0930333 encodeEntry.data(), encodeEntry.size(), &info),
334 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930335 // set attr handle = 0
336 encodeEntry[0] = 0;
337 encodeEntry[1] = 0;
338
339 EXPECT_EQ(stringEntryLength0, encodeEntry);
340}
341
342TEST(AttrTable, integerEntryEncodeTest)
343{
344 std::vector<uint8_t> integerEntry{
345 0, 0, /* attr handle */
346 3, /* attr type */
347 1, 0, /* attr name handle */
348 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
349 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
350 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530351 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930352 };
353
354 std::vector<uint16_t> pv_hdls{2, 3};
355 std::vector<uint8_t> defs{0};
356
357 struct pldm_bios_table_attr_entry_integer_info info = {
358 1, /* name handle */
359 false, /* read only */
360 1, /* lower bound */
361 10, /* upper bound */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530362 2, /* scalar increment */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930363 3 /* default value */
364 };
365 auto encodeLength = pldm_bios_table_attr_entry_integer_encode_length();
366 EXPECT_EQ(encodeLength, integerEntry.size());
367
368 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jeffery5347e272024-06-29 22:05:36 +0930369 ASSERT_EQ(pldm_bios_table_attr_entry_integer_encode(
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930370 encodeEntry.data(), encodeEntry.size(), &info),
371 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930372 // set attr handle = 0
373 encodeEntry[0] = 0;
374 encodeEntry[1] = 0;
375
376 EXPECT_EQ(integerEntry, encodeEntry);
377
Andrew Jeffery5347e272024-06-29 22:05:36 +0930378 EXPECT_NE(pldm_bios_table_attr_entry_integer_encode(
Andrew Jeffery0ecf6bc2023-07-14 15:36:39 +0930379 encodeEntry.data(), encodeEntry.size() - 1, &info),
380 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930381
Andrew Jeffery5347e272024-06-29 22:05:36 +0930382 auto rc = pldm_bios_table_attr_entry_integer_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930383 encodeEntry.data(), encodeEntry.size(), &info);
384 EXPECT_EQ(rc, PLDM_SUCCESS);
385 // set attr handle = 0
386 encodeEntry[0] = 0;
387 encodeEntry[1] = 0;
388
389 EXPECT_EQ(integerEntry, encodeEntry);
390
Andrew Jeffery5347e272024-06-29 22:05:36 +0930391 rc = pldm_bios_table_attr_entry_integer_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930392 encodeEntry.data(), encodeEntry.size() - 1, &info);
393 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
394
395 info.lower_bound = 100;
396 info.upper_bound = 50;
397 const char* errmsg;
398 rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
399 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
400 EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg);
Andrew Jeffery5347e272024-06-29 22:05:36 +0930401 rc = pldm_bios_table_attr_entry_integer_encode(encodeEntry.data(),
402 encodeEntry.size(), &info);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930403 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
404}
405
406TEST(AttrTable, integerEntryDecodeTest)
407{
408 std::vector<uint8_t> integerEntry{
409 0, 0, /* attr handle */
410 3, /* attr type */
411 1, 0, /* attr name handle */
412 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
413 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
414 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530415 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930416 };
417
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930418 uint64_t lower;
419 uint64_t upper;
420 uint64_t def;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930421 uint32_t scalar;
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930422 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930423 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
424 integerEntry.data());
425 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
426 &def);
427 EXPECT_EQ(lower, 1u);
428 EXPECT_EQ(upper, 10u);
429 EXPECT_EQ(scalar, 2u);
430 EXPECT_EQ(def, 3u);
431}
432
433TEST(AttrTable, ItearatorTest)
434{
435 std::vector<uint8_t> enumEntry{
436 0, 0, /* attr handle */
437 0, /* attr type */
438 1, 0, /* attr name handle */
439 2, /* number of possible value */
440 2, 0, /* possible value handle */
441 3, 0, /* possible value handle */
442 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530443 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930444 };
445 std::vector<uint8_t> stringEntry{
446 1, 0, /* attr handle */
447 1, /* attr type */
448 12, 0, /* attr name handle */
449 1, /* string type */
450 1, 0, /* minimum length of the string in bytes */
451 100, 0, /* maximum length of the string in bytes */
452 3, 0, /* length of default string in length */
453 'a', 'b', 'c' /* default string */
454 };
455 std::vector<uint8_t> integerEntry{
456 0, 0, /* attr handle */
457 3, /* attr type */
458 1, 0, /* attr name handle */
459 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
460 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
461 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530462 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930463 };
464
465 Table table;
466 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
467 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
468 PLDM_BIOS_ATTR_TABLE);
469 auto entry = pldm_bios_table_iter_attr_entry_value(iter);
470 auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
471 EXPECT_EQ(rc, 0);
472
473 pldm_bios_table_iter_next(iter);
474 entry = pldm_bios_table_iter_attr_entry_value(iter);
475 rc = std::memcmp(entry, stringEntry.data(), stringEntry.size());
476 EXPECT_EQ(rc, 0);
477
478 pldm_bios_table_iter_next(iter);
479 entry = pldm_bios_table_iter_attr_entry_value(iter);
480 rc = std::memcmp(entry, integerEntry.data(), integerEntry.size());
481 EXPECT_EQ(rc, 0);
482
483 pldm_bios_table_iter_next(iter);
484 entry = pldm_bios_table_iter_attr_entry_value(iter);
485 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
486 EXPECT_EQ(rc, 0);
487
488 pldm_bios_table_iter_next(iter);
489 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
490 pldm_bios_table_iter_free(iter);
Andrew Jeffery3b5ab922024-09-22 15:20:50 +0930491
492 EXPECT_TRUE(pldm_bios_table_iter_is_end(nullptr));
Andrew Jeffery9c766792022-08-10 23:12:49 +0930493}
494
495TEST(AttrTable, FindTest)
496{
497 std::vector<uint8_t> enumEntry{
498 0, 0, /* attr handle */
499 0, /* attr type */
500 1, 0, /* attr name handle */
501 2, /* number of possible value */
502 2, 0, /* possible value handle */
503 3, 0, /* possible value handle */
504 1, /* number of default value */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530505 0 /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930506 };
507 std::vector<uint8_t> stringEntry{
508 1, 0, /* attr handle */
509 1, /* attr type */
510 2, 0, /* attr name handle */
511 1, /* string type */
512 1, 0, /* minimum length of the string in bytes */
513 100, 0, /* maximum length of the string in bytes */
514 3, 0, /* length of default string in length */
515 'a', 'b', 'c' /* default string */
516 };
517 std::vector<uint8_t> integerEntry{
518 0, 0, /* attr handle */
519 3, /* attr type */
520 3, 0, /* attr name handle */
521 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */
522 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
523 2, 0, 0, 0, /* scalar increment */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530524 3, 0, 0, 0, 0, 0, 0, 0, /* default value */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930525 };
526
527 Table table;
528 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
529
530 auto entry =
531 pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 1);
532 EXPECT_NE(entry, nullptr);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930533 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930534 auto p = reinterpret_cast<const uint8_t*>(entry);
535 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
536 ElementsAreArray(stringEntry));
537
538 entry = pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 3);
539 EXPECT_EQ(entry, nullptr);
540
541 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
542 table.size(), 2);
543 EXPECT_NE(entry, nullptr);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930544 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930545 p = reinterpret_cast<const uint8_t*>(entry);
546 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
547 ElementsAreArray(stringEntry));
548
549 entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
550 table.size(), 4);
551 EXPECT_EQ(entry, nullptr);
552}
553
554TEST(AttrValTable, HeaderDecodeTest)
555{
556 std::vector<uint8_t> enumEntry{
557 1, 0, /* attr handle */
558 0, /* attr type */
559 2, /* number of current value */
560 0, /* current value string handle index */
561 1, /* current value string handle index */
562 };
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930563 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930564 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
565 enumEntry.data());
566 auto attrHandle =
567 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
568 EXPECT_EQ(attrHandle, 1);
569 auto attrType =
570 pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
571 EXPECT_EQ(attrType, 0);
572}
573
574TEST(AttrValTable, EnumEntryEncodeTest)
575{
576 std::vector<uint8_t> enumEntry{
577 0, 0, /* attr handle */
578 0, /* attr type */
579 2, /* number of current value */
580 0, /* current value string handle index */
581 1, /* current value string handle index */
582 };
583
584 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2);
585 EXPECT_EQ(length, enumEntry.size());
586 std::vector<uint8_t> encodeEntry(length, 0);
587 uint8_t handles[] = {0, 1};
Andrew Jeffery09004d62024-06-29 22:12:15 +0930588 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_enum(
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930589 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles),
590 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930591 EXPECT_EQ(encodeEntry, enumEntry);
592
Andrew Jeffery09004d62024-06-29 22:12:15 +0930593 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_enum(
Andrew Jeffery8b1c0342023-07-14 15:44:37 +0930594 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
595 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930596
Andrew Jeffery09004d62024-06-29 22:12:15 +0930597 auto rc = pldm_bios_table_attr_value_entry_encode_enum(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930598 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2,
599 handles);
600 EXPECT_EQ(rc, PLDM_SUCCESS);
601 EXPECT_EQ(encodeEntry, enumEntry);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930602 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930603 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
604 enumEntry.data());
605 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY;
Andrew Jeffery09004d62024-06-29 22:12:15 +0930606 rc = pldm_bios_table_attr_value_entry_encode_enum(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930607 encodeEntry.data(), encodeEntry.size(), 0,
608 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles);
609 EXPECT_EQ(rc, PLDM_SUCCESS);
610 EXPECT_EQ(encodeEntry, enumEntry);
Andrew Jeffery09004d62024-06-29 22:12:15 +0930611 rc = pldm_bios_table_attr_value_entry_encode_enum(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930612 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2,
613 handles);
614 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery09004d62024-06-29 22:12:15 +0930615 rc = pldm_bios_table_attr_value_entry_encode_enum(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930616 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2,
617 handles);
618 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
619}
620
621TEST(AttrValTable, EnumEntryDecodeTest)
622{
623 std::vector<uint8_t> enumEntry{
624 0, 0, /* attr handle */
625 0, /* attr type */
626 2, /* number of current value */
627 0, /* current value string handle index */
628 1, /* current value string handle index */
629 };
630
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930631 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930632 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
633 enumEntry.data());
634 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
635 EXPECT_EQ(2, number);
636
637 std::vector<uint8_t> handles(2, 0);
638 auto rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
639 entry, handles.data(), handles.size());
640 EXPECT_EQ(rc, 2);
641 EXPECT_EQ(handles[0], 0);
642 EXPECT_EQ(handles[1], 1);
Archana Kakanib9d951f2023-10-17 05:47:58 -0500643
644 /* Buffer size is more than the number of current string handles */
645 std::vector<uint8_t> handleIndexes(3, 0);
646 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
647 entry, handleIndexes.data(), handleIndexes.size());
648 EXPECT_EQ(rc, 2);
649 EXPECT_EQ(handleIndexes[0], 0);
650 EXPECT_EQ(handleIndexes[1], 1);
651
652 /* Buffersize is less than the number of current string handles */
653 std::vector<uint8_t> strHandles(1, 0);
654 rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
655 entry, strHandles.data(), strHandles.size());
656 EXPECT_EQ(rc, 1);
657 EXPECT_EQ(strHandles[0], 0);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930658}
659
660TEST(AttrValTable, stringEntryEncodeTest)
661{
662 std::vector<uint8_t> stringEntry{
663 0, 0, /* attr handle */
664 1, /* attr type */
665 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530666 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930667 };
668
669 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
670 EXPECT_EQ(length, stringEntry.size());
671 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery1a3983c2024-06-29 22:17:58 +0930672 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_string(
Andrew Jeffery46d07682023-07-14 15:51:51 +0930673 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc"),
674 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930675 EXPECT_EQ(encodeEntry, stringEntry);
676
Andrew Jeffery1a3983c2024-06-29 22:17:58 +0930677 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_string(
Andrew Jeffery46d07682023-07-14 15:51:51 +0930678 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
679 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930680
Andrew Jeffery1a3983c2024-06-29 22:17:58 +0930681 auto rc = pldm_bios_table_attr_value_entry_encode_string(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930682 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
683 EXPECT_EQ(rc, PLDM_SUCCESS);
684 EXPECT_EQ(encodeEntry, stringEntry);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930685 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930686 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
687 stringEntry.data());
688 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
Andrew Jeffery1a3983c2024-06-29 22:17:58 +0930689 rc = pldm_bios_table_attr_value_entry_encode_string(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930690 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
691 3, "abc");
692 EXPECT_EQ(rc, PLDM_SUCCESS);
693 EXPECT_EQ(encodeEntry, stringEntry);
Andrew Jeffery1a3983c2024-06-29 22:17:58 +0930694 rc = pldm_bios_table_attr_value_entry_encode_string(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930695 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
696 "abc");
697 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery1a3983c2024-06-29 22:17:58 +0930698 rc = pldm_bios_table_attr_value_entry_encode_string(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930699 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
700 "abc");
701 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
702}
703
704TEST(AttrValTable, StringEntryDecodeTest)
705{
706 std::vector<uint8_t> stringEntry{
707 0, 0, /* attr handle */
708 1, /* attr type */
709 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530710 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930711 };
712
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930713 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930714 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
715 stringEntry.data());
716 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
717 EXPECT_EQ(3, length);
718
719 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
720 EXPECT_EQ(0, handle);
721
722 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
723 EXPECT_EQ(stringEntry.size(), entryLength);
724
725 variable_field currentString{};
726 pldm_bios_table_attr_value_entry_string_decode_string(entry,
727 &currentString);
728 EXPECT_THAT(std::vector<uint8_t>(currentString.ptr,
729 currentString.ptr + currentString.length),
730 ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'}));
731}
732
733TEST(AttrValTable, integerEntryEncodeTest)
734{
735 std::vector<uint8_t> integerEntry{
736 0, 0, /* attr handle */
737 3, /* attr type */
738 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
739 };
740
741 auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
742 EXPECT_EQ(length, integerEntry.size());
743 std::vector<uint8_t> encodeEntry(length, 0);
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930744 ASSERT_EQ(
Andrew Jeffery504dd172024-06-29 22:23:15 +0930745 pldm_bios_table_attr_value_entry_encode_integer(
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930746 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10),
747 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930748 EXPECT_EQ(encodeEntry, integerEntry);
749
Andrew Jeffery504dd172024-06-29 22:23:15 +0930750 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_integer(
Andrew Jeffery4e1f1312023-07-14 15:56:51 +0930751 encodeEntry.data(), encodeEntry.size() - 1, 0,
752 PLDM_BIOS_INTEGER, 10),
753 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930754
Andrew Jeffery504dd172024-06-29 22:23:15 +0930755 auto rc = pldm_bios_table_attr_value_entry_encode_integer(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930756 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
757 EXPECT_EQ(rc, PLDM_SUCCESS);
758 EXPECT_EQ(encodeEntry, integerEntry);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930759 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930760 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
761 integerEntry.data());
762 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
Andrew Jeffery504dd172024-06-29 22:23:15 +0930763 rc = pldm_bios_table_attr_value_entry_encode_integer(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930764 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
765 10);
766 EXPECT_EQ(rc, PLDM_SUCCESS);
767 EXPECT_EQ(encodeEntry, integerEntry);
768
Andrew Jeffery504dd172024-06-29 22:23:15 +0930769 rc = pldm_bios_table_attr_value_entry_encode_integer(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930770 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
771 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery504dd172024-06-29 22:23:15 +0930772 rc = pldm_bios_table_attr_value_entry_encode_integer(
Andrew Jeffery9c766792022-08-10 23:12:49 +0930773 encodeEntry.data(), encodeEntry.size() - 1, 0,
774 PLDM_BIOS_INTEGER_READ_ONLY, 10);
775 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
776}
777
778TEST(AttrValTable, integerEntryDecodeTest)
779{
780 std::vector<uint8_t> integerEntry{
781 0, 0, /* attr handle */
782 3, /* attr type */
783 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
784 };
785
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930786 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930787 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
788 integerEntry.data());
789 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
790 EXPECT_EQ(cv, 10u);
791}
792
793TEST(AttrValTable, IteratorTest)
794{
795 std::vector<uint8_t> enumEntry{
796 0, 0, /* attr handle */
797 0, /* attr type */
798 2, /* number of current value */
799 0, /* current value string handle index */
800 1, /* current value string handle index */
801 };
802 std::vector<uint8_t> stringEntry{
803 0, 0, /* attr handle */
804 1, /* attr type */
805 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530806 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930807 };
808 std::vector<uint8_t> integerEntry{
809 0, 0, /* attr handle */
810 3, /* attr type */
811 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
812 };
813
814 Table table;
815 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
816
817 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
818 PLDM_BIOS_ATTR_VAL_TABLE);
819 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
820
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930821 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930822 auto p = reinterpret_cast<const uint8_t*>(entry);
823 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
824 ElementsAreArray(enumEntry));
825
826 pldm_bios_table_iter_next(iter);
827 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930828 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930829 p = reinterpret_cast<const uint8_t*>(entry);
830 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
831 ElementsAreArray(stringEntry));
832
833 pldm_bios_table_iter_next(iter);
834 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930835 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930836 p = reinterpret_cast<const uint8_t*>(entry);
837 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
838 ElementsAreArray(integerEntry));
839
840 pldm_bios_table_iter_next(iter);
841 entry = pldm_bios_table_iter_attr_value_entry_value(iter);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930842 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930843 p = reinterpret_cast<const uint8_t*>(entry);
844 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
845 ElementsAreArray(enumEntry));
846
847 pldm_bios_table_iter_next(iter);
848 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
849
850 pldm_bios_table_iter_free(iter);
851}
852
853TEST(AttrValTable, FindTest)
854{
855 std::vector<uint8_t> enumEntry{
856 0, 0, /* attr handle */
857 0, /* attr type */
858 2, /* number of current value */
859 0, /* current value string handle index */
860 1, /* current value string handle index */
861 };
862 std::vector<uint8_t> stringEntry{
863 1, 0, /* attr handle */
864 1, /* attr type */
865 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530866 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930867 };
868 std::vector<uint8_t> integerEntry{
869 2, 0, /* attr handle */
870 3, /* attr type */
871 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
872 };
873
874 Table table;
875 buildTable(table, enumEntry, stringEntry, integerEntry);
876
877 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
878 table.size(), 1);
879 EXPECT_NE(entry, nullptr);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930880 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930881 auto p = reinterpret_cast<const uint8_t*>(entry);
882 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
883 ElementsAreArray(stringEntry));
884
885 entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
886 table.size(), 3);
887 EXPECT_EQ(entry, nullptr);
888
889 auto firstEntry =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930890 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930891 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
892 firstEntry->attr_type = PLDM_BIOS_PASSWORD;
Andrew Jefferyfbaea232024-05-23 10:58:29 +0930893#ifdef NDEBUG
894 EXPECT_EQ(pldm_bios_table_attr_value_find_by_handle(table.data(),
895 table.size(), 1),
896 nullptr);
897#else
Andrew Jeffery9c766792022-08-10 23:12:49 +0930898 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
899 table.size(), 1),
900 "entry_length != NULL");
Andrew Jefferyfbaea232024-05-23 10:58:29 +0930901#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +0930902}
903
904TEST(AttrValTable, CopyAndUpdateTest)
905{
906 std::vector<uint8_t> enumEntry{
907 0, 0, /* attr handle */
908 0, /* attr type */
909 2, /* number of current value */
910 0, /* current value string handle index */
911 1, /* current value string handle index */
912 };
913 std::vector<uint8_t> stringEntry{
914 1, 0, /* attr handle */
915 1, /* attr type */
916 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530917 'a', 'b', 'c', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930918 };
919 std::vector<uint8_t> integerEntry{
920 2, 0, /* attr handle */
921 3, /* attr type */
922 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
923 };
924
925 Table srcTable;
926 buildTable(srcTable, enumEntry, stringEntry, integerEntry);
927
928 std::vector<uint8_t> stringEntry1{
929 1, 0, /* attr handle */
930 1, /* attr type */
931 3, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530932 'd', 'e', 'f', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930933 };
934
935 Table expectTable;
936 buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
937 Table destTable(expectTable.size() + 10);
938 auto destLength = destTable.size();
939 auto rc = pldm_bios_table_attr_value_copy_and_update(
940 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
941 stringEntry1.data(), stringEntry1.size());
942
943 EXPECT_EQ(rc, PLDM_SUCCESS);
944 EXPECT_EQ(destLength, expectTable.size());
945 destTable.resize(destLength);
946 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
947
948 std::vector<uint8_t> stringEntry2{
949 1, 0, /* attr handle */
950 1, /* attr type */
951 5, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530952 'd', 'e', 'f', 'a', 'b', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930953 };
954 expectTable.resize(0);
955 buildTable(expectTable, enumEntry, stringEntry2, integerEntry);
956 destTable.resize(expectTable.size() + 10);
957 destLength = destTable.size();
958 rc = pldm_bios_table_attr_value_copy_and_update(
959 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
960 stringEntry2.data(), stringEntry2.size());
961 EXPECT_EQ(rc, PLDM_SUCCESS);
962 EXPECT_EQ(destLength, expectTable.size());
963 destTable.resize(destLength);
964 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
965
966 std::vector<uint8_t> stringEntry3{
967 1, 0, /* attr handle */
968 1, /* attr type */
969 1, 0, /* current string length */
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +0530970 'd', /* default value string handle index */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930971 };
972 expectTable.resize(0);
973 buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
974 destTable.resize(expectTable.size() + 10);
975 destLength = destTable.size();
976 rc = pldm_bios_table_attr_value_copy_and_update(
977 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
978 stringEntry3.data(), stringEntry3.size());
979 EXPECT_EQ(rc, PLDM_SUCCESS);
980 EXPECT_EQ(destLength, expectTable.size());
981 destTable.resize(destLength);
982 EXPECT_THAT(destTable, ElementsAreArray(expectTable));
983
984 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer
985 rc = pldm_bios_table_attr_value_copy_and_update(
986 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
987 stringEntry3.data(), stringEntry3.size());
988 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
989 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string
990
991 destTable.resize(expectTable.size() - 1);
992 destLength = destTable.size();
993 rc = pldm_bios_table_attr_value_copy_and_update(
994 srcTable.data(), srcTable.size(), destTable.data(), &destLength,
995 stringEntry3.data(), stringEntry3.size());
996 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
997}
998
999TEST(StringTable, EntryEncodeTest)
1000{
1001 std::vector<uint8_t> stringEntry{
1002 0, 0, /* string handle*/
1003 7, 0, /* string length */
1004 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
1005 };
1006
1007 const char* str = "Allowed";
1008 auto str_length = std::strlen(str);
1009 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
1010 EXPECT_EQ(encodeLength, stringEntry.size());
1011
1012 std::vector<uint8_t> encodeEntry(encodeLength, 0);
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301013 ASSERT_EQ(pldm_bios_table_string_entry_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301014 encodeEntry.data(), encodeEntry.size(), str, str_length),
1015 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301016 // set string handle = 0
1017 encodeEntry[0] = 0;
1018 encodeEntry[1] = 0;
1019
1020 EXPECT_EQ(stringEntry, encodeEntry);
1021
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301022 EXPECT_NE(pldm_bios_table_string_entry_encode(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301023 encodeEntry.data(), encodeEntry.size() - 1, str, str_length),
1024 PLDM_SUCCESS);
Andrew Jefferye48fdd62024-06-25 00:36:20 +09301025 auto rc = pldm_bios_table_string_entry_encode(
Andrew Jeffery9c766792022-08-10 23:12:49 +09301026 encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
1027 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1028}
1029
1030TEST(StringTable, EntryDecodeTest)
1031{
1032 std::vector<uint8_t> stringEntry{
1033 4, 0, /* string handle*/
1034 7, 0, /* string length */
1035 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
1036 };
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301037 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301038 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
1039 stringEntry.data());
1040 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1041 EXPECT_EQ(handle, 4);
1042 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
1043 EXPECT_EQ(strLength, 7);
1044
1045 std::vector<char> buffer(strLength + 1, 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301046 pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1047 buffer.size());
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301048 EXPECT_EQ(strlen(buffer.data()), strLength);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301049 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301050 EXPECT_EQ(pldm_bios_table_string_entry_decode_string(
Andrew Jeffery6409c8a2023-06-14 11:38:31 +09301051 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/),
1052 PLDM_SUCCESS);
1053 EXPECT_EQ(strlen(buffer.data()), 2);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301054 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
1055
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301056 auto rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1057 buffer.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +09301058 EXPECT_EQ(rc, PLDM_SUCCESS);
1059 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
1060
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301061 /* Ensure equivalence with the unchecked API */
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301062 rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
1063 2 + 1 /* sizeof '\0' */);
Andrew Jeffery98c1e692023-06-14 14:41:19 +09301064 EXPECT_EQ(rc, std::strcmp("Al", buffer.data()));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301065}
1066
1067TEST(StringTable, IteratorTest)
1068{
1069 std::vector<uint8_t> stringHello{
1070 0, 0, /* string handle*/
1071 5, 0, /* string length */
1072 'H', 'e', 'l', 'l', 'o', /* string */
1073 };
1074 std::vector<uint8_t> stringWorld{
1075 1, 0, /* string handle*/
1076 6, 0, /* string length */
1077 'W', 'o', 'r', 'l', 'd', '!', /* string */
1078 };
1079
1080 Table table;
1081 buildTable(table, stringHello, stringWorld);
1082
1083 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1084 PLDM_BIOS_STRING_TABLE);
1085 auto entry = pldm_bios_table_iter_string_entry_value(iter);
1086 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
1087 EXPECT_EQ(rc, 0);
1088 pldm_bios_table_iter_next(iter);
1089 entry = pldm_bios_table_iter_string_entry_value(iter);
1090 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
1091 EXPECT_EQ(rc, 0);
1092 pldm_bios_table_iter_next(iter);
1093 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
1094 pldm_bios_table_iter_free(iter);
1095}
1096
1097TEST(StringTable, FindTest)
1098{
1099 std::vector<uint8_t> stringHello{
1100 1, 0, /* string handle*/
1101 5, 0, /* string length */
1102 'H', 'e', 'l', 'l', 'o', /* string */
1103 };
1104 std::vector<uint8_t> stringWorld{
1105 2, 0, /* string handle*/
1106 6, 0, /* string length */
1107 'W', 'o', 'r', 'l', 'd', '!', /* string */
1108 };
1109 std::vector<uint8_t> stringHi{
1110 3, 0, /* string handle*/
1111 2, 0, /* string length */
1112 'H', 'i', /* string */
1113 };
1114
1115 Table table;
1116 buildTable(table, stringHello, stringWorld, stringHi);
1117
1118 auto entry = pldm_bios_table_string_find_by_string(table.data(),
1119 table.size(), "World!");
1120 EXPECT_NE(entry, nullptr);
1121 auto handle = pldm_bios_table_string_entry_decode_handle(entry);
1122 EXPECT_EQ(handle, 2);
1123
1124 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
1125 "Worl");
1126 EXPECT_EQ(entry, nullptr);
1127
1128 entry =
1129 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
1130 EXPECT_NE(entry, nullptr);
1131 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
1132 EXPECT_EQ(str_length, 2);
1133 std::vector<char> strBuf(str_length + 1, 0);
Andrew Jeffery8c37ab32024-06-25 15:34:27 +09301134 auto rc = pldm_bios_table_string_entry_decode_string(entry, strBuf.data(),
1135 strBuf.size());
Andrew Jeffery9c766792022-08-10 23:12:49 +09301136 EXPECT_EQ(rc, PLDM_SUCCESS);
1137 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
1138
1139 entry =
1140 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
1141 EXPECT_EQ(entry, nullptr);
1142}
1143
Andrew Jefferybf6699b2023-07-05 16:27:59 +09301144TEST(Iterator, DeathTest)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301145{
1146
1147 Table table(256, 0);
1148
1149 /* first entry */
1150 auto attr_entry =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301151 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301152 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
1153 auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
1154 PLDM_BIOS_ATTR_TABLE);
1155 attr_entry->attr_type = PLDM_BIOS_PASSWORD;
Andrew Jefferyfbaea232024-05-23 10:58:29 +09301156#ifndef NDEBUG
Andrew Jeffery9c766792022-08-10 23:12:49 +09301157 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
Andrew Jefferyfbaea232024-05-23 10:58:29 +09301158#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301159 pldm_bios_table_iter_free(iter);
1160}
1161
1162TEST(PadAndChecksum, PadAndChecksum)
1163{
1164 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0));
1165 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1));
1166 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2));
1167 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3));
1168 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4));
1169
1170 // The table is borrowed from
1171 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
1172 // refer to the commit message
1173 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
1174 auto sizeWithoutPad = attrValTable.size();
1175 attrValTable.resize(sizeWithoutPad +
1176 pldm_bios_table_pad_checksum_size(sizeWithoutPad));
Andrew Jefferyd8bb75c2024-06-29 22:29:02 +09301177 ASSERT_EQ(pldm_bios_table_append_pad_checksum(
Andrew Jeffery50dd1592023-07-14 16:02:05 +09301178 attrValTable.data(), attrValTable.size(), &sizeWithoutPad),
1179 PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301180 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
1181 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
1182 EXPECT_EQ(attrValTable, expectedTable);
1183}
1184
1185TEST(BIOSTableChecksum, testBIOSTableChecksum)
1186{
1187 std::vector<uint8_t> stringTable{
1188 1, 0, /* string handle*/
1189 5, 0, /* string length */
1190 'T', 'a', 'b', 'l', 'e', /* string */
1191 };
1192
1193 buildTable(stringTable);
1194
1195 EXPECT_EQ(true,
1196 pldm_bios_table_checksum(stringTable.data(), stringTable.size()));
1197}