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