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