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 std::cerr << "PDR next record handle " << handle << "\n"; 201 std::cerr << "PDR type " << hdr->type << "\n"; 202 if (hdr->type == PLDM_STATE_EFFECTER_PDR) 203 { 204 pldm_state_effecter_pdr* pdr = 205 reinterpret_cast<pldm_state_effecter_pdr*>(resp->record_data); 206 std::cerr << "PDR entity type " << pdr->entity_type << "\n"; 207 if (pdr->entity_type == 100) 208 { 209 found = true; 210 // Rest of the PDR can be accessed as need be 211 break; 212 } 213 } 214 if (!resp->next_record_handle) // no more records 215 { 216 break; 217 } 218 } 219 ASSERT_EQ(found, true); 220 221 pldm_pdr_destroy(pdrRepo); 222 } 223 224 TEST(setStateEffecterStatesHandler, testGoodRequest) 225 { 226 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> 227 requestPayload{}; 228 auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); 229 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); 230 231 MockdBusHandler mockedUtils; 232 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 233 .Times(5) 234 .WillRepeatedly(Return("foo.bar")); 235 236 auto inPDRRepo = pldm_pdr_init(); 237 auto outPDRRepo = pldm_pdr_init(); 238 Repo outRepo(outPDRRepo); 239 auto event = sdeventplus::Event::get_default(); 240 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo, 241 nullptr, nullptr, nullptr, nullptr, event); 242 handler.getPDR(req, requestPayloadLength); 243 Repo inRepo(inPDRRepo); 244 getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR); 245 pdr_utils::PdrEntry e; 246 auto record1 = pdr::getRecordByHandle(outRepo, 2, e); 247 ASSERT_NE(record1, nullptr); 248 pldm_state_effecter_pdr* pdr = 249 reinterpret_cast<pldm_state_effecter_pdr*>(e.data); 250 EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR); 251 252 std::vector<set_effecter_state_field> stateField; 253 stateField.push_back({PLDM_REQUEST_SET, 1}); 254 stateField.push_back({PLDM_REQUEST_SET, 1}); 255 std::string value = "xyz.openbmc_project.Foo.Bar.V1"; 256 PropertyValue propertyValue = value; 257 258 DBusMapping dbusMapping{"/foo/bar", "xyz.openbmc_project.Foo.Bar", 259 "propertyName", "string"}; 260 261 EXPECT_CALL(mockedUtils, setDbusProperty(dbusMapping, propertyValue)) 262 .Times(2); 263 auto rc = platform_state_effecter::setStateEffecterStatesHandler< 264 MockdBusHandler, Handler>(mockedUtils, handler, 0x1, stateField); 265 ASSERT_EQ(rc, 0); 266 267 pldm_pdr_destroy(inPDRRepo); 268 pldm_pdr_destroy(outPDRRepo); 269 } 270 271 TEST(setStateEffecterStatesHandler, testBadRequest) 272 { 273 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> 274 requestPayload{}; 275 auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); 276 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); 277 278 MockdBusHandler mockedUtils; 279 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 280 .Times(5) 281 .WillRepeatedly(Return("foo.bar")); 282 283 auto inPDRRepo = pldm_pdr_init(); 284 auto outPDRRepo = pldm_pdr_init(); 285 Repo outRepo(outPDRRepo); 286 auto event = sdeventplus::Event::get_default(); 287 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo, 288 nullptr, nullptr, nullptr, nullptr, event); 289 handler.getPDR(req, requestPayloadLength); 290 Repo inRepo(inPDRRepo); 291 getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR); 292 pdr_utils::PdrEntry e; 293 auto record1 = pdr::getRecordByHandle(outRepo, 2, e); 294 ASSERT_NE(record1, nullptr); 295 pldm_state_effecter_pdr* pdr = 296 reinterpret_cast<pldm_state_effecter_pdr*>(e.data); 297 EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR); 298 299 std::vector<set_effecter_state_field> stateField; 300 stateField.push_back({PLDM_REQUEST_SET, 3}); 301 stateField.push_back({PLDM_REQUEST_SET, 4}); 302 303 auto rc = platform_state_effecter::setStateEffecterStatesHandler< 304 MockdBusHandler, Handler>(mockedUtils, handler, 0x1, stateField); 305 ASSERT_EQ(rc, PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE); 306 307 rc = platform_state_effecter::setStateEffecterStatesHandler<MockdBusHandler, 308 Handler>( 309 mockedUtils, handler, 0x9, stateField); 310 ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_EFFECTER_ID); 311 312 stateField.push_back({PLDM_REQUEST_SET, 4}); 313 rc = platform_state_effecter::setStateEffecterStatesHandler<MockdBusHandler, 314 Handler>( 315 mockedUtils, handler, 0x1, stateField); 316 ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA); 317 318 pldm_pdr_destroy(inPDRRepo); 319 pldm_pdr_destroy(outPDRRepo); 320 } 321 322 TEST(setNumericEffecterValueHandler, testGoodRequest) 323 { 324 MockdBusHandler mockedUtils; 325 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 326 .Times(5) 327 .WillRepeatedly(Return("foo.bar")); 328 329 auto inPDRRepo = pldm_pdr_init(); 330 auto numericEffecterPdrRepo = pldm_pdr_init(); 331 Repo numericEffecterPDRs(numericEffecterPdrRepo); 332 auto event = sdeventplus::Event::get_default(); 333 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo, 334 nullptr, nullptr, nullptr, nullptr, event); 335 Repo inRepo(inPDRRepo); 336 getRepoByType(inRepo, numericEffecterPDRs, PLDM_NUMERIC_EFFECTER_PDR); 337 338 pdr_utils::PdrEntry e; 339 auto record4 = pdr::getRecordByHandle(numericEffecterPDRs, 4, e); 340 ASSERT_NE(record4, nullptr); 341 342 pldm_numeric_effecter_value_pdr* pdr = 343 reinterpret_cast<pldm_numeric_effecter_value_pdr*>(e.data); 344 EXPECT_EQ(pdr->hdr.type, PLDM_NUMERIC_EFFECTER_PDR); 345 346 uint16_t effecterId = 3; 347 uint32_t effecterValue = 2100000000; // 2036-07-18 21:20:00 348 PropertyValue propertyValue = static_cast<uint64_t>(effecterValue); 349 350 DBusMapping dbusMapping{"/foo/bar", "xyz.openbmc_project.Foo.Bar", 351 "propertyName", "uint64_t"}; 352 EXPECT_CALL(mockedUtils, setDbusProperty(dbusMapping, propertyValue)) 353 .Times(1); 354 355 auto rc = platform_numeric_effecter::setNumericEffecterValueHandler< 356 MockdBusHandler, Handler>( 357 mockedUtils, handler, effecterId, PLDM_EFFECTER_DATA_SIZE_UINT32, 358 reinterpret_cast<uint8_t*>(&effecterValue), 4); 359 ASSERT_EQ(rc, 0); 360 361 pldm_pdr_destroy(inPDRRepo); 362 pldm_pdr_destroy(numericEffecterPdrRepo); 363 } 364 365 TEST(setNumericEffecterValueHandler, testBadRequest) 366 { 367 MockdBusHandler mockedUtils; 368 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 369 .Times(5) 370 .WillRepeatedly(Return("foo.bar")); 371 372 auto inPDRRepo = pldm_pdr_init(); 373 auto numericEffecterPdrRepo = pldm_pdr_init(); 374 Repo numericEffecterPDRs(numericEffecterPdrRepo); 375 auto event = sdeventplus::Event::get_default(); 376 Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo, 377 nullptr, nullptr, nullptr, nullptr, event); 378 Repo inRepo(inPDRRepo); 379 getRepoByType(inRepo, numericEffecterPDRs, PLDM_NUMERIC_EFFECTER_PDR); 380 381 pdr_utils::PdrEntry e; 382 auto record4 = pdr::getRecordByHandle(numericEffecterPDRs, 4, e); 383 ASSERT_NE(record4, nullptr); 384 385 pldm_numeric_effecter_value_pdr* pdr = 386 reinterpret_cast<pldm_numeric_effecter_value_pdr*>(e.data); 387 EXPECT_EQ(pdr->hdr.type, PLDM_NUMERIC_EFFECTER_PDR); 388 389 uint16_t effecterId = 3; 390 uint64_t effecterValue = 9876543210; 391 auto rc = platform_numeric_effecter::setNumericEffecterValueHandler< 392 MockdBusHandler, Handler>( 393 mockedUtils, handler, effecterId, PLDM_EFFECTER_DATA_SIZE_SINT32, 394 reinterpret_cast<uint8_t*>(&effecterValue), 3); 395 ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA); 396 397 pldm_pdr_destroy(inPDRRepo); 398 pldm_pdr_destroy(numericEffecterPdrRepo); 399 } 400 401 TEST(parseStateSensor, allScenarios) 402 { 403 // Sample state sensor with SensorID - 1, EntityType - Processor Module(67) 404 // State Set ID - Operational Running Status(11), Supported States - 3,4 405 std::vector<uint8_t> sample1PDR{0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 406 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 407 0x43, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 408 0x00, 0x01, 0x0b, 0x00, 0x01, 0x18}; 409 410 const auto& [terminusHandle1, sensorID1, sensorInfo1] = 411 parseStateSensorPDR(sample1PDR); 412 const auto& [containerID1, entityType1, entityInstance1] = 413 std::get<0>(sensorInfo1); 414 const auto& states1 = std::get<1>(sensorInfo1); 415 CompositeSensorStates statesCmp1{{3u, 4u}}; 416 417 ASSERT_EQ(le16toh(terminusHandle1), 0u); 418 ASSERT_EQ(le16toh(sensorID1), 1u); 419 ASSERT_EQ(le16toh(containerID1), 0u); 420 ASSERT_EQ(le16toh(entityType1), 67u); 421 ASSERT_EQ(le16toh(entityInstance1), 1u); 422 ASSERT_EQ(states1, statesCmp1); 423 424 // Sample state sensor with SensorID - 2, EntityType - System Firmware(31) 425 // State Set ID - Availability(2), Supported States - 3,4,9,10,11,13 426 std::vector<uint8_t> sample2PDR{0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 427 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 428 0x1F, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 429 0x00, 0x01, 0x02, 0x00, 0x02, 0x18, 0x2E}; 430 431 const auto& [terminusHandle2, sensorID2, sensorInfo2] = 432 parseStateSensorPDR(sample2PDR); 433 const auto& [containerID2, entityType2, entityInstance2] = 434 std::get<0>(sensorInfo2); 435 const auto& states2 = std::get<1>(sensorInfo2); 436 CompositeSensorStates statesCmp2{{3u, 4u, 9u, 10u, 11u, 13u}}; 437 438 ASSERT_EQ(le16toh(terminusHandle2), 0u); 439 ASSERT_EQ(le16toh(sensorID2), 2u); 440 ASSERT_EQ(le16toh(containerID2), 0u); 441 ASSERT_EQ(le16toh(entityType2), 31u); 442 ASSERT_EQ(le16toh(entityInstance2), 1u); 443 ASSERT_EQ(states2, statesCmp2); 444 445 // Sample state sensor with SensorID - 3, EntityType - Virtual Machine 446 // Manager(33), Composite State Sensor -2 , State Set ID - Link State(33), 447 // Supported States - 1,2, State Set ID - Configuration State(15), 448 // Supported States - 1,2,3,4 449 std::vector<uint8_t> sample3PDR{ 450 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x17, 0x00, 0x00, 451 0x00, 0x03, 0x00, 0x21, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 452 0x02, 0x21, 0x00, 0x01, 0x06, 0x0F, 0x00, 0x01, 0x1E}; 453 454 const auto& [terminusHandle3, sensorID3, sensorInfo3] = 455 parseStateSensorPDR(sample3PDR); 456 const auto& [containerID3, entityType3, entityInstance3] = 457 std::get<0>(sensorInfo3); 458 const auto& states3 = std::get<1>(sensorInfo3); 459 CompositeSensorStates statesCmp3{{1u, 2u}, {1u, 2u, 3u, 4u}}; 460 461 ASSERT_EQ(le16toh(terminusHandle3), 0u); 462 ASSERT_EQ(le16toh(sensorID3), 3u); 463 ASSERT_EQ(le16toh(containerID3), 1u); 464 ASSERT_EQ(le16toh(entityType3), 33u); 465 ASSERT_EQ(le16toh(entityInstance3), 2u); 466 ASSERT_EQ(states3, statesCmp3); 467 } 468 469 TEST(StateSensorHandler, allScenarios) 470 { 471 using namespace pldm::responder::events; 472 473 StateSensorHandler handler{"./event_jsons/good"}; 474 constexpr uint8_t eventState0 = 0; 475 constexpr uint8_t eventState1 = 1; 476 constexpr uint8_t eventState2 = 2; 477 constexpr uint8_t eventState3 = 3; 478 479 // Event Entry 1 480 { 481 StateSensorEntry entry{1, 64, 1, 0}; 482 const auto& [dbusMapping, eventStateMap] = handler.getEventInfo(entry); 483 DBusMapping mapping{"/xyz/abc/def", 484 "xyz.openbmc_project.example1.value", "value1", 485 "string"}; 486 ASSERT_EQ(mapping == dbusMapping, true); 487 488 const auto& propValue0 = eventStateMap.at(eventState0); 489 const auto& propValue1 = eventStateMap.at(eventState1); 490 const auto& propValue2 = eventStateMap.at(eventState2); 491 PropertyValue value0{std::in_place_type<std::string>, 492 "xyz.openbmc_project.State.Normal"}; 493 PropertyValue value1{std::in_place_type<std::string>, 494 "xyz.openbmc_project.State.Critical"}; 495 PropertyValue value2{std::in_place_type<std::string>, 496 "xyz.openbmc_project.State.Fatal"}; 497 ASSERT_EQ(value0 == propValue0, true); 498 ASSERT_EQ(value1 == propValue1, true); 499 ASSERT_EQ(value2 == propValue2, true); 500 } 501 502 // Event Entry 2 503 { 504 StateSensorEntry entry{1, 64, 1, 1}; 505 const auto& [dbusMapping, eventStateMap] = handler.getEventInfo(entry); 506 DBusMapping mapping{"/xyz/abc/def", 507 "xyz.openbmc_project.example2.value", "value2", 508 "uint8_t"}; 509 ASSERT_EQ(mapping == dbusMapping, true); 510 511 const auto& propValue0 = eventStateMap.at(eventState2); 512 const auto& propValue1 = eventStateMap.at(eventState3); 513 PropertyValue value0{std::in_place_type<uint8_t>, 9}; 514 PropertyValue value1{std::in_place_type<uint8_t>, 10}; 515 ASSERT_EQ(value0 == propValue0, true); 516 ASSERT_EQ(value1 == propValue1, true); 517 } 518 519 // Event Entry 3 520 { 521 StateSensorEntry entry{2, 67, 2, 0}; 522 const auto& [dbusMapping, eventStateMap] = handler.getEventInfo(entry); 523 DBusMapping mapping{"/xyz/abc/ghi", 524 "xyz.openbmc_project.example3.value", "value3", 525 "bool"}; 526 ASSERT_EQ(mapping == dbusMapping, true); 527 528 const auto& propValue0 = eventStateMap.at(eventState0); 529 const auto& propValue1 = eventStateMap.at(eventState1); 530 PropertyValue value0{std::in_place_type<bool>, false}; 531 PropertyValue value1{std::in_place_type<bool>, true}; 532 ASSERT_EQ(value0 == propValue0, true); 533 ASSERT_EQ(value1 == propValue1, true); 534 } 535 536 // Invalid Entry 537 { 538 StateSensorEntry entry{0, 0, 0, 0}; 539 ASSERT_THROW(handler.getEventInfo(entry), std::out_of_range); 540 } 541 } 542 543 TEST(TerminusLocatorPDR, BMCTerminusLocatorPDR) 544 { 545 auto inPDRRepo = pldm_pdr_init(); 546 auto outPDRRepo = pldm_pdr_init(); 547 Repo outRepo(outPDRRepo); 548 MockdBusHandler mockedUtils; 549 auto event = sdeventplus::Event::get_default(); 550 Handler handler(&mockedUtils, "", inPDRRepo, nullptr, nullptr, nullptr, 551 nullptr, event); 552 Repo inRepo(inPDRRepo); 553 getRepoByType(inRepo, outRepo, PLDM_TERMINUS_LOCATOR_PDR); 554 555 // 1 BMC terminus locator PDR in the PDR repository 556 ASSERT_EQ(outRepo.getRecordCount(), 1); 557 558 pdr_utils::PdrEntry entry; 559 auto record = pdr::getRecordByHandle(outRepo, 1, entry); 560 ASSERT_NE(record, nullptr); 561 562 auto pdr = reinterpret_cast<const pldm_terminus_locator_pdr*>(entry.data); 563 EXPECT_EQ(pdr->hdr.record_handle, 1); 564 EXPECT_EQ(pdr->hdr.version, 1); 565 EXPECT_EQ(pdr->hdr.type, PLDM_TERMINUS_LOCATOR_PDR); 566 EXPECT_EQ(pdr->hdr.record_change_num, 0); 567 EXPECT_EQ(pdr->hdr.length, 568 sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr)); 569 EXPECT_EQ(pdr->terminus_handle, BmcPldmTerminusHandle); 570 EXPECT_EQ(pdr->validity, PLDM_TL_PDR_VALID); 571 EXPECT_EQ(pdr->tid, BmcTerminusId); 572 EXPECT_EQ(pdr->container_id, 0); 573 EXPECT_EQ(pdr->terminus_locator_type, PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID); 574 EXPECT_EQ(pdr->terminus_locator_value_size, 575 sizeof(pldm_terminus_locator_type_mctp_eid)); 576 auto locatorValue = 577 reinterpret_cast<const pldm_terminus_locator_type_mctp_eid*>( 578 pdr->terminus_locator_value); 579 EXPECT_EQ(locatorValue->eid, BmcMctpEid); 580 pldm_pdr_destroy(inPDRRepo); 581 pldm_pdr_destroy(outPDRRepo); 582 } 583 584 TEST(getStateSensorReadingsHandler, testGoodRequest) 585 { 586 MockdBusHandler mockedUtils; 587 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 588 .Times(1) 589 .WillRepeatedly(Return("foo.bar")); 590 591 auto inPDRRepo = pldm_pdr_init(); 592 auto outPDRRepo = pldm_pdr_init(); 593 Repo outRepo(outPDRRepo); 594 auto event = sdeventplus::Event::get_default(); 595 Handler handler(&mockedUtils, "./pdr_jsons/state_sensor/good", inPDRRepo, 596 nullptr, nullptr, nullptr, nullptr, event); 597 Repo inRepo(inPDRRepo); 598 getRepoByType(inRepo, outRepo, PLDM_STATE_SENSOR_PDR); 599 pdr_utils::PdrEntry e; 600 auto record = pdr::getRecordByHandle(outRepo, 2, e); 601 ASSERT_NE(record, nullptr); 602 pldm_state_sensor_pdr* pdr = 603 reinterpret_cast<pldm_state_sensor_pdr*>(e.data); 604 EXPECT_EQ(pdr->hdr.type, PLDM_STATE_SENSOR_PDR); 605 606 std::vector<get_sensor_state_field> stateField; 607 uint8_t compSensorCnt{}; 608 uint8_t sensorRearmCnt = 1; 609 610 MockdBusHandler handlerObj; 611 EXPECT_CALL(handlerObj, 612 getDbusPropertyVariant(StrEq("/foo/bar"), StrEq("propertyName"), 613 StrEq("xyz.openbmc_project.Foo.Bar"))) 614 .WillOnce(Return( 615 PropertyValue(std::string("xyz.openbmc_project.Foo.Bar.V0")))); 616 617 auto rc = platform_state_sensor::getStateSensorReadingsHandler< 618 MockdBusHandler, Handler>(handlerObj, handler, 0x1, sensorRearmCnt, 619 compSensorCnt, stateField); 620 ASSERT_EQ(rc, 0); 621 ASSERT_EQ(compSensorCnt, 1); 622 ASSERT_EQ(stateField[0].sensor_op_state, PLDM_SENSOR_UNAVAILABLE); 623 ASSERT_EQ(stateField[0].present_state, PLDM_SENSOR_NORMAL); 624 ASSERT_EQ(stateField[0].previous_state, PLDM_SENSOR_UNKNOWN); 625 ASSERT_EQ(stateField[0].event_state, PLDM_SENSOR_UNKNOWN); 626 627 pldm_pdr_destroy(inPDRRepo); 628 pldm_pdr_destroy(outPDRRepo); 629 } 630 631 TEST(getStateSensorReadingsHandler, testBadRequest) 632 { 633 MockdBusHandler mockedUtils; 634 EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _)) 635 .Times(1) 636 .WillRepeatedly(Return("foo.bar")); 637 638 auto inPDRRepo = pldm_pdr_init(); 639 auto outPDRRepo = pldm_pdr_init(); 640 Repo outRepo(outPDRRepo); 641 auto event = sdeventplus::Event::get_default(); 642 Handler handler(&mockedUtils, "./pdr_jsons/state_sensor/good", inPDRRepo, 643 nullptr, nullptr, nullptr, nullptr, event); 644 Repo inRepo(inPDRRepo); 645 getRepoByType(inRepo, outRepo, PLDM_STATE_SENSOR_PDR); 646 pdr_utils::PdrEntry e; 647 auto record = pdr::getRecordByHandle(outRepo, 2, e); 648 ASSERT_NE(record, nullptr); 649 pldm_state_sensor_pdr* pdr = 650 reinterpret_cast<pldm_state_sensor_pdr*>(e.data); 651 EXPECT_EQ(pdr->hdr.type, PLDM_STATE_SENSOR_PDR); 652 653 std::vector<get_sensor_state_field> stateField; 654 uint8_t compSensorCnt{}; 655 uint8_t sensorRearmCnt = 3; 656 657 MockdBusHandler handlerObj; 658 auto rc = platform_state_sensor::getStateSensorReadingsHandler< 659 MockdBusHandler, Handler>(handlerObj, handler, 0x1, sensorRearmCnt, 660 compSensorCnt, stateField); 661 ASSERT_EQ(rc, PLDM_PLATFORM_REARM_UNAVAILABLE_IN_PRESENT_STATE); 662 663 pldm_pdr_destroy(inPDRRepo); 664 pldm_pdr_destroy(outPDRRepo); 665 } 666