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