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 <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 sdbusplus::bus_t bus(sdbusplus::bus::new_default()); 57 Requester requester(bus, "/abc/def"); 58 auto event = sdeventplus::Event::get_default(); 59 std::vector<get_sensor_state_field> stateField; 60 61 auto mockDbusHandler = std::make_unique<MockdBusHandler>(); 62 std::unique_ptr<CodeUpdate> mockCodeUpdate = 63 std::make_unique<MockCodeUpdate>(mockDbusHandler.get()); 64 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 65 66 oemPlatformHandler = std::make_unique<oem_ibm_platform::Handler>( 67 mockDbusHandler.get(), mockCodeUpdate.get(), 0x1, 0x9, requester, event, 68 nullptr); 69 70 auto rc = oemPlatformHandler->getOemStateSensorReadingsHandler( 71 entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField); 72 73 ASSERT_EQ(rc, PLDM_SUCCESS); 74 ASSERT_EQ(stateField.size(), 1); 75 ASSERT_EQ(stateField[0].event_state, tSideNum); 76 ASSERT_EQ(stateField[0].sensor_op_state, PLDM_SENSOR_ENABLED); 77 ASSERT_EQ(stateField[0].present_state, PLDM_SENSOR_UNKNOWN); 78 ASSERT_EQ(stateField[0].previous_state, PLDM_SENSOR_UNKNOWN); 79 80 entityInstance_ = 1; 81 82 std::vector<get_sensor_state_field> stateField1; 83 rc = oemPlatformHandler->getOemStateSensorReadingsHandler( 84 entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1); 85 ASSERT_EQ(stateField1.size(), 1); 86 ASSERT_EQ(stateField1[0].event_state, tSideNum); 87 88 entityInstance_ = 2; 89 rc = oemPlatformHandler->getOemStateSensorReadingsHandler( 90 entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1); 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 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 = 150 encodeEventMsg(PLDM_SENSOR_EVENT, sensorEventDataVec, requestMsg, 0x1); 151 152 EXPECT_EQ(rc, PLDM_SUCCESS); 153 } 154 155 TEST(EncodeCodeUpdate, testBadRequest) 156 { 157 std::vector<uint8_t> requestMsg; 158 std::vector<uint8_t> sensorEventDataVec{}; 159 160 auto rc = 161 encodeEventMsg(PLDM_SENSOR_EVENT, sensorEventDataVec, requestMsg, 0x1); 162 163 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 164 } 165 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 186 TEST(generateStateEffecterOEMPDR, testGoodRequest) 187 { 188 auto inPDRRepo = pldm_pdr_init(); 189 sdbusplus::bus_t bus(sdbusplus::bus::new_default()); 190 Requester requester(bus, "/abc/def"); 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 requester, 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, 0); 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, 0); 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, 0); 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 291 TEST(generateStateSensorOEMPDR, testGoodRequest) 292 { 293 auto inPDRRepo = pldm_pdr_init(); 294 sdbusplus::bus_t bus(sdbusplus::bus::new_default()); 295 Requester requester(bus, "/abc/def"); 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 requester, 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, 0); 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, 0); 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, 0); 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