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
TEST(FruParser,allScenarios)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
TEST(FruImpl,updateAssociationTreeTest)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 =
138 pldm_entity_association_tree_find(entityTree.get(), &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 =
147 pldm_entity_association_tree_find(entityTree.get(), &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
TEST(FruImpl,entityByObjectPath)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