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