| #include "libpldmresponder/pdr.hpp" |
| #include "libpldmresponder/pdr_utils.hpp" |
| #include "libpldmresponder/platform.hpp" |
| #include "libpldmresponder/platform_numeric_effecter.hpp" |
| #include "libpldmresponder/platform_state_effecter.hpp" |
| #include "mocked_utils.hpp" |
| #include "utils.hpp" |
| |
| #include <iostream> |
| |
| using namespace pldm::utils; |
| using namespace pldm::responder; |
| using namespace pldm::responder::platform; |
| using namespace pldm::responder::pdr; |
| using namespace pldm::responder::pdr_utils; |
| |
| TEST(getPDR, testGoodPath) |
| { |
| std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> |
| requestPayload{}; |
| auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); |
| size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); |
| |
| struct pldm_get_pdr_req* request = |
| reinterpret_cast<struct pldm_get_pdr_req*>(req->payload); |
| request->request_count = 100; |
| |
| auto pdrRepo = pldm_pdr_init(); |
| Handler handler("./pdr_jsons/state_effecter/good", pdrRepo, nullptr); |
| Repo repo(pdrRepo); |
| ASSERT_EQ(repo.empty(), false); |
| auto response = handler.getPDR(req, requestPayloadLength); |
| auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); |
| |
| struct pldm_get_pdr_resp* resp = |
| reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload); |
| ASSERT_EQ(PLDM_SUCCESS, resp->completion_code); |
| ASSERT_EQ(2, resp->next_record_handle); |
| ASSERT_EQ(true, resp->response_count != 0); |
| |
| pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(resp->record_data); |
| ASSERT_EQ(hdr->record_handle, 1); |
| ASSERT_EQ(hdr->version, 1); |
| |
| pldm_pdr_destroy(pdrRepo); |
| } |
| |
| TEST(getPDR, testShortRead) |
| { |
| std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> |
| requestPayload{}; |
| auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); |
| size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); |
| |
| struct pldm_get_pdr_req* request = |
| reinterpret_cast<struct pldm_get_pdr_req*>(req->payload); |
| request->request_count = 1; |
| |
| auto pdrRepo = pldm_pdr_init(); |
| Handler handler("./pdr_jsons/state_effecter/good", pdrRepo, nullptr); |
| Repo repo(pdrRepo); |
| ASSERT_EQ(repo.empty(), false); |
| auto response = handler.getPDR(req, requestPayloadLength); |
| auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); |
| struct pldm_get_pdr_resp* resp = |
| reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload); |
| ASSERT_EQ(PLDM_SUCCESS, resp->completion_code); |
| ASSERT_EQ(1, resp->response_count); |
| pldm_pdr_destroy(pdrRepo); |
| } |
| |
| TEST(getPDR, testBadRecordHandle) |
| { |
| std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> |
| requestPayload{}; |
| auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); |
| size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); |
| |
| struct pldm_get_pdr_req* request = |
| reinterpret_cast<struct pldm_get_pdr_req*>(req->payload); |
| request->record_handle = 100000; |
| request->request_count = 1; |
| |
| auto pdrRepo = pldm_pdr_init(); |
| Handler handler("./pdr_jsons/state_effecter/good", pdrRepo, nullptr); |
| Repo repo(pdrRepo); |
| ASSERT_EQ(repo.empty(), false); |
| auto response = handler.getPDR(req, requestPayloadLength); |
| auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); |
| |
| ASSERT_EQ(responsePtr->payload[0], PLDM_PLATFORM_INVALID_RECORD_HANDLE); |
| |
| pldm_pdr_destroy(pdrRepo); |
| } |
| |
| TEST(getPDR, testNoNextRecord) |
| { |
| std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> |
| requestPayload{}; |
| auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); |
| size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); |
| |
| struct pldm_get_pdr_req* request = |
| reinterpret_cast<struct pldm_get_pdr_req*>(req->payload); |
| request->record_handle = 1; |
| |
| auto pdrRepo = pldm_pdr_init(); |
| Handler handler("./pdr_jsons/state_effecter/good", pdrRepo, nullptr); |
| Repo repo(pdrRepo); |
| ASSERT_EQ(repo.empty(), false); |
| auto response = handler.getPDR(req, requestPayloadLength); |
| auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); |
| struct pldm_get_pdr_resp* resp = |
| reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload); |
| ASSERT_EQ(PLDM_SUCCESS, resp->completion_code); |
| ASSERT_EQ(2, resp->next_record_handle); |
| |
| pldm_pdr_destroy(pdrRepo); |
| } |
| |
| TEST(getPDR, testFindPDR) |
| { |
| std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES> |
| requestPayload{}; |
| auto req = reinterpret_cast<pldm_msg*>(requestPayload.data()); |
| size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr); |
| |
| struct pldm_get_pdr_req* request = |
| reinterpret_cast<struct pldm_get_pdr_req*>(req->payload); |
| request->request_count = 100; |
| |
| auto pdrRepo = pldm_pdr_init(); |
| Handler handler("./pdr_jsons/state_effecter/good", pdrRepo, nullptr); |
| Repo repo(pdrRepo); |
| ASSERT_EQ(repo.empty(), false); |
| auto response = handler.getPDR(req, requestPayloadLength); |
| |
| // Let's try to find a PDR of type stateEffecter (= 11) and entity type = |
| // 100 |
| bool found = false; |
| uint32_t handle = 0; // start asking for PDRs from recordHandle 0 |
| while (!found) |
| { |
| request->record_handle = handle; |
| auto response = handler.getPDR(req, requestPayloadLength); |
| auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); |
| struct pldm_get_pdr_resp* resp = |
| reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload); |
| ASSERT_EQ(PLDM_SUCCESS, resp->completion_code); |
| |
| handle = resp->next_record_handle; // point to the next pdr in case |
| // current is not what we want |
| |
| pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(resp->record_data); |
| std::cerr << "PDR next record handle " << handle << "\n"; |
| std::cerr << "PDR type " << hdr->type << "\n"; |
| if (hdr->type == PLDM_STATE_EFFECTER_PDR) |
| { |
| pldm_state_effecter_pdr* pdr = |
| reinterpret_cast<pldm_state_effecter_pdr*>(resp->record_data); |
| std::cerr << "PDR entity type " << pdr->entity_type << "\n"; |
| if (pdr->entity_type == 100) |
| { |
| found = true; |
| // Rest of the PDR can be accessed as need be |
| break; |
| } |
| } |
| if (!resp->next_record_handle) // no more records |
| { |
| break; |
| } |
| } |
| ASSERT_EQ(found, true); |
| |
| pldm_pdr_destroy(pdrRepo); |
| } |
| |
| TEST(setStateEffecterStatesHandler, testGoodRequest) |
| { |
| auto inPDRRepo = pldm_pdr_init(); |
| auto outPDRRepo = pldm_pdr_init(); |
| Repo outRepo(outPDRRepo); |
| Handler handler("./pdr_jsons/state_effecter/good", inPDRRepo, nullptr); |
| Repo inRepo(inPDRRepo); |
| getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR); |
| pdr_utils::PdrEntry e; |
| auto record1 = pdr::getRecordByHandle(outRepo, 1, e); |
| ASSERT_NE(record1, nullptr); |
| pldm_state_effecter_pdr* pdr = |
| reinterpret_cast<pldm_state_effecter_pdr*>(e.data); |
| EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR); |
| |
| std::vector<set_effecter_state_field> stateField; |
| stateField.push_back({PLDM_REQUEST_SET, 1}); |
| stateField.push_back({PLDM_REQUEST_SET, 1}); |
| std::string value = "xyz.openbmc_project.Foo.Bar.V1"; |
| PropertyValue propertyValue = value; |
| |
| MockdBusHandler handlerObj; |
| DBusMapping dbusMapping{"/foo/bar", "xyz.openbmc_project.Foo.Bar", |
| "propertyName", "string"}; |
| |
| EXPECT_CALL(handlerObj, setDbusProperty(dbusMapping, propertyValue)) |
| .Times(2); |
| auto rc = platform_state_effecter::setStateEffecterStatesHandler< |
| MockdBusHandler, Handler>(handlerObj, handler, 0x1, stateField); |
| ASSERT_EQ(rc, 0); |
| |
| pldm_pdr_destroy(inPDRRepo); |
| pldm_pdr_destroy(outPDRRepo); |
| } |
| |
| TEST(setStateEffecterStatesHandler, testBadRequest) |
| { |
| auto inPDRRepo = pldm_pdr_init(); |
| auto outPDRRepo = pldm_pdr_init(); |
| Repo outRepo(outPDRRepo); |
| Handler handler("./pdr_jsons/state_effecter/good", inPDRRepo, nullptr); |
| Repo inRepo(inPDRRepo); |
| getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR); |
| pdr_utils::PdrEntry e; |
| auto record1 = pdr::getRecordByHandle(outRepo, 1, e); |
| ASSERT_NE(record1, nullptr); |
| pldm_state_effecter_pdr* pdr = |
| reinterpret_cast<pldm_state_effecter_pdr*>(e.data); |
| EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR); |
| |
| std::vector<set_effecter_state_field> stateField; |
| stateField.push_back({PLDM_REQUEST_SET, 3}); |
| stateField.push_back({PLDM_REQUEST_SET, 4}); |
| |
| MockdBusHandler handlerObj; |
| auto rc = platform_state_effecter::setStateEffecterStatesHandler< |
| MockdBusHandler, Handler>(handlerObj, handler, 0x1, stateField); |
| ASSERT_EQ(rc, PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE); |
| |
| rc = platform_state_effecter::setStateEffecterStatesHandler<MockdBusHandler, |
| Handler>( |
| handlerObj, handler, 0x9, stateField); |
| ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_EFFECTER_ID); |
| |
| stateField.push_back({PLDM_REQUEST_SET, 4}); |
| rc = platform_state_effecter::setStateEffecterStatesHandler<MockdBusHandler, |
| Handler>( |
| handlerObj, handler, 0x1, stateField); |
| ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA); |
| |
| pldm_pdr_destroy(inPDRRepo); |
| pldm_pdr_destroy(outPDRRepo); |
| } |
| |
| TEST(setNumericEffecterValueHandler, testGoodRequest) |
| { |
| auto inPDRRepo = pldm_pdr_init(); |
| auto numericEffecterPdrRepo = pldm_pdr_init(); |
| Repo numericEffecterPDRs(numericEffecterPdrRepo); |
| Handler handler("./pdr_jsons/state_effecter/good", inPDRRepo, nullptr); |
| Repo inRepo(inPDRRepo); |
| getRepoByType(inRepo, numericEffecterPDRs, PLDM_NUMERIC_EFFECTER_PDR); |
| |
| pdr_utils::PdrEntry e; |
| auto record3 = pdr::getRecordByHandle(numericEffecterPDRs, 3, e); |
| ASSERT_NE(record3, nullptr); |
| |
| pldm_numeric_effecter_value_pdr* pdr = |
| reinterpret_cast<pldm_numeric_effecter_value_pdr*>(e.data); |
| EXPECT_EQ(pdr->hdr.type, PLDM_NUMERIC_EFFECTER_PDR); |
| |
| uint16_t effecterId = 3; |
| uint32_t effecterValue = 2100000000; // 2036-07-18 21:20:00 |
| PropertyValue propertyValue = static_cast<uint32_t>(effecterValue); |
| |
| MockdBusHandler handlerObj; |
| DBusMapping dbusMapping{"/foo/bar", "xyz.openbmc_project.Foo.Bar", |
| "propertyName", "uint64_t"}; |
| EXPECT_CALL(handlerObj, setDbusProperty(dbusMapping, propertyValue)) |
| .Times(1); |
| |
| auto rc = platform_numeric_effecter::setNumericEffecterValueHandler< |
| MockdBusHandler, Handler>( |
| handlerObj, handler, effecterId, PLDM_EFFECTER_DATA_SIZE_UINT32, |
| reinterpret_cast<uint8_t*>(&effecterValue), 4); |
| ASSERT_EQ(rc, 0); |
| |
| pldm_pdr_destroy(inPDRRepo); |
| pldm_pdr_destroy(numericEffecterPdrRepo); |
| } |
| |
| TEST(setNumericEffecterValueHandler, testBadRequest) |
| { |
| auto inPDRRepo = pldm_pdr_init(); |
| auto numericEffecterPdrRepo = pldm_pdr_init(); |
| Repo numericEffecterPDRs(numericEffecterPdrRepo); |
| Handler handler("./pdr_jsons/state_effecter/good", inPDRRepo, nullptr); |
| Repo inRepo(inPDRRepo); |
| getRepoByType(inRepo, numericEffecterPDRs, PLDM_NUMERIC_EFFECTER_PDR); |
| |
| pdr_utils::PdrEntry e; |
| auto record3 = pdr::getRecordByHandle(numericEffecterPDRs, 3, e); |
| ASSERT_NE(record3, nullptr); |
| |
| pldm_numeric_effecter_value_pdr* pdr = |
| reinterpret_cast<pldm_numeric_effecter_value_pdr*>(e.data); |
| EXPECT_EQ(pdr->hdr.type, PLDM_NUMERIC_EFFECTER_PDR); |
| |
| uint16_t effecterId = 3; |
| uint64_t effecterValue = 9876543210; |
| MockdBusHandler handlerObj; |
| auto rc = platform_numeric_effecter::setNumericEffecterValueHandler< |
| MockdBusHandler, Handler>( |
| handlerObj, handler, effecterId, PLDM_EFFECTER_DATA_SIZE_SINT32, |
| reinterpret_cast<uint8_t*>(&effecterValue), 3); |
| ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA); |
| |
| pldm_pdr_destroy(inPDRRepo); |
| pldm_pdr_destroy(numericEffecterPdrRepo); |
| } |