xref: /openbmc/pldm/oem/ibm/test/libpldmresponder_oem_platform_test.cpp (revision 7c1dc7ea0b3eec79518b6dcb9552256bfc1cec15)
1 #include "common/test/mocked_utils.hpp"
2 #include "common/utils.hpp"
3 #include "libpldmresponder/event_parser.hpp"
4 #include "libpldmresponder/pdr.hpp"
5 #include "libpldmresponder/pdr_utils.hpp"
6 #include "libpldmresponder/platform.hpp"
7 #include "oem/ibm/libpldmresponder/inband_code_update.hpp"
8 #include "oem/ibm/libpldmresponder/oem_ibm_handler.hpp"
9 #include "test/test_instance_id.hpp"
10 
11 #include <libpldm/entity.h>
12 #include <libpldm/entity_oem_ibm.h>
13 
14 #include <sdeventplus/event.hpp>
15 
16 #include <iostream>
17 
18 using namespace pldm::dbus_api;
19 using namespace pldm::utils;
20 using namespace pldm::responder;
21 using namespace pldm::responder::pdr;
22 using namespace pldm::responder::pdr_utils;
23 using namespace pldm::responder::oem_ibm_platform;
24 
25 class MockCodeUpdate : public CodeUpdate
26 {
27   public:
28     MockCodeUpdate(const pldm::utils::DBusHandler* dBusIntf) :
29         CodeUpdate(dBusIntf)
30     {}
31 
32     MOCK_METHOD(void, setVersions, (), (override));
33 };
34 
35 class MockOemPlatformHandler : public oem_ibm_platform::Handler
36 {
37   public:
38     MockOemPlatformHandler(const pldm::utils::DBusHandler* dBusIntf,
39                            pldm::responder::CodeUpdate* codeUpdate, int mctp_fd,
40                            uint8_t mctp_eid, Requester& requester,
41                            sdeventplus::Event& event) :
42         oem_ibm_platform::Handler(dBusIntf, codeUpdate, mctp_fd, mctp_eid,
43                                   requester, event, nullptr)
44     {}
45     MOCK_METHOD(uint16_t, getNextEffecterId, ());
46     MOCK_METHOD(uint16_t, getNextSensorId, ());
47 };
48 
49 TEST(OemSetStateEffecterStatesHandler, testGoodRequest)
50 {
51     uint16_t entityID_ = PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE;
52     uint16_t stateSetId_ = PLDM_OEM_IBM_BOOT_STATE;
53     uint16_t entityInstance_ = 0;
54     uint8_t compSensorCnt_ = 1;
55     uint16_t effecterId = 0xA;
56     TestInstanceIdDb instanceIdDb;
57 
58     sdbusplus::bus_t bus(sdbusplus::bus::new_default());
59     Requester requester(bus, "/abc/def", instanceIdDb);
60     auto event = sdeventplus::Event::get_default();
61     std::vector<get_sensor_state_field> stateField;
62 
63     auto mockDbusHandler = std::make_unique<MockdBusHandler>();
64     std::unique_ptr<CodeUpdate> mockCodeUpdate =
65         std::make_unique<MockCodeUpdate>(mockDbusHandler.get());
66     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
67 
68     oemPlatformHandler = std::make_unique<oem_ibm_platform::Handler>(
69         mockDbusHandler.get(), mockCodeUpdate.get(), 0x1, 0x9, requester, event,
70         nullptr);
71 
72     auto rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
73         entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField);
74 
75     ASSERT_EQ(rc, PLDM_SUCCESS);
76     ASSERT_EQ(stateField.size(), 1);
77     ASSERT_EQ(stateField[0].event_state, tSideNum);
78     ASSERT_EQ(stateField[0].sensor_op_state, PLDM_SENSOR_ENABLED);
79     ASSERT_EQ(stateField[0].present_state, PLDM_SENSOR_UNKNOWN);
80     ASSERT_EQ(stateField[0].previous_state, PLDM_SENSOR_UNKNOWN);
81 
82     entityInstance_ = 1;
83 
84     std::vector<get_sensor_state_field> stateField1;
85     rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
86         entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
87     ASSERT_EQ(stateField1.size(), 1);
88     ASSERT_EQ(stateField1[0].event_state, tSideNum);
89 
90     entityInstance_ = 2;
91     rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
92         entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
93     ASSERT_EQ(stateField1[0].event_state, PLDM_SENSOR_UNKNOWN);
94 
95     entityID_ = 40;
96     stateSetId_ = 50;
97     rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
98         entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
99     ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
100 
101     entityID_ = PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE;
102     entityInstance_ = 0;
103     stateSetId_ = PLDM_OEM_IBM_BOOT_STATE;
104     compSensorCnt_ = 1;
105 
106     std::vector<set_effecter_state_field> setEffecterStateField;
107     setEffecterStateField.push_back({PLDM_REQUEST_SET, pSideNum});
108 
109     rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
110         entityID_, entityInstance_, stateSetId_, compSensorCnt_,
111         setEffecterStateField, effecterId);
112     ASSERT_EQ(rc, PLDM_SUCCESS);
113 
114     entityInstance_ = 2;
115     rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
116         entityID_, entityInstance_, stateSetId_, compSensorCnt_,
117         setEffecterStateField, effecterId);
118 
119     ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
120 
121     entityID_ = 34;
122     stateSetId_ = 99;
123     entityInstance_ = 0;
124     rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
125         entityID_, entityInstance_, stateSetId_, compSensorCnt_,
126         setEffecterStateField, effecterId);
127     ASSERT_EQ(rc, PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE);
128 }
129 
130 TEST(EncodeCodeUpdateEvent, testGoodRequest)
131 {
132     size_t sensorEventSize = PLDM_SENSOR_EVENT_DATA_MIN_LENGTH + 1;
133     std::vector<uint8_t> sensorEventDataVec{};
134     sensorEventDataVec.resize(sensorEventSize);
135 
136     auto eventData = reinterpret_cast<struct pldm_sensor_event_data*>(
137         sensorEventDataVec.data());
138     eventData->sensor_id = 0xA;
139     eventData->sensor_event_class_type = PLDM_SENSOR_OP_STATE;
140 
141     auto opStateSensorEventData =
142         reinterpret_cast<struct pldm_sensor_event_sensor_op_state*>(
143             sensorEventDataVec.data());
144     opStateSensorEventData->present_op_state = uint8_t(CodeUpdateState::START);
145     opStateSensorEventData->previous_op_state = uint8_t(CodeUpdateState::END);
146 
147     std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
148                                     PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
149                                     sensorEventDataVec.size());
150 
151     auto rc = encodeEventMsg(PLDM_SENSOR_EVENT, sensorEventDataVec, requestMsg,
152                              0x1);
153 
154     EXPECT_EQ(rc, PLDM_SUCCESS);
155 }
156 
157 TEST(EncodeCodeUpdate, testBadRequest)
158 {
159     std::vector<uint8_t> requestMsg;
160     std::vector<uint8_t> sensorEventDataVec{};
161 
162     auto rc = encodeEventMsg(PLDM_SENSOR_EVENT, sensorEventDataVec, requestMsg,
163                              0x1);
164 
165     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
166 }
167 
168 TEST(clearDirPath, testClearDirPath)
169 {
170     char dirPath[] = "/tmp/testClearDir/";
171     fs::path dir(dirPath);
172     fs::create_directories(dir);
173     struct stat buffer;
174     ASSERT_EQ(stat(dirPath, &buffer), 0);
175     char filePath[] = "/tmp/testClearDir/file.txt";
176     std::ofstream file(filePath);
177     ASSERT_EQ(stat(filePath, &buffer), 0);
178 
179     auto mockDbusHandler = std::make_unique<MockdBusHandler>();
180     std::unique_ptr<CodeUpdate> mockCodeUpdate =
181         std::make_unique<MockCodeUpdate>(mockDbusHandler.get());
182 
183     mockCodeUpdate->clearDirPath(dirPath);
184     ASSERT_EQ(stat(filePath, &buffer), -1);
185     ASSERT_EQ(stat(dirPath, &buffer), 0);
186 }
187 
188 TEST(generateStateEffecterOEMPDR, testGoodRequest)
189 {
190     auto inPDRRepo = pldm_pdr_init();
191     sdbusplus::bus_t bus(sdbusplus::bus::new_default());
192     std::filesystem::path dbPath;
193     TestInstanceIdDb instanceIdDb;
194     Requester requester(bus, "/abc/def", instanceIdDb);
195     auto mockDbusHandler = std::make_unique<MockdBusHandler>();
196     auto event = sdeventplus::Event::get_default();
197     std::unique_ptr<CodeUpdate> mockCodeUpdate =
198         std::make_unique<MockCodeUpdate>(mockDbusHandler.get());
199     std::unique_ptr<oem_ibm_platform::Handler> mockoemPlatformHandler =
200         std::make_unique<MockOemPlatformHandler>(mockDbusHandler.get(),
201                                                  mockCodeUpdate.get(), 0x1, 0x9,
202                                                  requester, event);
203     Repo inRepo(inPDRRepo);
204 
205     mockoemPlatformHandler->buildOEMPDR(inRepo);
206     ASSERT_EQ(inRepo.empty(), false);
207 
208     pdr_utils::PdrEntry e;
209 
210     // Test for effecter number 1, for current boot side state
211     auto record1 = pdr::getRecordByHandle(inRepo, 1, e);
212     ASSERT_NE(record1, nullptr);
213 
214     pldm_state_effecter_pdr* pdr =
215         reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
216 
217     ASSERT_EQ(pdr->hdr.record_handle, 1);
218     ASSERT_EQ(pdr->hdr.version, 1);
219     ASSERT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR);
220     ASSERT_EQ(pdr->hdr.record_change_num, 0);
221     ASSERT_EQ(pdr->hdr.length, 16);
222     ASSERT_EQ(pdr->terminus_handle, TERMINUS_HANDLE);
223     ASSERT_EQ(pdr->entity_type, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE);
224     ASSERT_EQ(pdr->entity_instance, 0);
225     ASSERT_EQ(pdr->container_id, 1);
226     ASSERT_EQ(pdr->effecter_semantic_id, 0);
227     ASSERT_EQ(pdr->effecter_init, PLDM_NO_INIT);
228     ASSERT_EQ(pdr->has_description_pdr, false);
229     ASSERT_EQ(pdr->composite_effecter_count, 1);
230     state_effecter_possible_states* states =
231         reinterpret_cast<state_effecter_possible_states*>(pdr->possible_states);
232     ASSERT_EQ(states->state_set_id, 32769);
233     ASSERT_EQ(states->possible_states_size, 2);
234     bitfield8_t bf1{};
235     bf1.byte = 6;
236     ASSERT_EQ(states->states[0].byte, bf1.byte);
237 
238     // Test for effecter number 2, for next boot side state
239     auto record2 = pdr::getRecordByHandle(inRepo, 2, e);
240     ASSERT_NE(record2, nullptr);
241 
242     pdr = reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
243 
244     ASSERT_EQ(pdr->hdr.record_handle, 2);
245     ASSERT_EQ(pdr->hdr.version, 1);
246     ASSERT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR);
247     ASSERT_EQ(pdr->hdr.record_change_num, 0);
248     ASSERT_EQ(pdr->hdr.length, 16);
249     ASSERT_EQ(pdr->terminus_handle, TERMINUS_HANDLE);
250     ASSERT_EQ(pdr->entity_type, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE);
251     ASSERT_EQ(pdr->entity_instance, 1);
252     ASSERT_EQ(pdr->container_id, 1);
253     ASSERT_EQ(pdr->effecter_semantic_id, 0);
254     ASSERT_EQ(pdr->effecter_init, PLDM_NO_INIT);
255     ASSERT_EQ(pdr->has_description_pdr, false);
256     ASSERT_EQ(pdr->composite_effecter_count, 1);
257     states =
258         reinterpret_cast<state_effecter_possible_states*>(pdr->possible_states);
259     ASSERT_EQ(states->state_set_id, 32769);
260     ASSERT_EQ(states->possible_states_size, 2);
261     bitfield8_t bf2{};
262     bf2.byte = 6;
263     ASSERT_EQ(states->states[0].byte, bf2.byte);
264 
265     // Test for effecter number 3, for firmware update state control
266     auto record3 = pdr::getRecordByHandle(inRepo, 3, e);
267     ASSERT_NE(record3, nullptr);
268 
269     pdr = reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
270 
271     ASSERT_EQ(pdr->hdr.record_handle, 3);
272     ASSERT_EQ(pdr->hdr.version, 1);
273     ASSERT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR);
274     ASSERT_EQ(pdr->hdr.record_change_num, 0);
275     ASSERT_EQ(pdr->hdr.length, 16);
276     ASSERT_EQ(pdr->terminus_handle, TERMINUS_HANDLE);
277     ASSERT_EQ(pdr->entity_type, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE);
278     ASSERT_EQ(pdr->entity_instance, 0);
279     ASSERT_EQ(pdr->container_id, 1);
280     ASSERT_EQ(pdr->effecter_semantic_id, 0);
281     ASSERT_EQ(pdr->effecter_init, PLDM_NO_INIT);
282     ASSERT_EQ(pdr->has_description_pdr, false);
283     ASSERT_EQ(pdr->composite_effecter_count, 1);
284     states =
285         reinterpret_cast<state_effecter_possible_states*>(pdr->possible_states);
286     ASSERT_EQ(states->state_set_id, 32768);
287     ASSERT_EQ(states->possible_states_size, 2);
288     bitfield8_t bf3{};
289     bf3.byte = 126;
290     ASSERT_EQ(states->states[0].byte, bf3.byte);
291 
292     pldm_pdr_destroy(inPDRRepo);
293 }
294 
295 TEST(generateStateSensorOEMPDR, testGoodRequest)
296 {
297     auto inPDRRepo = pldm_pdr_init();
298     sdbusplus::bus_t bus(sdbusplus::bus::new_default());
299     std::filesystem::path dbPath;
300     TestInstanceIdDb instanceIdDb;
301     Requester requester(bus, "/abc/def", instanceIdDb);
302 
303     auto mockDbusHandler = std::make_unique<MockdBusHandler>();
304     auto event = sdeventplus::Event::get_default();
305     std::unique_ptr<CodeUpdate> mockCodeUpdate =
306         std::make_unique<MockCodeUpdate>(mockDbusHandler.get());
307     std::unique_ptr<oem_ibm_platform::Handler> mockoemPlatformHandler =
308         std::make_unique<MockOemPlatformHandler>(mockDbusHandler.get(),
309                                                  mockCodeUpdate.get(), 0x1, 0x9,
310                                                  requester, event);
311     Repo inRepo(inPDRRepo);
312     mockoemPlatformHandler->buildOEMPDR(inRepo);
313     ASSERT_EQ(inRepo.empty(), false);
314 
315     pdr_utils::PdrEntry e;
316 
317     // Test for sensor number 1, for current boot side state
318     auto record1 = pdr::getRecordByHandle(inRepo, 5, e);
319     ASSERT_NE(record1, nullptr);
320 
321     pldm_state_sensor_pdr* pdr =
322         reinterpret_cast<pldm_state_sensor_pdr*>(e.data);
323 
324     ASSERT_EQ(pdr->hdr.record_handle, 5);
325     ASSERT_EQ(pdr->hdr.version, 1);
326     ASSERT_EQ(pdr->hdr.type, PLDM_STATE_SENSOR_PDR);
327     ASSERT_EQ(pdr->hdr.record_change_num, 0);
328     ASSERT_EQ(pdr->hdr.length, 14);
329     ASSERT_EQ(pdr->terminus_handle, TERMINUS_HANDLE);
330     ASSERT_EQ(pdr->entity_type, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE);
331     ASSERT_EQ(pdr->entity_instance, 0);
332     ASSERT_EQ(pdr->container_id, 1);
333     ASSERT_EQ(pdr->sensor_init, PLDM_NO_INIT);
334     ASSERT_EQ(pdr->sensor_auxiliary_names_pdr, false);
335     ASSERT_EQ(pdr->composite_sensor_count, 1);
336     state_sensor_possible_states* states =
337         reinterpret_cast<state_sensor_possible_states*>(pdr->possible_states);
338     ASSERT_EQ(states->state_set_id, 32769);
339     ASSERT_EQ(states->possible_states_size, 2);
340     bitfield8_t bf1{};
341     bf1.byte = 6;
342     ASSERT_EQ(states->states[0].byte, bf1.byte);
343 
344     // Test for sensor number 2, for next boot side state
345     auto record2 = pdr::getRecordByHandle(inRepo, 6, e);
346     ASSERT_NE(record2, nullptr);
347 
348     pdr = reinterpret_cast<pldm_state_sensor_pdr*>(e.data);
349 
350     ASSERT_EQ(pdr->hdr.record_handle, 6);
351     ASSERT_EQ(pdr->hdr.version, 1);
352     ASSERT_EQ(pdr->hdr.type, PLDM_STATE_SENSOR_PDR);
353     ASSERT_EQ(pdr->hdr.record_change_num, 0);
354     ASSERT_EQ(pdr->hdr.length, 14);
355     ASSERT_EQ(pdr->terminus_handle, TERMINUS_HANDLE);
356     ASSERT_EQ(pdr->entity_type, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE);
357     ASSERT_EQ(pdr->entity_instance, 1);
358     ASSERT_EQ(pdr->container_id, 1);
359     ASSERT_EQ(pdr->sensor_init, PLDM_NO_INIT);
360     ASSERT_EQ(pdr->sensor_auxiliary_names_pdr, false);
361     ASSERT_EQ(pdr->composite_sensor_count, 1);
362     states =
363         reinterpret_cast<state_sensor_possible_states*>(pdr->possible_states);
364     ASSERT_EQ(states->state_set_id, 32769);
365     ASSERT_EQ(states->possible_states_size, 2);
366     bitfield8_t bf2{};
367     bf2.byte = 6;
368     ASSERT_EQ(states->states[0].byte, bf2.byte);
369 
370     // Test for sensor number 3, for firmware update state control
371     auto record3 = pdr::getRecordByHandle(inRepo, 7, e);
372     ASSERT_NE(record3, nullptr);
373 
374     pdr = reinterpret_cast<pldm_state_sensor_pdr*>(e.data);
375 
376     ASSERT_EQ(pdr->hdr.record_handle, 7);
377     ASSERT_EQ(pdr->hdr.version, 1);
378     ASSERT_EQ(pdr->hdr.type, PLDM_STATE_SENSOR_PDR);
379     ASSERT_EQ(pdr->hdr.record_change_num, 0);
380     ASSERT_EQ(pdr->hdr.length, 14);
381     ASSERT_EQ(pdr->terminus_handle, TERMINUS_HANDLE);
382     ASSERT_EQ(pdr->entity_type, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE);
383     ASSERT_EQ(pdr->entity_instance, 0);
384     ASSERT_EQ(pdr->container_id, 1);
385     ASSERT_EQ(pdr->sensor_init, PLDM_NO_INIT);
386     ASSERT_EQ(pdr->sensor_auxiliary_names_pdr, false);
387     ASSERT_EQ(pdr->composite_sensor_count, 1);
388     states =
389         reinterpret_cast<state_sensor_possible_states*>(pdr->possible_states);
390     ASSERT_EQ(states->state_set_id, 32768);
391     ASSERT_EQ(states->possible_states_size, 2);
392     bitfield8_t bf3{};
393     bf3.byte = 126;
394     ASSERT_EQ(states->states[0].byte, bf3.byte);
395 
396     pldm_pdr_destroy(inPDRRepo);
397 }
398