1 #include "common/utils.hpp" 2 #include "libpldmresponder/fru.hpp" 3 #include "libpldmresponder/fru_parser.hpp" 4 5 #include <config.h> 6 #include <libpldm/pdr.h> 7 8 #include <sdbusplus/message.hpp> 9 10 #include <gtest/gtest.h> 11 12 TEST(FruParser, allScenarios) 13 { 14 using namespace pldm::responder::fru_parser; 15 16 FruParser parser{"./fru_jsons/good", 17 "./fru_jsons/fru_master/fru_master.json"}; 18 19 // Get an item with a single PLDM FRU record 20 FruRecordInfos cpu{ 21 {1, 22 1, 23 {{"xyz.openbmc_project.Inventory.Decorator.Asset", "Model", "string", 24 2}, 25 {"xyz.openbmc_project.Inventory.Decorator.Asset", "PartNumber", 26 "string", 3}, 27 {"xyz.openbmc_project.Inventory.Decorator.Asset", "SerialNumber", 28 "string", 4}, 29 {"xyz.openbmc_project.Inventory.Decorator.Asset", "Manufacturer", 30 "string", 5}, 31 {"xyz.openbmc_project.Inventory.Item", "PrettyName", "string", 8}, 32 {"xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 33 "string", 11}, 34 {"xyz.openbmc_project.Inventory.Decorator.Revision", "Version", 35 "string", 10}}}, 36 {1, 37 1, 38 {{"xyz.openbmc_project.Inventory.Decorator.Asset", "PartNumber", 39 "string", 3}, 40 {"xyz.openbmc_project.Inventory.Decorator.Asset", "SerialNumber", 41 "string", 4}}}}; 42 auto cpuInfos = 43 parser.getRecordInfo("xyz.openbmc_project.Inventory.Item.Cpu"); 44 ASSERT_EQ(cpuInfos.size(), 2); 45 ASSERT_EQ(cpu == cpuInfos, true); 46 47 // Get an item type with 3 PLDM FRU records 48 auto boardInfos = 49 parser.getRecordInfo("xyz.openbmc_project.Inventory.Item.Board"); 50 ASSERT_EQ(boardInfos.size(), 3); 51 52 // D-Bus lookup info for FRU information 53 DBusLookupInfo lookupInfo{ 54 "xyz.openbmc_project.Inventory.Manager", 55 "/xyz/openbmc_project/inventory", 56 {"xyz.openbmc_project.Inventory.Item.Chassis", 57 "xyz.openbmc_project.Inventory.Item.Board", 58 "xyz.openbmc_project.Inventory.Item.PCIeDevice", 59 "xyz.openbmc_project.Inventory.Item.Board.Motherboard", 60 "xyz.openbmc_project.Inventory.Item.Dimm", 61 "xyz.openbmc_project.Inventory.Item.Panel", 62 "xyz.openbmc_project.Inventory.Item.DiskBackplane", 63 "xyz.openbmc_project.Inventory.Item.Fan", 64 "xyz.openbmc_project.Inventory.Item.PowerSupply", 65 "xyz.openbmc_project.Inventory.Item.Battery", 66 "xyz.openbmc_project.Inventory.Item.Vrm", 67 "xyz.openbmc_project.Inventory.Item.Cpu", 68 "xyz.openbmc_project.Inventory.Item.Bmc", 69 "xyz.openbmc_project.Inventory.Item.Connector", 70 "xyz.openbmc_project.Inventory.Item.PCIeSlot", 71 "xyz.openbmc_project.Inventory.Item.System", 72 "xyz.openbmc_project.Inventory.Item.Tpm"}}; 73 auto dbusInfo = parser.inventoryLookup(); 74 ASSERT_EQ(dbusInfo == lookupInfo, true); 75 76 ASSERT_THROW( 77 parser.getRecordInfo("xyz.openbmc_project.Inventory.Item.DIMM"), 78 std::exception); 79 } 80 81 TEST(FruImpl, updateAssociationTreeTest) 82 { 83 using namespace pldm::responder; 84 using namespace pldm::responder::fru_parser; 85 using namespace pldm::responder::dbus; 86 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> pdrRepo( 87 pldm_pdr_init(), pldm_pdr_destroy); 88 std::unique_ptr<pldm_entity_association_tree, 89 decltype(&pldm_entity_association_tree_destroy)> 90 entityTree(pldm_entity_association_tree_init(), 91 pldm_entity_association_tree_destroy); 92 std::unique_ptr<pldm_entity_association_tree, 93 decltype(&pldm_entity_association_tree_destroy)> 94 bmcEntityTree(pldm_entity_association_tree_init(), 95 pldm_entity_association_tree_destroy); 96 97 ObjectValueTree objects{ 98 {sdbusplus::message::object_path( 99 "/xyz/openbmc_project/inventory/system"), 100 {{"xyz.openbmc_project.Inventory.Item.System", {}}}}, 101 {sdbusplus::message::object_path( 102 "/xyz/openbmc_project/inventory/system/chassis"), 103 {{"xyz.openbmc_project.Inventory.Item.Chassis", {}}}}, 104 {sdbusplus::message::object_path( 105 "/xyz/openbmc_project/inventory/system/chassis/motherboard"), 106 {{"xyz.openbmc_project.Inventory.Item.Board.Motherboard", {}}}}}; 107 108 typedef struct test_pldm_entity_node 109 { 110 pldm_entity entity; 111 pldm_entity parent; 112 uint16_t host_container_id; 113 pldm_entity_node* first_child; 114 pldm_entity_node* next_sibling; 115 uint8_t association_type; 116 } test_pldm_entity_node; 117 118 pldm::responder::FruImpl mockedFruHandler( 119 FRU_JSONS_DIR, "./fru_jsons/fru_master/fru_master.json", pdrRepo.get(), 120 entityTree.get(), bmcEntityTree.get()); 121 122 pldm_entity systemEntity{0x2d01, 1, 0}; 123 pldm_entity chassisEntity{0x2d, 1, 1}; 124 pldm_entity motherboardEntity{0x40, 1, 2}; 125 pldm_entity panelEntity{0x45, 1, 3}; 126 127 dbus::InterfaceMap systemIface{ 128 {"xyz.openbmc_project.Inventory.Item.System", {}}}; 129 dbus::InterfaceMap chassisIface{ 130 {"xyz.openbmc_project.Inventory.Item.Chassis", {}}}; 131 dbus::InterfaceMap motherboardIface{ 132 {"xyz.openbmc_project.Inventory.Item.Board.Motherboard", {}}}; 133 134 mockedFruHandler.updateAssociationTree( 135 objects, "/xyz/openbmc_project/inventory/system/chassis/motherboard"); 136 137 pldm_entity_node* node = pldm_entity_association_tree_find(entityTree.get(), 138 &systemEntity); 139 EXPECT_TRUE(node != NULL); 140 141 node = pldm_entity_association_tree_find(entityTree.get(), &chassisEntity); 142 ASSERT_TRUE(node != NULL); 143 test_pldm_entity_node* test_node = (test_pldm_entity_node*)node; 144 EXPECT_TRUE((test_node->parent).entity_type == systemEntity.entity_type); 145 146 node = pldm_entity_association_tree_find(entityTree.get(), 147 &motherboardEntity); 148 ASSERT_TRUE(node != NULL); 149 test_node = (test_pldm_entity_node*)node; 150 EXPECT_TRUE((test_node->parent).entity_type == chassisEntity.entity_type); 151 152 node = pldm_entity_association_tree_find(entityTree.get(), &panelEntity); 153 EXPECT_TRUE(node == NULL); 154 } 155 156 TEST(FruImpl, entityByObjectPath) 157 { 158 using namespace pldm::responder::dbus; 159 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> pdrRepo( 160 pldm_pdr_init(), pldm_pdr_destroy); 161 std::unique_ptr<pldm_entity_association_tree, 162 decltype(&pldm_entity_association_tree_destroy)> 163 entityTree(pldm_entity_association_tree_init(), 164 pldm_entity_association_tree_destroy); 165 std::unique_ptr<pldm_entity_association_tree, 166 decltype(&pldm_entity_association_tree_destroy)> 167 bmcEntityTree(pldm_entity_association_tree_init(), 168 pldm_entity_association_tree_destroy); 169 170 InterfaceMap iface = {{"xyz.openbmc_project.Inventory.Item.Chassis", {}}}; 171 pldm::responder::FruImpl mockedFruHandler( 172 FRU_JSONS_DIR, "./fru_jsons/fru_master/fru_master.json", pdrRepo.get(), 173 entityTree.get(), bmcEntityTree.get()); 174 175 // Good path 176 auto entityPtr = mockedFruHandler.getEntityByObjectPath(iface); 177 pldm_entity entity = *entityPtr; 178 EXPECT_TRUE(entity.entity_type == 45); 179 // Bad Path 180 InterfaceMap invalidIface = { 181 {"xyz.openbmc_project.Inventory.Item.Motherboard", {}}}; 182 entityPtr = mockedFruHandler.getEntityByObjectPath(invalidIface); 183 ASSERT_TRUE(!entityPtr); 184 } 185