15327988eSTom Joseph #include "common/bios_utils.hpp"
25327988eSTom Joseph #include "common/test/mocked_utils.hpp"
35327988eSTom Joseph #include "libpldmresponder/bios_config.hpp"
45327988eSTom Joseph #include "libpldmresponder/bios_string_attribute.hpp"
511ce8d22SSagar Srinivas #include "libpldmresponder/oem_handler.hpp"
63c50c82aSKamalkumar Patel #include "libpldmresponder/platform_config.hpp"
75327988eSTom Joseph #include "mocked_bios.hpp"
85327988eSTom Joseph
95327988eSTom Joseph #include <nlohmann/json.hpp>
105327988eSTom Joseph
115327988eSTom Joseph #include <fstream>
125327988eSTom Joseph #include <memory>
135327988eSTom Joseph
145327988eSTom Joseph #include <gmock/gmock.h>
155327988eSTom Joseph #include <gtest/gtest.h>
165327988eSTom Joseph
175327988eSTom Joseph using namespace pldm::bios::utils;
185079ac4aSBrad Bishop using namespace pldm::responder::bios;
195079ac4aSBrad Bishop using namespace pldm::utils;
205327988eSTom Joseph
215327988eSTom Joseph using ::testing::_;
225327988eSTom Joseph using ::testing::ElementsAreArray;
2311ce8d22SSagar Srinivas using ::testing::Return;
2411ce8d22SSagar Srinivas using ::testing::StrEq;
255327988eSTom Joseph using ::testing::Throw;
265327988eSTom Joseph
275327988eSTom Joseph class TestBIOSConfig : public ::testing::Test
285327988eSTom Joseph {
295327988eSTom Joseph public:
SetUpTestCase()302576aecdSManojkiran Eda static void SetUpTestCase() // will execute once at the beginning of all
315327988eSTom Joseph // TestBIOSConfig objects
325327988eSTom Joseph {
335327988eSTom Joseph char tmpdir[] = "/tmp/BIOSTables.XXXXXX";
345327988eSTom Joseph tableDir = fs::path(mkdtemp(tmpdir));
355327988eSTom Joseph
36ac713eecSArchana Kakani std::vector<fs::path> paths = {"./bios_jsons/bios_attrs.json"};
375327988eSTom Joseph
3815b94111SPavithra Barithaya for (const auto& path : paths)
395327988eSTom Joseph {
405327988eSTom Joseph std::ifstream file;
415327988eSTom Joseph file.open(path);
425327988eSTom Joseph auto j = Json::parse(file);
435327988eSTom Joseph jsons.emplace_back(j);
445327988eSTom Joseph }
455327988eSTom Joseph }
465327988eSTom Joseph
findJsonEntry(const std::string & name)475327988eSTom Joseph std::optional<Json> findJsonEntry(const std::string& name)
485327988eSTom Joseph {
495327988eSTom Joseph for (auto& json : jsons)
505327988eSTom Joseph {
515327988eSTom Joseph auto entries = json.at("entries");
525327988eSTom Joseph for (auto& entry : entries)
535327988eSTom Joseph {
545327988eSTom Joseph auto n = entry.at("attribute_name").get<std::string>();
555327988eSTom Joseph if (n == name)
565327988eSTom Joseph {
575327988eSTom Joseph return entry;
585327988eSTom Joseph }
595327988eSTom Joseph }
605327988eSTom Joseph }
615327988eSTom Joseph return std::nullopt;
625327988eSTom Joseph }
635327988eSTom Joseph
TearDownTestCase()645327988eSTom Joseph static void TearDownTestCase() // will be executed once at th end of all
655327988eSTom Joseph // TestBIOSConfig objects
665327988eSTom Joseph {
675327988eSTom Joseph fs::remove_all(tableDir);
685327988eSTom Joseph }
695327988eSTom Joseph
705327988eSTom Joseph static fs::path tableDir;
715327988eSTom Joseph static std::vector<Json> jsons;
725327988eSTom Joseph };
735327988eSTom Joseph
745327988eSTom Joseph fs::path TestBIOSConfig::tableDir;
755327988eSTom Joseph std::vector<Json> TestBIOSConfig::jsons;
765327988eSTom Joseph
773c50c82aSKamalkumar Patel class MockSystemConfig : public pldm::responder::platform_config::Handler
7811ce8d22SSagar Srinivas {
7911ce8d22SSagar Srinivas public:
MockSystemConfig()803c50c82aSKamalkumar Patel MockSystemConfig() {}
8198e703f0SPatrick Williams MOCK_METHOD(void, ibmCompatibleAddedCallback, (sdbusplus::message_t&), ());
823c50c82aSKamalkumar Patel MOCK_METHOD(std::optional<std::filesystem::path>, getPlatformName, ());
8311ce8d22SSagar Srinivas };
8411ce8d22SSagar Srinivas
TEST_F(TestBIOSConfig,buildTablesTest)855327988eSTom Joseph TEST_F(TestBIOSConfig, buildTablesTest)
865327988eSTom Joseph {
875327988eSTom Joseph MockdBusHandler dbusHandler;
883c50c82aSKamalkumar Patel MockSystemConfig mockSystemConfig;
8946f352edSArchana Kakani std::string biosFilePath("./bios_jsons");
905327988eSTom Joseph
9146f352edSArchana Kakani BIOSConfig biosConfig(biosFilePath.c_str(), tableDir.c_str(), &dbusHandler,
9246f352edSArchana Kakani 0, 0, nullptr, nullptr, &mockSystemConfig, []() {});
935327988eSTom Joseph auto stringTable = biosConfig.getBIOSTable(PLDM_BIOS_STRING_TABLE);
945327988eSTom Joseph auto attrTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_TABLE);
955327988eSTom Joseph auto attrValueTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
965327988eSTom Joseph
975327988eSTom Joseph EXPECT_TRUE(stringTable);
985327988eSTom Joseph EXPECT_TRUE(attrTable);
995327988eSTom Joseph EXPECT_TRUE(attrValueTable);
1005327988eSTom Joseph
101*16c2a0a0SPatrick Williams std::set<std::string> expectedStrings = {
102*16c2a0a0SPatrick Williams "HMCManagedState",
1035327988eSTom Joseph "On",
1045327988eSTom Joseph "Off",
1055327988eSTom Joseph "FWBootSide",
1065327988eSTom Joseph "Perm",
1075327988eSTom Joseph "Temp",
1085327988eSTom Joseph "InbandCodeUpdate",
1095327988eSTom Joseph "Allowed",
11011ce8d22SSagar Srinivas "Allowed",
1115327988eSTom Joseph "NotAllowed",
1125327988eSTom Joseph "CodeUpdatePolicy",
1135327988eSTom Joseph "Concurrent",
1145327988eSTom Joseph "Disruptive",
1155327988eSTom Joseph "VDD_AVSBUS_RAIL",
1165327988eSTom Joseph "SBE_IMAGE_MINIMUM_VALID_ECS",
1175327988eSTom Joseph "INTEGER_INVALID_CASE",
1185327988eSTom Joseph "str_example1",
1195327988eSTom Joseph "str_example2",
1205327988eSTom Joseph "str_example3"};
1215327988eSTom Joseph std::set<std::string> strings;
1225327988eSTom Joseph for (auto entry : BIOSTableIter<PLDM_BIOS_STRING_TABLE>(
1235327988eSTom Joseph stringTable->data(), stringTable->size()))
1245327988eSTom Joseph {
1255327988eSTom Joseph auto str = table::string::decodeString(entry);
1265327988eSTom Joseph strings.emplace(str);
1275327988eSTom Joseph }
1285327988eSTom Joseph
1295327988eSTom Joseph EXPECT_EQ(strings, expectedStrings);
1305327988eSTom Joseph
1315327988eSTom Joseph BIOSStringTable biosStringTable(*stringTable);
1325327988eSTom Joseph
1335327988eSTom Joseph for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable->data(),
1345327988eSTom Joseph attrTable->size()))
1355327988eSTom Joseph {
1365327988eSTom Joseph auto header = table::attribute::decodeHeader(entry);
1375327988eSTom Joseph auto attrName = biosStringTable.findString(header.stringHandle);
1385327988eSTom Joseph auto jsonEntry = findJsonEntry(attrName);
1395327988eSTom Joseph EXPECT_TRUE(jsonEntry);
1405327988eSTom Joseph switch (header.attrType)
1415327988eSTom Joseph {
1425327988eSTom Joseph case PLDM_BIOS_STRING:
1435327988eSTom Joseph case PLDM_BIOS_STRING_READ_ONLY:
1445327988eSTom Joseph {
1455327988eSTom Joseph auto stringField = table::attribute::decodeStringEntry(entry);
1465327988eSTom Joseph auto stringType = BIOSStringAttribute::strTypeMap.at(
1475327988eSTom Joseph jsonEntry->at("string_type").get<std::string>());
1485327988eSTom Joseph EXPECT_EQ(stringField.stringType,
1495327988eSTom Joseph static_cast<uint8_t>(stringType));
1505327988eSTom Joseph
1515327988eSTom Joseph EXPECT_EQ(
1525327988eSTom Joseph stringField.minLength,
1535327988eSTom Joseph jsonEntry->at("minimum_string_length").get<uint16_t>());
1545327988eSTom Joseph EXPECT_EQ(
1555327988eSTom Joseph stringField.maxLength,
1565327988eSTom Joseph jsonEntry->at("maximum_string_length").get<uint16_t>());
1575327988eSTom Joseph EXPECT_EQ(stringField.defString,
1585327988eSTom Joseph jsonEntry->at("default_string").get<std::string>());
1597d47570cSArchana Kakani EXPECT_EQ(stringField.defLength,
1607d47570cSArchana Kakani (stringField.defString).length());
1615327988eSTom Joseph break;
1625327988eSTom Joseph }
1635327988eSTom Joseph case PLDM_BIOS_INTEGER:
1645327988eSTom Joseph case PLDM_BIOS_INTEGER_READ_ONLY:
1655327988eSTom Joseph {
1665327988eSTom Joseph auto integerField = table::attribute::decodeIntegerEntry(entry);
1675327988eSTom Joseph EXPECT_EQ(integerField.lowerBound,
1685327988eSTom Joseph jsonEntry->at("lower_bound").get<uint64_t>());
1695327988eSTom Joseph EXPECT_EQ(integerField.upperBound,
1705327988eSTom Joseph jsonEntry->at("upper_bound").get<uint64_t>());
1715327988eSTom Joseph EXPECT_EQ(integerField.scalarIncrement,
1725327988eSTom Joseph jsonEntry->at("scalar_increment").get<uint32_t>());
1735327988eSTom Joseph EXPECT_EQ(integerField.defaultValue,
1745327988eSTom Joseph jsonEntry->at("default_value").get<uint64_t>());
1755327988eSTom Joseph break;
1765327988eSTom Joseph }
1775327988eSTom Joseph case PLDM_BIOS_ENUMERATION:
1785327988eSTom Joseph case PLDM_BIOS_ENUMERATION_READ_ONLY:
1795327988eSTom Joseph {
1806da4f91bSPatrick Williams auto [pvHdls,
1816da4f91bSPatrick Williams defInds] = table::attribute::decodeEnumEntry(entry);
1825327988eSTom Joseph auto possibleValues = jsonEntry->at("possible_values")
1835327988eSTom Joseph .get<std::vector<std::string>>();
1845327988eSTom Joseph std::vector<std::string> strings;
1855327988eSTom Joseph for (auto pv : pvHdls)
1865327988eSTom Joseph {
1875327988eSTom Joseph auto s = biosStringTable.findString(pv);
1885327988eSTom Joseph strings.emplace_back(s);
1895327988eSTom Joseph }
1905327988eSTom Joseph EXPECT_EQ(strings, possibleValues);
1915327988eSTom Joseph EXPECT_EQ(defInds.size(), 1);
1925327988eSTom Joseph
1935327988eSTom Joseph auto defValue = biosStringTable.findString(pvHdls[defInds[0]]);
1945327988eSTom Joseph auto defaultValues = jsonEntry->at("default_values")
1955327988eSTom Joseph .get<std::vector<std::string>>();
1965327988eSTom Joseph EXPECT_EQ(defValue, defaultValues[0]);
1975327988eSTom Joseph
1985327988eSTom Joseph break;
1995327988eSTom Joseph }
2005327988eSTom Joseph default:
2015327988eSTom Joseph EXPECT_TRUE(false);
2025327988eSTom Joseph break;
2035327988eSTom Joseph }
2045327988eSTom Joseph }
2055327988eSTom Joseph
2065327988eSTom Joseph for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
2075327988eSTom Joseph attrValueTable->data(), attrValueTable->size()))
2085327988eSTom Joseph {
2095327988eSTom Joseph auto header = table::attribute_value::decodeHeader(entry);
210*16c2a0a0SPatrick Williams auto attrEntry =
211*16c2a0a0SPatrick Williams table::attribute::findByHandle(*attrTable, header.attrHandle);
2125327988eSTom Joseph auto attrHeader = table::attribute::decodeHeader(attrEntry);
2135327988eSTom Joseph auto attrName = biosStringTable.findString(attrHeader.stringHandle);
2145327988eSTom Joseph auto jsonEntry = findJsonEntry(attrName);
2155327988eSTom Joseph EXPECT_TRUE(jsonEntry);
2165327988eSTom Joseph switch (header.attrType)
2175327988eSTom Joseph {
2185327988eSTom Joseph case PLDM_BIOS_STRING:
2195327988eSTom Joseph case PLDM_BIOS_STRING_READ_ONLY:
2205327988eSTom Joseph {
2215327988eSTom Joseph auto value = table::attribute_value::decodeStringEntry(entry);
2225327988eSTom Joseph auto defValue =
2235327988eSTom Joseph jsonEntry->at("default_string").get<std::string>();
2245327988eSTom Joseph EXPECT_EQ(value, defValue);
2255327988eSTom Joseph break;
2265327988eSTom Joseph }
2275327988eSTom Joseph case PLDM_BIOS_INTEGER:
2285327988eSTom Joseph case PLDM_BIOS_INTEGER_READ_ONLY:
2295327988eSTom Joseph {
2305327988eSTom Joseph auto value = table::attribute_value::decodeIntegerEntry(entry);
2315327988eSTom Joseph auto defValue = jsonEntry->at("default_value").get<uint64_t>();
2325327988eSTom Joseph EXPECT_EQ(value, defValue);
2335327988eSTom Joseph break;
2345327988eSTom Joseph }
2355327988eSTom Joseph case PLDM_BIOS_ENUMERATION:
2365327988eSTom Joseph case PLDM_BIOS_ENUMERATION_READ_ONLY:
2375327988eSTom Joseph {
2385327988eSTom Joseph auto indices = table::attribute_value::decodeEnumEntry(entry);
2395327988eSTom Joseph EXPECT_EQ(indices.size(), 1);
2405327988eSTom Joseph auto possibleValues = jsonEntry->at("possible_values")
2415327988eSTom Joseph .get<std::vector<std::string>>();
2425327988eSTom Joseph
2435327988eSTom Joseph auto defValues = jsonEntry->at("default_values")
2445327988eSTom Joseph .get<std::vector<std::string>>();
2455327988eSTom Joseph EXPECT_EQ(possibleValues[indices[0]], defValues[0]);
2465327988eSTom Joseph break;
2475327988eSTom Joseph }
2485327988eSTom Joseph default:
2495327988eSTom Joseph EXPECT_TRUE(false);
2505327988eSTom Joseph break;
2515327988eSTom Joseph }
2525327988eSTom Joseph }
2535327988eSTom Joseph }
2545327988eSTom Joseph
TEST_F(TestBIOSConfig,setBIOSTable)25562dd8ff2SArchana Kakani TEST_F(TestBIOSConfig, setBIOSTable)
25662dd8ff2SArchana Kakani {
25762dd8ff2SArchana Kakani MockdBusHandler dbusHandler;
25862dd8ff2SArchana Kakani MockSystemConfig mockSystemConfig;
25962dd8ff2SArchana Kakani
26062dd8ff2SArchana Kakani BIOSConfig biosConfig("./", tableDir.c_str(), &dbusHandler, 0, 0, nullptr,
26162dd8ff2SArchana Kakani nullptr, &mockSystemConfig, []() {});
26262dd8ff2SArchana Kakani
26362dd8ff2SArchana Kakani std::set<std::string> strings{"pvm_system_name", "pvm_stop_at_standby",
26462dd8ff2SArchana Kakani "fw_boot_side", "fw_next_boot_side"};
26562dd8ff2SArchana Kakani
26662dd8ff2SArchana Kakani Table table;
26762dd8ff2SArchana Kakani for (const auto& elem : strings)
26862dd8ff2SArchana Kakani {
26962dd8ff2SArchana Kakani table::string::constructEntry(table, elem);
27062dd8ff2SArchana Kakani }
27162dd8ff2SArchana Kakani
27262dd8ff2SArchana Kakani table::appendPadAndChecksum(table);
27362dd8ff2SArchana Kakani auto rc = biosConfig.setBIOSTable(PLDM_BIOS_STRING_TABLE, table);
27462dd8ff2SArchana Kakani EXPECT_EQ(rc, PLDM_SUCCESS);
27562dd8ff2SArchana Kakani
27662dd8ff2SArchana Kakani auto stringTable = biosConfig.getBIOSTable(PLDM_BIOS_STRING_TABLE);
27762dd8ff2SArchana Kakani EXPECT_TRUE(stringTable);
27862dd8ff2SArchana Kakani }
27962dd8ff2SArchana Kakani
TEST_F(TestBIOSConfig,getBIOSTableFailure)28062dd8ff2SArchana Kakani TEST_F(TestBIOSConfig, getBIOSTableFailure)
28162dd8ff2SArchana Kakani {
28262dd8ff2SArchana Kakani MockdBusHandler dbusHandler;
28362dd8ff2SArchana Kakani MockSystemConfig mockSystemConfig;
28462dd8ff2SArchana Kakani
28546f352edSArchana Kakani BIOSConfig biosConfig("./jsons", tableDir.c_str(), &dbusHandler, 0, 0,
28646f352edSArchana Kakani nullptr, nullptr, &mockSystemConfig, []() {});
28762dd8ff2SArchana Kakani
28862dd8ff2SArchana Kakani auto stringTable = biosConfig.getBIOSTable(PLDM_BIOS_STRING_TABLE);
28962dd8ff2SArchana Kakani auto attrTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_TABLE);
29062dd8ff2SArchana Kakani auto attrValueTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
29162dd8ff2SArchana Kakani
29262dd8ff2SArchana Kakani EXPECT_FALSE(stringTable);
29362dd8ff2SArchana Kakani EXPECT_FALSE(attrTable);
29462dd8ff2SArchana Kakani EXPECT_FALSE(attrValueTable);
29562dd8ff2SArchana Kakani }
29662dd8ff2SArchana Kakani
TEST_F(TestBIOSConfig,setAttrValueFailure)29762dd8ff2SArchana Kakani TEST_F(TestBIOSConfig, setAttrValueFailure)
29862dd8ff2SArchana Kakani {
29962dd8ff2SArchana Kakani MockdBusHandler dbusHandler;
30062dd8ff2SArchana Kakani MockSystemConfig mockSystemConfig;
30162dd8ff2SArchana Kakani
30246f352edSArchana Kakani BIOSConfig biosConfig("./jsons", tableDir.c_str(), &dbusHandler, 0, 0,
30346f352edSArchana Kakani nullptr, nullptr, &mockSystemConfig, []() {});
30462dd8ff2SArchana Kakani
30562dd8ff2SArchana Kakani std::vector<uint8_t> attrValueEntry{
30662dd8ff2SArchana Kakani 0, 0, /* attr handle */
30762dd8ff2SArchana Kakani 1, /* attr type string read-write */
30862dd8ff2SArchana Kakani 4, 0, /* current string length */
3092576aecdSManojkiran Eda 'a', 'b', 'c', 'd', /* default value string handle index */
31062dd8ff2SArchana Kakani };
31162dd8ff2SArchana Kakani
31262dd8ff2SArchana Kakani uint16_t attrHandle{10};
31362dd8ff2SArchana Kakani attrValueEntry[0] = attrHandle & 0xff;
31462dd8ff2SArchana Kakani attrValueEntry[1] = (attrHandle >> 8) & 0xff;
31562dd8ff2SArchana Kakani
31662dd8ff2SArchana Kakani auto rc = biosConfig.setAttrValue(attrValueEntry.data(),
31762dd8ff2SArchana Kakani attrValueEntry.size(), false);
31862dd8ff2SArchana Kakani EXPECT_EQ(rc, PLDM_BIOS_TABLE_UNAVAILABLE);
31962dd8ff2SArchana Kakani }
32062dd8ff2SArchana Kakani
TEST_F(TestBIOSConfig,setAttrValue)3215327988eSTom Joseph TEST_F(TestBIOSConfig, setAttrValue)
3225327988eSTom Joseph {
3235327988eSTom Joseph MockdBusHandler dbusHandler;
3243c50c82aSKamalkumar Patel MockSystemConfig mockSystemConfig;
3255327988eSTom Joseph
3265327988eSTom Joseph BIOSConfig biosConfig("./bios_jsons", tableDir.c_str(), &dbusHandler, 0, 0,
32762dd8ff2SArchana Kakani nullptr, nullptr, &mockSystemConfig, []() {});
3285327988eSTom Joseph
3295327988eSTom Joseph auto stringTable = biosConfig.getBIOSTable(PLDM_BIOS_STRING_TABLE);
3305327988eSTom Joseph auto attrTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_TABLE);
3315327988eSTom Joseph
3325327988eSTom Joseph BIOSStringTable biosStringTable(*stringTable);
3335327988eSTom Joseph BIOSTableIter<PLDM_BIOS_ATTR_TABLE> attrTableIter(attrTable->data(),
3345327988eSTom Joseph attrTable->size());
3355327988eSTom Joseph auto stringHandle = biosStringTable.findHandle("str_example1");
3365327988eSTom Joseph uint16_t attrHandle{};
3375327988eSTom Joseph
3385327988eSTom Joseph for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable->data(),
3395327988eSTom Joseph attrTable->size()))
3405327988eSTom Joseph {
3415327988eSTom Joseph auto header = table::attribute::decodeHeader(entry);
3425327988eSTom Joseph if (header.stringHandle == stringHandle)
3435327988eSTom Joseph {
3445327988eSTom Joseph attrHandle = header.attrHandle;
3455327988eSTom Joseph break;
3465327988eSTom Joseph }
3475327988eSTom Joseph }
3485327988eSTom Joseph
3495327988eSTom Joseph EXPECT_NE(attrHandle, 0);
3505327988eSTom Joseph
3515327988eSTom Joseph std::vector<uint8_t> attrValueEntry{
3525327988eSTom Joseph 0, 0, /* attr handle */
3535327988eSTom Joseph 1, /* attr type string read-write */
3545327988eSTom Joseph 4, 0, /* current string length */
3552576aecdSManojkiran Eda 'a', 'b', 'c', 'd', /* default value string handle index */
3565327988eSTom Joseph };
3575327988eSTom Joseph
3585327988eSTom Joseph attrValueEntry[0] = attrHandle & 0xff;
3595327988eSTom Joseph attrValueEntry[1] = (attrHandle >> 8) & 0xff;
3605327988eSTom Joseph
3615327988eSTom Joseph DBusMapping dbusMapping{"/xyz/abc/def",
3625327988eSTom Joseph "xyz.openbmc_project.str_example1.value",
3635327988eSTom Joseph "Str_example1", "string"};
3645327988eSTom Joseph PropertyValue value = std::string("abcd");
3655327988eSTom Joseph EXPECT_CALL(dbusHandler, setDbusProperty(dbusMapping, value)).Times(1);
3665327988eSTom Joseph
367cac0ebb2SSagar Srinivas auto rc = biosConfig.setAttrValue(attrValueEntry.data(),
368cac0ebb2SSagar Srinivas attrValueEntry.size(), false);
3695327988eSTom Joseph EXPECT_EQ(rc, PLDM_SUCCESS);
3705327988eSTom Joseph
3715327988eSTom Joseph auto attrValueTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
372*16c2a0a0SPatrick Williams auto findEntry = [&attrValueTable](uint16_t handle)
373*16c2a0a0SPatrick Williams -> const pldm_bios_attr_val_table_entry* {
3745327988eSTom Joseph for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
3755327988eSTom Joseph attrValueTable->data(), attrValueTable->size()))
3765327988eSTom Joseph {
3775327988eSTom Joseph auto [attrHandle, _] = table::attribute_value::decodeHeader(entry);
3785327988eSTom Joseph if (attrHandle == handle)
3795327988eSTom Joseph return entry;
3805327988eSTom Joseph }
3815327988eSTom Joseph return nullptr;
3825327988eSTom Joseph };
3835327988eSTom Joseph
3845327988eSTom Joseph auto entry = findEntry(attrHandle);
3855327988eSTom Joseph EXPECT_NE(entry, nullptr);
3865327988eSTom Joseph
3875327988eSTom Joseph auto p = reinterpret_cast<const uint8_t*>(entry);
3885327988eSTom Joseph EXPECT_THAT(std::vector<uint8_t>(p, p + attrValueEntry.size()),
3895327988eSTom Joseph ElementsAreArray(attrValueEntry));
3905327988eSTom Joseph }
391