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 "libpldmresponder/platform_numeric_effecter.hpp" 8 #include "libpldmresponder/platform_state_effecter.hpp" 9 #include "libpldmresponder/platform_state_sensor.hpp" 10 11 #include <sdbusplus/test/sdbus_mock.hpp> 12 #include <sdeventplus/event.hpp> 13 14 #include <iostream> 15 16 using namespace pldm::pdr; 17 using namespace pldm::utils; 18 using namespace pldm::responder; 19 using namespace pldm::responder::platform; 20 using namespace pldm::responder::pdr; 21 using namespace pldm::responder::pdr_utils; 22 23 using ::testing::_; 24 using ::testing::Return; 25 using ::testing::StrEq; 26 27 TEST(getPDR, testGoodPath) 28 { 29 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> 30 requestPayload{}; 31 auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); 32 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); 33 34 struct pldm_get_pdr_req* request = 35 reinterpret_cast<struct pldm_get_pdr_req*>(req->payload); 36 request->request_count = 100; 37 38 MockdBusHandler mockedUtils; 39 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 40 .Times(5) 41 .WillRepeatedly(Return("foo.bar")); 42 43 auto pdrRepo = pldm_pdr_init(); 44 auto event = sdeventplus::Event::get_default(); 45 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo, 46 nullptr, nullptr, nullptr, nullptr, event); 47 Repo repo(pdrRepo); 48 ASSERT_EQ(repo.empty(), false); 49 auto response = handler.getPDR(req, requestPayloadLength); 50 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 51 52 struct pldm_get_pdr_resp* resp = 53 reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload); 54 ASSERT_EQ(PLDM_SUCCESS, resp->completion_code); 55 ASSERT_EQ(2, resp->next_record_handle); 56 ASSERT_EQ(true, resp->response_count != 0); 57 58 pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(resp->record_data); 59 ASSERT_EQ(hdr->record_handle, 1); 60 ASSERT_EQ(hdr->version, 1); 61 62 pldm_pdr_destroy(pdrRepo); 63 } 64 65 TEST(getPDR, testShortRead) 66 { 67 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> 68 requestPayload{}; 69 auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); 70 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); 71 72 struct pldm_get_pdr_req* request = 73 reinterpret_cast<struct pldm_get_pdr_req*>(req->payload); 74 request->request_count = 1; 75 76 MockdBusHandler mockedUtils; 77 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 78 .Times(5) 79 .WillRepeatedly(Return("foo.bar")); 80 81 auto pdrRepo = pldm_pdr_init(); 82 auto event = sdeventplus::Event::get_default(); 83 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo, 84 nullptr, nullptr, nullptr, nullptr, event); 85 Repo repo(pdrRepo); 86 ASSERT_EQ(repo.empty(), false); 87 auto response = handler.getPDR(req, requestPayloadLength); 88 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 89 struct pldm_get_pdr_resp* resp = 90 reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload); 91 ASSERT_EQ(PLDM_SUCCESS, resp->completion_code); 92 ASSERT_EQ(1, resp->response_count); 93 pldm_pdr_destroy(pdrRepo); 94 } 95 96 TEST(getPDR, testBadRecordHandle) 97 { 98 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> 99 requestPayload{}; 100 auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); 101 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); 102 103 struct pldm_get_pdr_req* request = 104 reinterpret_cast<struct pldm_get_pdr_req*>(req->payload); 105 request->record_handle = 100000; 106 request->request_count = 1; 107 108 MockdBusHandler mockedUtils; 109 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 110 .Times(5) 111 .WillRepeatedly(Return("foo.bar")); 112 113 auto pdrRepo = pldm_pdr_init(); 114 auto event = sdeventplus::Event::get_default(); 115 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo, 116 nullptr, nullptr, nullptr, nullptr, event); 117 Repo repo(pdrRepo); 118 ASSERT_EQ(repo.empty(), false); 119 auto response = handler.getPDR(req, requestPayloadLength); 120 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 121 122 ASSERT_EQ(responsePtr->payload[0], PLDM_PLATFORM_INVALID_RECORD_HANDLE); 123 124 pldm_pdr_destroy(pdrRepo); 125 } 126 127 TEST(getPDR, testNoNextRecord) 128 { 129 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> 130 requestPayload{}; 131 auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); 132 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); 133 134 struct pldm_get_pdr_req* request = 135 reinterpret_cast<struct pldm_get_pdr_req*>(req->payload); 136 request->record_handle = 1; 137 138 MockdBusHandler mockedUtils; 139 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 140 .Times(5) 141 .WillRepeatedly(Return("foo.bar")); 142 143 auto pdrRepo = pldm_pdr_init(); 144 auto event = sdeventplus::Event::get_default(); 145 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo, 146 nullptr, nullptr, nullptr, nullptr, event); 147 Repo repo(pdrRepo); 148 ASSERT_EQ(repo.empty(), false); 149 auto response = handler.getPDR(req, requestPayloadLength); 150 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 151 struct pldm_get_pdr_resp* resp = 152 reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload); 153 ASSERT_EQ(PLDM_SUCCESS, resp->completion_code); 154 ASSERT_EQ(2, resp->next_record_handle); 155 156 pldm_pdr_destroy(pdrRepo); 157 } 158 159 TEST(getPDR, testFindPDR) 160 { 161 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> 162 requestPayload{}; 163 auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); 164 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); 165 166 struct pldm_get_pdr_req* request = 167 reinterpret_cast<struct pldm_get_pdr_req*>(req->payload); 168 request->request_count = 100; 169 170 MockdBusHandler mockedUtils; 171 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 172 .Times(5) 173 .WillRepeatedly(Return("foo.bar")); 174 175 auto pdrRepo = pldm_pdr_init(); 176 auto event = sdeventplus::Event::get_default(); 177 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo, 178 nullptr, nullptr, nullptr, nullptr, event); 179 Repo repo(pdrRepo); 180 ASSERT_EQ(repo.empty(), false); 181 auto response = handler.getPDR(req, requestPayloadLength); 182 183 // Let's try to find a PDR of type stateEffecter (= 11) and entity type = 184 // 100 185 bool found = false; 186 uint32_t handle = 0; // start asking for PDRs from recordHandle 0 187 while (!found) 188 { 189 request->record_handle = handle; 190 auto response = handler.getPDR(req, requestPayloadLength); 191 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 192 struct pldm_get_pdr_resp* resp = 193 reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload); 194 ASSERT_EQ(PLDM_SUCCESS, resp->completion_code); 195 196 handle = resp->next_record_handle; // point to the next pdr in case 197 // current is not what we want 198 199 pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(resp->record_data); 200 if (hdr->type == PLDM_STATE_EFFECTER_PDR) 201 { 202 pldm_state_effecter_pdr* pdr = 203 reinterpret_cast<pldm_state_effecter_pdr*>(resp->record_data); 204 if (pdr->entity_type == 100) 205 { 206 found = true; 207 // Rest of the PDR can be accessed as need be 208 break; 209 } 210 } 211 if (!resp->next_record_handle) // no more records 212 { 213 break; 214 } 215 } 216 ASSERT_EQ(found, true); 217 218 pldm_pdr_destroy(pdrRepo); 219 } 220 221 TEST(setStateEffecterStatesHandler, testGoodRequest) 222 { 223 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> 224 requestPayload{}; 225 auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); 226 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); 227 228 MockdBusHandler mockedUtils; 229 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 230 .Times(5) 231 .WillRepeatedly(Return("foo.bar")); 232 233 auto inPDRRepo = pldm_pdr_init(); 234 auto outPDRRepo = pldm_pdr_init(); 235 Repo outRepo(outPDRRepo); 236 auto event = sdeventplus::Event::get_default(); 237 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo, 238 nullptr, nullptr, nullptr, nullptr, event); 239 handler.getPDR(req, requestPayloadLength); 240 Repo inRepo(inPDRRepo); 241 getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR); 242 pdr_utils::PdrEntry e; 243 auto record1 = pdr::getRecordByHandle(outRepo, 2, e); 244 ASSERT_NE(record1, nullptr); 245 pldm_state_effecter_pdr* pdr = 246 reinterpret_cast<pldm_state_effecter_pdr*>(e.data); 247 EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR); 248 249 std::vector<set_effecter_state_field> stateField; 250 stateField.push_back({PLDM_REQUEST_SET, 1}); 251 stateField.push_back({PLDM_REQUEST_SET, 1}); 252 std::string value = "xyz.openbmc_project.Foo.Bar.V1"; 253 PropertyValue propertyValue = value; 254 255 DBusMapping dbusMapping{"/foo/bar", "xyz.openbmc_project.Foo.Bar", 256 "propertyName", "string"}; 257 258 EXPECT_CALL(mockedUtils, setDbusProperty(dbusMapping, propertyValue)) 259 .Times(2); 260 auto rc = platform_state_effecter::setStateEffecterStatesHandler< 261 MockdBusHandler, Handler>(mockedUtils, handler, 0x1, stateField); 262 ASSERT_EQ(rc, 0); 263 264 pldm_pdr_destroy(inPDRRepo); 265 pldm_pdr_destroy(outPDRRepo); 266 } 267 268 TEST(setStateEffecterStatesHandler, testBadRequest) 269 { 270 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> 271 requestPayload{}; 272 auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); 273 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); 274 275 MockdBusHandler mockedUtils; 276 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 277 .Times(5) 278 .WillRepeatedly(Return("foo.bar")); 279 280 auto inPDRRepo = pldm_pdr_init(); 281 auto outPDRRepo = pldm_pdr_init(); 282 Repo outRepo(outPDRRepo); 283 auto event = sdeventplus::Event::get_default(); 284 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo, 285 nullptr, nullptr, nullptr, nullptr, event); 286 handler.getPDR(req, requestPayloadLength); 287 Repo inRepo(inPDRRepo); 288 getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR); 289 pdr_utils::PdrEntry e; 290 auto record1 = pdr::getRecordByHandle(outRepo, 2, e); 291 ASSERT_NE(record1, nullptr); 292 pldm_state_effecter_pdr* pdr = 293 reinterpret_cast<pldm_state_effecter_pdr*>(e.data); 294 EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR); 295 296 std::vector<set_effecter_state_field> stateField; 297 stateField.push_back({PLDM_REQUEST_SET, 3}); 298 stateField.push_back({PLDM_REQUEST_SET, 4}); 299 300 auto rc = platform_state_effecter::setStateEffecterStatesHandler< 301 MockdBusHandler, Handler>(mockedUtils, handler, 0x1, stateField); 302 ASSERT_EQ(rc, PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE); 303 304 rc = platform_state_effecter::setStateEffecterStatesHandler<MockdBusHandler, 305 Handler>( 306 mockedUtils, handler, 0x9, stateField); 307 ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_EFFECTER_ID); 308 309 stateField.push_back({PLDM_REQUEST_SET, 4}); 310 rc = platform_state_effecter::setStateEffecterStatesHandler<MockdBusHandler, 311 Handler>( 312 mockedUtils, handler, 0x1, stateField); 313 ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA); 314 315 pldm_pdr_destroy(inPDRRepo); 316 pldm_pdr_destroy(outPDRRepo); 317 } 318 319 TEST(setNumericEffecterValueHandler, testGoodRequest) 320 { 321 MockdBusHandler mockedUtils; 322 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 323 .Times(5) 324 .WillRepeatedly(Return("foo.bar")); 325 326 auto inPDRRepo = pldm_pdr_init(); 327 auto numericEffecterPdrRepo = pldm_pdr_init(); 328 Repo numericEffecterPDRs(numericEffecterPdrRepo); 329 auto event = sdeventplus::Event::get_default(); 330 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo, 331 nullptr, nullptr, nullptr, nullptr, event); 332 Repo inRepo(inPDRRepo); 333 getRepoByType(inRepo, numericEffecterPDRs, PLDM_NUMERIC_EFFECTER_PDR); 334 335 pdr_utils::PdrEntry e; 336 auto record4 = pdr::getRecordByHandle(numericEffecterPDRs, 4, e); 337 ASSERT_NE(record4, nullptr); 338 339 pldm_numeric_effecter_value_pdr* pdr = 340 reinterpret_cast<pldm_numeric_effecter_value_pdr*>(e.data); 341 EXPECT_EQ(pdr->hdr.type, PLDM_NUMERIC_EFFECTER_PDR); 342 343 uint16_t effecterId = 3; 344 uint32_t effecterValue = 2100000000; // 2036-07-18 21:20:00 345 PropertyValue propertyValue = static_cast<uint64_t>(effecterValue); 346 347 DBusMapping dbusMapping{"/foo/bar", "xyz.openbmc_project.Foo.Bar", 348 "propertyName", "uint64_t"}; 349 EXPECT_CALL(mockedUtils, setDbusProperty(dbusMapping, propertyValue)) 350 .Times(1); 351 352 auto rc = platform_numeric_effecter::setNumericEffecterValueHandler< 353 MockdBusHandler, Handler>( 354 mockedUtils, handler, effecterId, PLDM_EFFECTER_DATA_SIZE_UINT32, 355 reinterpret_cast<uint8_t*>(&effecterValue), 4); 356 ASSERT_EQ(rc, 0); 357 358 pldm_pdr_destroy(inPDRRepo); 359 pldm_pdr_destroy(numericEffecterPdrRepo); 360 } 361 362 TEST(setNumericEffecterValueHandler, testBadRequest) 363 { 364 MockdBusHandler mockedUtils; 365 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 366 .Times(5) 367 .WillRepeatedly(Return("foo.bar")); 368 369 auto inPDRRepo = pldm_pdr_init(); 370 auto numericEffecterPdrRepo = pldm_pdr_init(); 371 Repo numericEffecterPDRs(numericEffecterPdrRepo); 372 auto event = sdeventplus::Event::get_default(); 373 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo, 374 nullptr, nullptr, nullptr, nullptr, event); 375 Repo inRepo(inPDRRepo); 376 getRepoByType(inRepo, numericEffecterPDRs, PLDM_NUMERIC_EFFECTER_PDR); 377 378 pdr_utils::PdrEntry e; 379 auto record4 = pdr::getRecordByHandle(numericEffecterPDRs, 4, e); 380 ASSERT_NE(record4, nullptr); 381 382 pldm_numeric_effecter_value_pdr* pdr = 383 reinterpret_cast<pldm_numeric_effecter_value_pdr*>(e.data); 384 EXPECT_EQ(pdr->hdr.type, PLDM_NUMERIC_EFFECTER_PDR); 385 386 uint16_t effecterId = 3; 387 uint64_t effecterValue = 9876543210; 388 auto rc = platform_numeric_effecter::setNumericEffecterValueHandler< 389 MockdBusHandler, Handler>( 390 mockedUtils, handler, effecterId, PLDM_EFFECTER_DATA_SIZE_SINT32, 391 reinterpret_cast<uint8_t*>(&effecterValue), 3); 392 ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA); 393 394 pldm_pdr_destroy(inPDRRepo); 395 pldm_pdr_destroy(numericEffecterPdrRepo); 396 } 397 398 TEST(parseStateSensor, allScenarios) 399 { 400 // Sample state sensor with SensorID - 1, EntityType - Processor Module(67) 401 // State Set ID - Operational Running Status(11), Supported States - 3,4 402 std::vector<uint8_t> sample1PDR{0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 403 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 404 0x43, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 405 0x00, 0x01, 0x0b, 0x00, 0x01, 0x18}; 406 407 const auto& [terminusHandle1, sensorID1, 408 sensorInfo1] = parseStateSensorPDR(sample1PDR); 409 const auto& [containerID1, entityType1, 410 entityInstance1] = std::get<0>(sensorInfo1); 411 const auto& states1 = std::get<1>(sensorInfo1); 412 CompositeSensorStates statesCmp1{{3u, 4u}}; 413 414 ASSERT_EQ(le16toh(terminusHandle1), 0u); 415 ASSERT_EQ(le16toh(sensorID1), 1u); 416 ASSERT_EQ(le16toh(containerID1), 0u); 417 ASSERT_EQ(le16toh(entityType1), 67u); 418 ASSERT_EQ(le16toh(entityInstance1), 1u); 419 ASSERT_EQ(states1, statesCmp1); 420 421 // Sample state sensor with SensorID - 2, EntityType - System Firmware(31) 422 // State Set ID - Availability(2), Supported States - 3,4,9,10,11,13 423 std::vector<uint8_t> sample2PDR{0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 424 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 425 0x1F, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 426 0x00, 0x01, 0x02, 0x00, 0x02, 0x18, 0x2E}; 427 428 const auto& [terminusHandle2, sensorID2, 429 sensorInfo2] = parseStateSensorPDR(sample2PDR); 430 const auto& [containerID2, entityType2, 431 entityInstance2] = std::get<0>(sensorInfo2); 432 const auto& states2 = std::get<1>(sensorInfo2); 433 CompositeSensorStates statesCmp2{{3u, 4u, 9u, 10u, 11u, 13u}}; 434 435 ASSERT_EQ(le16toh(terminusHandle2), 0u); 436 ASSERT_EQ(le16toh(sensorID2), 2u); 437 ASSERT_EQ(le16toh(containerID2), 0u); 438 ASSERT_EQ(le16toh(entityType2), 31u); 439 ASSERT_EQ(le16toh(entityInstance2), 1u); 440 ASSERT_EQ(states2, statesCmp2); 441 442 // Sample state sensor with SensorID - 3, EntityType - Virtual Machine 443 // Manager(33), Composite State Sensor -2 , State Set ID - Link State(33), 444 // Supported States - 1,2, State Set ID - Configuration State(15), 445 // Supported States - 1,2,3,4 446 std::vector<uint8_t> sample3PDR{ 447 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x17, 0x00, 0x00, 448 0x00, 0x03, 0x00, 0x21, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 449 0x02, 0x21, 0x00, 0x01, 0x06, 0x0F, 0x00, 0x01, 0x1E}; 450 451 const auto& [terminusHandle3, sensorID3, 452 sensorInfo3] = parseStateSensorPDR(sample3PDR); 453 const auto& [containerID3, entityType3, 454 entityInstance3] = std::get<0>(sensorInfo3); 455 const auto& states3 = std::get<1>(sensorInfo3); 456 CompositeSensorStates statesCmp3{{1u, 2u}, {1u, 2u, 3u, 4u}}; 457 458 ASSERT_EQ(le16toh(terminusHandle3), 0u); 459 ASSERT_EQ(le16toh(sensorID3), 3u); 460 ASSERT_EQ(le16toh(containerID3), 1u); 461 ASSERT_EQ(le16toh(entityType3), 33u); 462 ASSERT_EQ(le16toh(entityInstance3), 2u); 463 ASSERT_EQ(states3, statesCmp3); 464 } 465 466 TEST(StateSensorHandler, allScenarios) 467 { 468 using namespace pldm::responder::events; 469 470 StateSensorHandler handler{"./event_jsons/good"}; 471 constexpr uint8_t eventState0 = 0; 472 constexpr uint8_t eventState1 = 1; 473 constexpr uint8_t eventState2 = 2; 474 constexpr uint8_t eventState3 = 3; 475 476 // Event Entry 1 477 { 478 StateSensorEntry entry{1, 64, 1, 0}; 479 const auto& [dbusMapping, eventStateMap] = handler.getEventInfo(entry); 480 DBusMapping mapping{"/xyz/abc/def", 481 "xyz.openbmc_project.example1.value", "value1", 482 "string"}; 483 ASSERT_EQ(mapping == dbusMapping, true); 484 485 const auto& propValue0 = eventStateMap.at(eventState0); 486 const auto& propValue1 = eventStateMap.at(eventState1); 487 const auto& propValue2 = eventStateMap.at(eventState2); 488 PropertyValue value0{std::in_place_type<std::string>, 489 "xyz.openbmc_project.State.Normal"}; 490 PropertyValue value1{std::in_place_type<std::string>, 491 "xyz.openbmc_project.State.Critical"}; 492 PropertyValue value2{std::in_place_type<std::string>, 493 "xyz.openbmc_project.State.Fatal"}; 494 ASSERT_EQ(value0 == propValue0, true); 495 ASSERT_EQ(value1 == propValue1, true); 496 ASSERT_EQ(value2 == propValue2, true); 497 } 498 499 // Event Entry 2 500 { 501 StateSensorEntry entry{1, 64, 1, 1}; 502 const auto& [dbusMapping, eventStateMap] = handler.getEventInfo(entry); 503 DBusMapping mapping{"/xyz/abc/def", 504 "xyz.openbmc_project.example2.value", "value2", 505 "uint8_t"}; 506 ASSERT_EQ(mapping == dbusMapping, true); 507 508 const auto& propValue0 = eventStateMap.at(eventState2); 509 const auto& propValue1 = eventStateMap.at(eventState3); 510 PropertyValue value0{std::in_place_type<uint8_t>, 9}; 511 PropertyValue value1{std::in_place_type<uint8_t>, 10}; 512 ASSERT_EQ(value0 == propValue0, true); 513 ASSERT_EQ(value1 == propValue1, true); 514 } 515 516 // Event Entry 3 517 { 518 StateSensorEntry entry{2, 67, 2, 0}; 519 const auto& [dbusMapping, eventStateMap] = handler.getEventInfo(entry); 520 DBusMapping mapping{"/xyz/abc/ghi", 521 "xyz.openbmc_project.example3.value", "value3", 522 "bool"}; 523 ASSERT_EQ(mapping == dbusMapping, true); 524 525 const auto& propValue0 = eventStateMap.at(eventState0); 526 const auto& propValue1 = eventStateMap.at(eventState1); 527 PropertyValue value0{std::in_place_type<bool>, false}; 528 PropertyValue value1{std::in_place_type<bool>, true}; 529 ASSERT_EQ(value0 == propValue0, true); 530 ASSERT_EQ(value1 == propValue1, true); 531 } 532 533 // Invalid Entry 534 { 535 StateSensorEntry entry{0, 0, 0, 0}; 536 ASSERT_THROW(handler.getEventInfo(entry), std::out_of_range); 537 } 538 } 539 540 TEST(TerminusLocatorPDR, BMCTerminusLocatorPDR) 541 { 542 auto inPDRRepo = pldm_pdr_init(); 543 auto outPDRRepo = pldm_pdr_init(); 544 Repo outRepo(outPDRRepo); 545 MockdBusHandler mockedUtils; 546 auto event = sdeventplus::Event::get_default(); 547 Handler handler(&mockedUtils, "", inPDRRepo, nullptr, nullptr, nullptr, 548 nullptr, event); 549 Repo inRepo(inPDRRepo); 550 getRepoByType(inRepo, outRepo, PLDM_TERMINUS_LOCATOR_PDR); 551 552 // 1 BMC terminus locator PDR in the PDR repository 553 ASSERT_EQ(outRepo.getRecordCount(), 1); 554 555 pdr_utils::PdrEntry entry; 556 auto record = pdr::getRecordByHandle(outRepo, 1, entry); 557 ASSERT_NE(record, nullptr); 558 559 auto pdr = reinterpret_cast<const pldm_terminus_locator_pdr*>(entry.data); 560 EXPECT_EQ(pdr->hdr.record_handle, 1); 561 EXPECT_EQ(pdr->hdr.version, 1); 562 EXPECT_EQ(pdr->hdr.type, PLDM_TERMINUS_LOCATOR_PDR); 563 EXPECT_EQ(pdr->hdr.record_change_num, 0); 564 EXPECT_EQ(pdr->hdr.length, 565 sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr)); 566 EXPECT_EQ(pdr->terminus_handle, TERMINUS_HANDLE); 567 EXPECT_EQ(pdr->validity, PLDM_TL_PDR_VALID); 568 EXPECT_EQ(pdr->tid, TERMINUS_ID); 569 EXPECT_EQ(pdr->container_id, 0); 570 EXPECT_EQ(pdr->terminus_locator_type, PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID); 571 EXPECT_EQ(pdr->terminus_locator_value_size, 572 sizeof(pldm_terminus_locator_type_mctp_eid)); 573 auto locatorValue = 574 reinterpret_cast<const pldm_terminus_locator_type_mctp_eid*>( 575 pdr->terminus_locator_value); 576 EXPECT_EQ(locatorValue->eid, BmcMctpEid); 577 pldm_pdr_destroy(inPDRRepo); 578 pldm_pdr_destroy(outPDRRepo); 579 } 580 581 TEST(getStateSensorReadingsHandler, testGoodRequest) 582 { 583 MockdBusHandler mockedUtils; 584 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 585 .Times(1) 586 .WillRepeatedly(Return("foo.bar")); 587 588 auto inPDRRepo = pldm_pdr_init(); 589 auto outPDRRepo = pldm_pdr_init(); 590 Repo outRepo(outPDRRepo); 591 auto event = sdeventplus::Event::get_default(); 592 Handler handler(&mockedUtils, "./pdr_jsons/state_sensor/good", inPDRRepo, 593 nullptr, nullptr, nullptr, nullptr, event); 594 Repo inRepo(inPDRRepo); 595 getRepoByType(inRepo, outRepo, PLDM_STATE_SENSOR_PDR); 596 pdr_utils::PdrEntry e; 597 auto record = pdr::getRecordByHandle(outRepo, 2, e); 598 ASSERT_NE(record, nullptr); 599 pldm_state_sensor_pdr* pdr = 600 reinterpret_cast<pldm_state_sensor_pdr*>(e.data); 601 EXPECT_EQ(pdr->hdr.type, PLDM_STATE_SENSOR_PDR); 602 603 std::vector<get_sensor_state_field> stateField; 604 uint8_t compSensorCnt{}; 605 uint8_t sensorRearmCnt = 1; 606 607 MockdBusHandler handlerObj; 608 EXPECT_CALL(handlerObj, 609 getDbusPropertyVariant(StrEq("/foo/bar"), StrEq("propertyName"), 610 StrEq("xyz.openbmc_project.Foo.Bar"))) 611 .WillOnce(Return( 612 PropertyValue(std::string("xyz.openbmc_project.Foo.Bar.V0")))); 613 614 auto rc = platform_state_sensor::getStateSensorReadingsHandler< 615 MockdBusHandler, Handler>(handlerObj, handler, 0x1, sensorRearmCnt, 616 compSensorCnt, stateField); 617 ASSERT_EQ(rc, 0); 618 ASSERT_EQ(compSensorCnt, 1); 619 ASSERT_EQ(stateField[0].sensor_op_state, PLDM_SENSOR_UNAVAILABLE); 620 ASSERT_EQ(stateField[0].present_state, PLDM_SENSOR_NORMAL); 621 ASSERT_EQ(stateField[0].previous_state, PLDM_SENSOR_UNKNOWN); 622 ASSERT_EQ(stateField[0].event_state, PLDM_SENSOR_UNKNOWN); 623 624 pldm_pdr_destroy(inPDRRepo); 625 pldm_pdr_destroy(outPDRRepo); 626 } 627 628 TEST(getStateSensorReadingsHandler, testBadRequest) 629 { 630 MockdBusHandler mockedUtils; 631 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 632 .Times(1) 633 .WillRepeatedly(Return("foo.bar")); 634 635 auto inPDRRepo = pldm_pdr_init(); 636 auto outPDRRepo = pldm_pdr_init(); 637 Repo outRepo(outPDRRepo); 638 auto event = sdeventplus::Event::get_default(); 639 Handler handler(&mockedUtils, "./pdr_jsons/state_sensor/good", inPDRRepo, 640 nullptr, nullptr, nullptr, nullptr, event); 641 Repo inRepo(inPDRRepo); 642 getRepoByType(inRepo, outRepo, PLDM_STATE_SENSOR_PDR); 643 pdr_utils::PdrEntry e; 644 auto record = pdr::getRecordByHandle(outRepo, 2, e); 645 ASSERT_NE(record, nullptr); 646 pldm_state_sensor_pdr* pdr = 647 reinterpret_cast<pldm_state_sensor_pdr*>(e.data); 648 EXPECT_EQ(pdr->hdr.type, PLDM_STATE_SENSOR_PDR); 649 650 std::vector<get_sensor_state_field> stateField; 651 uint8_t compSensorCnt{}; 652 uint8_t sensorRearmCnt = 3; 653 654 MockdBusHandler handlerObj; 655 auto rc = platform_state_sensor::getStateSensorReadingsHandler< 656 MockdBusHandler, Handler>(handlerObj, handler, 0x1, sensorRearmCnt, 657 compSensorCnt, stateField); 658 ASSERT_EQ(rc, PLDM_PLATFORM_REARM_UNAVAILABLE_IN_PRESENT_STATE); 659 660 pldm_pdr_destroy(inPDRRepo); 661 pldm_pdr_destroy(outPDRRepo); 662 } 663