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