1 #include <endian.h> 2 #include <libpldm/base.h> 3 #include <libpldm/bios.h> 4 #include <libpldm/bios_table.h> 5 #include <libpldm/utils.h> 6 7 #include <algorithm> 8 #include <cstdint> 9 #include <cstring> 10 #include <iterator> 11 #include <string> 12 #include <utility> 13 #include <vector> 14 15 #include <gmock/gmock.h> 16 #include <gtest/gtest.h> 17 18 using testing::ElementsAreArray; 19 using Table = std::vector<uint8_t>; 20 21 void 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 32 template <typename First, typename... Rest> 33 void buildTable(Table& table, First& first, Rest&... rest) 34 { 35 table.insert(table.end(), first.begin(), first.end()); 36 buildTable(table, rest...); 37 } 38 39 TEST(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 */ 49 0 /* default value string handle index */ 50 }; 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 61 TEST(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 */ 71 1 /* default value string handle index */ 72 }; 73 74 auto entry = 75 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data()); 76 uint8_t pvNumber; 77 ASSERT_EQ( 78 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber), 79 PLDM_SUCCESS); 80 EXPECT_EQ(pvNumber, 2); 81 pvNumber = 0; 82 auto rc = 83 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber); 84 EXPECT_EQ(rc, PLDM_SUCCESS); 85 EXPECT_EQ(pvNumber, 2); 86 87 std::vector<uint16_t> pvHandles(pvNumber, 0); 88 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check( 89 entry, pvHandles.data(), pvHandles.size()), 90 PLDM_SUCCESS); 91 EXPECT_EQ(pvNumber, 2); 92 EXPECT_EQ(pvHandles[0], 2); 93 EXPECT_EQ(pvHandles[1], 3); 94 pvHandles.resize(1); 95 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check( 96 entry, pvHandles.data(), pvHandles.size()), 97 PLDM_SUCCESS); 98 EXPECT_EQ(pvHandles[0], 2); 99 100 pvHandles.resize(2); 101 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check( 102 entry, pvHandles.data(), pvHandles.size()); 103 EXPECT_EQ(rc, PLDM_SUCCESS); 104 EXPECT_EQ(pvHandles[0], 2); 105 EXPECT_EQ(pvHandles[1], 3); 106 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check( 107 entry, pvHandles.data(), 1); 108 EXPECT_EQ(rc, PLDM_SUCCESS); 109 110 uint8_t defNumber; 111 ASSERT_EQ( 112 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber), 113 PLDM_SUCCESS); 114 EXPECT_EQ(defNumber, 1); 115 std::vector<uint8_t> defIndices(defNumber); 116 rc = pldm_bios_table_attr_entry_enum_decode_def_indices( 117 entry, defIndices.data(), defIndices.size()); 118 EXPECT_EQ(rc, defNumber); 119 EXPECT_THAT(defIndices, ElementsAreArray({1})); 120 121 defNumber = 0; 122 rc = 123 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber); 124 EXPECT_EQ(rc, PLDM_SUCCESS); 125 EXPECT_EQ(defNumber, 1); 126 127 rc = 128 pldm_bios_table_attr_entry_enum_decode_pv_num_check(nullptr, &pvNumber); 129 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 130 rc = pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, nullptr); 131 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 132 133 entry->attr_type = PLDM_BIOS_STRING; 134 rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber); 135 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 136 137 rc = 138 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber); 139 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 140 rc = 141 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(entry, nullptr, 0); 142 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 143 } 144 145 TEST(AttrTable, EnumEntryEncodeTest) 146 { 147 std::vector<uint8_t> enumEntry{ 148 0, 0, /* attr handle */ 149 0, /* attr type */ 150 1, 0, /* attr name handle */ 151 2, /* number of possible value */ 152 2, 0, /* possible value handle */ 153 3, 0, /* possible value handle */ 154 1, /* number of default value */ 155 0 /* default value string handle index */ 156 }; 157 158 std::vector<uint16_t> pv_hdls{2, 3}; 159 std::vector<uint8_t> defs{0}; 160 161 struct pldm_bios_table_attr_entry_enum_info info = { 162 1, /* name handle */ 163 false, /* read only */ 164 2, /* pv number */ 165 pv_hdls.data(), /* pv handle */ 166 1, /*def number */ 167 defs.data() /*def index*/ 168 }; 169 auto encodeLength = pldm_bios_table_attr_entry_enum_encode_length(2, 1); 170 EXPECT_EQ(encodeLength, enumEntry.size()); 171 172 std::vector<uint8_t> encodeEntry(encodeLength, 0); 173 ASSERT_EQ(pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(), 174 encodeEntry.size(), &info), 175 PLDM_SUCCESS); 176 // set attr handle = 0 177 encodeEntry[0] = 0; 178 encodeEntry[1] = 0; 179 180 EXPECT_EQ(enumEntry, encodeEntry); 181 182 EXPECT_NE(pldm_bios_table_attr_entry_enum_encode( 183 encodeEntry.data(), encodeEntry.size() - 1, &info), 184 PLDM_SUCCESS); 185 auto rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(), 186 encodeEntry.size(), &info); 187 EXPECT_EQ(rc, PLDM_SUCCESS); 188 // set attr handle = 0 189 encodeEntry[0] = 0; 190 encodeEntry[1] = 0; 191 192 EXPECT_EQ(enumEntry, encodeEntry); 193 rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(), 194 encodeEntry.size() - 1, &info); 195 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 196 } 197 198 TEST(AttrTable, StringEntryDecodeTest) 199 { 200 std::vector<uint8_t> stringEntry{ 201 1, 0, /* attr handle */ 202 1, /* attr type */ 203 12, 0, /* attr name handle */ 204 1, /* string type */ 205 1, 0, /* minimum length of the string in bytes */ 206 100, 0, /* maximum length of the string in bytes */ 207 3, 0, /* length of default string in length */ 208 'a', 'b', 'c' /* default string */ 209 }; 210 211 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>( 212 stringEntry.data()); 213 auto stringType = 214 pldm_bios_table_attr_entry_string_decode_string_type(entry); 215 EXPECT_EQ(stringType, 1); 216 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry); 217 EXPECT_EQ(minLength, 1); 218 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry); 219 EXPECT_EQ(maxLength, 100); 220 221 uint16_t defStringLength; 222 ASSERT_EQ(pldm_bios_table_attr_entry_string_decode_def_string_length_check( 223 entry, &defStringLength), 224 PLDM_SUCCESS); 225 EXPECT_EQ(defStringLength, 3); 226 std::vector<char> defString(defStringLength + 1); 227 auto rc = pldm_bios_table_attr_entry_string_decode_def_string( 228 entry, defString.data(), defString.size()); 229 EXPECT_EQ(rc, 3); 230 EXPECT_STREQ(defString.data(), "abc"); 231 rc = pldm_bios_table_attr_entry_string_decode_def_string( 232 entry, defString.data(), defString.size() - 1); 233 EXPECT_EQ(rc, 2); 234 EXPECT_STREQ(defString.data(), "ab"); 235 236 defStringLength = 0; 237 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check( 238 entry, &defStringLength); 239 EXPECT_EQ(rc, PLDM_SUCCESS); 240 EXPECT_EQ(defStringLength, 3); 241 242 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check( 243 entry, nullptr); 244 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 245 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check( 246 nullptr, &defStringLength); 247 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 248 entry->attr_type = PLDM_BIOS_INTEGER; 249 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check( 250 entry, &defStringLength); 251 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 252 rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check( 253 nullptr, &defStringLength); 254 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 255 } 256 257 TEST(AttrTable, StringEntryEncodeTest) 258 { 259 std::vector<uint8_t> stringEntry{ 260 0, 0, /* attr handle */ 261 1, /* attr type */ 262 3, 0, /* attr name handle */ 263 1, /* string type */ 264 1, 0, /* min string length */ 265 100, 0, /* max string length */ 266 3, 0, /* default string length */ 267 'a', 'b', 'c', /* default string */ 268 }; 269 270 struct pldm_bios_table_attr_entry_string_info info = { 271 3, /* name handle */ 272 false, /* read only */ 273 1, /* string type ascii */ 274 1, /* min length */ 275 100, /* max length */ 276 3, /* def length */ 277 "abc", /* def string */ 278 }; 279 auto encodeLength = pldm_bios_table_attr_entry_string_encode_length(3); 280 EXPECT_EQ(encodeLength, stringEntry.size()); 281 282 std::vector<uint8_t> encodeEntry(encodeLength, 0); 283 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check( 284 encodeEntry.data(), encodeEntry.size(), &info), 285 PLDM_SUCCESS); 286 // set attr handle = 0 287 encodeEntry[0] = 0; 288 encodeEntry[1] = 0; 289 290 EXPECT_EQ(stringEntry, encodeEntry); 291 292 EXPECT_NE(pldm_bios_table_attr_entry_string_encode_check( 293 encodeEntry.data(), encodeEntry.size() - 1, &info), 294 PLDM_SUCCESS); 295 auto rc = pldm_bios_table_attr_entry_string_encode_check( 296 encodeEntry.data(), encodeEntry.size(), &info); 297 EXPECT_EQ(rc, PLDM_SUCCESS); 298 // set attr handle = 0 299 encodeEntry[0] = 0; 300 encodeEntry[1] = 0; 301 302 EXPECT_EQ(stringEntry, encodeEntry); 303 rc = pldm_bios_table_attr_entry_string_encode_check( 304 encodeEntry.data(), encodeEntry.size() - 1, &info); 305 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 306 std::swap(info.max_length, info.min_length); 307 const char* errmsg; 308 rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg); 309 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 310 EXPECT_STREQ( 311 "MinimumStingLength should not be greater than MaximumStringLength", 312 errmsg); 313 rc = pldm_bios_table_attr_entry_string_encode_check( 314 encodeEntry.data(), encodeEntry.size(), &info); 315 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 316 std::swap(info.max_length, info.min_length); 317 318 std::vector<uint8_t> stringEntryLength0{ 319 0, 0, /* attr handle */ 320 1, /* attr type */ 321 3, 0, /* attr name handle */ 322 1, /* string type */ 323 0, 0, /* min string length */ 324 100, 0, /* max string length */ 325 0, 0, /* default string length */ 326 }; 327 328 info.min_length = 0; 329 info.def_length = 0; 330 info.def_string = nullptr; 331 332 encodeLength = pldm_bios_table_attr_entry_string_encode_length(0); 333 EXPECT_EQ(encodeLength, stringEntryLength0.size()); 334 335 encodeEntry.resize(encodeLength); 336 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check( 337 encodeEntry.data(), encodeEntry.size(), &info), 338 PLDM_SUCCESS); 339 // set attr handle = 0 340 encodeEntry[0] = 0; 341 encodeEntry[1] = 0; 342 343 EXPECT_EQ(stringEntryLength0, encodeEntry); 344 } 345 346 TEST(AttrTable, integerEntryEncodeTest) 347 { 348 std::vector<uint8_t> integerEntry{ 349 0, 0, /* attr handle */ 350 3, /* attr type */ 351 1, 0, /* attr name handle */ 352 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */ 353 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */ 354 2, 0, 0, 0, /* scalar increment */ 355 3, 0, 0, 0, 0, 0, 0, 0, /* default value */ 356 }; 357 358 std::vector<uint16_t> pv_hdls{2, 3}; 359 std::vector<uint8_t> defs{0}; 360 361 struct pldm_bios_table_attr_entry_integer_info info = { 362 1, /* name handle */ 363 false, /* read only */ 364 1, /* lower bound */ 365 10, /* upper bound */ 366 2, /* scalar increment */ 367 3 /* default value */ 368 }; 369 auto encodeLength = pldm_bios_table_attr_entry_integer_encode_length(); 370 EXPECT_EQ(encodeLength, integerEntry.size()); 371 372 std::vector<uint8_t> encodeEntry(encodeLength, 0); 373 ASSERT_EQ(pldm_bios_table_attr_entry_integer_encode_check( 374 encodeEntry.data(), encodeEntry.size(), &info), 375 PLDM_SUCCESS); 376 // set attr handle = 0 377 encodeEntry[0] = 0; 378 encodeEntry[1] = 0; 379 380 EXPECT_EQ(integerEntry, encodeEntry); 381 382 EXPECT_NE(pldm_bios_table_attr_entry_integer_encode_check( 383 encodeEntry.data(), encodeEntry.size() - 1, &info), 384 PLDM_SUCCESS); 385 386 auto rc = pldm_bios_table_attr_entry_integer_encode_check( 387 encodeEntry.data(), encodeEntry.size(), &info); 388 EXPECT_EQ(rc, PLDM_SUCCESS); 389 // set attr handle = 0 390 encodeEntry[0] = 0; 391 encodeEntry[1] = 0; 392 393 EXPECT_EQ(integerEntry, encodeEntry); 394 395 rc = pldm_bios_table_attr_entry_integer_encode_check( 396 encodeEntry.data(), encodeEntry.size() - 1, &info); 397 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 398 399 info.lower_bound = 100; 400 info.upper_bound = 50; 401 const char* errmsg; 402 rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg); 403 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 404 EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg); 405 rc = pldm_bios_table_attr_entry_integer_encode_check( 406 encodeEntry.data(), encodeEntry.size(), &info); 407 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 408 } 409 410 TEST(AttrTable, integerEntryDecodeTest) 411 { 412 std::vector<uint8_t> integerEntry{ 413 0, 0, /* attr handle */ 414 3, /* attr type */ 415 1, 0, /* attr name handle */ 416 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */ 417 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */ 418 2, 0, 0, 0, /* scalar increment */ 419 3, 0, 0, 0, 0, 0, 0, 0, /* default value */ 420 }; 421 422 uint64_t lower; 423 uint64_t upper; 424 uint64_t def; 425 uint32_t scalar; 426 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>( 427 integerEntry.data()); 428 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar, 429 &def); 430 EXPECT_EQ(lower, 1u); 431 EXPECT_EQ(upper, 10u); 432 EXPECT_EQ(scalar, 2u); 433 EXPECT_EQ(def, 3u); 434 } 435 436 TEST(AttrTable, ItearatorTest) 437 { 438 std::vector<uint8_t> enumEntry{ 439 0, 0, /* attr handle */ 440 0, /* attr type */ 441 1, 0, /* attr name handle */ 442 2, /* number of possible value */ 443 2, 0, /* possible value handle */ 444 3, 0, /* possible value handle */ 445 1, /* number of default value */ 446 0 /* default value string handle index */ 447 }; 448 std::vector<uint8_t> stringEntry{ 449 1, 0, /* attr handle */ 450 1, /* attr type */ 451 12, 0, /* attr name handle */ 452 1, /* string type */ 453 1, 0, /* minimum length of the string in bytes */ 454 100, 0, /* maximum length of the string in bytes */ 455 3, 0, /* length of default string in length */ 456 'a', 'b', 'c' /* default string */ 457 }; 458 std::vector<uint8_t> integerEntry{ 459 0, 0, /* attr handle */ 460 3, /* attr type */ 461 1, 0, /* attr name handle */ 462 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */ 463 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */ 464 2, 0, 0, 0, /* scalar increment */ 465 3, 0, 0, 0, 0, 0, 0, 0, /* default value */ 466 }; 467 468 Table table; 469 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry); 470 auto iter = pldm_bios_table_iter_create(table.data(), table.size(), 471 PLDM_BIOS_ATTR_TABLE); 472 auto entry = pldm_bios_table_iter_attr_entry_value(iter); 473 auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size()); 474 EXPECT_EQ(rc, 0); 475 476 pldm_bios_table_iter_next(iter); 477 entry = pldm_bios_table_iter_attr_entry_value(iter); 478 rc = std::memcmp(entry, stringEntry.data(), stringEntry.size()); 479 EXPECT_EQ(rc, 0); 480 481 pldm_bios_table_iter_next(iter); 482 entry = pldm_bios_table_iter_attr_entry_value(iter); 483 rc = std::memcmp(entry, integerEntry.data(), integerEntry.size()); 484 EXPECT_EQ(rc, 0); 485 486 pldm_bios_table_iter_next(iter); 487 entry = pldm_bios_table_iter_attr_entry_value(iter); 488 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size()); 489 EXPECT_EQ(rc, 0); 490 491 pldm_bios_table_iter_next(iter); 492 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter)); 493 pldm_bios_table_iter_free(iter); 494 } 495 496 TEST(AttrTable, FindTest) 497 { 498 std::vector<uint8_t> enumEntry{ 499 0, 0, /* attr handle */ 500 0, /* attr type */ 501 1, 0, /* attr name handle */ 502 2, /* number of possible value */ 503 2, 0, /* possible value handle */ 504 3, 0, /* possible value handle */ 505 1, /* number of default value */ 506 0 /* default value string handle index */ 507 }; 508 std::vector<uint8_t> stringEntry{ 509 1, 0, /* attr handle */ 510 1, /* attr type */ 511 2, 0, /* attr name handle */ 512 1, /* string type */ 513 1, 0, /* minimum length of the string in bytes */ 514 100, 0, /* maximum length of the string in bytes */ 515 3, 0, /* length of default string in length */ 516 'a', 'b', 'c' /* default string */ 517 }; 518 std::vector<uint8_t> integerEntry{ 519 0, 0, /* attr handle */ 520 3, /* attr type */ 521 3, 0, /* attr name handle */ 522 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */ 523 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */ 524 2, 0, 0, 0, /* scalar increment */ 525 3, 0, 0, 0, 0, 0, 0, 0, /* default value */ 526 }; 527 528 Table table; 529 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry); 530 531 auto entry = 532 pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 1); 533 EXPECT_NE(entry, nullptr); 534 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); 544 p = reinterpret_cast<const uint8_t*>(entry); 545 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()), 546 ElementsAreArray(stringEntry)); 547 548 entry = pldm_bios_table_attr_find_by_string_handle(table.data(), 549 table.size(), 4); 550 EXPECT_EQ(entry, nullptr); 551 } 552 553 TEST(AttrValTable, HeaderDecodeTest) 554 { 555 std::vector<uint8_t> enumEntry{ 556 1, 0, /* attr handle */ 557 0, /* attr type */ 558 2, /* number of current value */ 559 0, /* current value string handle index */ 560 1, /* current value string handle index */ 561 }; 562 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 563 enumEntry.data()); 564 auto attrHandle = 565 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry); 566 EXPECT_EQ(attrHandle, 1); 567 auto attrType = 568 pldm_bios_table_attr_value_entry_decode_attribute_type(entry); 569 EXPECT_EQ(attrType, 0); 570 } 571 572 TEST(AttrValTable, EnumEntryEncodeTest) 573 { 574 std::vector<uint8_t> enumEntry{ 575 0, 0, /* attr handle */ 576 0, /* attr type */ 577 2, /* number of current value */ 578 0, /* current value string handle index */ 579 1, /* current value string handle index */ 580 }; 581 582 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2); 583 EXPECT_EQ(length, enumEntry.size()); 584 std::vector<uint8_t> encodeEntry(length, 0); 585 uint8_t handles[] = {0, 1}; 586 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_enum_check( 587 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles), 588 PLDM_SUCCESS); 589 EXPECT_EQ(encodeEntry, enumEntry); 590 591 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_enum_check( 592 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles), 593 PLDM_SUCCESS); 594 595 auto rc = pldm_bios_table_attr_value_entry_encode_enum_check( 596 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2, 597 handles); 598 EXPECT_EQ(rc, PLDM_SUCCESS); 599 EXPECT_EQ(encodeEntry, enumEntry); 600 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 601 enumEntry.data()); 602 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY; 603 rc = pldm_bios_table_attr_value_entry_encode_enum_check( 604 encodeEntry.data(), encodeEntry.size(), 0, 605 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles); 606 EXPECT_EQ(rc, PLDM_SUCCESS); 607 EXPECT_EQ(encodeEntry, enumEntry); 608 rc = pldm_bios_table_attr_value_entry_encode_enum_check( 609 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2, 610 handles); 611 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 612 rc = pldm_bios_table_attr_value_entry_encode_enum_check( 613 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2, 614 handles); 615 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 616 } 617 618 TEST(AttrValTable, EnumEntryDecodeTest) 619 { 620 std::vector<uint8_t> enumEntry{ 621 0, 0, /* attr handle */ 622 0, /* attr type */ 623 2, /* number of current value */ 624 0, /* current value string handle index */ 625 1, /* current value string handle index */ 626 }; 627 628 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 629 enumEntry.data()); 630 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry); 631 EXPECT_EQ(2, number); 632 633 std::vector<uint8_t> handles(2, 0); 634 auto rc = pldm_bios_table_attr_value_entry_enum_decode_handles( 635 entry, handles.data(), handles.size()); 636 EXPECT_EQ(rc, 2); 637 EXPECT_EQ(handles[0], 0); 638 EXPECT_EQ(handles[1], 1); 639 640 /* Buffer size is more than the number of current string handles */ 641 std::vector<uint8_t> handleIndexes(3, 0); 642 rc = pldm_bios_table_attr_value_entry_enum_decode_handles( 643 entry, handleIndexes.data(), handleIndexes.size()); 644 EXPECT_EQ(rc, 2); 645 EXPECT_EQ(handleIndexes[0], 0); 646 EXPECT_EQ(handleIndexes[1], 1); 647 648 /* Buffersize is less than the number of current string handles */ 649 std::vector<uint8_t> strHandles(1, 0); 650 rc = pldm_bios_table_attr_value_entry_enum_decode_handles( 651 entry, strHandles.data(), strHandles.size()); 652 EXPECT_EQ(rc, 1); 653 EXPECT_EQ(strHandles[0], 0); 654 } 655 656 TEST(AttrValTable, stringEntryEncodeTest) 657 { 658 std::vector<uint8_t> stringEntry{ 659 0, 0, /* attr handle */ 660 1, /* attr type */ 661 3, 0, /* current string length */ 662 'a', 'b', 'c', /* default value string handle index */ 663 }; 664 665 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3); 666 EXPECT_EQ(length, stringEntry.size()); 667 std::vector<uint8_t> encodeEntry(length, 0); 668 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_string_check( 669 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc"), 670 PLDM_SUCCESS); 671 EXPECT_EQ(encodeEntry, stringEntry); 672 673 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_string_check( 674 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"), 675 PLDM_SUCCESS); 676 677 auto rc = pldm_bios_table_attr_value_entry_encode_string_check( 678 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc"); 679 EXPECT_EQ(rc, PLDM_SUCCESS); 680 EXPECT_EQ(encodeEntry, stringEntry); 681 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 682 stringEntry.data()); 683 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY; 684 rc = pldm_bios_table_attr_value_entry_encode_string_check( 685 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY, 686 3, "abc"); 687 EXPECT_EQ(rc, PLDM_SUCCESS); 688 EXPECT_EQ(encodeEntry, stringEntry); 689 rc = pldm_bios_table_attr_value_entry_encode_string_check( 690 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3, 691 "abc"); 692 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 693 rc = pldm_bios_table_attr_value_entry_encode_string_check( 694 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3, 695 "abc"); 696 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 697 } 698 699 TEST(AttrValTable, StringEntryDecodeTest) 700 { 701 std::vector<uint8_t> stringEntry{ 702 0, 0, /* attr handle */ 703 1, /* attr type */ 704 3, 0, /* current string length */ 705 'a', 'b', 'c', /* default value string handle index */ 706 }; 707 708 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 709 stringEntry.data()); 710 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry); 711 EXPECT_EQ(3, length); 712 713 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry); 714 EXPECT_EQ(0, handle); 715 716 auto entryLength = pldm_bios_table_attr_value_entry_length(entry); 717 EXPECT_EQ(stringEntry.size(), entryLength); 718 719 variable_field currentString{}; 720 pldm_bios_table_attr_value_entry_string_decode_string(entry, 721 ¤tString); 722 EXPECT_THAT(std::vector<uint8_t>(currentString.ptr, 723 currentString.ptr + currentString.length), 724 ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'})); 725 } 726 727 TEST(AttrValTable, integerEntryEncodeTest) 728 { 729 std::vector<uint8_t> integerEntry{ 730 0, 0, /* attr handle */ 731 3, /* attr type */ 732 10, 0, 0, 0, 0, 0, 0, 0, /* current value */ 733 }; 734 735 auto length = pldm_bios_table_attr_value_entry_encode_integer_length(); 736 EXPECT_EQ(length, integerEntry.size()); 737 std::vector<uint8_t> encodeEntry(length, 0); 738 ASSERT_EQ( 739 pldm_bios_table_attr_value_entry_encode_integer_check( 740 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10), 741 PLDM_SUCCESS); 742 EXPECT_EQ(encodeEntry, integerEntry); 743 744 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_integer_check( 745 encodeEntry.data(), encodeEntry.size() - 1, 0, 746 PLDM_BIOS_INTEGER, 10), 747 PLDM_SUCCESS); 748 749 auto rc = pldm_bios_table_attr_value_entry_encode_integer_check( 750 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10); 751 EXPECT_EQ(rc, PLDM_SUCCESS); 752 EXPECT_EQ(encodeEntry, integerEntry); 753 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 754 integerEntry.data()); 755 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY; 756 rc = pldm_bios_table_attr_value_entry_encode_integer_check( 757 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY, 758 10); 759 EXPECT_EQ(rc, PLDM_SUCCESS); 760 EXPECT_EQ(encodeEntry, integerEntry); 761 762 rc = pldm_bios_table_attr_value_entry_encode_integer_check( 763 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10); 764 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 765 rc = pldm_bios_table_attr_value_entry_encode_integer_check( 766 encodeEntry.data(), encodeEntry.size() - 1, 0, 767 PLDM_BIOS_INTEGER_READ_ONLY, 10); 768 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 769 } 770 771 TEST(AttrValTable, integerEntryDecodeTest) 772 { 773 std::vector<uint8_t> integerEntry{ 774 0, 0, /* attr handle */ 775 3, /* attr type */ 776 10, 0, 0, 0, 0, 0, 0, 0, /* current value */ 777 }; 778 779 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 780 integerEntry.data()); 781 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry); 782 EXPECT_EQ(cv, 10u); 783 } 784 785 TEST(AttrValTable, IteratorTest) 786 { 787 std::vector<uint8_t> enumEntry{ 788 0, 0, /* attr handle */ 789 0, /* attr type */ 790 2, /* number of current value */ 791 0, /* current value string handle index */ 792 1, /* current value string handle index */ 793 }; 794 std::vector<uint8_t> stringEntry{ 795 0, 0, /* attr handle */ 796 1, /* attr type */ 797 3, 0, /* current string length */ 798 'a', 'b', 'c', /* default value string handle index */ 799 }; 800 std::vector<uint8_t> integerEntry{ 801 0, 0, /* attr handle */ 802 3, /* attr type */ 803 10, 0, 0, 0, 0, 0, 0, 0, /* current value */ 804 }; 805 806 Table table; 807 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry); 808 809 auto iter = pldm_bios_table_iter_create(table.data(), table.size(), 810 PLDM_BIOS_ATTR_VAL_TABLE); 811 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter); 812 813 auto p = reinterpret_cast<const uint8_t*>(entry); 814 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()), 815 ElementsAreArray(enumEntry)); 816 817 pldm_bios_table_iter_next(iter); 818 entry = pldm_bios_table_iter_attr_value_entry_value(iter); 819 p = reinterpret_cast<const uint8_t*>(entry); 820 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()), 821 ElementsAreArray(stringEntry)); 822 823 pldm_bios_table_iter_next(iter); 824 entry = pldm_bios_table_iter_attr_value_entry_value(iter); 825 p = reinterpret_cast<const uint8_t*>(entry); 826 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()), 827 ElementsAreArray(integerEntry)); 828 829 pldm_bios_table_iter_next(iter); 830 entry = pldm_bios_table_iter_attr_value_entry_value(iter); 831 p = reinterpret_cast<const uint8_t*>(entry); 832 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()), 833 ElementsAreArray(enumEntry)); 834 835 pldm_bios_table_iter_next(iter); 836 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter)); 837 838 pldm_bios_table_iter_free(iter); 839 } 840 841 TEST(AttrValTable, FindTest) 842 { 843 std::vector<uint8_t> enumEntry{ 844 0, 0, /* attr handle */ 845 0, /* attr type */ 846 2, /* number of current value */ 847 0, /* current value string handle index */ 848 1, /* current value string handle index */ 849 }; 850 std::vector<uint8_t> stringEntry{ 851 1, 0, /* attr handle */ 852 1, /* attr type */ 853 3, 0, /* current string length */ 854 'a', 'b', 'c', /* default value string handle index */ 855 }; 856 std::vector<uint8_t> integerEntry{ 857 2, 0, /* attr handle */ 858 3, /* attr type */ 859 10, 0, 0, 0, 0, 0, 0, 0, /* current value */ 860 }; 861 862 Table table; 863 buildTable(table, enumEntry, stringEntry, integerEntry); 864 865 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(), 866 table.size(), 1); 867 EXPECT_NE(entry, nullptr); 868 auto p = reinterpret_cast<const uint8_t*>(entry); 869 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()), 870 ElementsAreArray(stringEntry)); 871 872 entry = pldm_bios_table_attr_value_find_by_handle(table.data(), 873 table.size(), 3); 874 EXPECT_EQ(entry, nullptr); 875 876 auto firstEntry = 877 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data()); 878 firstEntry->attr_type = PLDM_BIOS_PASSWORD; 879 #ifdef NDEBUG 880 EXPECT_EQ(pldm_bios_table_attr_value_find_by_handle(table.data(), 881 table.size(), 1), 882 nullptr); 883 #else 884 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(), 885 table.size(), 1), 886 "entry_length != NULL"); 887 #endif 888 } 889 890 TEST(AttrValTable, CopyAndUpdateTest) 891 { 892 std::vector<uint8_t> enumEntry{ 893 0, 0, /* attr handle */ 894 0, /* attr type */ 895 2, /* number of current value */ 896 0, /* current value string handle index */ 897 1, /* current value string handle index */ 898 }; 899 std::vector<uint8_t> stringEntry{ 900 1, 0, /* attr handle */ 901 1, /* attr type */ 902 3, 0, /* current string length */ 903 'a', 'b', 'c', /* default value string handle index */ 904 }; 905 std::vector<uint8_t> integerEntry{ 906 2, 0, /* attr handle */ 907 3, /* attr type */ 908 10, 0, 0, 0, 0, 0, 0, 0, /* current value */ 909 }; 910 911 Table srcTable; 912 buildTable(srcTable, enumEntry, stringEntry, integerEntry); 913 914 std::vector<uint8_t> stringEntry1{ 915 1, 0, /* attr handle */ 916 1, /* attr type */ 917 3, 0, /* current string length */ 918 'd', 'e', 'f', /* default value string handle index */ 919 }; 920 921 Table expectTable; 922 buildTable(expectTable, enumEntry, stringEntry1, integerEntry); 923 Table destTable(expectTable.size() + 10); 924 auto destLength = destTable.size(); 925 auto rc = pldm_bios_table_attr_value_copy_and_update( 926 srcTable.data(), srcTable.size(), destTable.data(), &destLength, 927 stringEntry1.data(), stringEntry1.size()); 928 929 EXPECT_EQ(rc, PLDM_SUCCESS); 930 EXPECT_EQ(destLength, expectTable.size()); 931 destTable.resize(destLength); 932 EXPECT_THAT(destTable, ElementsAreArray(expectTable)); 933 934 std::vector<uint8_t> stringEntry2{ 935 1, 0, /* attr handle */ 936 1, /* attr type */ 937 5, 0, /* current string length */ 938 'd', 'e', 'f', 'a', 'b', /* default value string handle index */ 939 }; 940 expectTable.resize(0); 941 buildTable(expectTable, enumEntry, stringEntry2, integerEntry); 942 destTable.resize(expectTable.size() + 10); 943 destLength = destTable.size(); 944 rc = pldm_bios_table_attr_value_copy_and_update( 945 srcTable.data(), srcTable.size(), destTable.data(), &destLength, 946 stringEntry2.data(), stringEntry2.size()); 947 EXPECT_EQ(rc, PLDM_SUCCESS); 948 EXPECT_EQ(destLength, expectTable.size()); 949 destTable.resize(destLength); 950 EXPECT_THAT(destTable, ElementsAreArray(expectTable)); 951 952 std::vector<uint8_t> stringEntry3{ 953 1, 0, /* attr handle */ 954 1, /* attr type */ 955 1, 0, /* current string length */ 956 'd', /* default value string handle index */ 957 }; 958 expectTable.resize(0); 959 buildTable(expectTable, enumEntry, stringEntry3, integerEntry); 960 destTable.resize(expectTable.size() + 10); 961 destLength = destTable.size(); 962 rc = pldm_bios_table_attr_value_copy_and_update( 963 srcTable.data(), srcTable.size(), destTable.data(), &destLength, 964 stringEntry3.data(), stringEntry3.size()); 965 EXPECT_EQ(rc, PLDM_SUCCESS); 966 EXPECT_EQ(destLength, expectTable.size()); 967 destTable.resize(destLength); 968 EXPECT_THAT(destTable, ElementsAreArray(expectTable)); 969 970 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer 971 rc = pldm_bios_table_attr_value_copy_and_update( 972 srcTable.data(), srcTable.size(), destTable.data(), &destLength, 973 stringEntry3.data(), stringEntry3.size()); 974 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 975 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string 976 977 destTable.resize(expectTable.size() - 1); 978 destLength = destTable.size(); 979 rc = pldm_bios_table_attr_value_copy_and_update( 980 srcTable.data(), srcTable.size(), destTable.data(), &destLength, 981 stringEntry3.data(), stringEntry3.size()); 982 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 983 } 984 985 TEST(StringTable, EntryEncodeTest) 986 { 987 std::vector<uint8_t> stringEntry{ 988 0, 0, /* string handle*/ 989 7, 0, /* string length */ 990 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */ 991 }; 992 993 const char* str = "Allowed"; 994 auto str_length = std::strlen(str); 995 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length); 996 EXPECT_EQ(encodeLength, stringEntry.size()); 997 998 std::vector<uint8_t> encodeEntry(encodeLength, 0); 999 ASSERT_EQ(pldm_bios_table_string_entry_encode( 1000 encodeEntry.data(), encodeEntry.size(), str, str_length), 1001 PLDM_SUCCESS); 1002 // set string handle = 0 1003 encodeEntry[0] = 0; 1004 encodeEntry[1] = 0; 1005 1006 EXPECT_EQ(stringEntry, encodeEntry); 1007 1008 EXPECT_NE(pldm_bios_table_string_entry_encode( 1009 encodeEntry.data(), encodeEntry.size() - 1, str, str_length), 1010 PLDM_SUCCESS); 1011 auto rc = pldm_bios_table_string_entry_encode( 1012 encodeEntry.data(), encodeEntry.size() - 1, str, str_length); 1013 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 1014 } 1015 1016 TEST(StringTable, EntryDecodeTest) 1017 { 1018 std::vector<uint8_t> stringEntry{ 1019 4, 0, /* string handle*/ 1020 7, 0, /* string length */ 1021 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */ 1022 }; 1023 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>( 1024 stringEntry.data()); 1025 auto handle = pldm_bios_table_string_entry_decode_handle(entry); 1026 EXPECT_EQ(handle, 4); 1027 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry); 1028 EXPECT_EQ(strLength, 7); 1029 1030 std::vector<char> buffer(strLength + 1, 0); 1031 pldm_bios_table_string_entry_decode_string(entry, buffer.data(), 1032 buffer.size()); 1033 EXPECT_EQ(strlen(buffer.data()), strLength); 1034 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0); 1035 EXPECT_EQ(pldm_bios_table_string_entry_decode_string( 1036 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/), 1037 PLDM_SUCCESS); 1038 EXPECT_EQ(strlen(buffer.data()), 2); 1039 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0); 1040 1041 auto rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(), 1042 buffer.size()); 1043 EXPECT_EQ(rc, PLDM_SUCCESS); 1044 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0); 1045 1046 /* Ensure equivalence with the unchecked API */ 1047 rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(), 1048 2 + 1 /* sizeof '\0' */); 1049 EXPECT_EQ(rc, std::strcmp("Al", buffer.data())); 1050 } 1051 1052 TEST(StringTable, IteratorTest) 1053 { 1054 std::vector<uint8_t> stringHello{ 1055 0, 0, /* string handle*/ 1056 5, 0, /* string length */ 1057 'H', 'e', 'l', 'l', 'o', /* string */ 1058 }; 1059 std::vector<uint8_t> stringWorld{ 1060 1, 0, /* string handle*/ 1061 6, 0, /* string length */ 1062 'W', 'o', 'r', 'l', 'd', '!', /* string */ 1063 }; 1064 1065 Table table; 1066 buildTable(table, stringHello, stringWorld); 1067 1068 auto iter = pldm_bios_table_iter_create(table.data(), table.size(), 1069 PLDM_BIOS_STRING_TABLE); 1070 auto entry = pldm_bios_table_iter_string_entry_value(iter); 1071 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size()); 1072 EXPECT_EQ(rc, 0); 1073 pldm_bios_table_iter_next(iter); 1074 entry = pldm_bios_table_iter_string_entry_value(iter); 1075 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size()); 1076 EXPECT_EQ(rc, 0); 1077 pldm_bios_table_iter_next(iter); 1078 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter)); 1079 pldm_bios_table_iter_free(iter); 1080 } 1081 1082 TEST(StringTable, FindTest) 1083 { 1084 std::vector<uint8_t> stringHello{ 1085 1, 0, /* string handle*/ 1086 5, 0, /* string length */ 1087 'H', 'e', 'l', 'l', 'o', /* string */ 1088 }; 1089 std::vector<uint8_t> stringWorld{ 1090 2, 0, /* string handle*/ 1091 6, 0, /* string length */ 1092 'W', 'o', 'r', 'l', 'd', '!', /* string */ 1093 }; 1094 std::vector<uint8_t> stringHi{ 1095 3, 0, /* string handle*/ 1096 2, 0, /* string length */ 1097 'H', 'i', /* string */ 1098 }; 1099 1100 Table table; 1101 buildTable(table, stringHello, stringWorld, stringHi); 1102 1103 auto entry = pldm_bios_table_string_find_by_string(table.data(), 1104 table.size(), "World!"); 1105 EXPECT_NE(entry, nullptr); 1106 auto handle = pldm_bios_table_string_entry_decode_handle(entry); 1107 EXPECT_EQ(handle, 2); 1108 1109 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(), 1110 "Worl"); 1111 EXPECT_EQ(entry, nullptr); 1112 1113 entry = 1114 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3); 1115 EXPECT_NE(entry, nullptr); 1116 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry); 1117 EXPECT_EQ(str_length, 2); 1118 std::vector<char> strBuf(str_length + 1, 0); 1119 auto rc = pldm_bios_table_string_entry_decode_string(entry, strBuf.data(), 1120 strBuf.size()); 1121 EXPECT_EQ(rc, PLDM_SUCCESS); 1122 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0); 1123 1124 entry = 1125 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4); 1126 EXPECT_EQ(entry, nullptr); 1127 } 1128 1129 TEST(Iterator, DeathTest) 1130 { 1131 1132 Table table(256, 0); 1133 1134 /* first entry */ 1135 auto attr_entry = 1136 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data()); 1137 auto iter = pldm_bios_table_iter_create(table.data(), table.size(), 1138 PLDM_BIOS_ATTR_TABLE); 1139 attr_entry->attr_type = PLDM_BIOS_PASSWORD; 1140 #ifndef NDEBUG 1141 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL"); 1142 #endif 1143 pldm_bios_table_iter_free(iter); 1144 } 1145 1146 TEST(PadAndChecksum, PadAndChecksum) 1147 { 1148 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0)); 1149 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1)); 1150 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2)); 1151 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3)); 1152 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4)); 1153 1154 // The table is borrowed from 1155 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38 1156 // refer to the commit message 1157 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66}; 1158 auto sizeWithoutPad = attrValTable.size(); 1159 attrValTable.resize(sizeWithoutPad + 1160 pldm_bios_table_pad_checksum_size(sizeWithoutPad)); 1161 ASSERT_EQ(pldm_bios_table_append_pad_checksum_check( 1162 attrValTable.data(), attrValTable.size(), &sizeWithoutPad), 1163 PLDM_SUCCESS); 1164 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 1165 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6}; 1166 EXPECT_EQ(attrValTable, expectedTable); 1167 } 1168 1169 TEST(BIOSTableChecksum, testBIOSTableChecksum) 1170 { 1171 std::vector<uint8_t> stringTable{ 1172 1, 0, /* string handle*/ 1173 5, 0, /* string length */ 1174 'T', 'a', 'b', 'l', 'e', /* string */ 1175 }; 1176 1177 buildTable(stringTable); 1178 1179 EXPECT_EQ(true, 1180 pldm_bios_table_checksum(stringTable.data(), stringTable.size())); 1181 } 1182