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_ibm_platform::Handler> mockoemPlatformHandler = 193 std::make_unique<MockOemPlatformHandler>(mockDbusHandler.get(), 194 mockCodeUpdate.get(), 0x1, 0x9, 195 requester, event); 196 Repo inRepo(inPDRRepo); 197 198 mockoemPlatformHandler->buildOEMPDR(inRepo); 199 ASSERT_EQ(inRepo.empty(), false); 200 201 pdr_utils::PdrEntry e; 202 203 // Test for effecter number 1, for current boot side state 204 auto record1 = pdr::getRecordByHandle(inRepo, 1, e); 205 ASSERT_NE(record1, nullptr); 206 207 pldm_state_effecter_pdr* pdr = 208 reinterpret_cast<pldm_state_effecter_pdr*>(e.data); 209 210 ASSERT_EQ(pdr->hdr.record_handle, 1); 211 ASSERT_EQ(pdr->hdr.version, 1); 212 ASSERT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR); 213 ASSERT_EQ(pdr->hdr.record_change_num, 0); 214 ASSERT_EQ(pdr->hdr.length, 16); 215 ASSERT_EQ(pdr->terminus_handle, BmcPldmTerminusHandle); 216 ASSERT_EQ(pdr->entity_type, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE); 217 ASSERT_EQ(pdr->entity_instance, 0); 218 ASSERT_EQ(pdr->container_id, 0); 219 ASSERT_EQ(pdr->effecter_semantic_id, 0); 220 ASSERT_EQ(pdr->effecter_init, PLDM_NO_INIT); 221 ASSERT_EQ(pdr->has_description_pdr, false); 222 ASSERT_EQ(pdr->composite_effecter_count, 1); 223 state_effecter_possible_states* states = 224 reinterpret_cast<state_effecter_possible_states*>(pdr->possible_states); 225 ASSERT_EQ(states->state_set_id, 32769); 226 ASSERT_EQ(states->possible_states_size, 2); 227 bitfield8_t bf1{}; 228 bf1.byte = 6; 229 ASSERT_EQ(states->states[0].byte, bf1.byte); 230 231 // Test for effecter number 2, for next boot side state 232 auto record2 = pdr::getRecordByHandle(inRepo, 2, e); 233 ASSERT_NE(record2, nullptr); 234 235 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(e.data); 236 237 ASSERT_EQ(pdr->hdr.record_handle, 2); 238 ASSERT_EQ(pdr->hdr.version, 1); 239 ASSERT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR); 240 ASSERT_EQ(pdr->hdr.record_change_num, 0); 241 ASSERT_EQ(pdr->hdr.length, 16); 242 ASSERT_EQ(pdr->terminus_handle, BmcPldmTerminusHandle); 243 ASSERT_EQ(pdr->entity_type, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE); 244 ASSERT_EQ(pdr->entity_instance, 1); 245 ASSERT_EQ(pdr->container_id, 0); 246 ASSERT_EQ(pdr->effecter_semantic_id, 0); 247 ASSERT_EQ(pdr->effecter_init, PLDM_NO_INIT); 248 ASSERT_EQ(pdr->has_description_pdr, false); 249 ASSERT_EQ(pdr->composite_effecter_count, 1); 250 states = 251 reinterpret_cast<state_effecter_possible_states*>(pdr->possible_states); 252 ASSERT_EQ(states->state_set_id, 32769); 253 ASSERT_EQ(states->possible_states_size, 2); 254 bitfield8_t bf2{}; 255 bf2.byte = 6; 256 ASSERT_EQ(states->states[0].byte, bf2.byte); 257 258 // Test for effecter number 3, for firmware update state control 259 auto record3 = pdr::getRecordByHandle(inRepo, 3, e); 260 ASSERT_NE(record3, nullptr); 261 262 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(e.data); 263 264 ASSERT_EQ(pdr->hdr.record_handle, 3); 265 ASSERT_EQ(pdr->hdr.version, 1); 266 ASSERT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR); 267 ASSERT_EQ(pdr->hdr.record_change_num, 0); 268 ASSERT_EQ(pdr->hdr.length, 16); 269 ASSERT_EQ(pdr->terminus_handle, BmcPldmTerminusHandle); 270 ASSERT_EQ(pdr->entity_type, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE); 271 ASSERT_EQ(pdr->entity_instance, 0); 272 ASSERT_EQ(pdr->container_id, 0); 273 ASSERT_EQ(pdr->effecter_semantic_id, 0); 274 ASSERT_EQ(pdr->effecter_init, PLDM_NO_INIT); 275 ASSERT_EQ(pdr->has_description_pdr, false); 276 ASSERT_EQ(pdr->composite_effecter_count, 1); 277 states = 278 reinterpret_cast<state_effecter_possible_states*>(pdr->possible_states); 279 ASSERT_EQ(states->state_set_id, 32768); 280 ASSERT_EQ(states->possible_states_size, 2); 281 bitfield8_t bf3{}; 282 bf3.byte = 126; 283 ASSERT_EQ(states->states[0].byte, bf3.byte); 284 285 pldm_pdr_destroy(inPDRRepo); 286 } 287 288 TEST(generateStateSensorOEMPDR, testGoodRequest) 289 { 290 auto inPDRRepo = pldm_pdr_init(); 291 sdbusplus::bus::bus bus(sdbusplus::bus::new_default()); 292 Requester requester(bus, "/abc/def"); 293 294 auto mockDbusHandler = std::make_unique<MockdBusHandler>(); 295 auto event = sdeventplus::Event::get_default(); 296 std::unique_ptr<CodeUpdate> mockCodeUpdate = 297 std::make_unique<MockCodeUpdate>(mockDbusHandler.get()); 298 std::unique_ptr<oem_ibm_platform::Handler> mockoemPlatformHandler = 299 std::make_unique<MockOemPlatformHandler>(mockDbusHandler.get(), 300 mockCodeUpdate.get(), 0x1, 0x9, 301 requester, event); 302 Repo inRepo(inPDRRepo); 303 mockoemPlatformHandler->buildOEMPDR(inRepo); 304 ASSERT_EQ(inRepo.empty(), false); 305 306 pdr_utils::PdrEntry e; 307 308 // Test for sensor number 1, for current boot side state 309 auto record1 = pdr::getRecordByHandle(inRepo, 5, e); 310 ASSERT_NE(record1, nullptr); 311 312 pldm_state_sensor_pdr* pdr = 313 reinterpret_cast<pldm_state_sensor_pdr*>(e.data); 314 315 ASSERT_EQ(pdr->hdr.record_handle, 5); 316 ASSERT_EQ(pdr->hdr.version, 1); 317 ASSERT_EQ(pdr->hdr.type, PLDM_STATE_SENSOR_PDR); 318 ASSERT_EQ(pdr->hdr.record_change_num, 0); 319 ASSERT_EQ(pdr->hdr.length, 14); 320 ASSERT_EQ(pdr->terminus_handle, BmcPldmTerminusHandle); 321 ASSERT_EQ(pdr->entity_type, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE); 322 ASSERT_EQ(pdr->entity_instance, 0); 323 ASSERT_EQ(pdr->container_id, 0); 324 ASSERT_EQ(pdr->sensor_init, PLDM_NO_INIT); 325 ASSERT_EQ(pdr->sensor_auxiliary_names_pdr, false); 326 ASSERT_EQ(pdr->composite_sensor_count, 1); 327 state_sensor_possible_states* states = 328 reinterpret_cast<state_sensor_possible_states*>(pdr->possible_states); 329 ASSERT_EQ(states->state_set_id, 32769); 330 ASSERT_EQ(states->possible_states_size, 2); 331 bitfield8_t bf1{}; 332 bf1.byte = 6; 333 ASSERT_EQ(states->states[0].byte, bf1.byte); 334 335 // Test for sensor number 2, for next boot side state 336 auto record2 = pdr::getRecordByHandle(inRepo, 6, e); 337 ASSERT_NE(record2, nullptr); 338 339 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(e.data); 340 341 ASSERT_EQ(pdr->hdr.record_handle, 6); 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, 1); 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 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 bf2{}; 358 bf2.byte = 6; 359 ASSERT_EQ(states->states[0].byte, bf2.byte); 360 361 // Test for sensor number 3, for firmware update state control 362 auto record3 = pdr::getRecordByHandle(inRepo, 7, e); 363 ASSERT_NE(record3, nullptr); 364 365 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(e.data); 366 367 ASSERT_EQ(pdr->hdr.record_handle, 7); 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, 0); 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, 32768); 382 ASSERT_EQ(states->possible_states_size, 2); 383 bitfield8_t bf3{}; 384 bf3.byte = 126; 385 ASSERT_EQ(states->states[0].byte, bf3.byte); 386 387 pldm_pdr_destroy(inPDRRepo); 388 } 389