libpldm: Reorganize source and test files

Primarily this is about moving specification-specific files into
'dsp/' (in the "DMTF Standard Publication" sense[1]) subdirectories of
both src/ and tests/.

[1]: https://www.dmtf.org/sites/default/files/standards/documents/DSP4014_2.14.0.pdf

libpldm is a concrete C implementation of the PLDM family of
specifications. This invokes some accidental complexity[2] such as the
msgbuf APIs and other concerns.

[2]: https://en.wikipedia.org/wiki/No_Silver_Bullet

Separate the essential complexity (everything under the dsp/
subdirectories) from the accidental complexity (almost everything else).

While doing so, I took the opportunity to drop the 'libpldm_' prefix
and '_test' suffix from a variety of tests. The 'libpldm_' prefix is a
hangover from the days when libpldm was a subproject of OpenBMC's pldm
repo. The '_test' suffix feels redundant given the parent directory
path.

Note that we maintain separation of the src/ and tests/. The test suite
is implemented in C++ while libpldm's APIs are declared and defined in
C. The ability to chop all the tests and C++ out of the implementation
by ignoring a subtree seems like a desirable property when vendoring the
library into other projects.

Finally, update the x86_64 GCC ABI dump, as rearranging the source
causes a lot of churn in its definitions.

Change-Id: Icffcc6cf48b3101ecd38168827c0a81cffb8f083
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
diff --git a/tests/dsp/base.cpp b/tests/dsp/base.cpp
new file mode 100644
index 0000000..5b1fb2c
--- /dev/null
+++ b/tests/dsp/base.cpp
@@ -0,0 +1,950 @@
+#include <libpldm/base.h>
+#include <libpldm/pldm_types.h>
+
+#include <array>
+#include <cstdint>
+#include <cstring>
+#include <vector>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using testing::ElementsAreArray;
+
+constexpr auto hdrSize = sizeof(pldm_msg_hdr);
+
+TEST(PackPLDMMessage, BadPathTest)
+{
+    struct pldm_header_info hdr;
+    struct pldm_header_info* hdr_ptr = NULL;
+    pldm_msg_hdr msg{};
+
+    // PLDM header information pointer is NULL
+    auto rc = pack_pldm_header(hdr_ptr, &msg);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // PLDM message pointer is NULL
+    rc = pack_pldm_header(&hdr, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // PLDM header information pointer and PLDM message pointer is NULL
+    rc = pack_pldm_header(hdr_ptr, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // RESERVED message type
+    hdr.msg_type = PLDM_RESERVED;
+    rc = pack_pldm_header(&hdr, &msg);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Instance ID out of range
+    hdr.msg_type = PLDM_REQUEST;
+    hdr.instance = 32;
+    rc = pack_pldm_header(&hdr, &msg);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // PLDM type out of range
+    hdr.msg_type = PLDM_REQUEST;
+    hdr.instance = 31;
+    hdr.pldm_type = 64;
+    rc = pack_pldm_header(&hdr, &msg);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_PLDM_TYPE);
+}
+
+TEST(PackPLDMMessage, RequestMessageGoodPath)
+{
+    struct pldm_header_info hdr;
+    pldm_msg_hdr msg{};
+
+    // Message type is REQUEST and lower range of the field values
+    hdr.msg_type = PLDM_REQUEST;
+    hdr.instance = 0;
+    hdr.pldm_type = 0;
+    hdr.command = 0;
+
+    auto rc = pack_pldm_header(&hdr, &msg);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(msg.request, 1);
+    EXPECT_EQ(msg.datagram, 0);
+    EXPECT_EQ(msg.instance_id, 0);
+    EXPECT_EQ(msg.type, 0);
+    EXPECT_EQ(msg.command, 0);
+
+    // Message type is REQUEST and upper range of the field values
+    hdr.instance = 31;
+    hdr.pldm_type = 63;
+    hdr.command = 255;
+
+    rc = pack_pldm_header(&hdr, &msg);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(msg.request, 1);
+    EXPECT_EQ(msg.datagram, 0);
+    EXPECT_EQ(msg.instance_id, 31);
+    EXPECT_EQ(msg.type, 63);
+    EXPECT_EQ(msg.command, 255);
+
+    // Message type is PLDM_ASYNC_REQUEST_NOTIFY
+    hdr.msg_type = PLDM_ASYNC_REQUEST_NOTIFY;
+
+    rc = pack_pldm_header(&hdr, &msg);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(msg.request, 1);
+    EXPECT_EQ(msg.datagram, 1);
+    EXPECT_EQ(msg.instance_id, 31);
+    EXPECT_EQ(msg.type, 63);
+    EXPECT_EQ(msg.command, 255);
+}
+
+TEST(PackPLDMMessage, ResponseMessageGoodPath)
+{
+    struct pldm_header_info hdr;
+    pldm_msg_hdr msg{};
+
+    // Message type is PLDM_RESPONSE and lower range of the field values
+    hdr.msg_type = PLDM_RESPONSE;
+    hdr.instance = 0;
+    hdr.pldm_type = 0;
+    hdr.command = 0;
+
+    auto rc = pack_pldm_header(&hdr, &msg);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(msg.request, 0);
+    EXPECT_EQ(msg.datagram, 0);
+    EXPECT_EQ(msg.instance_id, 0);
+    EXPECT_EQ(msg.type, 0);
+    EXPECT_EQ(msg.command, 0);
+
+    // Message type is PLDM_RESPONSE and upper range of the field values
+    hdr.instance = 31;
+    hdr.pldm_type = 63;
+    hdr.command = 255;
+
+    rc = pack_pldm_header(&hdr, &msg);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(msg.request, 0);
+    EXPECT_EQ(msg.datagram, 0);
+    EXPECT_EQ(msg.instance_id, 31);
+    EXPECT_EQ(msg.type, 63);
+    EXPECT_EQ(msg.command, 255);
+}
+
+TEST(UnpackPLDMMessage, BadPathTest)
+{
+    struct pldm_header_info hdr;
+
+    // PLDM message pointer is NULL
+    auto rc = unpack_pldm_header(nullptr, &hdr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(UnpackPLDMMessage, RequestMessageGoodPath)
+{
+    struct pldm_header_info hdr;
+    pldm_msg_hdr msg{};
+
+    // Unpack PLDM request message and lower range of field values
+    msg.request = 1;
+    auto rc = unpack_pldm_header(&msg, &hdr);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(hdr.msg_type, PLDM_REQUEST);
+    EXPECT_EQ(hdr.instance, 0);
+    EXPECT_EQ(hdr.pldm_type, 0);
+    EXPECT_EQ(hdr.command, 0);
+
+    // Unpack PLDM async request message and lower range of field values
+    msg.datagram = 1;
+    rc = unpack_pldm_header(&msg, &hdr);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(hdr.msg_type, PLDM_ASYNC_REQUEST_NOTIFY);
+
+    // Unpack PLDM request message and upper range of field values
+    msg.datagram = 0;
+    msg.instance_id = 31;
+    msg.type = 63;
+    msg.command = 255;
+    rc = unpack_pldm_header(&msg, &hdr);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(hdr.msg_type, PLDM_REQUEST);
+    EXPECT_EQ(hdr.instance, 31);
+    EXPECT_EQ(hdr.pldm_type, 63);
+    EXPECT_EQ(hdr.command, 255);
+}
+
+TEST(UnpackPLDMMessage, ResponseMessageGoodPath)
+{
+    struct pldm_header_info hdr;
+    pldm_msg_hdr msg{};
+
+    // Unpack PLDM response message and lower range of field values
+    auto rc = unpack_pldm_header(&msg, &hdr);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(hdr.msg_type, PLDM_RESPONSE);
+    EXPECT_EQ(hdr.instance, 0);
+    EXPECT_EQ(hdr.pldm_type, 0);
+    EXPECT_EQ(hdr.command, 0);
+
+    // Unpack PLDM response message and upper range of field values
+    msg.instance_id = 31;
+    msg.type = 63;
+    msg.command = 255;
+    rc = unpack_pldm_header(&msg, &hdr);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(hdr.msg_type, PLDM_RESPONSE);
+    EXPECT_EQ(hdr.instance, 31);
+    EXPECT_EQ(hdr.pldm_type, 63);
+    EXPECT_EQ(hdr.command, 255);
+}
+
+TEST(GetPLDMCommands, testEncodeRequest)
+{
+    uint8_t pldmType = 0x05;
+    ver32_t version{0xff, 0xff, 0xff, 0xff};
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_REQ_BYTES>
+        requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_get_commands_req(0, pldmType, version, request);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(0, memcmp(request->payload, &pldmType, sizeof(pldmType)));
+    EXPECT_EQ(0, memcmp(request->payload + sizeof(pldmType), &version,
+                        sizeof(version)));
+}
+
+TEST(GetPLDMCommands, testDecodeRequest)
+{
+    uint8_t pldmType = 0x05;
+    ver32_t version{0xff, 0xff, 0xff, 0xff};
+    uint8_t pldmTypeOut{};
+    ver32_t versionOut{0xff, 0xff, 0xff, 0xff};
+    std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_REQ_BYTES> requestMsg{};
+
+    memcpy(requestMsg.data() + hdrSize, &pldmType, sizeof(pldmType));
+    memcpy(requestMsg.data() + sizeof(pldmType) + hdrSize, &version,
+           sizeof(version));
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto rc = decode_get_commands_req(request, requestMsg.size() - hdrSize,
+                                      &pldmTypeOut, &versionOut);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(pldmTypeOut, pldmType);
+    EXPECT_EQ(0, memcmp(&versionOut, &version, sizeof(version)));
+}
+
+TEST(GetPLDMCommands, testEncodeResponse)
+{
+    uint8_t completionCode = 0;
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_RESP_BYTES>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> commands{};
+    commands[0].byte = 1;
+    commands[1].byte = 2;
+    commands[2].byte = 3;
+
+    auto rc =
+        encode_get_commands_resp(0, PLDM_SUCCESS, commands.data(), response);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    uint8_t* payload_ptr = response->payload;
+    EXPECT_EQ(completionCode, payload_ptr[0]);
+    EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]);
+    EXPECT_EQ(2,
+              payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte)]);
+    EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte) +
+                             sizeof(commands[1].byte)]);
+}
+
+TEST(GetPLDMTypes, testEncodeResponse)
+{
+    uint8_t completionCode = 0;
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_TYPES_RESP_BYTES>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    std::array<bitfield8_t, PLDM_MAX_TYPES / 8> types{};
+    types[0].byte = 1;
+    types[1].byte = 2;
+    types[2].byte = 3;
+
+    auto rc = encode_get_types_resp(0, PLDM_SUCCESS, types.data(), response);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    uint8_t* payload_ptr = response->payload;
+    EXPECT_EQ(completionCode, payload_ptr[0]);
+    EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]);
+    EXPECT_EQ(2, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte)]);
+    EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte) +
+                             sizeof(types[1].byte)]);
+}
+
+TEST(GetPLDMTypes, testGoodDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_TYPES_RESP_BYTES> responseMsg{};
+    responseMsg[1 + hdrSize] = 1;
+    responseMsg[2 + hdrSize] = 2;
+    responseMsg[3 + hdrSize] = 3;
+    std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{};
+
+    uint8_t completion_code;
+    responseMsg[hdrSize] = PLDM_SUCCESS;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize,
+                                    &completion_code, outTypes.data());
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completion_code, PLDM_SUCCESS);
+    EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte);
+    EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte);
+    EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte);
+}
+
+TEST(GetPLDMTypes, testBadDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_TYPES_RESP_BYTES> responseMsg{};
+    responseMsg[1 + hdrSize] = 1;
+    responseMsg[2 + hdrSize] = 2;
+    responseMsg[3 + hdrSize] = 3;
+    std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{};
+
+    uint8_t retcompletion_code = 0;
+    responseMsg[hdrSize] = PLDM_SUCCESS;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize - 1,
+                                    &retcompletion_code, outTypes.data());
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetPLDMCommands, testGoodDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{};
+    responseMsg[1 + hdrSize] = 1;
+    responseMsg[2 + hdrSize] = 2;
+    responseMsg[3 + hdrSize] = 3;
+    std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{};
+
+    uint8_t completion_code;
+    responseMsg[hdrSize] = PLDM_SUCCESS;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_get_commands_resp(response, responseMsg.size() - hdrSize,
+                                       &completion_code, outTypes.data());
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completion_code, PLDM_SUCCESS);
+    EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte);
+    EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte);
+    EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte);
+}
+
+TEST(GetPLDMCommands, testBadDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{};
+    responseMsg[1 + hdrSize] = 1;
+    responseMsg[2 + hdrSize] = 2;
+    responseMsg[3 + hdrSize] = 3;
+    std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{};
+
+    uint8_t retcompletion_code = 0;
+    responseMsg[hdrSize] = PLDM_SUCCESS;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc =
+        decode_get_commands_resp(response, responseMsg.size() - hdrSize - 1,
+                                 &retcompletion_code, outTypes.data());
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetPLDMVersion, testGoodEncodeRequest)
+{
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES>
+        requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    uint8_t pldmType = 0x03;
+    uint32_t transferHandle = 0x0;
+    uint8_t opFlag = 0x01;
+
+    auto rc =
+        encode_get_version_req(0, transferHandle, opFlag, pldmType, request);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(
+        0, memcmp(request->payload, &transferHandle, sizeof(transferHandle)));
+    EXPECT_EQ(0, memcmp(request->payload + sizeof(transferHandle), &opFlag,
+                        sizeof(opFlag)));
+    EXPECT_EQ(0,
+              memcmp(request->payload + sizeof(transferHandle) + sizeof(opFlag),
+                     &pldmType, sizeof(pldmType)));
+}
+
+TEST(GetPLDMVersion, testBadEncodeRequest)
+{
+    uint8_t pldmType = 0x03;
+    uint32_t transferHandle = 0x0;
+    uint8_t opFlag = 0x01;
+
+    auto rc =
+        encode_get_version_req(0, transferHandle, opFlag, pldmType, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetPLDMVersion, testEncodeResponse)
+{
+    uint8_t completionCode = 0;
+    uint32_t transferHandle = 0;
+    uint8_t flag = PLDM_START_AND_END;
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    ver32_t version = {0xff, 0xff, 0xff, 0xff};
+
+    auto rc = encode_get_version_resp(0, PLDM_SUCCESS, 0, PLDM_START_AND_END,
+                                      &version, sizeof(ver32_t), response);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, response->payload[0]);
+    EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]),
+                        &transferHandle, sizeof(transferHandle)));
+    EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
+                            sizeof(transferHandle),
+                        &flag, sizeof(flag)));
+    EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
+                            sizeof(transferHandle) + sizeof(flag),
+                        &version, sizeof(version)));
+}
+
+TEST(GetPLDMVersion, testDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_VERSION_REQ_BYTES> requestMsg{};
+    uint32_t transferHandle = 0x0;
+    uint32_t retTransferHandle = 0x0;
+    uint8_t flag = PLDM_GET_FIRSTPART;
+    uint8_t retFlag = PLDM_GET_FIRSTPART;
+    uint8_t pldmType = PLDM_BASE;
+    uint8_t retType = PLDM_BASE;
+
+    memcpy(requestMsg.data() + hdrSize, &transferHandle,
+           sizeof(transferHandle));
+    memcpy(requestMsg.data() + sizeof(transferHandle) + hdrSize, &flag,
+           sizeof(flag));
+    memcpy(requestMsg.data() + sizeof(transferHandle) + sizeof(flag) + hdrSize,
+           &pldmType, sizeof(pldmType));
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = decode_get_version_req(request, requestMsg.size() - hdrSize,
+                                     &retTransferHandle, &retFlag, &retType);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(transferHandle, retTransferHandle);
+    EXPECT_EQ(flag, retFlag);
+    EXPECT_EQ(pldmType, retType);
+}
+
+TEST(GetPLDMVersion, testDecodeResponse)
+{
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES>
+        responseMsg{};
+    uint32_t transferHandle = 0x0;
+    uint32_t retTransferHandle = 0x0;
+    uint8_t flag = PLDM_START_AND_END;
+    uint8_t retFlag = PLDM_START_AND_END;
+    uint8_t completionCode = 0;
+    ver32_t version = {0xff, 0xff, 0xff, 0xff};
+    ver32_t versionOut;
+    uint8_t completion_code;
+
+    memcpy(responseMsg.data() + sizeof(completionCode) + hdrSize,
+           &transferHandle, sizeof(transferHandle));
+    memcpy(responseMsg.data() + sizeof(completionCode) +
+               sizeof(transferHandle) + hdrSize,
+           &flag, sizeof(flag));
+    memcpy(responseMsg.data() + sizeof(completionCode) +
+               sizeof(transferHandle) + sizeof(flag) + hdrSize,
+           &version, sizeof(version));
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_get_version_resp(response, responseMsg.size() - hdrSize,
+                                      &completion_code, &retTransferHandle,
+                                      &retFlag, &versionOut);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(transferHandle, retTransferHandle);
+    EXPECT_EQ(flag, retFlag);
+
+    EXPECT_EQ(versionOut.major, version.major);
+    EXPECT_EQ(versionOut.minor, version.minor);
+    EXPECT_EQ(versionOut.update, version.update);
+    EXPECT_EQ(versionOut.alpha, version.alpha);
+}
+
+TEST(GetTID, testEncodeRequest)
+{
+    pldm_msg request{};
+
+    auto rc = encode_get_tid_req(0, &request);
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+}
+
+TEST(GetTID, testEncodeResponse)
+{
+    uint8_t completionCode = 0;
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_TID_RESP_BYTES>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    uint8_t tid = 1;
+
+    auto rc = encode_get_tid_resp(0, PLDM_SUCCESS, tid, response);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    uint8_t* payload = response->payload;
+    EXPECT_EQ(completionCode, payload[0]);
+    EXPECT_EQ(1, payload[sizeof(completionCode)]);
+}
+
+TEST(GetTID, testDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_TID_RESP_BYTES> responseMsg{};
+    responseMsg[1 + hdrSize] = 1;
+
+    uint8_t tid;
+    uint8_t completion_code;
+    responseMsg[hdrSize] = PLDM_SUCCESS;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_get_tid_resp(response, responseMsg.size() - hdrSize,
+                                  &completion_code, &tid);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completion_code, PLDM_SUCCESS);
+    EXPECT_EQ(tid, 1);
+}
+
+TEST(MultipartReceive, testDecodeRequestPass)
+{
+    constexpr uint8_t kPldmType = PLDM_BASE;
+    constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
+    constexpr uint32_t kTransferCtx = 0x01;
+    constexpr uint32_t kTransferHandle = 0x10;
+    constexpr uint32_t kSectionOffset = 0x0;
+    constexpr uint32_t kSectionLength = 0x10;
+    uint8_t pldm_type = 0x0;
+    uint8_t flag = PLDM_GET_FIRSTPART;
+    uint32_t transfer_ctx;
+    uint32_t transfer_handle;
+    uint32_t section_offset;
+    uint32_t section_length;
+
+    // Header values don't matter for this test.
+    pldm_msg_hdr hdr{};
+    // Assign values to the packet struct and memcpy to ensure correct byte
+    // ordering.
+    pldm_multipart_receive_req req_pkt = {
+        .pldm_type = kPldmType,
+        .transfer_opflag = kFlag,
+        .transfer_ctx = kTransferCtx,
+        .transfer_handle = kTransferHandle,
+        .section_offset = kSectionOffset,
+        .section_length = kSectionLength,
+    };
+    std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    std::memcpy(req.data(), &hdr, sizeof(hdr));
+    std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
+
+    pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
+    int rc = decode_multipart_receive_req(
+        pldm_request, req.size() - hdrSize, &pldm_type, &flag, &transfer_ctx,
+        &transfer_handle, &section_offset, &section_length);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(pldm_type, kPldmType);
+    EXPECT_EQ(flag, kFlag);
+    EXPECT_EQ(transfer_ctx, kTransferCtx);
+    EXPECT_EQ(transfer_handle, kTransferHandle);
+    EXPECT_EQ(section_offset, kSectionOffset);
+    EXPECT_EQ(section_length, kSectionLength);
+}
+
+TEST(MultipartReceive, testDecodeRequestFailNullData)
+{
+    EXPECT_EQ(decode_multipart_receive_req(NULL, 0, NULL, NULL, NULL, NULL,
+                                           NULL, NULL),
+              PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(MultipartReceive, testDecodeRequestFailBadLength)
+{
+    constexpr uint8_t kPldmType = PLDM_BASE;
+    constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
+    uint8_t pldm_type;
+    uint8_t flag;
+    uint32_t transfer_ctx;
+    uint32_t transfer_handle;
+    uint32_t section_offset;
+    uint32_t section_length;
+
+    // Header values don't matter for this test.
+    pldm_msg_hdr hdr{};
+    // Assign values to the packet struct and memcpy to ensure correct byte
+    // ordering.
+    pldm_multipart_receive_req req_pkt{};
+    req_pkt.pldm_type = kPldmType;
+    req_pkt.transfer_opflag = kFlag;
+
+    std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    std::memcpy(req.data(), &hdr, sizeof(hdr));
+    std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
+
+    pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
+    EXPECT_EQ(decode_multipart_receive_req(
+                  pldm_request, (req.size() - hdrSize) + 1, &pldm_type, &flag,
+                  &transfer_ctx, &transfer_handle, &section_offset,
+                  &section_length),
+              PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(MultipartReceive, testDecodeRequestFailBadPldmType)
+{
+    constexpr uint8_t kPldmType = 0xff;
+    constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
+    uint8_t pldm_type;
+    uint8_t flag;
+    uint32_t transfer_ctx;
+    uint32_t transfer_handle;
+    uint32_t section_offset;
+    uint32_t section_length;
+
+    // Header values don't matter for this test.
+    pldm_msg_hdr hdr{};
+    // Assign values to the packet struct and memcpy to ensure correct byte
+    // ordering.
+    pldm_multipart_receive_req req_pkt{};
+    req_pkt.pldm_type = kPldmType;
+    req_pkt.transfer_opflag = kFlag;
+
+    std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    std::memcpy(req.data(), &hdr, sizeof(hdr));
+    std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
+
+    pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
+    EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
+                                           &pldm_type, &flag, &transfer_ctx,
+                                           &transfer_handle, &section_offset,
+                                           &section_length),
+              PLDM_ERROR_INVALID_PLDM_TYPE);
+}
+
+TEST(MultipartReceive, testDecodeRequestFailBadTransferFlag)
+{
+    constexpr uint8_t kPldmType = PLDM_BASE;
+    constexpr uint8_t kFlag = PLDM_XFER_CURRENT_PART + 0x10;
+    uint8_t pldm_type;
+    uint8_t flag;
+    uint32_t transfer_ctx;
+    uint32_t transfer_handle;
+    uint32_t section_offset;
+    uint32_t section_length;
+
+    // Header values don't matter for this test.
+    pldm_msg_hdr hdr{};
+    // Assign values to the packet struct and memcpy to ensure correct byte
+    // ordering.
+    pldm_multipart_receive_req req_pkt{};
+    req_pkt.pldm_type = kPldmType;
+    req_pkt.transfer_opflag = kFlag;
+
+    std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    std::memcpy(req.data(), &hdr, sizeof(hdr));
+    std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
+
+    pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
+    EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
+                                           &pldm_type, &flag, &transfer_ctx,
+                                           &transfer_handle, &section_offset,
+                                           &section_length),
+              PLDM_INVALID_TRANSFER_OPERATION_FLAG);
+}
+
+TEST(MultipartReceive, testDecodeRequestFailBadOffset)
+{
+    constexpr uint8_t kPldmType = PLDM_BASE;
+    constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART;
+    constexpr uint32_t kTransferHandle = 0x01;
+    constexpr uint32_t kSectionOffset = 0x0;
+    uint8_t pldm_type;
+    uint8_t flag;
+    uint32_t transfer_ctx;
+    uint32_t transfer_handle;
+    uint32_t section_offset;
+    uint32_t section_length;
+
+    // Header values don't matter for this test.
+    pldm_msg_hdr hdr{};
+    // Assign values to the packet struct and memcpy to ensure correct byte
+    // ordering.
+    pldm_multipart_receive_req req_pkt{};
+    req_pkt.pldm_type = kPldmType;
+    req_pkt.transfer_opflag = kFlag;
+    req_pkt.transfer_handle = kTransferHandle;
+    req_pkt.section_offset = kSectionOffset;
+
+    std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    std::memcpy(req.data(), &hdr, sizeof(hdr));
+    std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
+
+    pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
+    EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
+                                           &pldm_type, &flag, &transfer_ctx,
+                                           &transfer_handle, &section_offset,
+                                           &section_length),
+              PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(MultipartReceive, testDecodeRequestFailBadHandle)
+{
+    constexpr uint8_t kPldmType = PLDM_BASE;
+    constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART;
+    constexpr uint32_t kSectionOffset = 0x100;
+    constexpr uint32_t kTransferHandle = 0x0;
+    uint8_t pldm_type;
+    uint8_t flag;
+    uint32_t transfer_ctx;
+    uint32_t transfer_handle;
+    uint32_t section_offset;
+    uint32_t section_length;
+
+    // Header values don't matter for this test.
+    pldm_msg_hdr hdr{};
+    // Assign values to the packet struct and memcpy to ensure correct byte
+    // ordering.
+    pldm_multipart_receive_req req_pkt{};
+    req_pkt.pldm_type = kPldmType;
+    req_pkt.transfer_opflag = kFlag;
+    req_pkt.transfer_handle = kTransferHandle;
+    req_pkt.section_offset = kSectionOffset;
+
+    std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    std::memcpy(req.data(), &hdr, sizeof(hdr));
+    std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
+
+    pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
+    EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
+                                           &pldm_type, &flag, &transfer_ctx,
+                                           &transfer_handle, &section_offset,
+                                           &section_length),
+              PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(CcOnlyResponse, testEncode)
+{
+    struct pldm_msg responseMsg;
+
+    auto rc =
+        encode_cc_only_resp(0 /*instance id*/, 1 /*pldm type*/, 2 /*command*/,
+                            3 /*complection code*/, &responseMsg);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    auto p = reinterpret_cast<uint8_t*>(&responseMsg);
+    EXPECT_THAT(std::vector<uint8_t>(p, p + sizeof(responseMsg)),
+                ElementsAreArray({0, 1, 2, 3}));
+
+    rc = encode_cc_only_resp(PLDM_INSTANCE_MAX + 1, 1, 2, 3, &responseMsg);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_cc_only_resp(0, 1, 2, 3, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(SetTID, testGoodEncodeRequest)
+{
+    uint8_t instanceId = 0;
+    uint8_t tid = 0x01;
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_set_tid_req(instanceId, tid, request);
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+
+    EXPECT_EQ(request->hdr.command, PLDM_SET_TID);
+    EXPECT_EQ(request->hdr.type, PLDM_BASE);
+    EXPECT_EQ(request->hdr.request, 1);
+    EXPECT_EQ(request->hdr.datagram, 0);
+    EXPECT_EQ(request->hdr.instance_id, instanceId);
+    EXPECT_EQ(0, memcmp(request->payload, &tid, sizeof(tid)));
+}
+
+TEST(SetTID, testBadEncodeRequest)
+{
+    uint8_t tid = 0x01;
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_set_tid_req(0, tid, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_set_tid_req(0, 0, request);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_set_tid_req(0, 0xff, request);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PldmMsgHdr, correlateSuccess)
+{
+    static const struct pldm_msg_hdr req = {
+        .instance_id = 0,
+        .reserved = 0,
+        .datagram = 0,
+        .request = 1,
+        .type = 0,
+        .header_ver = 1,
+        .command = 0x01,
+    };
+    static const struct pldm_msg_hdr resp = {
+        .instance_id = 0,
+        .reserved = 0,
+        .datagram = 0,
+        .request = 0,
+        .type = 0,
+        .header_ver = 1,
+        .command = 0x01,
+    };
+
+    ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), true);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PldmMsgHdr, correlateFailInstanceID)
+{
+    static const struct pldm_msg_hdr req = {
+        .instance_id = 0,
+        .reserved = 0,
+        .datagram = 0,
+        .request = 1,
+        .type = 0,
+        .header_ver = 1,
+        .command = 0x01,
+    };
+    static const struct pldm_msg_hdr resp = {
+        .instance_id = 1,
+        .reserved = 0,
+        .datagram = 0,
+        .request = 0,
+        .type = 0,
+        .header_ver = 1,
+        .command = 0x01,
+    };
+
+    ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PldmMsgHdr, correlateFailRequest)
+{
+    static const struct pldm_msg_hdr req = {
+        .instance_id = 0,
+        .reserved = 0,
+        .datagram = 0,
+        .request = 1,
+        .type = 0,
+        .header_ver = 1,
+        .command = 0x01,
+    };
+    static const struct pldm_msg_hdr resp = {
+        .instance_id = 0,
+        .reserved = 0,
+        .datagram = 0,
+        .request = 1,
+        .type = 0,
+        .header_ver = 1,
+        .command = 0x01,
+    };
+
+    ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PldmMsgHdr, correlateFailType)
+{
+    static const struct pldm_msg_hdr req = {
+        .instance_id = 0,
+        .reserved = 0,
+        .datagram = 0,
+        .request = 1,
+        .type = 0,
+        .header_ver = 1,
+        .command = 0x01,
+    };
+    static const struct pldm_msg_hdr resp = {
+        .instance_id = 0,
+        .reserved = 0,
+        .datagram = 0,
+        .request = 0,
+        .type = 1,
+        .header_ver = 1,
+        .command = 0x01,
+    };
+
+    ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PldmMsgHdr, correlateFailCommand)
+{
+    static const struct pldm_msg_hdr req = {
+        .instance_id = 0,
+        .reserved = 0,
+        .datagram = 0,
+        .request = 1,
+        .type = 0,
+        .header_ver = 1,
+        .command = 0x01,
+    };
+    static const struct pldm_msg_hdr resp = {
+        .instance_id = 0,
+        .reserved = 0,
+        .datagram = 0,
+        .request = 0,
+        .type = 0,
+        .header_ver = 1,
+        .command = 0x02,
+    };
+
+    ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PldmMsgHdr, correlateFailRequestIsResponse)
+{
+    static const struct pldm_msg_hdr req = {
+        .instance_id = 0,
+        .reserved = 0,
+        .datagram = 0,
+        .request = 0,
+        .type = 0,
+        .header_ver = 1,
+        .command = 0x01,
+    };
+    static const struct pldm_msg_hdr resp = {
+        .instance_id = 0,
+        .reserved = 0,
+        .datagram = 0,
+        .request = 0,
+        .type = 0,
+        .header_ver = 1,
+        .command = 0x02,
+    };
+
+    ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
+}
+#endif
diff --git a/tests/dsp/bios.cpp b/tests/dsp/bios.cpp
new file mode 100644
index 0000000..3f64a2a
--- /dev/null
+++ b/tests/dsp/bios.cpp
@@ -0,0 +1,1095 @@
+#include <endian.h>
+#include <libpldm/base.h>
+#include <libpldm/bios.h>
+#include <libpldm/utils.h>
+
+#include <array>
+#include <cstdint>
+#include <cstring>
+#include <memory>
+
+#include <gtest/gtest.h>
+
+constexpr auto hdrSize = sizeof(pldm_msg_hdr);
+
+TEST(GetDateTime, testEncodeRequest)
+{
+    pldm_msg request{};
+
+    auto rc = encode_get_date_time_req(0, &request);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+}
+
+TEST(GetDateTime, testEncodeResponse)
+{
+    uint8_t completionCode = 0;
+    uint8_t seconds = 50;
+    uint8_t minutes = 20;
+    uint8_t hours = 5;
+    uint8_t day = 23;
+    uint8_t month = 11;
+    uint16_t year = 2019;
+
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_DATE_TIME_RESP_BYTES>
+        responseMsg{};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = encode_get_date_time_resp(0, PLDM_SUCCESS, seconds, minutes,
+                                        hours, day, month, year, response);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, response->payload[0]);
+
+    EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]),
+                        &seconds, sizeof(seconds)));
+    EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
+                            sizeof(seconds),
+                        &minutes, sizeof(minutes)));
+    EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
+                            sizeof(seconds) + sizeof(minutes),
+                        &hours, sizeof(hours)));
+    EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
+                            sizeof(seconds) + sizeof(minutes) + sizeof(hours),
+                        &day, sizeof(day)));
+    EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
+                            sizeof(seconds) + sizeof(minutes) + sizeof(hours) +
+                            sizeof(day),
+                        &month, sizeof(month)));
+    uint16_t yearLe = htole16(year);
+    EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
+                            sizeof(seconds) + sizeof(minutes) + sizeof(hours) +
+                            sizeof(day) + sizeof(month),
+                        &yearLe, sizeof(yearLe)));
+}
+
+TEST(GetDateTime, testDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_DATE_TIME_RESP_BYTES> responseMsg{};
+
+    uint8_t completionCode = 0;
+
+    uint8_t seconds = 55;
+    uint8_t minutes = 2;
+    uint8_t hours = 8;
+    uint8_t day = 9;
+    uint8_t month = 7;
+    uint16_t year = 2020;
+    uint16_t yearLe = htole16(year);
+
+    uint8_t retSeconds = 0;
+    uint8_t retMinutes = 0;
+    uint8_t retHours = 0;
+    uint8_t retDay = 0;
+    uint8_t retMonth = 0;
+    uint16_t retYear = 0;
+
+    memcpy(responseMsg.data() + sizeof(completionCode) + hdrSize, &seconds,
+           sizeof(seconds));
+    memcpy(responseMsg.data() + sizeof(completionCode) + sizeof(seconds) +
+               hdrSize,
+           &minutes, sizeof(minutes));
+    memcpy(responseMsg.data() + sizeof(completionCode) + sizeof(seconds) +
+               sizeof(minutes) + hdrSize,
+           &hours, sizeof(hours));
+    memcpy(responseMsg.data() + sizeof(completionCode) + sizeof(seconds) +
+               sizeof(minutes) + sizeof(hours) + hdrSize,
+           &day, sizeof(day));
+    memcpy(responseMsg.data() + sizeof(completionCode) + sizeof(seconds) +
+               sizeof(minutes) + sizeof(hours) + sizeof(day) + hdrSize,
+           &month, sizeof(month));
+    memcpy(responseMsg.data() + sizeof(completionCode) + sizeof(seconds) +
+               sizeof(minutes) + sizeof(hours) + sizeof(day) + sizeof(month) +
+               hdrSize,
+           &yearLe, sizeof(yearLe));
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_get_date_time_resp(
+        response, responseMsg.size() - hdrSize, &completionCode, &retSeconds,
+        &retMinutes, &retHours, &retDay, &retMonth, &retYear);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(seconds, retSeconds);
+    EXPECT_EQ(minutes, retMinutes);
+    EXPECT_EQ(hours, retHours);
+    EXPECT_EQ(day, retDay);
+    EXPECT_EQ(month, retMonth);
+    EXPECT_EQ(year, retYear);
+}
+
+TEST(SetDateTime, testGoodEncodeResponse)
+{
+    uint8_t instanceId = 0;
+    uint8_t completionCode = PLDM_SUCCESS;
+
+    std::array<uint8_t, hdrSize + sizeof(struct pldm_only_cc_resp)>
+        responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+
+    auto rc = encode_set_date_time_resp(instanceId, completionCode, response,
+                                        responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_only_cc_resp* resp =
+        reinterpret_cast<struct pldm_only_cc_resp*>(response->payload);
+    EXPECT_EQ(completionCode, resp->completion_code);
+}
+
+TEST(SetDateTime, testBadEncodeResponse)
+{
+
+    uint8_t instanceId = 10;
+    uint8_t completionCode = PLDM_SUCCESS;
+    std::array<uint8_t, hdrSize + sizeof(struct pldm_only_cc_resp)>
+        responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+    auto rc = encode_set_date_time_resp(instanceId, completionCode, nullptr,
+                                        responseMsg.size() - hdrSize);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc = encode_set_date_time_resp(instanceId, completionCode, response,
+                                   responseMsg.size() - hdrSize - 1);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(SetDateTime, testGoodDecodeResponse)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    std::array<uint8_t, hdrSize + sizeof(struct pldm_only_cc_resp)>
+        responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+    struct pldm_only_cc_resp* resp =
+        reinterpret_cast<struct pldm_only_cc_resp*>(response->payload);
+
+    resp->completion_code = completionCode;
+
+    uint8_t retCompletionCode;
+    auto rc = decode_set_date_time_resp(response, responseMsg.size() - hdrSize,
+                                        &retCompletionCode);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, retCompletionCode);
+}
+
+TEST(SetDateTime, testBadDecodeResponse)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+
+    std::array<uint8_t, hdrSize + sizeof(struct pldm_only_cc_resp)>
+        responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+    auto rc = decode_set_date_time_resp(nullptr, responseMsg.size() - hdrSize,
+                                        &completionCode);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_set_date_time_resp(response, responseMsg.size() - hdrSize - 1,
+                                   &completionCode);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(SetDateTime, testGoodEncodeRequset)
+{
+    uint8_t instanceId = 0;
+    uint8_t seconds = 50;
+    uint8_t minutes = 20;
+    uint8_t hours = 10;
+    uint8_t day = 11;
+    uint8_t month = 11;
+    uint16_t year = 2019;
+
+    std::array<uint8_t, hdrSize + sizeof(struct pldm_set_date_time_req)>
+        requestMsg{};
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto rc = encode_set_date_time_req(instanceId, seconds, minutes, hours, day,
+                                       month, year, request,
+                                       requestMsg.size() - hdrSize);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_set_date_time_req* req =
+        reinterpret_cast<struct pldm_set_date_time_req*>(request->payload);
+    EXPECT_EQ(seconds, bcd2dec8(req->seconds));
+    EXPECT_EQ(minutes, bcd2dec8(req->minutes));
+    EXPECT_EQ(hours, bcd2dec8(req->hours));
+    EXPECT_EQ(day, bcd2dec8(req->day));
+    EXPECT_EQ(month, bcd2dec8(req->month));
+    EXPECT_EQ(year, bcd2dec16(le16toh(req->year)));
+}
+
+TEST(SetDateTime, testBadEncodeRequset)
+{
+    uint8_t instanceId = 0;
+
+    uint8_t seconds = 50;
+    uint8_t minutes = 20;
+    uint8_t hours = 10;
+    uint8_t day = 13;
+    uint8_t month = 11;
+    uint16_t year = 2019;
+
+    uint8_t erday = 43;
+
+    std::array<uint8_t, hdrSize + sizeof(struct pldm_set_date_time_req)>
+        requestMsg{};
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_set_date_time_req(instanceId, seconds, minutes, hours, day,
+                                       month, year, nullptr,
+                                       requestMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_set_date_time_req(instanceId, seconds, minutes, hours, erday,
+                                  month, year, request,
+                                  requestMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_set_date_time_req(instanceId, seconds, minutes, hours, day,
+                                  month, year, request,
+                                  requestMsg.size() - hdrSize - 4);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(SetDateTime, testGoodDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + sizeof(struct pldm_set_date_time_req)>
+        requestMsg{};
+    uint8_t seconds = 0x50;
+    uint8_t minutes = 0x20;
+    uint8_t hours = 0x10;
+    uint8_t day = 0x11;
+    uint8_t month = 0x11;
+    uint16_t year = 0x2019;
+
+    auto request = reinterpret_cast<struct pldm_msg*>(requestMsg.data());
+    struct pldm_set_date_time_req* req =
+        reinterpret_cast<struct pldm_set_date_time_req*>(request->payload);
+    req->seconds = seconds;
+    req->minutes = minutes;
+    req->hours = hours;
+    req->day = day;
+    req->month = month;
+    req->year = htole16(year);
+
+    uint8_t retseconds;
+    uint8_t retminutes;
+    uint8_t rethours;
+    uint8_t retday;
+    uint8_t retmonth;
+    uint16_t retyear;
+
+    auto rc = decode_set_date_time_req(request, requestMsg.size() - hdrSize,
+                                       &retseconds, &retminutes, &rethours,
+                                       &retday, &retmonth, &retyear);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retseconds, 50);
+    EXPECT_EQ(retminutes, 20);
+    EXPECT_EQ(rethours, 10);
+    EXPECT_EQ(retday, 11);
+    EXPECT_EQ(retmonth, 11);
+    EXPECT_EQ(retyear, 2019);
+}
+
+TEST(SetDateTime, testBadDecodeRequest)
+{
+    uint8_t seconds = 0x50;
+    uint8_t minutes = 0x20;
+    uint8_t hours = 0x10;
+    uint8_t day = 0x11;
+    uint8_t month = 0x11;
+    uint16_t year = htole16(0x2019);
+
+    std::array<uint8_t, hdrSize + sizeof(struct pldm_set_date_time_req)>
+        requestMsg{};
+
+    auto request = reinterpret_cast<struct pldm_msg*>(requestMsg.data());
+
+    decode_set_date_time_req(request, requestMsg.size() - hdrSize, &seconds,
+                             &minutes, &hours, &day, &month, &year);
+
+    auto rc =
+        decode_set_date_time_req(nullptr, requestMsg.size() - hdrSize, &seconds,
+                                 &minutes, &hours, &day, &month, &year);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_set_date_time_req(request, requestMsg.size() - hdrSize, nullptr,
+                                  nullptr, nullptr, nullptr, nullptr, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_set_date_time_req(request, requestMsg.size() - hdrSize - 4,
+                                  &seconds, &minutes, &hours, &day, &month,
+                                  &year);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetBIOSTable, testGoodEncodeResponse)
+{
+    std::array<uint8_t,
+               sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES + 4>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint32_t nextTransferHandle = 32;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    std::array<uint8_t, 4> tableData{1, 2, 3, 4};
+
+    auto rc = encode_get_bios_table_resp(
+        0, PLDM_SUCCESS, nextTransferHandle, transferFlag, tableData.data(),
+        sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES + 4,
+        response);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_get_bios_table_resp* resp =
+        reinterpret_cast<struct pldm_get_bios_table_resp*>(response->payload);
+
+    EXPECT_EQ(completionCode, resp->completion_code);
+    EXPECT_EQ(nextTransferHandle, le32toh(resp->next_transfer_handle));
+    EXPECT_EQ(transferFlag, resp->transfer_flag);
+    EXPECT_EQ(0, memcmp(tableData.data(), resp->table_data, tableData.size()));
+}
+
+TEST(GetBIOSTable, testBadEncodeResponse)
+{
+    uint32_t nextTransferHandle = 32;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    std::array<uint8_t, 4> tableData{1, 2, 3, 4};
+
+    auto rc = encode_get_bios_table_resp(
+        0, PLDM_SUCCESS, nextTransferHandle, transferFlag, tableData.data(),
+        sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES + 4, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetBIOSTable, testGoodEncodeRequest)
+{
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
+        requestMsg{};
+    uint32_t transferHandle = 0x0;
+    uint8_t transferOpFlag = 0x01;
+    uint8_t tableType = PLDM_BIOS_ATTR_TABLE;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto rc = encode_get_bios_table_req(0, transferHandle, transferOpFlag,
+                                        tableType, request);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_get_bios_table_req* req =
+        reinterpret_cast<struct pldm_get_bios_table_req*>(request->payload);
+    EXPECT_EQ(transferHandle, le32toh(req->transfer_handle));
+    EXPECT_EQ(transferOpFlag, req->transfer_op_flag);
+    EXPECT_EQ(tableType, req->table_type);
+}
+
+TEST(GetBIOSTable, testBadEncodeRequest)
+{
+    uint32_t transferHandle = 0x0;
+    uint8_t transferOpFlag = 0x01;
+    uint8_t tableType = PLDM_BIOS_ATTR_TABLE;
+
+    auto rc = encode_get_bios_table_req(0, transferHandle, transferOpFlag,
+                                        tableType, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetBIOSTable, testGoodDecodeRequest)
+{
+    const auto hdr_size = sizeof(pldm_msg_hdr);
+    std::array<uint8_t, hdr_size + PLDM_GET_BIOS_TABLE_REQ_BYTES> requestMsg{};
+    uint32_t transferHandle = 31;
+    uint8_t transferOpFlag = PLDM_GET_FIRSTPART;
+    uint8_t tableType = PLDM_BIOS_ATTR_TABLE;
+    uint32_t retTransferHandle = 0;
+    uint8_t retTransferOpFlag = 0;
+    uint8_t retTableType = 0;
+
+    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_get_bios_table_req* request =
+        reinterpret_cast<struct pldm_get_bios_table_req*>(req->payload);
+
+    request->transfer_handle = htole32(transferHandle);
+    request->transfer_op_flag = transferOpFlag;
+    request->table_type = tableType;
+
+    auto rc = decode_get_bios_table_req(req, requestMsg.size() - hdr_size,
+                                        &retTransferHandle, &retTransferOpFlag,
+                                        &retTableType);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(transferHandle, retTransferHandle);
+    EXPECT_EQ(transferOpFlag, retTransferOpFlag);
+    EXPECT_EQ(tableType, retTableType);
+}
+TEST(GetBIOSTable, testBadDecodeRequest)
+{
+    const auto hdr_size = sizeof(pldm_msg_hdr);
+    std::array<uint8_t, hdr_size + PLDM_GET_BIOS_TABLE_REQ_BYTES> requestMsg{};
+    uint32_t transferHandle = 31;
+    uint8_t transferOpFlag = PLDM_GET_FIRSTPART;
+    uint8_t tableType = PLDM_BIOS_ATTR_TABLE;
+    uint32_t retTransferHandle = 0;
+    uint8_t retTransferOpFlag = 0;
+    uint8_t retTableType = 0;
+
+    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_get_bios_table_req* request =
+        reinterpret_cast<struct pldm_get_bios_table_req*>(req->payload);
+
+    request->transfer_handle = htole32(transferHandle);
+    request->transfer_op_flag = transferOpFlag;
+    request->table_type = tableType;
+
+    auto rc = decode_get_bios_table_req(req, requestMsg.size() - hdr_size,
+                                        &retTransferHandle, &retTransferOpFlag,
+                                        &retTableType);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(transferHandle, retTransferHandle);
+    EXPECT_EQ(transferOpFlag, retTransferOpFlag);
+    EXPECT_EQ(tableType, retTableType);
+}
+/*
+TEST(GetBIOSTable, testBadDecodeRequest)
+{
+    const auto hdr_size = sizeof(pldm_msg_hdr);
+    std::array<uint8_t, hdr_size + PLDM_GET_BIOS_TABLE_REQ_BYTES> requestMsg{};
+    uint32_t transferHandle = 31;
+    uint8_t transferOpFlag = PLDM_GET_FIRSTPART;
+    uint8_t tableType = PLDM_BIOS_ATTR_TABLE;
+    uint32_t retTransferHandle = 0;
+    uint8_t retTransferOpFlag = 0;
+    uint8_t retTableType = 0;
+
+    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_get_bios_table_req* request =
+        reinterpret_cast<struct pldm_get_bios_table_req*>(req->payload);
+
+    request->transfer_handle = htole32(transferHandle);
+    request->transfer_op_flag = transferOpFlag;
+    request->table_type = tableType;
+
+    auto rc = decode_get_bios_table_req(req, requestMsg.size() - hdr_size - 3,
+                                        &retTransferHandle, &retTransferOpFlag,
+                                        &retTableType);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}*/
+
+TEST(GetBIOSAttributeCurrentValueByHandle, testGoodDecodeRequest)
+{
+    uint32_t transferHandle = 45;
+    uint8_t transferOpFlag = PLDM_GET_FIRSTPART;
+    uint16_t attributehandle = 10;
+    uint32_t retTransferHandle = 0;
+    uint8_t retTransferOpFlag = 0;
+    uint16_t retattributehandle = 0;
+    std::array<uint8_t, hdrSize + sizeof(transferHandle) +
+                            sizeof(transferOpFlag) + sizeof(attributehandle)>
+        requestMsg{};
+
+    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_get_bios_attribute_current_value_by_handle_req* request =
+        reinterpret_cast<
+            struct pldm_get_bios_attribute_current_value_by_handle_req*>(
+            req->payload);
+
+    request->transfer_handle = htole32(transferHandle);
+    request->transfer_op_flag = transferOpFlag;
+    request->attribute_handle = htole16(attributehandle);
+
+    auto rc = decode_get_bios_attribute_current_value_by_handle_req(
+        req, requestMsg.size() - hdrSize, &retTransferHandle,
+        &retTransferOpFlag, &retattributehandle);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(transferHandle, retTransferHandle);
+    EXPECT_EQ(transferOpFlag, retTransferOpFlag);
+    EXPECT_EQ(attributehandle, retattributehandle);
+}
+
+TEST(GetBIOSAttributeCurrentValueByHandle, testBadDecodeRequest)
+{
+
+    uint32_t transferHandle = 0;
+    uint8_t transferOpFlag = PLDM_GET_FIRSTPART;
+    uint16_t attribute_handle = 0;
+    uint32_t retTransferHandle = 0;
+    uint8_t retTransferOpFlag = 0;
+    uint16_t retattribute_handle = 0;
+    std::array<uint8_t, hdrSize + sizeof(transferHandle) +
+                            sizeof(transferOpFlag) + sizeof(attribute_handle)>
+        requestMsg{};
+
+    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_get_bios_attribute_current_value_by_handle_req* request =
+        reinterpret_cast<
+            struct pldm_get_bios_attribute_current_value_by_handle_req*>(
+            req->payload);
+
+    request->transfer_handle = htole32(transferHandle);
+    request->transfer_op_flag = transferOpFlag;
+    request->attribute_handle = attribute_handle;
+
+    auto rc = decode_get_bios_attribute_current_value_by_handle_req(
+        NULL, requestMsg.size() - hdrSize, &retTransferHandle,
+        &retTransferOpFlag, &retattribute_handle);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    transferHandle = 31;
+    request->transfer_handle = htole32(transferHandle);
+
+    rc = decode_get_bios_attribute_current_value_by_handle_req(
+        req, 0, &retTransferHandle, &retTransferOpFlag, &retattribute_handle);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetBIOSAttributeCurrentValueByHandle, testGoodEncodeRequest)
+{
+    std::array<uint8_t, sizeof(pldm_msg_hdr) +
+                            PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES>
+        requestMsg{};
+    uint32_t transferHandle = 45;
+    uint8_t transferOpFlag = PLDM_GET_FIRSTPART;
+    uint8_t attributeHandle = 10;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto rc = encode_get_bios_attribute_current_value_by_handle_req(
+        0, transferHandle, transferOpFlag, attributeHandle, request);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_get_bios_attribute_current_value_by_handle_req* req =
+        reinterpret_cast<
+            struct pldm_get_bios_attribute_current_value_by_handle_req*>(
+            request->payload);
+    EXPECT_EQ(transferHandle, le32toh(req->transfer_handle));
+    EXPECT_EQ(transferOpFlag, req->transfer_op_flag);
+    EXPECT_EQ(attributeHandle, le16toh(req->attribute_handle));
+}
+
+TEST(GetBIOSAttributeCurrentValueByHandle, testBadEncodeRequest)
+{
+    uint32_t transferHandle = 0;
+    uint8_t transferOpFlag = PLDM_GET_FIRSTPART;
+    uint8_t attributeHandle = 0;
+
+    auto rc = encode_get_bios_attribute_current_value_by_handle_req(
+        0, transferHandle, transferOpFlag, attributeHandle, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetBIOSAttributeCurrentValueByHandle, testGoodEncodeResponse)
+{
+
+    uint8_t instanceId = 10;
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint32_t nextTransferHandle = 32;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    uint8_t attributeData = 44;
+    std::array<uint8_t,
+               hdrSize +
+                   sizeof(pldm_get_bios_attribute_current_value_by_handle_resp)>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = encode_get_bios_current_value_by_handle_resp(
+        instanceId, completionCode, nextTransferHandle, transferFlag,
+        &attributeData, sizeof(attributeData), response);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_get_bios_attribute_current_value_by_handle_resp* resp =
+        reinterpret_cast<
+            struct pldm_get_bios_attribute_current_value_by_handle_resp*>(
+            response->payload);
+
+    EXPECT_EQ(completionCode, resp->completion_code);
+    EXPECT_EQ(nextTransferHandle, le32toh(resp->next_transfer_handle));
+    EXPECT_EQ(transferFlag, resp->transfer_flag);
+    EXPECT_EQ(
+        0, memcmp(&attributeData, resp->attribute_data, sizeof(attributeData)));
+}
+
+TEST(GetBIOSAttributeCurrentValueByHandle, testBadEncodeResponse)
+{
+    uint32_t nextTransferHandle = 32;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    uint8_t attributeData = 44;
+
+    auto rc = encode_get_bios_current_value_by_handle_resp(
+        0, PLDM_SUCCESS, nextTransferHandle, transferFlag, &attributeData,
+        sizeof(attributeData), nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    std::array<uint8_t,
+               hdrSize +
+                   sizeof(pldm_get_bios_attribute_current_value_by_handle_resp)>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    rc = encode_get_bios_current_value_by_handle_resp(
+        0, PLDM_SUCCESS, nextTransferHandle, transferFlag, nullptr,
+        sizeof(attributeData), response);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(SetBiosAttributeCurrentValue, testGoodEncodeRequest)
+{
+    uint8_t instanceId = 10;
+    uint32_t transferHandle = 32;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    uint32_t attributeData = 44;
+    std::array<uint8_t, hdrSize + PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES +
+                            sizeof(attributeData)>
+        requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto rc = encode_set_bios_attribute_current_value_req(
+        instanceId, transferHandle, transferFlag,
+        reinterpret_cast<uint8_t*>(&attributeData), sizeof(attributeData),
+        request, requestMsg.size() - hdrSize);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_set_bios_attribute_current_value_req* req =
+        reinterpret_cast<struct pldm_set_bios_attribute_current_value_req*>(
+            request->payload);
+    EXPECT_EQ(htole32(transferHandle), req->transfer_handle);
+    EXPECT_EQ(transferFlag, req->transfer_flag);
+    EXPECT_EQ(
+        0, memcmp(&attributeData, req->attribute_data, sizeof(attributeData)));
+}
+
+TEST(SetBiosAttributeCurrentValue, testBadEncodeRequest)
+{
+    uint8_t instanceId = 10;
+    uint32_t transferHandle = 32;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    uint32_t attributeData = 44;
+    std::array<uint8_t, hdrSize + PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES>
+        requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_set_bios_attribute_current_value_req(
+        instanceId, transferHandle, transferFlag, nullptr, 0, nullptr, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc = encode_set_bios_attribute_current_value_req(
+        instanceId, transferHandle, transferFlag,
+        reinterpret_cast<uint8_t*>(&attributeData), sizeof(attributeData),
+        request, requestMsg.size() - hdrSize);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(SetBiosAttributeCurrentValue, testGoodDecodeRequest)
+{
+    uint32_t transferHandle = 32;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    uint32_t attributeData = 44;
+
+    std::array<uint8_t, hdrSize + PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES +
+                            sizeof(attributeData)>
+        requestMsg{};
+    auto request = reinterpret_cast<struct pldm_msg*>(requestMsg.data());
+    struct pldm_set_bios_attribute_current_value_req* req =
+        reinterpret_cast<struct pldm_set_bios_attribute_current_value_req*>(
+            request->payload);
+    req->transfer_handle = htole32(transferHandle);
+    req->transfer_flag = transferFlag;
+    memcpy(req->attribute_data, &attributeData, sizeof(attributeData));
+
+    uint32_t retTransferHandle;
+    uint8_t retTransferFlag;
+    struct variable_field attribute;
+    auto rc = decode_set_bios_attribute_current_value_req(
+        request, requestMsg.size() - hdrSize, &retTransferHandle,
+        &retTransferFlag, &attribute);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retTransferHandle, transferHandle);
+    EXPECT_EQ(retTransferFlag, transferFlag);
+    EXPECT_EQ(attribute.length, sizeof(attributeData));
+    EXPECT_EQ(0, memcmp(attribute.ptr, &attributeData, sizeof(attributeData)));
+}
+
+TEST(SetBiosAttributeCurrentValue, testBadDecodeRequest)
+{
+    uint32_t transferHandle = 32;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    struct variable_field attribute;
+    std::array<uint8_t, hdrSize + PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES - 1>
+        requestMsg{};
+    auto request = reinterpret_cast<struct pldm_msg*>(requestMsg.data());
+
+    auto rc = decode_set_bios_attribute_current_value_req(
+        nullptr, 0, &transferHandle, &transferFlag, &attribute);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc = decode_set_bios_attribute_current_value_req(
+        request, requestMsg.size() - hdrSize, &transferHandle, &transferFlag,
+        &attribute);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(SetBiosAttributeCurrentValue, testGoodEncodeResponse)
+{
+    uint8_t instanceId = 10;
+    uint32_t nextTransferHandle = 32;
+    uint8_t completionCode = PLDM_SUCCESS;
+
+    std::array<uint8_t, hdrSize + PLDM_SET_BIOS_ATTR_CURR_VAL_RESP_BYTES>
+        responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+    auto rc = encode_set_bios_attribute_current_value_resp(
+        instanceId, completionCode, nextTransferHandle, response);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_set_bios_attribute_current_value_resp* resp =
+        reinterpret_cast<struct pldm_set_bios_attribute_current_value_resp*>(
+            response->payload);
+    EXPECT_EQ(completionCode, resp->completion_code);
+    EXPECT_EQ(htole32(nextTransferHandle), resp->next_transfer_handle);
+}
+
+TEST(SetBiosAttributeCurrentValue, testBadEncodeResponse)
+{
+    uint8_t instanceId = 10;
+    uint32_t nextTransferHandle = 32;
+    uint8_t completionCode = PLDM_SUCCESS;
+    auto rc = encode_set_bios_attribute_current_value_resp(
+        instanceId, completionCode, nextTransferHandle, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+TEST(SetBiosAttributeCurrentValue, testGoodDecodeResponse)
+{
+    uint32_t nextTransferHandle = 32;
+    uint8_t completionCode = PLDM_SUCCESS;
+    std::array<uint8_t, hdrSize + PLDM_SET_BIOS_ATTR_CURR_VAL_RESP_BYTES>
+        responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+    struct pldm_set_bios_attribute_current_value_resp* resp =
+        reinterpret_cast<struct pldm_set_bios_attribute_current_value_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->next_transfer_handle = htole32(nextTransferHandle);
+
+    uint8_t retCompletionCode;
+    uint32_t retNextTransferHandle;
+    auto rc = decode_set_bios_attribute_current_value_resp(
+        response, responseMsg.size() - hdrSize, &retCompletionCode,
+        &retNextTransferHandle);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, retCompletionCode);
+    EXPECT_EQ(nextTransferHandle, retNextTransferHandle);
+}
+
+TEST(SetBiosAttributeCurrentValue, testBadDecodeResponse)
+{
+    uint32_t nextTransferHandle = 32;
+    uint8_t completionCode = PLDM_SUCCESS;
+
+    std::array<uint8_t, hdrSize + PLDM_SET_BIOS_ATTR_CURR_VAL_RESP_BYTES>
+        responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+    struct pldm_set_bios_attribute_current_value_resp* resp =
+        reinterpret_cast<struct pldm_set_bios_attribute_current_value_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->next_transfer_handle = htole32(nextTransferHandle);
+
+    auto rc = decode_set_bios_attribute_current_value_resp(
+        nullptr, 0, &completionCode, &nextTransferHandle);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_set_bios_attribute_current_value_resp(
+        response, responseMsg.size() - hdrSize - 1, &completionCode,
+        &nextTransferHandle);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetBIOSTable, testDecodeResponse)
+{
+    uint32_t nextTransferHandle = 32;
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t transfer_flag = PLDM_START_AND_END;
+
+    std::array<uint8_t, hdrSize + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES>
+        responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+
+    struct pldm_get_bios_table_resp* resp =
+        reinterpret_cast<struct pldm_get_bios_table_resp*>(response->payload);
+
+    resp->completion_code = completionCode;
+    resp->next_transfer_handle = htole32(nextTransferHandle);
+    resp->transfer_flag = transfer_flag;
+    size_t biosTableOffset = sizeof(completionCode) +
+                             sizeof(nextTransferHandle) + sizeof(transfer_flag);
+
+    uint8_t retCompletionCode;
+    uint32_t retNextTransferHandle;
+    uint8_t retransfer_flag;
+    size_t rebiosTableOffset = 0;
+    auto rc = decode_get_bios_table_resp(
+        response, responseMsg.size(), &retCompletionCode,
+        &retNextTransferHandle, &retransfer_flag, &rebiosTableOffset);
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(completionCode, retCompletionCode);
+    ASSERT_EQ(nextTransferHandle, retNextTransferHandle);
+    ASSERT_EQ(transfer_flag, retransfer_flag);
+    ASSERT_EQ(biosTableOffset, rebiosTableOffset);
+}
+
+TEST(GetBIOSAttributeCurrentValueByHandle, testDecodeResponse)
+{
+    uint32_t nextTransferHandle = 32;
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t transfer_flag = PLDM_START_AND_END;
+    uint32_t attributeData = 44;
+
+    std::array<uint8_t,
+               hdrSize + PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES +
+                   sizeof(attributeData)>
+        responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+
+    struct pldm_get_bios_attribute_current_value_by_handle_resp* resp =
+        reinterpret_cast<
+            struct pldm_get_bios_attribute_current_value_by_handle_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->next_transfer_handle = htole32(nextTransferHandle);
+    resp->transfer_flag = transfer_flag;
+    memcpy(resp->attribute_data, &attributeData, sizeof(attributeData));
+
+    uint8_t retCompletionCode;
+    uint32_t retNextTransferHandle;
+    uint8_t retransfer_flag;
+    struct variable_field retAttributeData;
+    auto rc = decode_get_bios_attribute_current_value_by_handle_resp(
+        response, responseMsg.size() - hdrSize, &retCompletionCode,
+        &retNextTransferHandle, &retransfer_flag, &retAttributeData);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, retCompletionCode);
+    EXPECT_EQ(nextTransferHandle, retNextTransferHandle);
+    EXPECT_EQ(transfer_flag, retransfer_flag);
+    EXPECT_EQ(sizeof(attributeData), retAttributeData.length);
+    EXPECT_EQ(
+        0, memcmp(retAttributeData.ptr, &attributeData, sizeof(attributeData)));
+}
+
+TEST(SetBIOSTable, testGoodEncodeRequest)
+{
+    uint8_t instanceId = 10;
+    uint32_t transferHandle = 32;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    uint8_t tableType = PLDM_BIOS_STRING_TABLE;
+    uint32_t tableData = 44;
+    std::array<uint8_t,
+               hdrSize + PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES + sizeof(tableData)>
+        requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto rc = encode_set_bios_table_req(
+        instanceId, transferHandle, transferFlag, tableType,
+        reinterpret_cast<uint8_t*>(&tableData), sizeof(tableData), request,
+        requestMsg.size() - hdrSize);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_set_bios_table_req* req =
+        reinterpret_cast<struct pldm_set_bios_table_req*>(request->payload);
+
+    EXPECT_EQ(htole32(transferHandle), req->transfer_handle);
+    EXPECT_EQ(transferFlag, req->transfer_flag);
+    EXPECT_EQ(tableType, req->table_type);
+    EXPECT_EQ(0, memcmp(&tableData, req->table_data, sizeof(tableData)));
+}
+
+TEST(SetBIOSTable, testBadEncodeRequest)
+{
+    uint8_t instanceId = 10;
+    uint32_t transferHandle = 32;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    uint8_t tableType = PLDM_BIOS_STRING_TABLE;
+    uint32_t tableData = 44;
+    std::array<uint8_t,
+               hdrSize + PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES + sizeof(tableData)>
+        requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_set_bios_table_req(
+        instanceId, transferHandle, transferFlag, tableType, NULL,
+        sizeof(tableData), request, requestMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_set_bios_table_req(
+        instanceId, transferHandle, transferFlag, tableType,
+        reinterpret_cast<uint8_t*>(&tableData), sizeof(tableData), request,
+        requestMsg.size() - hdrSize + 1);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(SetBIOSTable, testGoodDecodeResponse)
+{
+    uint32_t nextTransferHandle = 32;
+    uint8_t completionCode = PLDM_SUCCESS;
+    std::array<uint8_t, hdrSize + PLDM_SET_BIOS_TABLE_RESP_BYTES> responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+    struct pldm_set_bios_table_resp* resp =
+        reinterpret_cast<struct pldm_set_bios_table_resp*>(response->payload);
+
+    resp->completion_code = completionCode;
+    resp->next_transfer_handle = htole32(nextTransferHandle);
+
+    uint8_t retCompletionCode;
+    uint32_t retNextTransferHandle;
+    auto rc =
+        decode_set_bios_table_resp(response, responseMsg.size() - hdrSize,
+                                   &retCompletionCode, &retNextTransferHandle);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, retCompletionCode);
+    EXPECT_EQ(nextTransferHandle, retNextTransferHandle);
+}
+
+TEST(SetBIOSTable, testBadDecodeResponse)
+{
+    uint32_t nextTransferHandle = 32;
+    uint8_t completionCode = PLDM_SUCCESS;
+    std::array<uint8_t, hdrSize + PLDM_SET_BIOS_TABLE_RESP_BYTES> responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+    struct pldm_set_bios_table_resp* resp =
+        reinterpret_cast<struct pldm_set_bios_table_resp*>(response->payload);
+
+    resp->completion_code = completionCode;
+    resp->next_transfer_handle = htole32(nextTransferHandle);
+
+    uint8_t retCompletionCode;
+    uint32_t retNextTransferHandle;
+
+    auto rc = decode_set_bios_table_resp(NULL, responseMsg.size() - hdrSize,
+                                         NULL, NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_set_bios_table_resp(response, responseMsg.size() - hdrSize + 1,
+                                    &retCompletionCode, &retNextTransferHandle);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(SetBIOSTable, testGoodEncodeResponse)
+{
+    uint8_t instanceId = 10;
+    uint32_t nextTransferHandle = 32;
+    uint8_t completionCode = PLDM_SUCCESS;
+
+    std::array<uint8_t, hdrSize + PLDM_SET_BIOS_TABLE_RESP_BYTES> responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+    auto rc = encode_set_bios_table_resp(instanceId, completionCode,
+                                         nextTransferHandle, response);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_set_bios_table_resp* resp =
+        reinterpret_cast<struct pldm_set_bios_table_resp*>(response->payload);
+    EXPECT_EQ(completionCode, resp->completion_code);
+    EXPECT_EQ(htole32(nextTransferHandle), resp->next_transfer_handle);
+}
+
+TEST(SetBIOSTable, testBadEncodeResponse)
+{
+    auto rc = encode_set_bios_table_resp(0, PLDM_SUCCESS, 1, NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(SetBIOSTable, testGoodDecodeRequest)
+{
+    uint32_t transferHandle = 32;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    uint8_t tableType = PLDM_BIOS_STRING_TABLE;
+    uint32_t tableData = 44;
+
+    std::array<uint8_t,
+               hdrSize + PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES + sizeof(tableData)>
+        requestMsg{};
+    auto request = reinterpret_cast<struct pldm_msg*>(requestMsg.data());
+    struct pldm_set_bios_table_req* req =
+        reinterpret_cast<struct pldm_set_bios_table_req*>(request->payload);
+    req->transfer_handle = htole32(transferHandle);
+    req->transfer_flag = transferFlag;
+    req->table_type = tableType;
+    memcpy(req->table_data, &tableData, sizeof(tableData));
+
+    uint32_t retTransferHandle;
+    uint8_t retTransferFlag;
+    uint8_t retTableType;
+    struct variable_field table;
+    auto rc = decode_set_bios_table_req(request, requestMsg.size() - hdrSize,
+                                        &retTransferHandle, &retTransferFlag,
+                                        &retTableType, &table);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retTransferHandle, transferHandle);
+    EXPECT_EQ(retTransferFlag, transferFlag);
+    EXPECT_EQ(retTableType, tableType);
+    EXPECT_EQ(table.length, sizeof(tableData));
+    EXPECT_EQ(0, memcmp(table.ptr, &tableData, sizeof(tableData)));
+}
+
+TEST(SetBIOSTable, testBadDecodeRequest)
+{
+    uint32_t transferHandle = 32;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    uint8_t tableType = PLDM_BIOS_STRING_TABLE;
+    uint32_t tableData = 44;
+
+    std::array<uint8_t,
+               hdrSize + PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES + sizeof(tableData)>
+        requestMsg{};
+    auto request = reinterpret_cast<struct pldm_msg*>(requestMsg.data());
+    struct pldm_set_bios_table_req* req =
+        reinterpret_cast<struct pldm_set_bios_table_req*>(request->payload);
+    req->transfer_handle = htole32(transferHandle);
+    req->transfer_flag = transferFlag;
+    req->table_type = tableType;
+    memcpy(req->table_data, &tableData, sizeof(tableData));
+
+    uint32_t retTransferHandle;
+    uint8_t retTransferFlag;
+    uint8_t retTableType;
+
+    auto rc = decode_set_bios_table_req(request, requestMsg.size() - hdrSize,
+                                        &retTransferHandle, &retTransferFlag,
+                                        &retTableType, NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    struct variable_field table;
+    rc = decode_set_bios_table_req(
+        request, requestMsg.size() - hdrSize - sizeof(tableData) - 1,
+        &retTransferHandle, &retTransferFlag, &retTableType, &table);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
diff --git a/tests/dsp/bios_table.cpp b/tests/dsp/bios_table.cpp
new file mode 100644
index 0000000..95a9310
--- /dev/null
+++ b/tests/dsp/bios_table.cpp
@@ -0,0 +1,1181 @@
+#include <endian.h>
+#include <libpldm/base.h>
+#include <libpldm/bios.h>
+#include <libpldm/bios_table.h>
+#include <libpldm/utils.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <cstring>
+#include <iterator>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using testing::ElementsAreArray;
+using Table = std::vector<uint8_t>;
+
+void buildTable(Table& table)
+{
+    auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
+    table.insert(table.end(), padSize, 0);
+    uint32_t checksum = crc32(table.data(), table.size());
+    checksum = htole32(checksum);
+    uint8_t a[4];
+    std::memcpy(a, &checksum, sizeof(checksum));
+    table.insert(table.end(), std::begin(a), std::end(a));
+}
+
+template <typename First, typename... Rest>
+void buildTable(Table& table, First& first, Rest&... rest)
+{
+    table.insert(table.end(), first.begin(), first.end());
+    buildTable(table, rest...);
+}
+
+TEST(AttrTable, HeaderDecodeTest)
+{
+    std::vector<uint8_t> enumEntry{
+        2, 0, /* attr handle */
+        0,    /* attr type */
+        1, 0, /* attr name handle (string handle) */
+        2,    /* number of possible value */
+        2, 0, /* possible value handle */
+        3, 0, /* possible value handle */
+        1,    /* number of default value */
+        0     /* defaut value string handle index */
+    };
+    auto entry =
+        reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
+    auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
+    EXPECT_EQ(attrHandle, 2);
+    auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
+    EXPECT_EQ(attrType, 0);
+    auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
+    EXPECT_EQ(stringHandle, 1);
+}
+
+TEST(AttrTable, EnumEntryDecodeTest)
+{
+    std::vector<uint8_t> enumEntry{
+        0, 0, /* attr handle */
+        0,    /* attr type */
+        1, 0, /* attr name handle */
+        2,    /* number of possible value */
+        2, 0, /* possible value handle */
+        3, 0, /* possible value handle */
+        1,    /* number of default value */
+        1     /* defaut value string handle index */
+    };
+
+    auto entry =
+        reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
+    uint8_t pvNumber;
+    ASSERT_EQ(
+        pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber),
+        PLDM_SUCCESS);
+    EXPECT_EQ(pvNumber, 2);
+    pvNumber = 0;
+    auto rc =
+        pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(pvNumber, 2);
+
+    std::vector<uint16_t> pvHandles(pvNumber, 0);
+    ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
+                  entry, pvHandles.data(), pvHandles.size()),
+              PLDM_SUCCESS);
+    EXPECT_EQ(pvNumber, 2);
+    EXPECT_EQ(pvHandles[0], 2);
+    EXPECT_EQ(pvHandles[1], 3);
+    pvHandles.resize(1);
+    ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
+                  entry, pvHandles.data(), pvHandles.size()),
+              PLDM_SUCCESS);
+    EXPECT_EQ(pvHandles[0], 2);
+
+    pvHandles.resize(2);
+    rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
+        entry, pvHandles.data(), pvHandles.size());
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(pvHandles[0], 2);
+    EXPECT_EQ(pvHandles[1], 3);
+    rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
+        entry, pvHandles.data(), 1);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    uint8_t defNumber;
+    ASSERT_EQ(
+        pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber),
+        PLDM_SUCCESS);
+    EXPECT_EQ(defNumber, 1);
+    std::vector<uint8_t> defIndices(defNumber);
+    rc = pldm_bios_table_attr_entry_enum_decode_def_indices(
+        entry, defIndices.data(), defIndices.size());
+    EXPECT_EQ(rc, defNumber);
+    EXPECT_THAT(defIndices, ElementsAreArray({1}));
+
+    defNumber = 0;
+    rc =
+        pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(defNumber, 1);
+
+    rc =
+        pldm_bios_table_attr_entry_enum_decode_pv_num_check(nullptr, &pvNumber);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc = pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    entry->attr_type = PLDM_BIOS_STRING;
+    rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc =
+        pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc =
+        pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(entry, nullptr, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(AttrTable, EnumEntryEncodeTest)
+{
+    std::vector<uint8_t> enumEntry{
+        0, 0, /* attr handle */
+        0,    /* attr type */
+        1, 0, /* attr name handle */
+        2,    /* number of possible value */
+        2, 0, /* possible value handle */
+        3, 0, /* possible value handle */
+        1,    /* number of default value */
+        0     /* defaut value string handle index */
+    };
+
+    std::vector<uint16_t> pv_hdls{2, 3};
+    std::vector<uint8_t> defs{0};
+
+    struct pldm_bios_table_attr_entry_enum_info info = {
+        1,              /* name handle */
+        false,          /* read only */
+        2,              /* pv number */
+        pv_hdls.data(), /* pv handle */
+        1,              /*def number */
+        defs.data()     /*def index*/
+    };
+    auto encodeLength = pldm_bios_table_attr_entry_enum_encode_length(2, 1);
+    EXPECT_EQ(encodeLength, enumEntry.size());
+
+    std::vector<uint8_t> encodeEntry(encodeLength, 0);
+    ASSERT_EQ(pldm_bios_table_attr_entry_enum_encode_check(
+                  encodeEntry.data(), encodeEntry.size(), &info),
+              PLDM_SUCCESS);
+    // set attr handle = 0
+    encodeEntry[0] = 0;
+    encodeEntry[1] = 0;
+
+    EXPECT_EQ(enumEntry, encodeEntry);
+
+    EXPECT_NE(pldm_bios_table_attr_entry_enum_encode_check(
+                  encodeEntry.data(), encodeEntry.size() - 1, &info),
+              PLDM_SUCCESS);
+    auto rc = pldm_bios_table_attr_entry_enum_encode_check(
+        encodeEntry.data(), encodeEntry.size(), &info);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    // set attr handle = 0
+    encodeEntry[0] = 0;
+    encodeEntry[1] = 0;
+
+    EXPECT_EQ(enumEntry, encodeEntry);
+    rc = pldm_bios_table_attr_entry_enum_encode_check(
+        encodeEntry.data(), encodeEntry.size() - 1, &info);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(AttrTable, StringEntryDecodeTest)
+{
+    std::vector<uint8_t> stringEntry{
+        1,   0,       /* attr handle */
+        1,            /* attr type */
+        12,  0,       /* attr name handle */
+        1,            /* string type */
+        1,   0,       /* minimum length of the string in bytes */
+        100, 0,       /* maximum length of the string in bytes */
+        3,   0,       /* length of default string in length */
+        'a', 'b', 'c' /* default string  */
+    };
+
+    auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
+        stringEntry.data());
+    auto stringType =
+        pldm_bios_table_attr_entry_string_decode_string_type(entry);
+    EXPECT_EQ(stringType, 1);
+    auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
+    EXPECT_EQ(minLength, 1);
+    auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
+    EXPECT_EQ(maxLength, 100);
+
+    uint16_t defStringLength;
+    ASSERT_EQ(pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+                  entry, &defStringLength),
+              PLDM_SUCCESS);
+    EXPECT_EQ(defStringLength, 3);
+    std::vector<char> defString(defStringLength + 1);
+    auto rc = pldm_bios_table_attr_entry_string_decode_def_string(
+        entry, defString.data(), defString.size());
+    EXPECT_EQ(rc, 3);
+    EXPECT_STREQ(defString.data(), "abc");
+    rc = pldm_bios_table_attr_entry_string_decode_def_string(
+        entry, defString.data(), defString.size() - 1);
+    EXPECT_EQ(rc, 2);
+    EXPECT_STREQ(defString.data(), "ab");
+
+    defStringLength = 0;
+    rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+        entry, &defStringLength);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(defStringLength, 3);
+
+    rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+        entry, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+        nullptr, &defStringLength);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    entry->attr_type = PLDM_BIOS_INTEGER;
+    rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+        entry, &defStringLength);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+        nullptr, &defStringLength);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(AttrTable, StringEntryEncodeTest)
+{
+    std::vector<uint8_t> stringEntry{
+        0,   0,        /* attr handle */
+        1,             /* attr type */
+        3,   0,        /* attr name handle */
+        1,             /* string type */
+        1,   0,        /* min string length */
+        100, 0,        /* max string length */
+        3,   0,        /* default string length */
+        'a', 'b', 'c', /* defaul string */
+    };
+
+    struct pldm_bios_table_attr_entry_string_info info = {
+        3,     /* name handle */
+        false, /* read only */
+        1,     /* string type ascii */
+        1,     /* min length */
+        100,   /* max length */
+        3,     /* def length */
+        "abc", /* def string */
+    };
+    auto encodeLength = pldm_bios_table_attr_entry_string_encode_length(3);
+    EXPECT_EQ(encodeLength, stringEntry.size());
+
+    std::vector<uint8_t> encodeEntry(encodeLength, 0);
+    ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check(
+                  encodeEntry.data(), encodeEntry.size(), &info),
+              PLDM_SUCCESS);
+    // set attr handle = 0
+    encodeEntry[0] = 0;
+    encodeEntry[1] = 0;
+
+    EXPECT_EQ(stringEntry, encodeEntry);
+
+    EXPECT_NE(pldm_bios_table_attr_entry_string_encode_check(
+                  encodeEntry.data(), encodeEntry.size() - 1, &info),
+              PLDM_SUCCESS);
+    auto rc = pldm_bios_table_attr_entry_string_encode_check(
+        encodeEntry.data(), encodeEntry.size(), &info);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    // set attr handle = 0
+    encodeEntry[0] = 0;
+    encodeEntry[1] = 0;
+
+    EXPECT_EQ(stringEntry, encodeEntry);
+    rc = pldm_bios_table_attr_entry_string_encode_check(
+        encodeEntry.data(), encodeEntry.size() - 1, &info);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+    std::swap(info.max_length, info.min_length);
+    const char* errmsg;
+    rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    EXPECT_STREQ(
+        "MinimumStingLength should not be greater than MaximumStringLength",
+        errmsg);
+    rc = pldm_bios_table_attr_entry_string_encode_check(
+        encodeEntry.data(), encodeEntry.size(), &info);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    std::swap(info.max_length, info.min_length);
+
+    std::vector<uint8_t> stringEntryLength0{
+        0,   0, /* attr handle */
+        1,      /* attr type */
+        3,   0, /* attr name handle */
+        1,      /* string type */
+        0,   0, /* min string length */
+        100, 0, /* max string length */
+        0,   0, /* default string length */
+    };
+
+    info.min_length = 0;
+    info.def_length = 0;
+    info.def_string = nullptr;
+
+    encodeLength = pldm_bios_table_attr_entry_string_encode_length(0);
+    EXPECT_EQ(encodeLength, stringEntryLength0.size());
+
+    encodeEntry.resize(encodeLength);
+    ASSERT_EQ(pldm_bios_table_attr_entry_string_encode_check(
+                  encodeEntry.data(), encodeEntry.size(), &info),
+              PLDM_SUCCESS);
+    // set attr handle = 0
+    encodeEntry[0] = 0;
+    encodeEntry[1] = 0;
+
+    EXPECT_EQ(stringEntryLength0, encodeEntry);
+}
+
+TEST(AttrTable, integerEntryEncodeTest)
+{
+    std::vector<uint8_t> integerEntry{
+        0,  0,                   /* attr handle */
+        3,                       /* attr type */
+        1,  0,                   /* attr name handle */
+        1,  0, 0, 0, 0, 0, 0, 0, /* lower bound */
+        10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
+        2,  0, 0, 0,             /* scalar increment */
+        3,  0, 0, 0, 0, 0, 0, 0, /* defaut value */
+    };
+
+    std::vector<uint16_t> pv_hdls{2, 3};
+    std::vector<uint8_t> defs{0};
+
+    struct pldm_bios_table_attr_entry_integer_info info = {
+        1,     /* name handle */
+        false, /* read only */
+        1,     /* lower bound */
+        10,    /* upper bound */
+        2,     /* sacalar increment */
+        3      /* default value */
+    };
+    auto encodeLength = pldm_bios_table_attr_entry_integer_encode_length();
+    EXPECT_EQ(encodeLength, integerEntry.size());
+
+    std::vector<uint8_t> encodeEntry(encodeLength, 0);
+    ASSERT_EQ(pldm_bios_table_attr_entry_integer_encode_check(
+                  encodeEntry.data(), encodeEntry.size(), &info),
+              PLDM_SUCCESS);
+    // set attr handle = 0
+    encodeEntry[0] = 0;
+    encodeEntry[1] = 0;
+
+    EXPECT_EQ(integerEntry, encodeEntry);
+
+    EXPECT_NE(pldm_bios_table_attr_entry_integer_encode_check(
+                  encodeEntry.data(), encodeEntry.size() - 1, &info),
+              PLDM_SUCCESS);
+
+    auto rc = pldm_bios_table_attr_entry_integer_encode_check(
+        encodeEntry.data(), encodeEntry.size(), &info);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    // set attr handle = 0
+    encodeEntry[0] = 0;
+    encodeEntry[1] = 0;
+
+    EXPECT_EQ(integerEntry, encodeEntry);
+
+    rc = pldm_bios_table_attr_entry_integer_encode_check(
+        encodeEntry.data(), encodeEntry.size() - 1, &info);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    info.lower_bound = 100;
+    info.upper_bound = 50;
+    const char* errmsg;
+    rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg);
+    rc = pldm_bios_table_attr_entry_integer_encode_check(
+        encodeEntry.data(), encodeEntry.size(), &info);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(AttrTable, integerEntryDecodeTest)
+{
+    std::vector<uint8_t> integerEntry{
+        0,  0,                   /* attr handle */
+        3,                       /* attr type */
+        1,  0,                   /* attr name handle */
+        1,  0, 0, 0, 0, 0, 0, 0, /* lower bound */
+        10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
+        2,  0, 0, 0,             /* scalar increment */
+        3,  0, 0, 0, 0, 0, 0, 0, /* defaut value */
+    };
+
+    uint64_t lower;
+    uint64_t upper;
+    uint64_t def;
+    uint32_t scalar;
+    auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
+        integerEntry.data());
+    pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
+                                              &def);
+    EXPECT_EQ(lower, 1u);
+    EXPECT_EQ(upper, 10u);
+    EXPECT_EQ(scalar, 2u);
+    EXPECT_EQ(def, 3u);
+}
+
+TEST(AttrTable, ItearatorTest)
+{
+    std::vector<uint8_t> enumEntry{
+        0, 0, /* attr handle */
+        0,    /* attr type */
+        1, 0, /* attr name handle */
+        2,    /* number of possible value */
+        2, 0, /* possible value handle */
+        3, 0, /* possible value handle */
+        1,    /* number of default value */
+        0     /* defaut value string handle index */
+    };
+    std::vector<uint8_t> stringEntry{
+        1,   0,       /* attr handle */
+        1,            /* attr type */
+        12,  0,       /* attr name handle */
+        1,            /* string type */
+        1,   0,       /* minimum length of the string in bytes */
+        100, 0,       /* maximum length of the string in bytes */
+        3,   0,       /* length of default string in length */
+        'a', 'b', 'c' /* default string  */
+    };
+    std::vector<uint8_t> integerEntry{
+        0,  0,                   /* attr handle */
+        3,                       /* attr type */
+        1,  0,                   /* attr name handle */
+        1,  0, 0, 0, 0, 0, 0, 0, /* lower bound */
+        10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
+        2,  0, 0, 0,             /* scalar increment */
+        3,  0, 0, 0, 0, 0, 0, 0, /* defaut value */
+    };
+
+    Table table;
+    buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
+    auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
+                                            PLDM_BIOS_ATTR_TABLE);
+    auto entry = pldm_bios_table_iter_attr_entry_value(iter);
+    auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
+    EXPECT_EQ(rc, 0);
+
+    pldm_bios_table_iter_next(iter);
+    entry = pldm_bios_table_iter_attr_entry_value(iter);
+    rc = std::memcmp(entry, stringEntry.data(), stringEntry.size());
+    EXPECT_EQ(rc, 0);
+
+    pldm_bios_table_iter_next(iter);
+    entry = pldm_bios_table_iter_attr_entry_value(iter);
+    rc = std::memcmp(entry, integerEntry.data(), integerEntry.size());
+    EXPECT_EQ(rc, 0);
+
+    pldm_bios_table_iter_next(iter);
+    entry = pldm_bios_table_iter_attr_entry_value(iter);
+    rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
+    EXPECT_EQ(rc, 0);
+
+    pldm_bios_table_iter_next(iter);
+    EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
+    pldm_bios_table_iter_free(iter);
+}
+
+TEST(AttrTable, FindTest)
+{
+    std::vector<uint8_t> enumEntry{
+        0, 0, /* attr handle */
+        0,    /* attr type */
+        1, 0, /* attr name handle */
+        2,    /* number of possible value */
+        2, 0, /* possible value handle */
+        3, 0, /* possible value handle */
+        1,    /* number of default value */
+        0     /* defaut value string handle index */
+    };
+    std::vector<uint8_t> stringEntry{
+        1,   0,       /* attr handle */
+        1,            /* attr type */
+        2,   0,       /* attr name handle */
+        1,            /* string type */
+        1,   0,       /* minimum length of the string in bytes */
+        100, 0,       /* maximum length of the string in bytes */
+        3,   0,       /* length of default string in length */
+        'a', 'b', 'c' /* default string  */
+    };
+    std::vector<uint8_t> integerEntry{
+        0,  0,                   /* attr handle */
+        3,                       /* attr type */
+        3,  0,                   /* attr name handle */
+        1,  0, 0, 0, 0, 0, 0, 0, /* lower bound */
+        10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
+        2,  0, 0, 0,             /* scalar increment */
+        3,  0, 0, 0, 0, 0, 0, 0, /* defaut value */
+    };
+
+    Table table;
+    buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
+
+    auto entry =
+        pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 1);
+    EXPECT_NE(entry, nullptr);
+    auto p = reinterpret_cast<const uint8_t*>(entry);
+    EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
+                ElementsAreArray(stringEntry));
+
+    entry = pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 3);
+    EXPECT_EQ(entry, nullptr);
+
+    entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
+                                                       table.size(), 2);
+    EXPECT_NE(entry, nullptr);
+    p = reinterpret_cast<const uint8_t*>(entry);
+    EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
+                ElementsAreArray(stringEntry));
+
+    entry = pldm_bios_table_attr_find_by_string_handle(table.data(),
+                                                       table.size(), 4);
+    EXPECT_EQ(entry, nullptr);
+}
+
+TEST(AttrValTable, HeaderDecodeTest)
+{
+    std::vector<uint8_t> enumEntry{
+        1, 0, /* attr handle */
+        0,    /* attr type */
+        2,    /* number of current value */
+        0,    /* current value string handle index */
+        1,    /* current value string handle index */
+    };
+    auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
+        enumEntry.data());
+    auto attrHandle =
+        pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
+    EXPECT_EQ(attrHandle, 1);
+    auto attrType =
+        pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
+    EXPECT_EQ(attrType, 0);
+}
+
+TEST(AttrValTable, EnumEntryEncodeTest)
+{
+    std::vector<uint8_t> enumEntry{
+        0, 0, /* attr handle */
+        0,    /* attr type */
+        2,    /* number of current value */
+        0,    /* current value string handle index */
+        1,    /* current value string handle index */
+    };
+
+    auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2);
+    EXPECT_EQ(length, enumEntry.size());
+    std::vector<uint8_t> encodeEntry(length, 0);
+    uint8_t handles[] = {0, 1};
+    ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_enum_check(
+                  encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles),
+              PLDM_SUCCESS);
+    EXPECT_EQ(encodeEntry, enumEntry);
+
+    EXPECT_NE(pldm_bios_table_attr_value_entry_encode_enum_check(
+                  encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles),
+              PLDM_SUCCESS);
+
+    auto rc = pldm_bios_table_attr_value_entry_encode_enum_check(
+        encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2,
+        handles);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(encodeEntry, enumEntry);
+    auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
+        enumEntry.data());
+    entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY;
+    rc = pldm_bios_table_attr_value_entry_encode_enum_check(
+        encodeEntry.data(), encodeEntry.size(), 0,
+        PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(encodeEntry, enumEntry);
+    rc = pldm_bios_table_attr_value_entry_encode_enum_check(
+        encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2,
+        handles);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc = pldm_bios_table_attr_value_entry_encode_enum_check(
+        encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2,
+        handles);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(AttrValTable, EnumEntryDecodeTest)
+{
+    std::vector<uint8_t> enumEntry{
+        0, 0, /* attr handle */
+        0,    /* attr type */
+        2,    /* number of current value */
+        0,    /* current value string handle index */
+        1,    /* current value string handle index */
+    };
+
+    auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
+        enumEntry.data());
+    auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
+    EXPECT_EQ(2, number);
+
+    std::vector<uint8_t> handles(2, 0);
+    auto rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
+        entry, handles.data(), handles.size());
+    EXPECT_EQ(rc, 2);
+    EXPECT_EQ(handles[0], 0);
+    EXPECT_EQ(handles[1], 1);
+
+    /* Buffer size is more than the number of current string handles */
+    std::vector<uint8_t> handleIndexes(3, 0);
+    rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
+        entry, handleIndexes.data(), handleIndexes.size());
+    EXPECT_EQ(rc, 2);
+    EXPECT_EQ(handleIndexes[0], 0);
+    EXPECT_EQ(handleIndexes[1], 1);
+
+    /* Buffersize is less than the number of current string handles */
+    std::vector<uint8_t> strHandles(1, 0);
+    rc = pldm_bios_table_attr_value_entry_enum_decode_handles(
+        entry, strHandles.data(), strHandles.size());
+    EXPECT_EQ(rc, 1);
+    EXPECT_EQ(strHandles[0], 0);
+}
+
+TEST(AttrValTable, stringEntryEncodeTest)
+{
+    std::vector<uint8_t> stringEntry{
+        0,   0,        /* attr handle */
+        1,             /* attr type */
+        3,   0,        /* current string length */
+        'a', 'b', 'c', /* defaut value string handle index */
+    };
+
+    auto length = pldm_bios_table_attr_value_entry_encode_string_length(3);
+    EXPECT_EQ(length, stringEntry.size());
+    std::vector<uint8_t> encodeEntry(length, 0);
+    ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_string_check(
+                  encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc"),
+              PLDM_SUCCESS);
+    EXPECT_EQ(encodeEntry, stringEntry);
+
+    EXPECT_NE(pldm_bios_table_attr_value_entry_encode_string_check(
+                  encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"),
+              PLDM_SUCCESS);
+
+    auto rc = pldm_bios_table_attr_value_entry_encode_string_check(
+        encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc");
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(encodeEntry, stringEntry);
+    auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
+        stringEntry.data());
+    entry->attr_type = PLDM_BIOS_STRING_READ_ONLY;
+    rc = pldm_bios_table_attr_value_entry_encode_string_check(
+        encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY,
+        3, "abc");
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(encodeEntry, stringEntry);
+    rc = pldm_bios_table_attr_value_entry_encode_string_check(
+        encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3,
+        "abc");
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc = pldm_bios_table_attr_value_entry_encode_string_check(
+        encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3,
+        "abc");
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(AttrValTable, StringEntryDecodeTest)
+{
+    std::vector<uint8_t> stringEntry{
+        0,   0,        /* attr handle */
+        1,             /* attr type */
+        3,   0,        /* current string length */
+        'a', 'b', 'c', /* defaut value string handle index */
+    };
+
+    auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
+        stringEntry.data());
+    auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
+    EXPECT_EQ(3, length);
+
+    auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
+    EXPECT_EQ(0, handle);
+
+    auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
+    EXPECT_EQ(stringEntry.size(), entryLength);
+
+    variable_field currentString{};
+    pldm_bios_table_attr_value_entry_string_decode_string(entry,
+                                                          &currentString);
+    EXPECT_THAT(std::vector<uint8_t>(currentString.ptr,
+                                     currentString.ptr + currentString.length),
+                ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'}));
+}
+
+TEST(AttrValTable, integerEntryEncodeTest)
+{
+    std::vector<uint8_t> integerEntry{
+        0,  0,                   /* attr handle */
+        3,                       /* attr type */
+        10, 0, 0, 0, 0, 0, 0, 0, /* current value */
+    };
+
+    auto length = pldm_bios_table_attr_value_entry_encode_integer_length();
+    EXPECT_EQ(length, integerEntry.size());
+    std::vector<uint8_t> encodeEntry(length, 0);
+    ASSERT_EQ(
+        pldm_bios_table_attr_value_entry_encode_integer_check(
+            encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10),
+        PLDM_SUCCESS);
+    EXPECT_EQ(encodeEntry, integerEntry);
+
+    EXPECT_NE(pldm_bios_table_attr_value_entry_encode_integer_check(
+                  encodeEntry.data(), encodeEntry.size() - 1, 0,
+                  PLDM_BIOS_INTEGER, 10),
+              PLDM_SUCCESS);
+
+    auto rc = pldm_bios_table_attr_value_entry_encode_integer_check(
+        encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(encodeEntry, integerEntry);
+    auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
+        integerEntry.data());
+    entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY;
+    rc = pldm_bios_table_attr_value_entry_encode_integer_check(
+        encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY,
+        10);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(encodeEntry, integerEntry);
+
+    rc = pldm_bios_table_attr_value_entry_encode_integer_check(
+        encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc = pldm_bios_table_attr_value_entry_encode_integer_check(
+        encodeEntry.data(), encodeEntry.size() - 1, 0,
+        PLDM_BIOS_INTEGER_READ_ONLY, 10);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(AttrValTable, integerEntryDecodeTest)
+{
+    std::vector<uint8_t> integerEntry{
+        0,  0,                   /* attr handle */
+        3,                       /* attr type */
+        10, 0, 0, 0, 0, 0, 0, 0, /* current value */
+    };
+
+    auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
+        integerEntry.data());
+    auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
+    EXPECT_EQ(cv, 10u);
+}
+
+TEST(AttrValTable, IteratorTest)
+{
+    std::vector<uint8_t> enumEntry{
+        0, 0, /* attr handle */
+        0,    /* attr type */
+        2,    /* number of current value */
+        0,    /* current value string handle index */
+        1,    /* current value string handle index */
+    };
+    std::vector<uint8_t> stringEntry{
+        0,   0,        /* attr handle */
+        1,             /* attr type */
+        3,   0,        /* current string length */
+        'a', 'b', 'c', /* defaut value string handle index */
+    };
+    std::vector<uint8_t> integerEntry{
+        0,  0,                   /* attr handle */
+        3,                       /* attr type */
+        10, 0, 0, 0, 0, 0, 0, 0, /* current value */
+    };
+
+    Table table;
+    buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry);
+
+    auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
+                                            PLDM_BIOS_ATTR_VAL_TABLE);
+    auto entry = pldm_bios_table_iter_attr_value_entry_value(iter);
+
+    auto p = reinterpret_cast<const uint8_t*>(entry);
+    EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
+                ElementsAreArray(enumEntry));
+
+    pldm_bios_table_iter_next(iter);
+    entry = pldm_bios_table_iter_attr_value_entry_value(iter);
+    p = reinterpret_cast<const uint8_t*>(entry);
+    EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
+                ElementsAreArray(stringEntry));
+
+    pldm_bios_table_iter_next(iter);
+    entry = pldm_bios_table_iter_attr_value_entry_value(iter);
+    p = reinterpret_cast<const uint8_t*>(entry);
+    EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()),
+                ElementsAreArray(integerEntry));
+
+    pldm_bios_table_iter_next(iter);
+    entry = pldm_bios_table_iter_attr_value_entry_value(iter);
+    p = reinterpret_cast<const uint8_t*>(entry);
+    EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()),
+                ElementsAreArray(enumEntry));
+
+    pldm_bios_table_iter_next(iter);
+    EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
+
+    pldm_bios_table_iter_free(iter);
+}
+
+TEST(AttrValTable, FindTest)
+{
+    std::vector<uint8_t> enumEntry{
+        0, 0, /* attr handle */
+        0,    /* attr type */
+        2,    /* number of current value */
+        0,    /* current value string handle index */
+        1,    /* current value string handle index */
+    };
+    std::vector<uint8_t> stringEntry{
+        1,   0,        /* attr handle */
+        1,             /* attr type */
+        3,   0,        /* current string length */
+        'a', 'b', 'c', /* defaut value string handle index */
+    };
+    std::vector<uint8_t> integerEntry{
+        2,  0,                   /* attr handle */
+        3,                       /* attr type */
+        10, 0, 0, 0, 0, 0, 0, 0, /* current value */
+    };
+
+    Table table;
+    buildTable(table, enumEntry, stringEntry, integerEntry);
+
+    auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
+                                                           table.size(), 1);
+    EXPECT_NE(entry, nullptr);
+    auto p = reinterpret_cast<const uint8_t*>(entry);
+    EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
+                ElementsAreArray(stringEntry));
+
+    entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
+                                                      table.size(), 3);
+    EXPECT_EQ(entry, nullptr);
+
+    auto firstEntry =
+        reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
+    firstEntry->attr_type = PLDM_BIOS_PASSWORD;
+#ifdef NDEBUG
+    EXPECT_EQ(pldm_bios_table_attr_value_find_by_handle(table.data(),
+                                                        table.size(), 1),
+              nullptr);
+#else
+    EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
+                                                           table.size(), 1),
+                 "entry_length != NULL");
+#endif
+}
+
+TEST(AttrValTable, CopyAndUpdateTest)
+{
+    std::vector<uint8_t> enumEntry{
+        0, 0, /* attr handle */
+        0,    /* attr type */
+        2,    /* number of current value */
+        0,    /* current value string handle index */
+        1,    /* current value string handle index */
+    };
+    std::vector<uint8_t> stringEntry{
+        1,   0,        /* attr handle */
+        1,             /* attr type */
+        3,   0,        /* current string length */
+        'a', 'b', 'c', /* defaut value string handle index */
+    };
+    std::vector<uint8_t> integerEntry{
+        2,  0,                   /* attr handle */
+        3,                       /* attr type */
+        10, 0, 0, 0, 0, 0, 0, 0, /* current value */
+    };
+
+    Table srcTable;
+    buildTable(srcTable, enumEntry, stringEntry, integerEntry);
+
+    std::vector<uint8_t> stringEntry1{
+        1,   0,        /* attr handle */
+        1,             /* attr type */
+        3,   0,        /* current string length */
+        'd', 'e', 'f', /* defaut value string handle index */
+    };
+
+    Table expectTable;
+    buildTable(expectTable, enumEntry, stringEntry1, integerEntry);
+    Table destTable(expectTable.size() + 10);
+    auto destLength = destTable.size();
+    auto rc = pldm_bios_table_attr_value_copy_and_update(
+        srcTable.data(), srcTable.size(), destTable.data(), &destLength,
+        stringEntry1.data(), stringEntry1.size());
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(destLength, expectTable.size());
+    destTable.resize(destLength);
+    EXPECT_THAT(destTable, ElementsAreArray(expectTable));
+
+    std::vector<uint8_t> stringEntry2{
+        1,   0,                  /* attr handle */
+        1,                       /* attr type */
+        5,   0,                  /* current string length */
+        'd', 'e', 'f', 'a', 'b', /* defaut value string handle index */
+    };
+    expectTable.resize(0);
+    buildTable(expectTable, enumEntry, stringEntry2, integerEntry);
+    destTable.resize(expectTable.size() + 10);
+    destLength = destTable.size();
+    rc = pldm_bios_table_attr_value_copy_and_update(
+        srcTable.data(), srcTable.size(), destTable.data(), &destLength,
+        stringEntry2.data(), stringEntry2.size());
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(destLength, expectTable.size());
+    destTable.resize(destLength);
+    EXPECT_THAT(destTable, ElementsAreArray(expectTable));
+
+    std::vector<uint8_t> stringEntry3{
+        1,   0, /* attr handle */
+        1,      /* attr type */
+        1,   0, /* current string length */
+        'd',    /* defaut value string handle index */
+    };
+    expectTable.resize(0);
+    buildTable(expectTable, enumEntry, stringEntry3, integerEntry);
+    destTable.resize(expectTable.size() + 10);
+    destLength = destTable.size();
+    rc = pldm_bios_table_attr_value_copy_and_update(
+        srcTable.data(), srcTable.size(), destTable.data(), &destLength,
+        stringEntry3.data(), stringEntry3.size());
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(destLength, expectTable.size());
+    destTable.resize(destLength);
+    EXPECT_THAT(destTable, ElementsAreArray(expectTable));
+
+    stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer
+    rc = pldm_bios_table_attr_value_copy_and_update(
+        srcTable.data(), srcTable.size(), destTable.data(), &destLength,
+        stringEntry3.data(), stringEntry3.size());
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string
+
+    destTable.resize(expectTable.size() - 1);
+    destLength = destTable.size();
+    rc = pldm_bios_table_attr_value_copy_and_update(
+        srcTable.data(), srcTable.size(), destTable.data(), &destLength,
+        stringEntry3.data(), stringEntry3.size());
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(StringTable, EntryEncodeTest)
+{
+    std::vector<uint8_t> stringEntry{
+        0,   0,                            /* string handle*/
+        7,   0,                            /* string length */
+        'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
+    };
+
+    const char* str = "Allowed";
+    auto str_length = std::strlen(str);
+    auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length);
+    EXPECT_EQ(encodeLength, stringEntry.size());
+
+    std::vector<uint8_t> encodeEntry(encodeLength, 0);
+    ASSERT_EQ(pldm_bios_table_string_entry_encode_check(
+                  encodeEntry.data(), encodeEntry.size(), str, str_length),
+              PLDM_SUCCESS);
+    // set string handle = 0
+    encodeEntry[0] = 0;
+    encodeEntry[1] = 0;
+
+    EXPECT_EQ(stringEntry, encodeEntry);
+
+    EXPECT_NE(pldm_bios_table_string_entry_encode_check(
+                  encodeEntry.data(), encodeEntry.size() - 1, str, str_length),
+              PLDM_SUCCESS);
+    auto rc = pldm_bios_table_string_entry_encode_check(
+        encodeEntry.data(), encodeEntry.size() - 1, str, str_length);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(StringTable, EntryDecodeTest)
+{
+    std::vector<uint8_t> stringEntry{
+        4,   0,                            /* string handle*/
+        7,   0,                            /* string length */
+        'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */
+    };
+    auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>(
+        stringEntry.data());
+    auto handle = pldm_bios_table_string_entry_decode_handle(entry);
+    EXPECT_EQ(handle, 4);
+    auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
+    EXPECT_EQ(strLength, 7);
+
+    std::vector<char> buffer(strLength + 1, 0);
+    pldm_bios_table_string_entry_decode_string_check(entry, buffer.data(),
+                                                     buffer.size());
+    EXPECT_EQ(strlen(buffer.data()), strLength);
+    EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
+    EXPECT_EQ(pldm_bios_table_string_entry_decode_string_check(
+                  entry, buffer.data(), 2 + 1 /* sizeof '\0'*/),
+              PLDM_SUCCESS);
+    EXPECT_EQ(strlen(buffer.data()), 2);
+    EXPECT_EQ(std::strcmp("Al", buffer.data()), 0);
+
+    auto rc = pldm_bios_table_string_entry_decode_string_check(
+        entry, buffer.data(), buffer.size());
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0);
+
+    /* Ensure equivalence with the unchecked API */
+    rc = pldm_bios_table_string_entry_decode_string_check(
+        entry, buffer.data(), 2 + 1 /* sizeof '\0' */);
+    EXPECT_EQ(rc, std::strcmp("Al", buffer.data()));
+}
+
+TEST(StringTable, IteratorTest)
+{
+    std::vector<uint8_t> stringHello{
+        0,   0,                  /* string handle*/
+        5,   0,                  /* string length */
+        'H', 'e', 'l', 'l', 'o', /* string */
+    };
+    std::vector<uint8_t> stringWorld{
+        1,   0,                       /* string handle*/
+        6,   0,                       /* string length */
+        'W', 'o', 'r', 'l', 'd', '!', /* string */
+    };
+
+    Table table;
+    buildTable(table, stringHello, stringWorld);
+
+    auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
+                                            PLDM_BIOS_STRING_TABLE);
+    auto entry = pldm_bios_table_iter_string_entry_value(iter);
+    auto rc = std::memcmp(entry, stringHello.data(), stringHello.size());
+    EXPECT_EQ(rc, 0);
+    pldm_bios_table_iter_next(iter);
+    entry = pldm_bios_table_iter_string_entry_value(iter);
+    rc = std::memcmp(entry, stringWorld.data(), stringWorld.size());
+    EXPECT_EQ(rc, 0);
+    pldm_bios_table_iter_next(iter);
+    EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
+    pldm_bios_table_iter_free(iter);
+}
+
+TEST(StringTable, FindTest)
+{
+    std::vector<uint8_t> stringHello{
+        1,   0,                  /* string handle*/
+        5,   0,                  /* string length */
+        'H', 'e', 'l', 'l', 'o', /* string */
+    };
+    std::vector<uint8_t> stringWorld{
+        2,   0,                       /* string handle*/
+        6,   0,                       /* string length */
+        'W', 'o', 'r', 'l', 'd', '!', /* string */
+    };
+    std::vector<uint8_t> stringHi{
+        3,   0,   /* string handle*/
+        2,   0,   /* string length */
+        'H', 'i', /* string */
+    };
+
+    Table table;
+    buildTable(table, stringHello, stringWorld, stringHi);
+
+    auto entry = pldm_bios_table_string_find_by_string(table.data(),
+                                                       table.size(), "World!");
+    EXPECT_NE(entry, nullptr);
+    auto handle = pldm_bios_table_string_entry_decode_handle(entry);
+    EXPECT_EQ(handle, 2);
+
+    entry = pldm_bios_table_string_find_by_string(table.data(), table.size(),
+                                                  "Worl");
+    EXPECT_EQ(entry, nullptr);
+
+    entry =
+        pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3);
+    EXPECT_NE(entry, nullptr);
+    auto str_length = pldm_bios_table_string_entry_decode_string_length(entry);
+    EXPECT_EQ(str_length, 2);
+    std::vector<char> strBuf(str_length + 1, 0);
+    auto rc = pldm_bios_table_string_entry_decode_string_check(
+        entry, strBuf.data(), strBuf.size());
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0);
+
+    entry =
+        pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4);
+    EXPECT_EQ(entry, nullptr);
+}
+
+TEST(Iterator, DeathTest)
+{
+
+    Table table(256, 0);
+
+    /* first entry */
+    auto attr_entry =
+        reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
+    auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
+                                            PLDM_BIOS_ATTR_TABLE);
+    attr_entry->attr_type = PLDM_BIOS_PASSWORD;
+#ifndef NDEBUG
+    EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
+#endif
+    pldm_bios_table_iter_free(iter);
+}
+
+TEST(PadAndChecksum, PadAndChecksum)
+{
+    EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0));
+    EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1));
+    EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2));
+    EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3));
+    EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4));
+
+    // The table is borrowed from
+    // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38
+    // refer to the commit message
+    Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66};
+    auto sizeWithoutPad = attrValTable.size();
+    attrValTable.resize(sizeWithoutPad +
+                        pldm_bios_table_pad_checksum_size(sizeWithoutPad));
+    ASSERT_EQ(pldm_bios_table_append_pad_checksum_check(
+                  attrValTable.data(), attrValTable.size(), &sizeWithoutPad),
+              PLDM_SUCCESS);
+    Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65,
+                           0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6};
+    EXPECT_EQ(attrValTable, expectedTable);
+}
+
+TEST(BIOSTableChecksum, testBIOSTableChecksum)
+{
+    std::vector<uint8_t> stringTable{
+        1,   0,                  /* string handle*/
+        5,   0,                  /* string length */
+        'T', 'a', 'b', 'l', 'e', /* string */
+    };
+
+    buildTable(stringTable);
+
+    EXPECT_EQ(true,
+              pldm_bios_table_checksum(stringTable.data(), stringTable.size()));
+}
diff --git a/tests/dsp/bios_table_iter.c b/tests/dsp/bios_table_iter.c
new file mode 100644
index 0000000..5e187b4
--- /dev/null
+++ b/tests/dsp/bios_table_iter.c
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
+/* Force elision of assert() */
+#ifndef NDEBUG
+#define NDEBUG
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/* NOLINTNEXTLINE(bugprone-suspicious-include) */
+#include "dsp/bios_table.c"
+
+/* Satisfy the symbol needs of bios_table.c */
+uint32_t crc32(const void* data __attribute__((unused)),
+               size_t size __attribute__((unused)))
+{
+    return 0;
+}
+
+/* This is the non-death version of TEST(Iterator, DeathTest) */
+int main(void)
+{
+    struct pldm_bios_attr_table_entry entries[2] = {0};
+    struct pldm_bios_table_iter* iter;
+    int result;
+
+    static_assert(2 * sizeof(entries[0]) == sizeof(entries), "");
+
+    entries[0].attr_type = PLDM_BIOS_PASSWORD;
+    entries[1].attr_type = PLDM_BIOS_STRING_READ_ONLY;
+
+    iter = pldm_bios_table_iter_create(entries, sizeof(entries),
+                                       PLDM_BIOS_ATTR_TABLE);
+
+    /*
+     * We expect the test configuration to claim the iterator has reached the
+     * end beause the there's no entry length descriptor for the
+     * PLDM_BIOS_PASSWORD entry type. By the attr_able_entry_length()
+     * implementation this would normally trigger an assert() to uphold that the
+     * necessary pointers are not NULL. However, we've defined NDEBUG above and
+     * so the assert() is elided. That should force us down the path of the
+     * early-exit, which should in-turn yield a `true` result from
+     * pldm_bios_table_iter_is_end() to prevent further attempts to access
+     * invalid objects.
+     */
+    result = pldm_bios_table_iter_is_end(iter) ? EXIT_SUCCESS : EXIT_FAILURE;
+
+    pldm_bios_table_iter_free(iter);
+
+    exit(result);
+
+    return 0;
+}
diff --git a/tests/dsp/firmware_update.cpp b/tests/dsp/firmware_update.cpp
new file mode 100644
index 0000000..24bde16
--- /dev/null
+++ b/tests/dsp/firmware_update.cpp
@@ -0,0 +1,3335 @@
+#include <endian.h>
+#include <libpldm/base.h>
+#include <libpldm/firmware_update.h>
+#include <libpldm/pldm_types.h>
+#include <libpldm/utils.h>
+
+#include <algorithm>
+#include <array>
+#include <bitset>
+#include <cstdint>
+#include <cstring>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include "msgbuf.h"
+
+#include <gtest/gtest.h>
+
+constexpr auto hdrSize = sizeof(pldm_msg_hdr);
+
+TEST(DecodePackageHeaderInfo, goodPath)
+{
+    // Package header identifier for Version 1.0.x
+    constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
+        0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43,
+        0x98, 0x00, 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02};
+    // Package header version for DSP0267 version 1.0.x
+    constexpr uint8_t pkgHeaderFormatRevision = 0x01;
+    // Random PackageHeaderSize
+    constexpr uint16_t pkgHeaderSize = 303;
+    // PackageReleaseDateTime - "25/12/2021 00:00:00"
+    std::array<uint8_t, PLDM_TIMESTAMP104_SIZE> package_release_date_time{
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
+    constexpr uint16_t componentBitmapBitLength = 8;
+    // PackageVersionString
+    constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
+    constexpr size_t packagerHeaderSize =
+        sizeof(pldm_package_header_information) + packageVersionStr.size();
+
+    constexpr std::array<uint8_t, packagerHeaderSize> packagerHeaderInfo{
+        0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
+        0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b,
+        0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
+    pldm_package_header_information pkgHeader{};
+    variable_field packageVersion{};
+
+    auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
+                                              packagerHeaderInfo.size(),
+                                              &pkgHeader, &packageVersion);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(true,
+              std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
+                         uuid.begin(), uuid.end()));
+    EXPECT_EQ(pkgHeader.package_header_format_version, pkgHeaderFormatRevision);
+    EXPECT_EQ(pkgHeader.package_header_size, pkgHeaderSize);
+    EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time,
+                               pkgHeader.package_release_date_time +
+                                   PLDM_TIMESTAMP104_SIZE,
+                               package_release_date_time.begin(),
+                               package_release_date_time.end()));
+    EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
+    EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
+    EXPECT_EQ(pkgHeader.package_version_string_length,
+              packageVersionStr.size());
+    std::string packageVersionString(
+        reinterpret_cast<const char*>(packageVersion.ptr),
+        packageVersion.length);
+    EXPECT_EQ(packageVersionString, packageVersionStr);
+}
+
+TEST(DecodePackageHeaderInfo, errorPaths)
+{
+    int rc = 0;
+    constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
+    constexpr size_t packagerHeaderSize =
+        sizeof(pldm_package_header_information) + packageVersionStr.size();
+
+    // Invalid Package Version String Type - 0x06
+    constexpr std::array<uint8_t, packagerHeaderSize>
+        invalidPackagerHeaderInfo1{
+            0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
+            0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
+            0x07, 0x00, 0x08, 0x00, 0x06, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
+            0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
+
+    pldm_package_header_information packageHeader{};
+    variable_field packageVersion{};
+
+    rc = decode_pldm_package_header_info(nullptr,
+                                         invalidPackagerHeaderInfo1.size(),
+                                         &packageHeader, &packageVersion);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
+                                         invalidPackagerHeaderInfo1.size(),
+                                         nullptr, &packageVersion);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
+                                         invalidPackagerHeaderInfo1.size(),
+                                         &packageHeader, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_pldm_package_header_info(
+        invalidPackagerHeaderInfo1.data(),
+        sizeof(pldm_package_header_information) - 1, &packageHeader,
+        &packageVersion);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
+                                         invalidPackagerHeaderInfo1.size(),
+                                         &packageHeader, &packageVersion);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Invalid Package Version String Length - 0x00
+    constexpr std::array<uint8_t, packagerHeaderSize>
+        invalidPackagerHeaderInfo2{
+            0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
+            0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
+            0x07, 0x00, 0x08, 0x00, 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e,
+            0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
+    rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo2.data(),
+                                         invalidPackagerHeaderInfo2.size(),
+                                         &packageHeader, &packageVersion);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Package version string length less than in the header information
+    constexpr std::array<uint8_t, packagerHeaderSize - 1>
+        invalidPackagerHeaderInfo3{
+            0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
+            0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
+            0x07, 0x00, 0x08, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
+            0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e};
+    rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo3.data(),
+                                         invalidPackagerHeaderInfo3.size(),
+                                         &packageHeader, &packageVersion);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    // ComponentBitmapBitLength not a multiple of 8
+    constexpr std::array<uint8_t, packagerHeaderSize>
+        invalidPackagerHeaderInfo4{
+            0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
+            0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
+            0x07, 0x00, 0x09, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
+            0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
+    rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo4.data(),
+                                         invalidPackagerHeaderInfo4.size(),
+                                         &packageHeader, &packageVersion);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(DecodeFirmwareDeviceIdRecord, goodPath)
+{
+    constexpr uint8_t descriptorCount = 1;
+    // Continue component updates after failure
+    constexpr std::bitset<32> deviceUpdateFlag{1};
+    constexpr uint16_t componentBitmapBitLength = 16;
+    // Applicable Components - 1,2,5,8,9
+    std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01};
+    // ComponentImageSetVersionString
+    constexpr std::string_view imageSetVersionStr{"VersionString1"};
+    // Initial descriptor - UUID
+    constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
+        0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
+        0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
+    constexpr uint16_t fwDevicePkgDataLen = 2;
+    // FirmwareDevicePackageData
+    constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab,
+                                                                      0xcd};
+    // Size of the firmware device ID record
+    constexpr uint16_t recordLen =
+        sizeof(pldm_firmware_device_id_record) +
+        (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
+        imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 +
+        uuid.size() + fwDevicePkgData.size();
+    // Firmware device ID record
+    constexpr std::array<uint8_t, recordLen> record{
+        0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02,
+        0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+        0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10,
+        0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0,
+        0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd};
+
+    pldm_firmware_device_id_record deviceIdRecHeader{};
+    variable_field applicableComponents{};
+    variable_field outCompImageSetVersionStr{};
+    variable_field recordDescriptors{};
+    variable_field outFwDevicePkgData{};
+
+    auto rc = decode_firmware_device_id_record(
+        record.data(), record.size(), componentBitmapBitLength,
+        &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
+        &recordDescriptors, &outFwDevicePkgData);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
+    EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
+    EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
+              deviceUpdateFlag);
+    EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
+              PLDM_STR_TYPE_ASCII);
+    EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
+              imageSetVersionStr.size());
+    EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen);
+
+    EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
+    EXPECT_EQ(true,
+              std::equal(applicableComponents.ptr,
+                         applicableComponents.ptr + applicableComponents.length,
+                         applicableComponentsBitfield.begin(),
+                         applicableComponentsBitfield.end()));
+
+    EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
+    std::string compImageSetVersionStr(
+        reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
+        outCompImageSetVersionStr.length);
+    EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
+
+    uint16_t descriptorType = 0;
+    uint16_t descriptorLen = 0;
+    variable_field descriptorData{};
+    // DescriptorCount is 1, so decode_descriptor_type_length_value called once
+    rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
+                                             recordDescriptors.length,
+                                             &descriptorType, &descriptorData);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
+                                            sizeof(descriptorLen) +
+                                            descriptorData.length);
+    EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
+    EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
+    EXPECT_EQ(true, std::equal(descriptorData.ptr,
+                               descriptorData.ptr + descriptorData.length,
+                               uuid.begin(), uuid.end()));
+
+    EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size());
+    EXPECT_EQ(true,
+              std::equal(outFwDevicePkgData.ptr,
+                         outFwDevicePkgData.ptr + outFwDevicePkgData.length,
+                         fwDevicePkgData.begin(), fwDevicePkgData.end()));
+}
+
+TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData)
+{
+    constexpr uint8_t descriptorCount = 1;
+    // Continue component updates after failure
+    constexpr std::bitset<32> deviceUpdateFlag{1};
+    constexpr uint16_t componentBitmapBitLength = 8;
+    // Applicable Components - 1,2
+    std::vector<std::bitset<8>> applicableComponentsBitfield{0x03};
+    // ComponentImageSetVersionString
+    constexpr std::string_view imageSetVersionStr{"VersionString1"};
+    // Initial descriptor - UUID
+    constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
+        0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
+        0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
+    constexpr uint16_t fwDevicePkgDataLen = 0;
+
+    // Size of the firmware device ID record
+    constexpr uint16_t recordLen =
+        sizeof(pldm_firmware_device_id_record) +
+        (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
+        imageSetVersionStr.size() +
+        sizeof(pldm_descriptor_tlv().descriptor_type) +
+        sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() +
+        fwDevicePkgDataLen;
+    // Firmware device ID record
+    constexpr std::array<uint8_t, recordLen> record{
+        0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03,
+        0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e,
+        0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d,
+        0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
+
+    pldm_firmware_device_id_record deviceIdRecHeader{};
+    variable_field applicableComponents{};
+    variable_field outCompImageSetVersionStr{};
+    variable_field recordDescriptors{};
+    variable_field outFwDevicePkgData{};
+
+    auto rc = decode_firmware_device_id_record(
+        record.data(), record.size(), componentBitmapBitLength,
+        &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
+        &recordDescriptors, &outFwDevicePkgData);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
+    EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
+    EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
+              deviceUpdateFlag);
+    EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
+              PLDM_STR_TYPE_ASCII);
+    EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
+              imageSetVersionStr.size());
+    EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0);
+
+    EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
+    EXPECT_EQ(true,
+              std::equal(applicableComponents.ptr,
+                         applicableComponents.ptr + applicableComponents.length,
+                         applicableComponentsBitfield.begin(),
+                         applicableComponentsBitfield.end()));
+
+    EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
+    std::string compImageSetVersionStr(
+        reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
+        outCompImageSetVersionStr.length);
+    EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
+
+    uint16_t descriptorType = 0;
+    uint16_t descriptorLen = 0;
+    variable_field descriptorData{};
+    // DescriptorCount is 1, so decode_descriptor_type_length_value called once
+    rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
+                                             recordDescriptors.length,
+                                             &descriptorType, &descriptorData);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
+                                            sizeof(descriptorLen) +
+                                            descriptorData.length);
+    EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
+    EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
+    EXPECT_EQ(true, std::equal(descriptorData.ptr,
+                               descriptorData.ptr + descriptorData.length,
+                               uuid.begin(), uuid.end()));
+
+    EXPECT_EQ(outFwDevicePkgData.ptr, nullptr);
+    EXPECT_EQ(outFwDevicePkgData.length, 0);
+}
+
+TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths)
+{
+    constexpr uint16_t componentBitmapBitLength = 8;
+    // Invalid ComponentImageSetVersionStringType
+    constexpr std::array<uint8_t, 11> invalidRecord1{
+        0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
+
+    int rc = 0;
+    pldm_firmware_device_id_record deviceIdRecHeader{};
+    variable_field applicableComponents{};
+    variable_field outCompImageSetVersionStr{};
+    variable_field recordDescriptors{};
+    variable_field outFwDevicePkgData{};
+
+    rc = decode_firmware_device_id_record(
+        nullptr, invalidRecord1.size(), componentBitmapBitLength,
+        &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
+        &recordDescriptors, &outFwDevicePkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_firmware_device_id_record(
+        invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
+        nullptr, &applicableComponents, &outCompImageSetVersionStr,
+        &recordDescriptors, &outFwDevicePkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_firmware_device_id_record(
+        invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
+        &deviceIdRecHeader, nullptr, &outCompImageSetVersionStr,
+        &recordDescriptors, &outFwDevicePkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_firmware_device_id_record(
+        invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
+        &deviceIdRecHeader, &applicableComponents, nullptr, &recordDescriptors,
+        &outFwDevicePkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_firmware_device_id_record(
+        invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
+        &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
+        nullptr, &outFwDevicePkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_firmware_device_id_record(
+        invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
+        &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
+        &recordDescriptors, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_firmware_device_id_record(
+        invalidRecord1.data(), invalidRecord1.size() - 1,
+        componentBitmapBitLength, &deviceIdRecHeader, &applicableComponents,
+        &outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_firmware_device_id_record(
+        invalidRecord1.data(), invalidRecord1.size(),
+        componentBitmapBitLength + 1, &deviceIdRecHeader, &applicableComponents,
+        &outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_firmware_device_id_record(
+        invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
+        &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
+        &recordDescriptors, &outFwDevicePkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Invalid ComponentImageSetVersionStringLength
+    constexpr std::array<uint8_t, 11> invalidRecord2{
+        0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
+    rc = decode_firmware_device_id_record(
+        invalidRecord2.data(), invalidRecord2.size(), componentBitmapBitLength,
+        &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
+        &recordDescriptors, &outFwDevicePkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // invalidRecord3 size is less than RecordLength
+    constexpr std::array<uint8_t, 11> invalidRecord3{
+        0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00};
+    rc = decode_firmware_device_id_record(
+        invalidRecord3.data(), invalidRecord3.size(), componentBitmapBitLength,
+        &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
+        &recordDescriptors, &outFwDevicePkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    // RecordLength is less than the calculated RecordLength
+    constexpr std::array<uint8_t, 11> invalidRecord4{
+        0x15, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02, 0x00};
+    rc = decode_firmware_device_id_record(
+        invalidRecord4.data(), invalidRecord4.size(), componentBitmapBitLength,
+        &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
+        &recordDescriptors, &outFwDevicePkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(DecodeDescriptors, goodPath3Descriptors)
+{
+    // In the descriptor data there are 3 descriptor entries
+    // 1) IANA enterprise ID
+    constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
+        0x0a, 0x0b, 0x0c, 0xd};
+    // 2) UUID
+    constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
+        0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
+        0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
+    // 3) Vendor Defined
+    constexpr std::string_view vendorTitle{"OpenBMC"};
+    constexpr size_t vendorDescriptorLen = 2;
+    constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
+        0x01, 0x02};
+
+    constexpr size_t vendorDefinedDescriptorLen =
+        sizeof(pldm_vendor_defined_descriptor_title_data()
+                   .vendor_defined_descriptor_title_str_type) +
+        sizeof(pldm_vendor_defined_descriptor_title_data()
+                   .vendor_defined_descriptor_title_str_len) +
+        vendorTitle.size() + vendorDescriptorData.size();
+
+    constexpr size_t descriptorsLength =
+        3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
+             sizeof(pldm_descriptor_tlv().descriptor_length)) +
+        iana.size() + uuid.size() + vendorDefinedDescriptorLen;
+
+    constexpr std::array<uint8_t, descriptorsLength> descriptors{
+        0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
+        0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
+        0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
+        0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
+
+    size_t descriptorCount = 1;
+    size_t descriptorsRemainingLength = descriptorsLength;
+    int rc = 0;
+
+    while (descriptorsRemainingLength && (descriptorCount <= 3))
+    {
+        uint16_t descriptorType = 0;
+        uint16_t descriptorLen = 0;
+        variable_field descriptorData{};
+
+        rc = decode_descriptor_type_length_value(
+            descriptors.data() + descriptorsLength - descriptorsRemainingLength,
+            descriptorsRemainingLength, &descriptorType, &descriptorData);
+        EXPECT_EQ(rc, PLDM_SUCCESS);
+
+        if (descriptorCount == 1)
+        {
+            EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
+            EXPECT_EQ(descriptorData.length,
+                      PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
+            EXPECT_EQ(true,
+                      std::equal(descriptorData.ptr,
+                                 descriptorData.ptr + descriptorData.length,
+                                 iana.begin(), iana.end()));
+        }
+        else if (descriptorCount == 2)
+        {
+            EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
+            EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
+            EXPECT_EQ(true,
+                      std::equal(descriptorData.ptr,
+                                 descriptorData.ptr + descriptorData.length,
+                                 uuid.begin(), uuid.end()));
+        }
+        else if (descriptorCount == 3)
+        {
+            EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
+            EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
+
+            uint8_t descriptorTitleStrType = 0;
+            variable_field descriptorTitleStr{};
+            variable_field vendorDefinedDescriptorData{};
+
+            rc = decode_vendor_defined_descriptor_value(
+                descriptorData.ptr, descriptorData.length,
+                &descriptorTitleStrType, &descriptorTitleStr,
+                &vendorDefinedDescriptorData);
+            EXPECT_EQ(rc, PLDM_SUCCESS);
+
+            EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
+            EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
+            std::string vendorTitleStr(
+                reinterpret_cast<const char*>(descriptorTitleStr.ptr),
+                descriptorTitleStr.length);
+            EXPECT_EQ(vendorTitleStr, vendorTitle);
+
+            EXPECT_EQ(vendorDefinedDescriptorData.length,
+                      vendorDescriptorData.size());
+            EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
+                                       vendorDefinedDescriptorData.ptr +
+                                           vendorDefinedDescriptorData.length,
+                                       vendorDescriptorData.begin(),
+                                       vendorDescriptorData.end()));
+        }
+
+        descriptorsRemainingLength -= sizeof(descriptorType) +
+                                      sizeof(descriptorLen) +
+                                      descriptorData.length;
+        descriptorCount++;
+    }
+}
+
+TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
+{
+    int rc = 0;
+    // IANA Enterprise ID descriptor length incorrect
+    constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
+        0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
+    uint16_t descriptorType = 0;
+    variable_field descriptorData{};
+
+    rc = decode_descriptor_type_length_value(nullptr,
+                                             invalidIANADescriptor1.size(),
+                                             &descriptorType, &descriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
+                                             invalidIANADescriptor1.size(),
+                                             nullptr, &descriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
+                                             invalidIANADescriptor1.size(),
+                                             &descriptorType, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_descriptor_type_length_value(
+        invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
+        &descriptorType, &descriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
+                                             invalidIANADescriptor1.size(),
+                                             &descriptorType, &descriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    // IANA Enterprise ID descriptor data less than length
+    std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
+                                                  0x0a, 0x0b, 0x0c};
+    rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
+                                             invalidIANADescriptor2.size(),
+                                             &descriptorType, &descriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
+{
+    int rc = 0;
+    // VendorDefinedDescriptorTitleStringType is invalid
+    constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
+        0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
+    uint8_t descriptorStringType = 0;
+    variable_field descriptorTitleStr{};
+    variable_field vendorDefinedDescriptorData{};
+
+    rc = decode_vendor_defined_descriptor_value(
+        nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
+        &descriptorTitleStr, &vendorDefinedDescriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_vendor_defined_descriptor_value(
+        invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
+        &descriptorStringType, &descriptorTitleStr,
+        &vendorDefinedDescriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_vendor_defined_descriptor_value(
+        invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
+        nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_vendor_defined_descriptor_value(
+        invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
+        &descriptorStringType, nullptr, &vendorDefinedDescriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_vendor_defined_descriptor_value(
+        invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
+        &descriptorStringType, &descriptorTitleStr, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_vendor_defined_descriptor_value(
+        invalidVendorDescriptor1.data(),
+        sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
+        &descriptorStringType, &descriptorTitleStr,
+        &vendorDefinedDescriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_vendor_defined_descriptor_value(
+        invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
+        &descriptorStringType, &descriptorTitleStr,
+        &vendorDefinedDescriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // VendorDefinedDescriptorTitleStringLength is 0
+    std::array<uint8_t, 9> invalidVendorDescriptor2{
+        0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
+    rc = decode_vendor_defined_descriptor_value(
+        invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
+        &descriptorStringType, &descriptorTitleStr,
+        &vendorDefinedDescriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // VendorDefinedDescriptorData not present in the data
+    std::array<uint8_t, 9> invalidVendorDescriptor3{
+        0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
+    rc = decode_vendor_defined_descriptor_value(
+        invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
+        &descriptorStringType, &descriptorTitleStr,
+        &vendorDefinedDescriptorData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(DecodeComponentImageInfo, goodPath)
+{
+    // Firmware
+    constexpr uint16_t compClassification = 16;
+    constexpr uint16_t compIdentifier = 300;
+    constexpr uint32_t compComparisonStamp = 0xffffffff;
+    // Force update
+    constexpr std::bitset<16> compOptions{1};
+    // System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
+    constexpr std::bitset<16> reqCompActivationMethod{0x0c};
+    // Random ComponentLocationOffset
+    constexpr uint32_t compLocOffset = 357;
+    // Random ComponentSize
+    constexpr uint32_t compSize = 27;
+    // ComponentVersionString
+    constexpr std::string_view compVersionStr{"VersionString1"};
+    constexpr size_t compImageInfoSize =
+        sizeof(pldm_component_image_information) + compVersionStr.size();
+
+    constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
+        0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
+        0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
+        0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
+    pldm_component_image_information outCompImageInfo{};
+    variable_field outCompVersionStr{};
+
+    auto rc =
+        decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
+                                    &outCompImageInfo, &outCompVersionStr);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
+    EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
+    EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
+    EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
+    EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
+              reqCompActivationMethod);
+    EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
+    EXPECT_EQ(outCompImageInfo.comp_size, compSize);
+    EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
+    EXPECT_EQ(outCompImageInfo.comp_version_string_length,
+              compVersionStr.size());
+
+    EXPECT_EQ(outCompVersionStr.length,
+              outCompImageInfo.comp_version_string_length);
+    std::string componentVersionString(
+        reinterpret_cast<const char*>(outCompVersionStr.ptr),
+        outCompVersionStr.length);
+    EXPECT_EQ(componentVersionString, compVersionStr);
+}
+
+TEST(DecodeComponentImageInfo, errorPaths)
+{
+    int rc = 0;
+    // ComponentVersionString
+    constexpr std::string_view compVersionStr{"VersionString1"};
+    constexpr size_t compImageInfoSize =
+        sizeof(pldm_component_image_information) + compVersionStr.size();
+    // Invalid ComponentVersionStringType - 0x06
+    constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
+        0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
+        0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
+        0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
+    pldm_component_image_information outCompImageInfo{};
+    variable_field outCompVersionStr{};
+
+    rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
+                                     &outCompImageInfo, &outCompVersionStr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
+                                     invalidCompImageInfo1.size(), nullptr,
+                                     &outCompVersionStr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
+                                     invalidCompImageInfo1.size(),
+                                     &outCompImageInfo, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
+                                     sizeof(pldm_component_image_information) -
+                                         1,
+                                     &outCompImageInfo, &outCompVersionStr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
+                                     invalidCompImageInfo1.size(),
+                                     &outCompImageInfo, &outCompVersionStr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Invalid ComponentVersionStringLength - 0x00
+    constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
+        0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
+        0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
+        0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
+    rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
+                                     invalidCompImageInfo2.size(),
+                                     &outCompImageInfo, &outCompVersionStr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Use Component Comparison Stamp is not set, but ComponentComparisonStamp
+    // is not 0xffffffff
+    constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
+        0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
+        0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
+        0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
+
+    rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
+                                     invalidCompImageInfo3.size() - 1,
+                                     &outCompImageInfo, &outCompVersionStr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
+                                     invalidCompImageInfo3.size(),
+                                     &outCompImageInfo, &outCompVersionStr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Invalid ComponentLocationOffset - 0
+    constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
+        0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
+        0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
+    rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(),
+                                     invalidCompImageInfo4.size(),
+                                     &outCompImageInfo, &outCompVersionStr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Invalid ComponentSize - 0
+    constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
+        0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
+        0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
+        0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
+    rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
+                                     invalidCompImageInfo5.size(),
+                                     &outCompImageInfo, &outCompVersionStr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
+{
+    std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
+    auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    uint8_t instanceId = 0x01;
+
+    auto rc = encode_query_device_identifiers_req(
+        instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
+    EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
+    EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
+    EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
+}
+
+TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
+{
+    // descriptorDataLen is not fixed here taking it as 6
+    constexpr uint8_t descriptorDataLen = 6;
+    std::array<uint8_t, hdrSize +
+                            sizeof(struct pldm_query_device_identifiers_resp) +
+                            descriptorDataLen>
+        responseMsg{};
+    auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
+        responseMsg.data() + hdrSize);
+
+    inResp->completion_code = PLDM_SUCCESS;
+    inResp->device_identifiers_len = htole32(descriptorDataLen);
+    inResp->descriptor_count = 1;
+
+    // filling descriptor data
+    std::fill_n(responseMsg.data() + hdrSize +
+                    sizeof(struct pldm_query_device_identifiers_resp),
+                descriptorDataLen, 0xff);
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint32_t deviceIdentifiersLen = 0;
+    uint8_t descriptorCount = 0;
+    uint8_t* outDescriptorData = nullptr;
+
+    auto rc = decode_query_device_identifiers_resp(
+        response, responseMsg.size() - hdrSize, &completionCode,
+        &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_SUCCESS);
+    EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
+    EXPECT_EQ(descriptorCount, inResp->descriptor_count);
+    EXPECT_EQ(true,
+              std::equal(outDescriptorData,
+                         outDescriptorData + deviceIdentifiersLen,
+                         responseMsg.begin() + hdrSize +
+                             sizeof(struct pldm_query_device_identifiers_resp),
+                         responseMsg.end()));
+}
+
+TEST(GetFirmwareParameters, goodPathEncodeRequest)
+{
+    std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
+    auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    uint8_t instanceId = 0x01;
+
+    auto rc = encode_get_firmware_parameters_req(
+        instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
+    EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
+    EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
+    EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
+}
+
+TEST(GetFirmwareParameters, decodeResponse)
+{
+    // CapabilitiesDuringUpdate of the firmware device
+    // Firmware device downgrade restrictions [Bit position 8] &
+    // Firmware Device Partial Updates [Bit position 3]
+    constexpr std::bitset<32> fdCapabilities{0x00000104};
+    constexpr uint16_t compCount = 1;
+    constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
+    constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
+
+    // constexpr uint16_t compClassification = 16;
+    // constexpr uint16_t compIdentifier = 300;
+    // constexpr uint8_t compClassificationIndex = 20;
+    // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
+    // constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
+    //     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
+    // constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
+    // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
+    //     0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
+    constexpr std::string_view activeCompVersion{"VersionString3"};
+    constexpr std::string_view pendingCompVersion{"VersionString4"};
+
+    constexpr size_t compParamTableSize =
+        sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
+        pendingCompVersion.size();
+
+    constexpr std::array<uint8_t, compParamTableSize> compParamTable{
+        0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
+        0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
+        0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
+        0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
+        0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+        0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
+
+    constexpr size_t getFwParamsPayloadLen =
+        sizeof(pldm_get_firmware_parameters_resp) +
+        activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
+        compParamTableSize;
+
+    constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
+        getFwParamsResponse{
+            0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
+            0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
+            0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
+            0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00,
+            0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
+            0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
+            0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
+            0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+            0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
+            0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
+
+    auto responseMsg =
+        reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
+    pldm_get_firmware_parameters_resp outResp{};
+    variable_field outActiveCompImageSetVersion{};
+    variable_field outPendingCompImageSetVersion{};
+    variable_field outCompParameterTable{};
+
+    auto rc = decode_get_firmware_parameters_resp(
+        responseMsg, getFwParamsPayloadLen, &outResp,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
+        &outCompParameterTable);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
+    EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
+    EXPECT_EQ(outResp.comp_count, compCount);
+    EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
+    EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
+              activeCompImageSetVersion.size());
+    EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
+    EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
+              pendingCompImageSetVersion.size());
+    std::string activeCompImageSetVersionStr(
+        reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
+        outActiveCompImageSetVersion.length);
+    EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
+    std::string pendingCompImageSetVersionStr(
+        reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
+        outPendingCompImageSetVersion.length);
+    EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
+    EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
+    EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
+                               outCompParameterTable.ptr +
+                                   outCompParameterTable.length,
+                               compParamTable.begin(), compParamTable.end()));
+}
+
+TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
+{
+    // CapabilitiesDuringUpdate of the firmware device
+    // FD Host Functionality during Firmware Update [Bit position 2] &
+    // Component Update Failure Retry Capability [Bit position 1]
+    constexpr std::bitset<32> fdCapabilities{0x06};
+    constexpr uint16_t compCount = 0;
+    constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
+    constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
+
+    constexpr size_t getFwParamsPayloadLen =
+        sizeof(pldm_get_firmware_parameters_resp) +
+        activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
+
+    constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
+        getFwParamsResponse{
+            0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+            0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
+            0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
+            0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
+
+    auto responseMsg =
+        reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
+    pldm_get_firmware_parameters_resp outResp{};
+    variable_field outActiveCompImageSetVersion{};
+    variable_field outPendingCompImageSetVersion{};
+    variable_field outCompParameterTable{};
+
+    auto rc = decode_get_firmware_parameters_resp(
+        responseMsg, getFwParamsPayloadLen, &outResp,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
+        &outCompParameterTable);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
+    EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
+    EXPECT_EQ(outResp.comp_count, compCount);
+    EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
+    EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
+              activeCompImageSetVersion.size());
+    EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
+    EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
+              pendingCompImageSetVersion.size());
+    std::string activeCompImageSetVersionStr(
+        reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
+        outActiveCompImageSetVersion.length);
+    EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
+    std::string pendingCompImageSetVersionStr(
+        reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
+        outPendingCompImageSetVersion.length);
+    EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
+    EXPECT_EQ(outCompParameterTable.ptr, nullptr);
+    EXPECT_EQ(outCompParameterTable.length, 0);
+}
+
+TEST(GetFirmwareParameters,
+     decodeResponseNoPendingCompImageVersionStrZeroCompCount)
+{
+    // CapabilitiesDuringUpdate of the firmware device
+    // FD Host Functionality during Firmware Update [Bit position 2] &
+    // Component Update Failure Retry Capability [Bit position 1]
+    constexpr std::bitset<32> fdCapabilities{0x06};
+    constexpr uint16_t compCount = 0;
+    constexpr std::string_view activeCompImageSetVersion{"VersionString"};
+
+    constexpr size_t getFwParamsPayloadLen =
+        sizeof(pldm_get_firmware_parameters_resp) +
+        activeCompImageSetVersion.size();
+
+    constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
+        getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
+                            0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
+                            0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+                            0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
+
+    auto responseMsg =
+        reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
+    pldm_get_firmware_parameters_resp outResp{};
+    variable_field outActiveCompImageSetVersion{};
+    variable_field outPendingCompImageSetVersion{};
+    variable_field outCompParameterTable{};
+
+    auto rc = decode_get_firmware_parameters_resp(
+        responseMsg, getFwParamsPayloadLen, &outResp,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
+        &outCompParameterTable);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
+    EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
+    EXPECT_EQ(outResp.comp_count, compCount);
+    EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
+    EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
+              activeCompImageSetVersion.size());
+    EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
+              PLDM_STR_TYPE_UNKNOWN);
+    EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
+    std::string activeCompImageSetVersionStr(
+        reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
+        outActiveCompImageSetVersion.length);
+    EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
+    EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
+    EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
+    EXPECT_EQ(outCompParameterTable.ptr, nullptr);
+    EXPECT_EQ(outCompParameterTable.length, 0);
+}
+
+TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
+{
+    constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
+        getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
+
+    auto responseMsg =
+        reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
+    pldm_get_firmware_parameters_resp outResp{};
+    variable_field outActiveCompImageSetVersion{};
+    variable_field outPendingCompImageSetVersion{};
+    variable_field outCompParameterTable{};
+
+    auto rc = decode_get_firmware_parameters_resp(
+        responseMsg, getFwParamsResponse.size(), &outResp,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
+        &outCompParameterTable);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
+}
+
+TEST(GetFirmwareParameters, errorPathdecodeResponse)
+{
+    int rc = 0;
+    // Invalid ActiveComponentImageSetVersionStringType
+    constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
+
+    auto responseMsg =
+        reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
+    pldm_get_firmware_parameters_resp outResp{};
+    variable_field outActiveCompImageSetVersion{};
+    variable_field outPendingCompImageSetVersion{};
+    variable_field outCompParameterTable{};
+
+    rc = decode_get_firmware_parameters_resp(
+        nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
+        &outCompParameterTable);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_firmware_parameters_resp(
+        responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
+        &outCompParameterTable);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_firmware_parameters_resp(
+        responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
+        nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_firmware_parameters_resp(
+        responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
+        &outActiveCompImageSetVersion, nullptr, &outCompParameterTable);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_firmware_parameters_resp(
+        responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_firmware_parameters_resp(
+        responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
+        &outPendingCompImageSetVersion, &outCompParameterTable);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_firmware_parameters_resp(
+        responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
+        &outCompParameterTable);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_get_firmware_parameters_resp(
+        responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
+        &outCompParameterTable);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Invalid ActiveComponentImageSetVersionStringLength
+    constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
+    responseMsg =
+        reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
+    rc = decode_get_firmware_parameters_resp(
+        responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
+        &outCompParameterTable);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Invalid PendingComponentImageSetVersionStringType &
+    // PendingComponentImageSetVersionStringLength
+    constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
+        0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
+    responseMsg =
+        reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
+    rc = decode_get_firmware_parameters_resp(
+        responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
+        &outCompParameterTable);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Invalid PendingComponentImageSetVersionStringType &
+    // PendingComponentImageSetVersionStringLength
+    constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
+        0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
+    responseMsg =
+        reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
+    rc = decode_get_firmware_parameters_resp(
+        responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
+        &outCompParameterTable);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Total payload length less than expected
+    constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
+        0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
+    responseMsg =
+        reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
+    rc = decode_get_firmware_parameters_resp(
+        responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
+        &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
+        &outCompParameterTable);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
+{
+    // Random value for component classification
+    constexpr uint16_t compClassification = 0x0a0b;
+    // Random value for component classification
+    constexpr uint16_t compIdentifier = 0x0c0d;
+    // Random value for component classification
+    constexpr uint32_t timestamp = 0x12345678;
+    // Random value for component activation methods
+    constexpr uint16_t compActivationMethods = 0xbbdd;
+    // Random value for capabilities during update
+    constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
+
+    // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
+    constexpr uint8_t activeCompVerStrLen = 8;
+    // PendingCompImageSetVerStrLen is not fixed here taking it as 8
+    constexpr uint8_t pendingCompVerStrLen = 8;
+    constexpr size_t entryLength =
+        sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
+        pendingCompVerStrLen;
+    std::array<uint8_t, entryLength> entry{};
+
+    auto inEntry =
+        reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
+
+    inEntry->comp_classification = htole16(compClassification);
+    inEntry->comp_identifier = htole16(compIdentifier);
+    inEntry->comp_classification_index = 0x0f;
+    inEntry->active_comp_comparison_stamp = htole32(timestamp);
+    inEntry->active_comp_ver_str_type = 1;
+    inEntry->active_comp_ver_str_len = activeCompVerStrLen;
+    std::fill_n(inEntry->active_comp_release_date,
+                sizeof(inEntry->active_comp_release_date), 0xff);
+    inEntry->pending_comp_comparison_stamp = htole32(timestamp);
+    inEntry->pending_comp_ver_str_type = 1;
+    inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
+    std::fill_n(inEntry->pending_comp_release_date,
+                sizeof(inEntry->pending_comp_release_date), 0xff);
+    inEntry->comp_activation_methods.value = htole16(compActivationMethods);
+    inEntry->capabilities_during_update.value =
+        htole32(capabilitiesDuringUpdate);
+    constexpr auto activeCompVerStrPos =
+        sizeof(struct pldm_component_parameter_entry);
+    std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
+    constexpr auto pendingCompVerStrPos =
+        activeCompVerStrPos + activeCompVerStrLen;
+    std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
+                0xbb);
+
+    struct pldm_component_parameter_entry outEntry;
+    struct variable_field outActiveCompVerStr;
+    struct variable_field outPendingCompVerStr;
+
+    auto rc = decode_get_firmware_parameters_resp_comp_entry(
+        entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
+        &outPendingCompVerStr);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    EXPECT_EQ(outEntry.comp_classification, compClassification);
+    EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
+    EXPECT_EQ(inEntry->comp_classification_index,
+              outEntry.comp_classification_index);
+    EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
+    EXPECT_EQ(inEntry->active_comp_ver_str_type,
+              outEntry.active_comp_ver_str_type);
+    EXPECT_EQ(inEntry->active_comp_ver_str_len,
+              outEntry.active_comp_ver_str_len);
+    EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
+                        outEntry.active_comp_release_date,
+                        sizeof(inEntry->active_comp_release_date)));
+    EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
+    EXPECT_EQ(inEntry->pending_comp_ver_str_type,
+              outEntry.pending_comp_ver_str_type);
+    EXPECT_EQ(inEntry->pending_comp_ver_str_len,
+              outEntry.pending_comp_ver_str_len);
+    EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
+                        outEntry.pending_comp_release_date,
+                        sizeof(inEntry->pending_comp_release_date)));
+    EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
+    EXPECT_EQ(outEntry.capabilities_during_update.value,
+              capabilitiesDuringUpdate);
+
+    EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
+                        entry.data() + activeCompVerStrPos,
+                        outActiveCompVerStr.length));
+    EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
+                        entry.data() + pendingCompVerStrPos,
+                        outPendingCompVerStr.length));
+}
+
+#ifdef LIBPLDM_API_TESTING
+TEST(QueryDownstreamDevices, goodPathEncodeRequest)
+{
+    constexpr uint8_t instanceId = 1;
+    std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
+    auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
+    EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
+    EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
+    EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(QueryDownstreamDevices, encodeRequestInvalidData)
+{
+    constexpr uint8_t instanceId = 1;
+
+    auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(QueryDownstreamDevices, goodPathDecodeResponse)
+{
+    uint8_t completion_code_resp = PLDM_SUCCESS;
+    uint8_t downstream_device_update_supported_resp =
+        PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
+    uint16_t number_of_downstream_devices_resp = 1;
+    uint16_t max_number_of_downstream_devices_resp = 1;
+    /** Capabilities of updating downstream devices
+     * FDP supports downstream devices dynamically attached [Bit position 0] &
+     * FDP supports downstream devices dynamically removed [Bit position 1]
+     */
+    bitfield32_t capabilities_resp = {.value = 0x0002};
+    int rc;
+
+    std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
+        responseMsg{};
+
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    rc = pldm_msgbuf_init_cc(buf, 0, responseMsg.data() + hdrSize,
+                             responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    pldm_msgbuf_insert_uint8(buf, completion_code_resp);
+    pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
+    pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
+    pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
+    pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_query_downstream_devices_resp resp_data;
+
+    rc = decode_query_downstream_devices_resp(
+        response, responseMsg.size() - hdrSize, &resp_data);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(resp_data.completion_code, completion_code_resp);
+    EXPECT_EQ(resp_data.downstream_device_update_supported,
+              downstream_device_update_supported_resp);
+    EXPECT_EQ(resp_data.number_of_downstream_devices,
+              number_of_downstream_devices_resp);
+    EXPECT_EQ(resp_data.max_number_of_downstream_devices,
+              max_number_of_downstream_devices_resp);
+    EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
+{
+    uint8_t completion_code_resp = PLDM_SUCCESS;
+    uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
+    uint16_t number_of_downstream_devices_resp = 1;
+    uint16_t max_number_of_downstream_devices_resp = 1;
+    /** Capabilities of updating downstream devices
+     * FDP supports downstream devices dynamically attached [Bit position 0] &
+     * FDP supports downstream devices dynamically removed [Bit position 1]
+     */
+    bitfield32_t capabilities_resp = {.value = 0x0002};
+    int rc;
+
+    std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
+        responseMsg{};
+
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    rc = pldm_msgbuf_init_cc(buf, 0, responseMsg.data() + hdrSize,
+                             responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    pldm_msgbuf_insert_uint8(buf, completion_code_resp);
+    pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
+    pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
+    pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
+    pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_query_downstream_devices_resp resp_data;
+
+    rc = decode_query_downstream_devices_resp(
+        response, responseMsg.size() - hdrSize, &resp_data);
+
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
+{
+    uint8_t completion_code_resp = PLDM_SUCCESS;
+    uint8_t downstream_device_update_supported_resp =
+        PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
+    uint16_t number_of_downstream_devices_resp = 1;
+    uint16_t max_number_of_downstream_devices_resp = 1;
+    /** Capabilities of updating downstream devices
+     * FDP supports downstream devices dynamically attached [Bit position 0] &
+     * FDP supports downstream devices dynamically removed [Bit position 1]
+     */
+    bitfield32_t capabilities_resp = {.value = 0x0002};
+    int rc;
+
+    std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
+                            2 /* Inject error length*/>
+        responseMsg{};
+
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    rc = pldm_msgbuf_init_cc(buf, 0, responseMsg.data() + hdrSize,
+                             responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    pldm_msgbuf_insert_uint8(buf, completion_code_resp);
+    pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
+    pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
+    pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
+    // Inject error value
+    pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_query_downstream_devices_resp resp_data;
+
+    rc = decode_query_downstream_devices_resp(
+        response, responseMsg.size() - hdrSize, &resp_data);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
+{
+    constexpr uint8_t instanceId = 1;
+    constexpr uint32_t dataTransferHandle = 0xFFFFFFFF;
+    constexpr enum transfer_op_flag transferOperationFlag = PLDM_GET_FIRSTPART;
+    constexpr size_t payload_length =
+        PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
+    std::array<uint8_t, hdrSize + payload_length> requestMsg{};
+    auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_query_downstream_identifiers_req(
+        instanceId, dataTransferHandle, transferOperationFlag, requestPtr,
+        payload_length);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES>
+        expectedReq{0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01};
+    EXPECT_EQ(requestMsg, expectedReq);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
+{
+    constexpr uint8_t instanceId = 1;
+    constexpr uint32_t dataTransferHandle = 0x0;
+    constexpr enum transfer_op_flag transferOperationFlag = PLDM_GET_FIRSTPART;
+    constexpr enum transfer_op_flag invalidTransferOperationFlag =
+        PLDM_ACKNOWLEDGEMENT_ONLY;
+    constexpr size_t payload_length =
+        PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
+    std::array<uint8_t, hdrSize + payload_length> requestMsg{};
+    auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_query_downstream_identifiers_req(
+        instanceId, dataTransferHandle, transferOperationFlag, nullptr,
+        payload_length);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_query_downstream_identifiers_req(
+        instanceId, dataTransferHandle, transferOperationFlag, requestPtr,
+        payload_length - 1);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = encode_query_downstream_identifiers_req(instanceId, dataTransferHandle,
+                                                 invalidTransferOperationFlag,
+                                                 requestPtr, payload_length);
+    EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(QueryDownstreamIdentifiers, goodPathDecodeResponse)
+{
+    // Len is not fixed here taking it as 9, constains 1 downstream device with
+    // 1 descriptor
+    constexpr uint32_t downstreamDevicesLen = 9;
+    constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
+    constexpr uint32_t next_data_transfer_handle_resp = 0x0;
+    constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
+    const uint32_t downstream_devices_length_resp =
+        htole32(downstreamDevicesLen);
+    constexpr uint16_t number_of_downstream_devices_resp = 1;
+    std::array<uint8_t, hdrSize +
+                            PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
+                            downstreamDevicesLen>
+        responseMsg{};
+    int rc = 0;
+
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    rc = pldm_msgbuf_init_cc(buf, 0, responseMsg.data() + hdrSize,
+                             responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    pldm_msgbuf_insert_uint8(buf, complition_code_resp);
+    pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
+    pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
+    pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
+    pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
+
+    /** Filling descriptor data, the correctness of the downstream devices data
+     *  is not checked in this test case so filling with 0xff
+     */
+    std::fill_n(responseMsg.data() + hdrSize +
+                    PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN,
+                downstreamDevicesLen, 0xff);
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_query_downstream_identifiers_resp resp_data = {};
+    struct variable_field downstreamDevices = {};
+
+    rc = decode_query_downstream_identifiers_resp(
+        response, responseMsg.size() - hdrSize, &resp_data, &downstreamDevices);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(resp_data.completion_code, complition_code_resp);
+    EXPECT_EQ(resp_data.next_data_transfer_handle,
+              next_data_transfer_handle_resp);
+    EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
+    EXPECT_EQ(resp_data.downstream_devices_length,
+              downstream_devices_length_resp);
+    EXPECT_EQ(resp_data.number_of_downstream_devices,
+              number_of_downstream_devices_resp);
+    EXPECT_EQ(downstreamDevices.length, downstreamDevicesLen);
+    EXPECT_EQ(true,
+              std::equal(downstreamDevices.ptr,
+                         downstreamDevices.ptr + downstreamDevices.length,
+                         responseMsg.begin() + hdrSize +
+                             PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN,
+                         responseMsg.end()));
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
+{
+    std::array<uint8_t, hdrSize + sizeof(uint8_t)> responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_query_downstream_identifiers_resp resp_data = {};
+    struct variable_field downstreamDevices = {};
+
+    // Test nullptr
+    auto rc = decode_query_downstream_identifiers_resp(
+        nullptr, responseMsg.size() - hdrSize, nullptr, &downstreamDevices);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Test not PLDM_SUCCESS completion code
+    response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+    rc = decode_query_downstream_identifiers_resp(
+        response, responseMsg.size() - hdrSize, &resp_data, &downstreamDevices);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
+
+    // Test payload length less than minimum length
+    response->payload[0] = PLDM_SUCCESS;
+    rc = decode_query_downstream_identifiers_resp(
+        response, responseMsg.size() - hdrSize, &resp_data, &downstreamDevices);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
+{
+    // Len is not fixed here taking it as 9, constains 1 downstream device with
+    // 1 descriptor
+    constexpr uint32_t actualDownstreamDevicesLen = 9;
+    constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
+    constexpr uint32_t next_data_transfer_handle_resp = 0x0;
+    constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
+    const uint32_t downstream_devices_length_resp =
+        htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
+    constexpr uint16_t number_of_downstream_devices_resp = 1;
+    std::array<uint8_t, hdrSize +
+                            PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
+                            actualDownstreamDevicesLen>
+        responseMsg{};
+    int rc = 0;
+
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    rc = pldm_msgbuf_init_cc(buf, 0, responseMsg.data() + hdrSize,
+                             responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    pldm_msgbuf_insert_uint8(buf, complition_code_resp);
+    pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
+    pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
+    pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
+    pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
+
+    /** Filling descriptor data, the correctness of the downstream devices data
+     *  is not checked in this test case so filling with 0xff
+     */
+    std::fill_n(responseMsg.data() + hdrSize +
+                    PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN,
+                actualDownstreamDevicesLen, 0xff);
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_query_downstream_identifiers_resp resp_data = {};
+    struct variable_field downstreamDevices = {};
+
+    /** In test mode, this will trigger an assert failure and cause the unit
+     * test to fail if only testing by the rc. Use ASSERT_DEATH to test this
+     * scenario.
+     *
+     *  The 1st parameter is the function under test.
+     *  The 2nd parameter compares the output of the program.
+     */
+#ifdef NDEBUG
+    EXPECT_NE(decode_query_downstream_identifiers_resp(
+                  response, responseMsg.size() - hdrSize, &resp_data,
+                  &downstreamDevices),
+              PLDM_SUCCESS);
+#else
+    EXPECT_DEATH(
+        decode_query_downstream_identifiers_resp(
+            response, responseMsg.size() - hdrSize, &resp_data,
+            &downstreamDevices),
+        // This error doesn't output any error message, leave it be empty
+        "");
+#endif
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
+{
+    constexpr uint32_t actualDownstreamDevicesLen = 0;
+    constexpr uint16_t number_of_downstream_devices_resp = 1;
+    constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
+    constexpr uint32_t next_data_transfer_handle_resp = 0x0;
+    constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
+    const uint32_t downstream_devices_length_resp =
+        htole32(actualDownstreamDevicesLen);
+
+    std::array<uint8_t, hdrSize +
+                            PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN -
+                            1 /* Inject error length*/>
+        responseMsg{};
+    int rc = 0;
+
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    rc = pldm_msgbuf_init_cc(buf, 0, responseMsg.data() + hdrSize,
+                             responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    pldm_msgbuf_insert_uint8(buf, complition_code_resp);
+    pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
+    pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
+    pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
+    // Inject error buffer size
+    pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_query_downstream_identifiers_resp resp_data = {};
+    struct variable_field downstreamDevices = {};
+
+    rc = decode_query_downstream_identifiers_resp(
+        response, responseMsg.size() - hdrSize, &resp_data, &downstreamDevices);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+#endif
+
+TEST(RequestUpdate, goodPathEncodeRequest)
+{
+    constexpr uint8_t instanceId = 1;
+    constexpr uint32_t maxTransferSize = 512;
+    constexpr uint16_t numOfComp = 3;
+    constexpr uint8_t maxOutstandingTransferReq = 2;
+    constexpr uint16_t pkgDataLen = 0x1234;
+    constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
+    constexpr uint8_t compImgSetVerStrLen =
+        static_cast<uint8_t>(compImgSetVerStr.size());
+    variable_field compImgSetVerStrInfo{};
+    compImgSetVerStrInfo.ptr =
+        reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
+    compImgSetVerStrInfo.length = compImgSetVerStrLen;
+
+    std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
+                            compImgSetVerStrLen>
+        request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_request_update_req(
+        instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
+        pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
+        &compImgSetVerStrInfo, requestMsg,
+        sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
+                            compImgSetVerStrLen>
+        outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
+                   0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
+                   0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
+    EXPECT_EQ(request, outRequest);
+}
+
+TEST(RequestUpdate, errorPathEncodeRequest)
+{
+    constexpr uint8_t instanceId = 1;
+    uint32_t maxTransferSize = 512;
+    constexpr uint16_t numOfComp = 3;
+    uint8_t maxOutstandingTransferReq = 2;
+    constexpr uint16_t pkgDataLen = 0x1234;
+    constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
+    uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
+    variable_field compImgSetVerStrInfo{};
+    compImgSetVerStrInfo.ptr =
+        reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
+    compImgSetVerStrInfo.length = compImgSetVerStrLen;
+
+    std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
+                            compImgSetVerStr.size()>
+        request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_request_update_req(
+        instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
+        pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
+        requestMsg,
+        sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    compImgSetVerStrInfo.ptr = nullptr;
+    rc = encode_request_update_req(
+        instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
+        pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
+        &compImgSetVerStrInfo, requestMsg,
+        sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    compImgSetVerStrInfo.ptr =
+        reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
+
+    rc = encode_request_update_req(
+        instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
+        pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
+        &compImgSetVerStrInfo, nullptr,
+        sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
+                                   maxOutstandingTransferReq, pkgDataLen,
+                                   PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
+                                   &compImgSetVerStrInfo, requestMsg, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    compImgSetVerStrLen = 0;
+    rc = encode_request_update_req(
+        instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
+        pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
+        sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
+
+    compImgSetVerStrInfo.length = 0xffff;
+    rc = encode_request_update_req(
+        instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
+        pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
+        &compImgSetVerStrInfo, nullptr,
+        sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    compImgSetVerStrInfo.length = compImgSetVerStrLen;
+
+    maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
+    rc = encode_request_update_req(
+        instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
+        pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
+        &compImgSetVerStrInfo, nullptr,
+        sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
+
+    maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
+    rc = encode_request_update_req(
+        instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
+        pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
+        &compImgSetVerStrInfo, nullptr,
+        sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
+
+    rc = encode_request_update_req(
+        instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
+        pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
+        &compImgSetVerStrInfo, nullptr,
+        sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(RequestUpdate, goodPathDecodeResponse)
+{
+    constexpr uint16_t fdMetaDataLen = 1024;
+    constexpr uint8_t fdWillSendPkgData = 1;
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
+        requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
+
+    auto responseMsg1 =
+        reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
+    uint8_t outCompletionCode = 0;
+    uint16_t outFdMetaDataLen = 0;
+    uint8_t outFdWillSendPkgData = 0;
+
+    auto rc = decode_request_update_resp(
+        responseMsg1, requestUpdateResponse1.size() - hdrSize,
+        &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
+    EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
+    EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
+
+    outCompletionCode = 0;
+    outFdMetaDataLen = 0;
+    outFdWillSendPkgData = 0;
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
+        requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
+    auto responseMsg2 =
+        reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
+    rc = decode_request_update_resp(
+        responseMsg2, requestUpdateResponse2.size() - hdrSize,
+        &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
+}
+
+TEST(RequestUpdate, errorPathDecodeResponse)
+{
+    constexpr std::array<uint8_t,
+                         hdrSize + sizeof(pldm_request_update_resp) - 1>
+        requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
+
+    auto responseMsg =
+        reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
+    uint8_t outCompletionCode = 0;
+    uint16_t outFdMetaDataLen = 0;
+    uint8_t outFdWillSendPkgData = 0;
+
+    auto rc = decode_request_update_resp(
+        nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
+        &outFdMetaDataLen, &outFdWillSendPkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_request_update_resp(
+        responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
+        &outFdMetaDataLen, &outFdWillSendPkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_request_update_resp(
+        responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
+        nullptr, &outFdWillSendPkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_request_update_resp(
+        responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
+        &outFdMetaDataLen, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
+                                    &outFdMetaDataLen, &outFdWillSendPkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_request_update_resp(
+        responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
+        &outFdMetaDataLen, &outFdWillSendPkgData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(PassComponentTable, goodPathEncodeRequest)
+{
+    constexpr uint8_t instanceId = 1;
+    constexpr uint16_t compIdentifier = 400;
+    constexpr uint8_t compClassificationIndex = 40;
+    constexpr uint32_t compComparisonStamp = 0x12345678;
+    constexpr std::string_view compVerStr = "0penBmcv1.1";
+    constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
+    variable_field compVerStrInfo{};
+    compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
+    compVerStrInfo.length = compVerStrLen;
+
+    std::array<uint8_t,
+               hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
+        request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_pass_component_table_req(
+        instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
+        compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
+        compVerStrLen, &compVerStrInfo, requestMsg,
+        sizeof(pldm_pass_component_table_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    std::array<uint8_t,
+               hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
+        outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
+                   0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
+                   0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
+    EXPECT_EQ(request, outRequest);
+}
+
+TEST(PassComponentTable, errorPathEncodeRequest)
+{
+    constexpr uint8_t instanceId = 1;
+    constexpr uint16_t compIdentifier = 400;
+    constexpr uint8_t compClassificationIndex = 40;
+    constexpr uint32_t compComparisonStamp = 0x12345678;
+    constexpr std::string_view compVerStr = "0penBmcv1.1";
+    constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
+    variable_field compVerStrInfo{};
+    compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
+    compVerStrInfo.length = compVerStrLen;
+
+    std::array<uint8_t,
+               hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
+        request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_pass_component_table_req(
+        instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
+        compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
+        compVerStrLen, nullptr, requestMsg,
+        sizeof(pldm_pass_component_table_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    compVerStrInfo.ptr = nullptr;
+    rc = encode_pass_component_table_req(
+        instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
+        compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
+        compVerStrLen, &compVerStrInfo, requestMsg,
+        sizeof(pldm_pass_component_table_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
+
+    rc = encode_pass_component_table_req(
+        instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
+        compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
+        compVerStrLen, &compVerStrInfo, nullptr,
+        sizeof(pldm_pass_component_table_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_pass_component_table_req(
+        instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
+        compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
+        compVerStrLen, &compVerStrInfo, requestMsg,
+        sizeof(pldm_pass_component_table_req));
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = encode_pass_component_table_req(
+        instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
+        compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
+        &compVerStrInfo, requestMsg,
+        sizeof(pldm_pass_component_table_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_pass_component_table_req(
+        instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
+        compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
+        compVerStrLen - 1, &compVerStrInfo, requestMsg,
+        sizeof(pldm_pass_component_table_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_pass_component_table_req(
+        instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
+        compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
+        compVerStrLen, &compVerStrInfo, requestMsg,
+        sizeof(pldm_pass_component_table_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
+
+    rc = encode_pass_component_table_req(
+        instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
+        compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
+        compVerStrLen, &compVerStrInfo, requestMsg,
+        sizeof(pldm_pass_component_table_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(PassComponentTable, goodPathDecodeResponse)
+{
+    constexpr std::array<uint8_t,
+                         hdrSize + sizeof(pldm_pass_component_table_resp)>
+        passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
+    auto responseMsg1 =
+        reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
+
+    uint8_t completionCode = 0;
+    uint8_t compResp = 0;
+    uint8_t compRespCode = 0;
+
+    auto rc = decode_pass_component_table_resp(
+        responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
+        &compResp, &compRespCode);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_SUCCESS);
+    EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
+    EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
+
+    constexpr std::array<uint8_t,
+                         hdrSize + sizeof(pldm_pass_component_table_resp)>
+        passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
+    auto responseMsg2 =
+        reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
+    rc = decode_pass_component_table_resp(
+        responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
+        &compResp, &compRespCode);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_SUCCESS);
+    EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
+    EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
+
+    constexpr std::array<uint8_t,
+                         hdrSize + sizeof(pldm_pass_component_table_resp)>
+        passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
+    auto responseMsg3 =
+        reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
+
+    rc = decode_pass_component_table_resp(
+        responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
+        &compResp, &compRespCode);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
+}
+
+TEST(PassComponentTable, errorPathDecodeResponse)
+{
+    constexpr std::array<uint8_t,
+                         hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
+        passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg1 =
+        reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
+
+    uint8_t completionCode = 0;
+    uint8_t compResp = 0;
+    uint8_t compRespCode = 0;
+
+    auto rc = decode_pass_component_table_resp(
+        nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
+        &compResp, &compRespCode);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_pass_component_table_resp(
+        responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
+        &compResp, &compRespCode);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_pass_component_table_resp(
+        responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
+        &completionCode, nullptr, &compRespCode);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_pass_component_table_resp(
+        responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
+        &completionCode, &compResp, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
+                                          &compResp, &compRespCode);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_pass_component_table_resp(
+        responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
+        &completionCode, &compResp, &compRespCode);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    constexpr std::array<uint8_t,
+                         hdrSize + sizeof(pldm_pass_component_table_resp)>
+        passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
+    auto responseMsg2 =
+        reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
+    rc = decode_pass_component_table_resp(
+        responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
+        &compResp, &compRespCode);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    constexpr std::array<uint8_t,
+                         hdrSize + sizeof(pldm_pass_component_table_resp)>
+        passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
+    auto responseMsg3 =
+        reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
+    rc = decode_pass_component_table_resp(
+        responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
+        &compResp, &compRespCode);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    constexpr std::array<uint8_t,
+                         hdrSize + sizeof(pldm_pass_component_table_resp)>
+        passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
+    auto responseMsg4 =
+        reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
+    rc = decode_pass_component_table_resp(
+        responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
+        &compResp, &compRespCode);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(UpdateComponent, goodPathEncodeRequest)
+{
+    constexpr uint8_t instanceId = 2;
+    constexpr uint16_t compIdentifier = 500;
+    constexpr uint8_t compClassificationIndex = 50;
+    constexpr uint32_t compComparisonStamp = 0x89abcdef;
+    constexpr uint32_t compImageSize = 4096;
+    constexpr bitfield32_t updateOptionFlags{1};
+    constexpr std::string_view compVerStr = "OpenBmcv2.2";
+    constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
+    variable_field compVerStrInfo{};
+    compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
+    compVerStrInfo.length = compVerStrLen;
+
+    std::array<uint8_t,
+               hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
+        request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_update_component_req(
+        instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
+        compComparisonStamp, compImageSize, updateOptionFlags,
+        PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
+        sizeof(pldm_update_component_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    std::array<uint8_t,
+               hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
+        outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
+                   0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
+                   0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
+                   0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
+    EXPECT_EQ(request, outRequest);
+}
+
+TEST(UpdateComponent, errorPathEncodeRequest)
+{
+    constexpr uint8_t instanceId = 2;
+    constexpr uint16_t compIdentifier = 500;
+    constexpr uint8_t compClassificationIndex = 50;
+    constexpr uint32_t compComparisonStamp = 0x89abcdef;
+    constexpr uint32_t compImageSize = 4096;
+    constexpr bitfield32_t updateOptionFlags{1};
+    constexpr std::string_view compVerStr = "OpenBmcv2.2";
+    constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
+    variable_field compVerStrInfo{};
+    compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
+    compVerStrInfo.length = compVerStrLen;
+
+    std::array<uint8_t,
+               hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
+        request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_update_component_req(
+        instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
+        compComparisonStamp, compImageSize, updateOptionFlags,
+        PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
+        sizeof(pldm_update_component_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    compVerStrInfo.ptr = nullptr;
+    rc = encode_update_component_req(
+        instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
+        compComparisonStamp, compImageSize, updateOptionFlags,
+        PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
+        sizeof(pldm_update_component_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
+
+    rc = encode_update_component_req(
+        instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
+        compComparisonStamp, compImageSize, updateOptionFlags,
+        PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
+        sizeof(pldm_update_component_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_update_component_req(
+        instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
+        compComparisonStamp, compImageSize, updateOptionFlags,
+        PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
+        sizeof(pldm_update_component_req));
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = encode_update_component_req(
+        instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
+        compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
+        compVerStrLen, &compVerStrInfo, requestMsg,
+        sizeof(pldm_update_component_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_update_component_req(
+        instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
+        compComparisonStamp, compImageSize, updateOptionFlags,
+        PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
+        sizeof(pldm_update_component_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_update_component_req(
+        instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
+        compComparisonStamp, compImageSize, updateOptionFlags,
+        PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
+        sizeof(pldm_update_component_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_update_component_req(
+        instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
+        compComparisonStamp, compImageSize, updateOptionFlags,
+        PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
+        sizeof(pldm_update_component_req) + compVerStrLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(UpdateComponent, goodPathDecodeResponse)
+{
+    constexpr std::bitset<32> forceUpdateComp{1};
+    constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
+        updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
+    auto responseMsg1 =
+        reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
+
+    uint8_t completionCode = 0;
+    uint8_t compCompatibilityResp = 0;
+    uint8_t compCompatibilityRespCode = 0;
+    bitfield32_t updateOptionFlagsEnabled{};
+    uint16_t timeBeforeReqFWData = 0;
+
+    auto rc = decode_update_component_resp(
+        responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
+        &compCompatibilityResp, &compCompatibilityRespCode,
+        &updateOptionFlagsEnabled, &timeBeforeReqFWData);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_SUCCESS);
+    EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
+    EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
+    EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
+    EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
+
+    constexpr std::bitset<32> noFlags{};
+    constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
+        updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
+                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg2 =
+        reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
+    rc = decode_update_component_resp(
+        responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
+        &compCompatibilityResp, &compCompatibilityRespCode,
+        &updateOptionFlagsEnabled, &timeBeforeReqFWData);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_SUCCESS);
+    EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
+    EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
+    EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
+    EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
+        updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
+    auto responseMsg3 =
+        reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
+
+    rc = decode_update_component_resp(
+        responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
+        &compCompatibilityResp, &compCompatibilityRespCode,
+        &updateOptionFlagsEnabled, &timeBeforeReqFWData);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
+}
+
+TEST(UpdateComponent, errorPathDecodeResponse)
+{
+    constexpr std::array<uint8_t,
+                         hdrSize + sizeof(pldm_update_component_resp) - 1>
+        updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
+                                 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg1 =
+        reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
+
+    uint8_t completionCode = 0;
+    uint8_t compCompatibilityResp = 0;
+    uint8_t compCompatibilityRespCode = 0;
+    bitfield32_t updateOptionFlagsEnabled{};
+    uint16_t timeBeforeReqFWData = 0;
+
+    auto rc = decode_update_component_resp(
+        nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
+        &compCompatibilityResp, &compCompatibilityRespCode,
+        &updateOptionFlagsEnabled, &timeBeforeReqFWData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_update_component_resp(
+        responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
+        &compCompatibilityResp, &compCompatibilityRespCode,
+        &updateOptionFlagsEnabled, &timeBeforeReqFWData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_update_component_resp(
+        responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
+        nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
+        &timeBeforeReqFWData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_update_component_resp(
+        responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
+        &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
+        &timeBeforeReqFWData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_update_component_resp(
+        responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
+        &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
+        &timeBeforeReqFWData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_update_component_resp(
+        responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
+        &compCompatibilityResp, &compCompatibilityRespCode,
+        &updateOptionFlagsEnabled, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_update_component_resp(
+        responseMsg1, 0, &completionCode, &compCompatibilityResp,
+        &compCompatibilityRespCode, &updateOptionFlagsEnabled,
+        &timeBeforeReqFWData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_update_component_resp(
+        responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
+        &compCompatibilityResp, &compCompatibilityRespCode,
+        &updateOptionFlagsEnabled, &timeBeforeReqFWData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
+        updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+                                 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
+    auto responseMsg2 =
+        reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
+    rc = decode_update_component_resp(
+        responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
+        &compCompatibilityResp, &compCompatibilityRespCode,
+        &updateOptionFlagsEnabled, &timeBeforeReqFWData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
+        updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+                                 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
+    auto responseMsg3 =
+        reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
+    rc = decode_update_component_resp(
+        responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
+        &compCompatibilityResp, &compCompatibilityRespCode,
+        &updateOptionFlagsEnabled, &timeBeforeReqFWData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
+        updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+                                 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
+    auto responseMsg4 =
+        reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
+    rc = decode_update_component_resp(
+        responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
+        &compCompatibilityResp, &compCompatibilityRespCode,
+        &updateOptionFlagsEnabled, &timeBeforeReqFWData);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(RequestFirmwareData, goodPathDecodeRequest)
+{
+    constexpr uint32_t offset = 300;
+    constexpr uint32_t length = 255;
+    constexpr std::array<uint8_t,
+                         hdrSize + sizeof(pldm_request_firmware_data_req)>
+        reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
+                     0x00, 0xff, 0x00, 0x00, 0x00};
+    auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
+
+    uint32_t outOffset = 0;
+    uint32_t outLength = 0;
+    auto rc = decode_request_firmware_data_req(
+        requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
+        &outLength);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outOffset, offset);
+    EXPECT_EQ(outLength, length);
+}
+
+TEST(RequestFirmwareData, errorPathDecodeRequest)
+{
+    constexpr std::array<uint8_t,
+                         hdrSize + sizeof(pldm_request_firmware_data_req)>
+        reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
+                     0x00, 0x1f, 0x00, 0x00, 0x00};
+    auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
+
+    uint32_t outOffset = 0;
+    uint32_t outLength = 0;
+    auto rc = decode_request_firmware_data_req(
+        nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
+        &outLength);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_request_firmware_data_req(
+        requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
+        &outLength);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_request_firmware_data_req(
+        requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
+        nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_request_firmware_data_req(
+        requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
+        &outLength);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_request_firmware_data_req(
+        requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
+        &outLength);
+    EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
+}
+
+TEST(RequestFirmwareData, goodPathEncodeResponse)
+{
+    constexpr uint8_t instanceId = 3;
+    constexpr uint8_t completionCode = PLDM_SUCCESS;
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
+                                      PLDM_FWUP_BASELINE_TRANSFER_SIZE>
+        outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
+                              0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
+                              0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+                              0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
+                              0x1d, 0x1e, 0x1f, 0x20};
+    std::array<uint8_t, hdrSize + sizeof(completionCode) +
+                            PLDM_FWUP_BASELINE_TRANSFER_SIZE>
+        reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
+                           0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
+                           0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+                           0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
+                           0x1d, 0x1e, 0x1f, 0x20};
+    auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
+    auto rc = encode_request_firmware_data_resp(
+        instanceId, completionCode, responseMsg1,
+        sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
+    std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
+        0x00, 0x00, 0x00, 0x00};
+    auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
+    rc = encode_request_firmware_data_resp(
+        instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
+        sizeof(completionCode));
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
+}
+
+TEST(RequestFirmwareData, errorPathEncodeResponse)
+{
+    std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
+    auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
+    auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(TransferComplete, goodPathDecodeRequest)
+{
+    constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
+    constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
+        transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
+    auto requestMsg1 =
+        reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
+    uint8_t outTransferResult = 0;
+
+    auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
+                                           &outTransferResult);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outTransferResult, transferResult);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
+        transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
+    auto requestMsg2 =
+        reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
+    rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
+                                      &outTransferResult);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
+}
+
+TEST(TransferComplete, errorPathDecodeRequest)
+{
+    constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
+                                                               0x00};
+    auto requestMsg =
+        reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
+    uint8_t outTransferResult = 0;
+
+    auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(TransferComplete, goodPathEncodeResponse)
+{
+    constexpr uint8_t instanceId = 4;
+    constexpr uint8_t completionCode = PLDM_SUCCESS;
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
+    std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
+    auto responseMsg1 =
+        reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
+    auto rc = encode_transfer_complete_resp(
+        instanceId, completionCode, responseMsg1, sizeof(completionCode));
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
+    std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
+    auto responseMsg2 =
+        reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
+    rc = encode_transfer_complete_resp(instanceId,
+                                       PLDM_FWUP_COMMAND_NOT_EXPECTED,
+                                       responseMsg2, sizeof(completionCode));
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
+}
+
+TEST(TransferComplete, errorPathEncodeResponse)
+{
+    std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
+    auto responseMsg =
+        reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
+    auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(VerifyComplete, goodPathDecodeRequest)
+{
+    constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
+    constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
+        verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
+    auto requestMsg1 =
+        reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
+    uint8_t outVerifyResult = 0;
+
+    auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
+                                         &outVerifyResult);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outVerifyResult, verifyResult);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
+        verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
+    auto requestMsg2 =
+        reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
+    rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
+                                    &outVerifyResult);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
+}
+
+TEST(VerifyComplete, errorPathDecodeRequest)
+{
+    constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
+    auto requestMsg =
+        reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
+    uint8_t outVerifyResult = 0;
+
+    auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_verify_complete_req(requestMsg, 0, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(VerifyComplete, goodPathEncodeResponse)
+{
+    constexpr uint8_t instanceId = 5;
+    constexpr uint8_t completionCode = PLDM_SUCCESS;
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
+    std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
+    auto responseMsg1 =
+        reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
+    auto rc = encode_verify_complete_resp(instanceId, completionCode,
+                                          responseMsg1, sizeof(completionCode));
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
+    std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
+    auto responseMsg2 =
+        reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
+    rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
+                                     responseMsg2, sizeof(completionCode));
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
+}
+
+TEST(VerifyComplete, errorPathEncodeResponse)
+{
+    std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
+    auto responseMsg =
+        reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
+    auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(ApplyComplete, goodPathDecodeRequest)
+{
+    constexpr uint8_t applyResult1 =
+        PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
+    // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
+    constexpr std::bitset<16> compActivationModification1{0x30};
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
+        applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
+    auto requestMsg1 =
+        reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
+    uint8_t outApplyResult = 0;
+    bitfield16_t outCompActivationModification{};
+    auto rc = decode_apply_complete_req(
+        requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
+        &outCompActivationModification);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outApplyResult, applyResult1);
+    EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
+
+    constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
+    constexpr std::bitset<16> compActivationModification2{};
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
+        applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto requestMsg2 =
+        reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
+    rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
+                                   &outApplyResult,
+                                   &outCompActivationModification);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(outApplyResult, applyResult2);
+    EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
+}
+
+TEST(ApplyComplete, errorPathDecodeRequest)
+{
+    constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
+    auto requestMsg1 =
+        reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
+    uint8_t outApplyResult = 0;
+    bitfield16_t outCompActivationModification{};
+
+    auto rc = decode_apply_complete_req(
+        nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
+        &outCompActivationModification);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
+                                   nullptr, &outCompActivationModification);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
+                                   &outApplyResult, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
+                                   &outCompActivationModification);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
+        applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
+    auto requestMsg2 =
+        reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
+    rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
+                                   &outApplyResult,
+                                   &outCompActivationModification);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(ApplyComplete, goodPathEncodeResponse)
+{
+    constexpr uint8_t instanceId = 6;
+    constexpr uint8_t completionCode = PLDM_SUCCESS;
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
+    std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
+    auto responseMsg1 =
+        reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
+    auto rc = encode_apply_complete_resp(instanceId, completionCode,
+                                         responseMsg1, sizeof(completionCode));
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
+    std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
+    auto responseMsg2 =
+        reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
+    rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
+                                    responseMsg2, sizeof(completionCode));
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
+}
+
+TEST(ApplyComplete, errorPathEncodeResponse)
+{
+    std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
+    auto responseMsg =
+        reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
+    auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(ActivateFirmware, goodPathEncodeRequest)
+{
+    constexpr uint8_t instanceId = 7;
+
+    std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_activate_firmware_req(
+        instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
+        sizeof(pldm_activate_firmware_req));
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
+        outRequest{0x87, 0x05, 0x1a, 0x01};
+    EXPECT_EQ(request, outRequest);
+}
+
+TEST(ActivateFirmware, errorPathEncodeRequest)
+{
+    std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_activate_firmware_req(
+        0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
+        sizeof(pldm_activate_firmware_req));
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_activate_firmware_req(
+        0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = encode_activate_firmware_req(0, 2, requestMsg,
+                                      sizeof(pldm_activate_firmware_req));
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(ActivateFirmware, goodPathDecodeResponse)
+{
+    constexpr uint16_t estimatedTimeForActivation100s = 100;
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
+        activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
+    auto responseMsg1 =
+        reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
+
+    uint8_t completionCode = 0;
+    uint16_t estimatedTimeForActivation = 0;
+
+    auto rc = decode_activate_firmware_resp(
+        responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
+        &estimatedTimeForActivation);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_SUCCESS);
+    EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
+    auto responseMsg2 =
+        reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
+
+    rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
+                                       &completionCode,
+                                       &estimatedTimeForActivation);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
+}
+
+TEST(ActivateFirmware, errorPathDecodeResponse)
+{
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
+        activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg =
+        reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
+
+    uint8_t completionCode = 0;
+    uint16_t estimatedTimeForActivation = 0;
+
+    auto rc = decode_activate_firmware_resp(
+        nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
+        &estimatedTimeForActivation);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_activate_firmware_resp(responseMsg,
+                                       sizeof(pldm_activate_firmware_resp),
+                                       nullptr, &estimatedTimeForActivation);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_activate_firmware_resp(responseMsg,
+                                       sizeof(pldm_activate_firmware_resp),
+                                       &completionCode, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
+                                       &estimatedTimeForActivation);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_activate_firmware_resp(
+        responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
+        &estimatedTimeForActivation);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetStatus, goodPathEncodeRequest)
+{
+    constexpr uint8_t instanceId = 8;
+    std::array<uint8_t, hdrSize> request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_get_status_req(instanceId, requestMsg,
+                                    PLDM_GET_STATUS_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
+    EXPECT_EQ(request, outRequest);
+}
+
+TEST(GetStatus, errorPathEncodeRequest)
+{
+    std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetStatus, goodPathDecodeResponse)
+{
+    constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
+        getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
+                           0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg1 =
+        reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
+
+    uint8_t completionCode = 0;
+    uint8_t currentState = 0;
+    uint8_t previousState = 0;
+    uint8_t auxState = 0;
+    uint8_t auxStateStatus = 0;
+    uint8_t progressPercent = 0;
+    uint8_t reasonCode = 0;
+    bitfield32_t updateOptionFlagsEnabled{0};
+
+    auto rc = decode_get_status_resp(
+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_SUCCESS);
+    EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
+    EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
+    EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
+    EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
+    EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
+    EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
+    EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
+
+    // Bit position 0 - Force update of component – FD will perform a force
+    // update of the component.
+    constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
+    constexpr uint8_t progressPercent2 = 50;
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
+        getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
+                           0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
+    auto responseMsg2 =
+        reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
+
+    rc = decode_get_status_resp(
+        responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_SUCCESS);
+    EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
+    EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
+    EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
+    EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
+    EXPECT_EQ(progressPercent, progressPercent2);
+    EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
+    EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        getStatusResponse3{0x00, 0x00, 0x00, 0x04};
+    auto responseMsg3 =
+        reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
+    rc = decode_get_status_resp(
+        responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
+}
+
+TEST(GetStatus, errorPathDecodeResponse)
+{
+    uint8_t completionCode = 0;
+    uint8_t currentState = 0;
+    uint8_t previousState = 0;
+    uint8_t auxState = 0;
+    uint8_t auxStateStatus = 0;
+    uint8_t progressPercent = 0;
+    uint8_t reasonCode = 0;
+    bitfield32_t updateOptionFlagsEnabled{0};
+
+    constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
+    auto responseMsg1 =
+        reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
+
+    auto rc = decode_get_status_resp(
+        nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_status_resp(
+        responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_status_resp(
+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
+        nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
+        &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_status_resp(
+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
+        &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
+        &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_status_resp(
+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
+        &currentState, &previousState, nullptr, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_status_resp(
+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, nullptr, &progressPercent,
+        &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_status_resp(
+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
+        &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_status_resp(
+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, nullptr, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_status_resp(
+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_status_resp(
+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
+        getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg2 =
+        reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
+    rc = decode_get_status_resp(
+        responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
+        getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
+                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg3 =
+        reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
+    rc = decode_get_status_resp(
+        responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
+        getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
+                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg4 =
+        reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
+    rc = decode_get_status_resp(
+        responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
+        getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg5 =
+        reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
+    rc = decode_get_status_resp(
+        responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
+        getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                           0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg6 =
+        reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
+    rc = decode_get_status_resp(
+        responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
+        getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                           0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg7 =
+        reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
+    rc = decode_get_status_resp(
+        responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
+        getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                           0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg8 =
+        reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
+    rc = decode_get_status_resp(
+        responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
+    // IDLE
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
+        getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg9 =
+        reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
+    rc = decode_get_status_resp(
+        responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
+        &currentState, &previousState, &auxState, &auxStateStatus,
+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(CancelUpdateComponent, goodPathEncodeRequest)
+{
+    constexpr uint8_t instanceId = 9;
+    std::array<uint8_t, hdrSize> request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_cancel_update_component_req(
+        instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
+    EXPECT_EQ(request, outRequest);
+}
+
+TEST(CancelUpdateComponent, errorPathEncodeRequest)
+{
+    std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_cancel_update_component_req(
+        0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_cancel_update_component_req(
+        0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(CancelUpdateComponent, testGoodDecodeResponse)
+{
+    uint8_t completionCode = 0;
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
+    auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
+        cancelUpdateComponentResponse1.data());
+    auto rc = decode_cancel_update_component_resp(
+        responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
+        &completionCode);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_SUCCESS);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
+    auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
+        cancelUpdateComponentResponse2.data());
+    rc = decode_cancel_update_component_resp(
+        responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
+        &completionCode);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
+}
+
+TEST(CancelUpdateComponent, testBadDecodeResponse)
+{
+    uint8_t completionCode = 0;
+    constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
+        0x00, 0x00, 0x00};
+    auto responseMsg =
+        reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
+
+    auto rc = decode_cancel_update_component_resp(
+        nullptr, cancelUpdateComponentResponse.size() - hdrSize,
+        &completionCode);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_cancel_update_component_resp(
+        responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_cancel_update_component_resp(
+        responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
+        &completionCode);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(CancelUpdate, goodPathEncodeRequest)
+{
+    constexpr uint8_t instanceId = 10;
+    std::array<uint8_t, hdrSize> request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_cancel_update_req(instanceId, requestMsg,
+                                       PLDM_CANCEL_UPDATE_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
+    EXPECT_EQ(request, outRequest);
+}
+
+TEST(CancelUpdate, errorPathEncodeRequest)
+{
+    std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc =
+        encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_cancel_update_req(0, requestMsg,
+                                  PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(CancelUpdate, goodPathDecodeResponse)
+{
+    constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
+        cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg1 =
+        reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
+    uint8_t completionCode = 0;
+    bool8_t nonFunctioningComponentIndication = 0;
+    bitfield64_t nonFunctioningComponentBitmap{0};
+    auto rc = decode_cancel_update_resp(
+        responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
+        &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_SUCCESS);
+    EXPECT_EQ(nonFunctioningComponentIndication,
+              PLDM_FWUP_COMPONENTS_FUNCTIONING);
+    EXPECT_EQ(nonFunctioningComponentBitmap.value,
+              nonFunctioningComponentBitmap1);
+
+    constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
+        cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg2 =
+        reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
+    rc = decode_cancel_update_resp(
+        responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
+        &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_SUCCESS);
+    EXPECT_EQ(nonFunctioningComponentIndication,
+              PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
+    EXPECT_EQ(nonFunctioningComponentBitmap.value,
+              nonFunctioningComponentBitmap2);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
+    auto responseMsg3 =
+        reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
+    rc = decode_cancel_update_resp(
+        responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
+        &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
+}
+
+TEST(CancelUpdate, errorPathDecodeResponse)
+{
+    constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
+                                                                 0x00};
+    auto responseMsg1 =
+        reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
+    uint8_t completionCode = 0;
+    bool8_t nonFunctioningComponentIndication = 0;
+    bitfield64_t nonFunctioningComponentBitmap{0};
+
+    auto rc = decode_cancel_update_resp(
+        nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
+        &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_cancel_update_resp(
+        responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
+        &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_cancel_update_resp(
+        responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
+        nullptr, &nonFunctioningComponentBitmap);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_cancel_update_resp(
+        responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
+        &nonFunctioningComponentIndication, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_cancel_update_resp(
+        responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
+        &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+        cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
+    auto responseMsg2 =
+        reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
+    rc = decode_cancel_update_resp(
+        responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
+        &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
+        cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    auto responseMsg3 =
+        reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
+    rc = decode_cancel_update_resp(
+        responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
+        &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
diff --git a/tests/dsp/fru.cpp b/tests/dsp/fru.cpp
new file mode 100644
index 0000000..11cbc5d
--- /dev/null
+++ b/tests/dsp/fru.cpp
@@ -0,0 +1,889 @@
+#include <endian.h>
+#include <libpldm/base.h>
+#include <libpldm/fru.h>
+#include <libpldm/utils.h>
+
+#include <array>
+#include <cstdint>
+#include <cstring>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+TEST(GetFruRecordTableMetadata, testGoodEncodeRequest)
+{
+    std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
+    auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto rc = encode_get_fru_record_table_metadata_req(
+        0, requestPtr, PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
+    ASSERT_EQ(requestPtr->hdr.instance_id, 0u);
+    ASSERT_EQ(requestPtr->hdr.type, PLDM_FRU);
+    ASSERT_EQ(requestPtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE_METADATA);
+}
+
+TEST(GetFruRecordTableMetadata, testBadEncodeRequest)
+{
+    auto rc = encode_get_fru_record_table_metadata_req(0, NULL, 0);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
+    auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    rc = encode_get_fru_record_table_metadata_req(0, requestPtr, 1);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetFruRecordTableMetadata, testGoodDecodeResponse)
+{
+
+    std::vector<uint8_t> responseMsg(
+        sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    size_t payload_length = responseMsg.size() - sizeof(pldm_msg_hdr);
+    auto response = reinterpret_cast<pldm_get_fru_record_table_metadata_resp*>(
+        responsePtr->payload);
+
+    responsePtr->hdr.request = PLDM_RESPONSE;
+    responsePtr->hdr.instance_id = 0;
+    responsePtr->hdr.type = PLDM_FRU;
+    responsePtr->hdr.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
+    response->completion_code = PLDM_SUCCESS;
+    response->fru_data_major_version = 0x12;
+    response->fru_data_minor_version = 0x21;
+    response->fru_table_maximum_size = htole32(0x1234abcd);
+    response->fru_table_length = htole32(0x56781234);
+    response->total_record_set_identifiers = htole16(0x34ef);
+    response->total_table_records = htole16(0xeeef);
+    response->checksum = htole32(0x6543fa71);
+
+    uint8_t completion_code = 0xff;
+    uint8_t fru_data_major_version = 0x00;
+    uint8_t fru_data_minor_version = 0x00;
+    uint32_t fru_table_maximum_size = htole32(0x00000000);
+    uint32_t fru_table_length = htole32(0x00000000);
+    uint16_t total_record_set_identifiers = htole16(0x0000);
+    uint16_t total_table_records = htole16(0x0000);
+    uint32_t checksum = htole32(0x00000000);
+
+    auto rc = decode_get_fru_record_table_metadata_resp(
+        responsePtr, payload_length, &completion_code, &fru_data_major_version,
+        &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
+        &total_record_set_identifiers, &total_table_records, &checksum);
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(completion_code, PLDM_SUCCESS);
+    ASSERT_EQ(fru_data_major_version, 0x12u);
+    ASSERT_EQ(fru_data_minor_version, 0x21u);
+    ASSERT_EQ(fru_table_maximum_size, 0x1234abcdu);
+    ASSERT_EQ(fru_table_length, 0x56781234u);
+    ASSERT_EQ(total_record_set_identifiers, 0x34efu);
+    ASSERT_EQ(total_table_records, 0xeeefu);
+    ASSERT_EQ(checksum, 0x6543fa71u);
+
+    response->fru_data_major_version = 0x00;
+    response->fru_data_minor_version = 0x00;
+    response->fru_table_maximum_size = htole32(0x00000000);
+    response->fru_table_length = htole32(0x00000000);
+    response->total_record_set_identifiers = htole16(0x0000);
+    response->total_table_records = htole16(0x0000);
+    response->checksum = htole32(0x00000000);
+    fru_data_major_version = 0x00;
+    fru_data_minor_version = 0x00;
+    fru_table_maximum_size = htole32(0x00000000);
+    fru_table_length = htole32(0x00000000);
+    total_record_set_identifiers = htole16(0x0000);
+    total_table_records = htole16(0x0000);
+    checksum = htole32(0x00000000);
+    response->completion_code = PLDM_ERROR_INVALID_LENGTH;
+    rc = decode_get_fru_record_table_metadata_resp(
+        responsePtr, payload_length, &completion_code, &fru_data_major_version,
+        &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
+        &total_record_set_identifiers, &total_table_records, &checksum);
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(responsePtr->hdr.request, PLDM_RESPONSE);
+    ASSERT_EQ(responsePtr->hdr.instance_id, 0u);
+    ASSERT_EQ(responsePtr->hdr.type, PLDM_FRU);
+    ASSERT_EQ(responsePtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE_METADATA);
+    ASSERT_EQ(completion_code, PLDM_ERROR_INVALID_LENGTH);
+    ASSERT_EQ(fru_data_major_version, 0x00u);
+    ASSERT_EQ(fru_data_minor_version, 0x00u);
+    ASSERT_EQ(fru_table_maximum_size, 0x00000000u);
+    ASSERT_EQ(fru_table_length, 0x00000000u);
+    ASSERT_EQ(total_record_set_identifiers, 0x0000u);
+    ASSERT_EQ(total_table_records, 0x0000u);
+    ASSERT_EQ(checksum, 0x00000000u);
+}
+
+TEST(GetFruRecordTableMetadata, testBadDecodeResponse)
+{
+    std::vector<uint8_t> responseMsg(
+        sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    size_t payload_length = responseMsg.size() - sizeof(pldm_msg_hdr);
+    auto response = reinterpret_cast<pldm_get_fru_record_table_metadata_resp*>(
+        responsePtr->payload);
+
+    response->completion_code = PLDM_SUCCESS;
+    response->fru_data_major_version = 0x12;
+    response->fru_data_minor_version = 0x21;
+    response->fru_table_maximum_size = htole32(0x1234abcd);
+    response->fru_table_length = htole32(0x56781234);
+    response->total_record_set_identifiers = htole16(0x34ef);
+    response->total_table_records = htole16(0xeeef);
+    response->checksum = htole32(0x6543fa71);
+
+    uint8_t completion_code = 0xff;
+    uint8_t fru_data_major_version = 0x00;
+    uint8_t fru_data_minor_version = 0x00;
+    uint32_t fru_table_maximum_size = htole32(0x00000000);
+    uint32_t fru_table_length = htole32(0x00000000);
+    uint16_t total_record_set_identifiers = htole16(0x0000);
+    uint16_t total_table_records = htole16(0x0000);
+    uint32_t checksum = htole32(0x00000000);
+
+    auto rc = decode_get_fru_record_table_metadata_resp(
+        responsePtr, PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES + 2,
+        &completion_code, &fru_data_major_version, &fru_data_minor_version,
+        &fru_table_maximum_size, &fru_table_length,
+        &total_record_set_identifiers, &total_table_records, &checksum);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_get_fru_record_table_metadata_resp(
+        responsePtr, payload_length, &completion_code, NULL,
+        &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
+        &total_record_set_identifiers, &total_table_records, &checksum);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_fru_record_table_metadata_resp(
+        responsePtr, payload_length, &completion_code, &fru_data_major_version,
+        NULL, &fru_table_maximum_size, &fru_table_length,
+        &total_record_set_identifiers, &total_table_records, &checksum);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_fru_record_table_metadata_resp(
+        responsePtr, payload_length, &completion_code, &fru_data_major_version,
+        &fru_data_minor_version, NULL, &fru_table_length,
+        &total_record_set_identifiers, &total_table_records, &checksum);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_fru_record_table_metadata_resp(
+        responsePtr, payload_length, &completion_code, &fru_data_major_version,
+        &fru_data_minor_version, &fru_table_maximum_size, NULL,
+        &total_record_set_identifiers, &total_table_records, &checksum);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_fru_record_table_metadata_resp(
+        responsePtr, payload_length, &completion_code, &fru_data_major_version,
+        &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
+        NULL, &total_table_records, &checksum);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_fru_record_table_metadata_resp(
+        responsePtr, payload_length, &completion_code, &fru_data_major_version,
+        &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
+        &total_record_set_identifiers, NULL, &checksum);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_fru_record_table_metadata_resp(
+        responsePtr, payload_length, &completion_code, &fru_data_major_version,
+        &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
+        &total_record_set_identifiers, &total_table_records, NULL);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetFruRecordTableMetadata, testGoodEncodeResponse)
+{
+
+    std::array<uint8_t, sizeof(pldm_msg_hdr) +
+                            PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES>
+        responseMsg{};
+    auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    responsePtr->hdr.request = PLDM_RESPONSE;
+    responsePtr->hdr.instance_id = 0;
+    responsePtr->hdr.type = PLDM_FRU;
+    responsePtr->hdr.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
+
+    uint8_t completion_code = PLDM_SUCCESS;
+    uint8_t fru_data_major_version = 0x12;
+    uint8_t fru_data_minor_version = 0x21;
+    uint32_t fru_table_maximum_size = htole32(0x1234abcd);
+    uint32_t fru_table_length = htole32(0x56781234);
+    uint16_t total_record_set_identifiers = htole16(0x34ef);
+    uint16_t total_table_records = htole16(0xeeef);
+    uint32_t checksum = htole32(0x6543fa71);
+
+    auto rc = encode_get_fru_record_table_metadata_resp(
+        0, completion_code, fru_data_major_version, fru_data_minor_version,
+        fru_table_maximum_size, fru_table_length, total_record_set_identifiers,
+        total_table_records, checksum, responsePtr);
+
+    auto response = reinterpret_cast<pldm_get_fru_record_table_metadata_resp*>(
+        responsePtr->payload);
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(responsePtr->hdr.request, PLDM_RESPONSE);
+    ASSERT_EQ(responsePtr->hdr.instance_id, 0u);
+    ASSERT_EQ(responsePtr->hdr.type, PLDM_FRU);
+    ASSERT_EQ(responsePtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE_METADATA);
+    ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
+    ASSERT_EQ(response->fru_data_major_version, 0x12u);
+    ASSERT_EQ(response->fru_data_minor_version, 0x21u);
+    ASSERT_EQ(response->fru_table_maximum_size, 0x1234abcdu);
+    ASSERT_EQ(response->fru_table_length, 0x56781234u);
+    ASSERT_EQ(response->total_record_set_identifiers, 0x34efu);
+    ASSERT_EQ(response->total_table_records, 0xeeefu);
+    ASSERT_EQ(response->checksum, 0x6543fa71u);
+
+    response->fru_data_major_version = 0;
+    response->fru_data_major_version = 0x00;
+    response->fru_data_minor_version = 0x00;
+    response->fru_table_maximum_size = htole32(0x00000000);
+    response->fru_table_length = htole32(0x00000000);
+    response->total_record_set_identifiers = htole16(0x0000);
+    response->total_table_records = htole16(0x0000);
+    response->checksum = htole32(0x00000000);
+    completion_code = PLDM_ERROR_INVALID_DATA;
+    rc = encode_get_fru_record_table_metadata_resp(
+        0, completion_code, fru_data_major_version, fru_data_minor_version,
+        fru_table_maximum_size, fru_table_length, total_record_set_identifiers,
+        total_table_records, checksum, responsePtr);
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(responsePtr->hdr.request, PLDM_RESPONSE);
+    ASSERT_EQ(responsePtr->hdr.instance_id, 0u);
+    ASSERT_EQ(responsePtr->hdr.type, PLDM_FRU);
+    ASSERT_EQ(responsePtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE_METADATA);
+    ASSERT_EQ(completion_code, PLDM_ERROR_INVALID_DATA);
+    ASSERT_EQ(response->fru_data_major_version, 0x00u);
+    ASSERT_EQ(response->fru_data_minor_version, 0x00u);
+    ASSERT_EQ(response->fru_table_maximum_size, 0x00000000u);
+    ASSERT_EQ(response->fru_table_length, 0x00000000u);
+    ASSERT_EQ(response->total_record_set_identifiers, 0x0000u);
+    ASSERT_EQ(response->total_table_records, 0x0000u);
+    ASSERT_EQ(response->checksum, 0x00000000u);
+}
+
+TEST(GetFruRecordTableMetadata, testBadEncodeResponse)
+{
+    std::array<uint8_t, sizeof(pldm_msg_hdr) +
+                            PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES>
+        responseMsg{};
+    auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    uint8_t completion_code = PLDM_SUCCESS;
+    uint8_t fru_data_major_version = 0x12;
+    uint8_t fru_data_minor_version = 0x21;
+    uint32_t fru_table_maximum_size = htole32(0x1234abcd);
+    uint32_t fru_table_length = htole32(0x56781234);
+    uint16_t total_record_set_identifiers = htole16(0x34ef);
+    uint16_t total_table_records = htole16(0xeeef);
+    uint32_t checksum = htole32(0x6543fa71);
+
+    auto rc = encode_get_fru_record_table_metadata_resp(
+        0, completion_code, fru_data_major_version, fru_data_minor_version,
+        fru_table_maximum_size, fru_table_length, total_record_set_identifiers,
+        total_table_records, checksum, NULL);
+
+    auto response = reinterpret_cast<pldm_get_fru_record_table_metadata_resp*>(
+        responsePtr->payload);
+
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    ASSERT_EQ(completion_code, PLDM_SUCCESS);
+    ASSERT_EQ(response->fru_data_major_version, 0x00u);
+    ASSERT_EQ(response->fru_data_minor_version, 0x00u);
+    ASSERT_EQ(response->fru_table_maximum_size, 0x00000000u);
+    ASSERT_EQ(response->fru_table_length, 0x00000000u);
+    ASSERT_EQ(response->total_record_set_identifiers, 0x0000u);
+    ASSERT_EQ(response->total_table_records, 0x0000u);
+    ASSERT_EQ(response->checksum, 0x00000000u);
+}
+
+TEST(GetFruRecordTable, testGoodDecodeRequest)
+{
+    uint32_t data_transfer_handle = 31;
+    uint8_t transfer_operation_flag = PLDM_GET_FIRSTPART;
+    std::array<uint8_t,
+               PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES + sizeof(pldm_msg_hdr)>
+        requestMsg{};
+    auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    size_t payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
+    auto request =
+        reinterpret_cast<pldm_get_fru_record_table_req*>(requestPtr->payload);
+
+    request->data_transfer_handle = htole32(data_transfer_handle);
+    request->transfer_operation_flag = transfer_operation_flag;
+
+    uint32_t ret_data_transfer_handle = 0;
+    uint8_t ret_transfer_operation_flag = 0;
+
+    // Invoke decode get FRU record table request api
+    auto rc = decode_get_fru_record_table_req(requestPtr, payload_length,
+                                              &ret_data_transfer_handle,
+                                              &ret_transfer_operation_flag);
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(data_transfer_handle, ret_data_transfer_handle);
+    ASSERT_EQ(transfer_operation_flag, ret_transfer_operation_flag);
+}
+
+TEST(GetFruRecordTable, testBadDecodeRequest)
+{
+    uint32_t data_transfer_handle = 0x0;
+    uint8_t transfer_operation_flag = PLDM_GET_FIRSTPART;
+
+    std::array<uint8_t,
+               sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES>
+        requestMsg{};
+    auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    // Payload message is missing
+    auto rc = decode_get_fru_record_table_req(NULL, 0, &data_transfer_handle,
+                                              &transfer_operation_flag);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Payload length is invalid
+    rc = decode_get_fru_record_table_req(requestPtr, 0, &data_transfer_handle,
+                                         &transfer_operation_flag);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetFruRecordTable, testGoodEncodeResponse)
+{
+    uint8_t completion_code = 0;
+    uint32_t next_data_transfer_handle = 32;
+    uint8_t transfer_flag = PLDM_START_AND_END;
+
+    std::vector<uint8_t> responseMsg(sizeof(pldm_msg_hdr) +
+                                     PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES);
+
+    auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    auto response =
+        reinterpret_cast<pldm_get_fru_record_table_resp*>(responsePtr->payload);
+
+    // Invoke encode get FRU record table response api
+    auto rc = encode_get_fru_record_table_resp(0, completion_code,
+                                               next_data_transfer_handle,
+                                               transfer_flag, responsePtr);
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(responsePtr->hdr.request, PLDM_RESPONSE);
+    ASSERT_EQ(responsePtr->hdr.instance_id, 0u);
+    ASSERT_EQ(responsePtr->hdr.type, PLDM_FRU);
+    ASSERT_EQ(responsePtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE);
+    ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
+    ASSERT_EQ(le32toh(response->next_data_transfer_handle),
+              next_data_transfer_handle);
+    ASSERT_EQ(response->transfer_flag, transfer_flag);
+}
+
+TEST(GetFruRecordTable, testBadEncodeResponse)
+{
+    uint32_t next_data_transfer_handle = 32;
+    uint8_t transfer_flag = PLDM_START_AND_END;
+
+    std::vector<uint8_t> responseMsg(sizeof(pldm_msg_hdr) +
+                                     PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES);
+
+    auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    auto rc = encode_get_fru_record_table_resp(
+        0, PLDM_ERROR, next_data_transfer_handle, transfer_flag, responsePtr);
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(responsePtr->hdr.request, PLDM_RESPONSE);
+    ASSERT_EQ(responsePtr->hdr.instance_id, 0u);
+    ASSERT_EQ(responsePtr->hdr.type, PLDM_FRU);
+    ASSERT_EQ(responsePtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE);
+    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR);
+
+    rc = encode_get_fru_record_table_resp(
+        0, PLDM_SUCCESS, next_data_transfer_handle, transfer_flag, nullptr);
+
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetFruRecordTable, testGoodEncodeRequest)
+
+{
+    std::array<uint8_t,
+               sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES>
+        requestMsg{};
+
+    auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto request =
+        reinterpret_cast<pldm_get_fru_record_table_req*>(requestPtr->payload);
+
+    // Random value for data transfer handle and transfer operation flag
+    uint32_t data_transfer_handle = 32;
+    uint8_t transfer_operation_flag = PLDM_GET_FIRSTPART;
+
+    // Invoke encode get FRU record table request api
+    auto rc = encode_get_fru_record_table_req(
+        0, data_transfer_handle, transfer_operation_flag, requestPtr,
+        requestMsg.size() - sizeof(pldm_msg_hdr));
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
+    ASSERT_EQ(requestPtr->hdr.instance_id, 0u);
+    ASSERT_EQ(requestPtr->hdr.type, PLDM_FRU);
+    ASSERT_EQ(requestPtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE);
+    ASSERT_EQ(le32toh(data_transfer_handle), request->data_transfer_handle);
+    ASSERT_EQ(transfer_operation_flag, request->transfer_operation_flag);
+}
+
+TEST(GetFruRecordTable, testBadEncodeRequest)
+
+{
+    uint32_t data_transfer_handle = 0x0;
+    uint8_t transfer_operation_flag = PLDM_GET_FIRSTPART;
+
+    std::array<uint8_t,
+               sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES>
+        requestMsg{};
+    auto rc = encode_get_fru_record_table_req(
+        0, data_transfer_handle, transfer_operation_flag, NULL,
+        requestMsg.size() - sizeof(pldm_msg_hdr));
+
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetFruRecordTable, testGoodDecodeResponse)
+{
+    uint8_t completion_code = PLDM_SUCCESS;
+    uint32_t next_data_transfer_handle = 0x16;
+    uint8_t transfer_flag = PLDM_START_AND_END;
+    std::vector<uint8_t> fru_record_table_data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+    std::vector<uint8_t> responseMsg(sizeof(pldm_msg_hdr) +
+                                     PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES +
+                                     fru_record_table_data.size());
+
+    auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    size_t payload_length = responseMsg.size() - sizeof(pldm_msg_hdr);
+    auto response =
+        reinterpret_cast<pldm_get_fru_record_table_resp*>(responsePtr->payload);
+
+    response->completion_code = completion_code;
+    response->next_data_transfer_handle = htole32(next_data_transfer_handle);
+    response->transfer_flag = transfer_flag;
+    memcpy(response->fru_record_table_data, fru_record_table_data.data(),
+           fru_record_table_data.size());
+
+    uint8_t ret_completion_code = 0;
+    uint32_t ret_next_data_transfer_handle = 0;
+    uint8_t ret_transfer_flag = 0;
+    std::vector<uint8_t> ret_fru_record_table_data(9, 0);
+    size_t ret_fru_record_table_length = 0;
+
+    // Invoke decode get FRU record table response api
+    auto rc = decode_get_fru_record_table_resp(
+        responsePtr, payload_length, &ret_completion_code,
+        &ret_next_data_transfer_handle, &ret_transfer_flag,
+        ret_fru_record_table_data.data(), &ret_fru_record_table_length);
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(completion_code, ret_completion_code);
+    ASSERT_EQ(next_data_transfer_handle, ret_next_data_transfer_handle);
+    ASSERT_EQ(transfer_flag, ret_transfer_flag);
+    ASSERT_EQ(0, memcmp(fru_record_table_data.data(),
+                        ret_fru_record_table_data.data(),
+                        ret_fru_record_table_length));
+    ASSERT_EQ(fru_record_table_data.size(), ret_fru_record_table_length);
+}
+
+TEST(GetFruRecordTable, testBadDecodeResponse)
+{
+    uint8_t completion_code = 0;
+    uint32_t next_data_transfer_handle = 0;
+    uint8_t transfer_flag = PLDM_START_AND_END;
+    std::vector<uint8_t> fru_record_table_data(9, 0);
+    size_t fru_record_table_length = 0;
+
+    std::vector<uint8_t> responseMsg(sizeof(pldm_msg_hdr) +
+                                     PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES +
+                                     fru_record_table_data.size());
+
+    auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    // Payload message is missing
+    auto rc = decode_get_fru_record_table_resp(
+        NULL, 0, &completion_code, &next_data_transfer_handle, &transfer_flag,
+        fru_record_table_data.data(), &fru_record_table_length);
+
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Payload length is invalid
+    rc = decode_get_fru_record_table_resp(
+        responsePtr, 0, &completion_code, &next_data_transfer_handle,
+        &transfer_flag, fru_record_table_data.data(), &fru_record_table_length);
+
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetFRURecordByOption, testGoodEncodeRequest)
+{
+    uint8_t instanceId = 2;
+    uint32_t dataTransferHandle = 3;
+    uint16_t fruTableHandle = 4;
+    uint16_t recordSetIdentifier = 5;
+    uint8_t recordType = 6;
+    uint8_t fieldType = 7;
+    uint8_t transferOpFlag = 0;
+
+    constexpr auto payLoadLength = sizeof(pldm_get_fru_record_by_option_req);
+
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> request;
+    auto reqMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_get_fru_record_by_option_req(
+        instanceId, dataTransferHandle, fruTableHandle, recordSetIdentifier,
+        recordType, fieldType, transferOpFlag, reqMsg, payLoadLength);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(instanceId, reqMsg->hdr.instance_id);
+
+    auto payLoadMsg =
+        reinterpret_cast<pldm_get_fru_record_by_option_req*>(reqMsg->payload);
+
+    EXPECT_EQ(le32toh(payLoadMsg->data_transfer_handle), dataTransferHandle);
+    EXPECT_EQ(le16toh(payLoadMsg->fru_table_handle), fruTableHandle);
+    EXPECT_EQ(le16toh(payLoadMsg->record_set_identifier), recordSetIdentifier);
+    EXPECT_EQ(payLoadMsg->record_type, recordType);
+    EXPECT_EQ(payLoadMsg->field_type, fieldType);
+    EXPECT_EQ(payLoadMsg->transfer_op_flag, transferOpFlag);
+}
+
+TEST(GetFRURecordByOption, testBadEncodeRequest)
+{
+
+    constexpr auto payLoadLength = sizeof(pldm_get_fru_record_by_option_req);
+
+    auto rc = encode_get_fru_record_by_option_req(1, 2, 3, 4, 5, 6, 0, nullptr,
+                                                  payLoadLength);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> request;
+    auto reqMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    rc = encode_get_fru_record_by_option_req(1, 2, 3, 4, 5, 6, 0, reqMsg,
+                                             payLoadLength - 1);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetFRURecordByOption, testGoodDecodeRequest)
+{
+    uint8_t instanceId = 2;
+    uint32_t dataTransferHandle = 3;
+    uint16_t fruTableHandle = 4;
+    uint16_t recordSetIdentifier = 5;
+    uint8_t recordType = 6;
+    uint8_t fieldType = 7;
+    uint8_t transferOpFlag = 0;
+
+    constexpr auto payLoadLength = sizeof(pldm_get_fru_record_by_option_req);
+
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> request;
+    auto reqMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    auto rc = encode_get_fru_record_by_option_req(
+        instanceId, dataTransferHandle, fruTableHandle, recordSetIdentifier,
+        recordType, fieldType, transferOpFlag, reqMsg, payLoadLength);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    uint32_t retDataTransferHandle{};
+    uint16_t retFruTableHandle{};
+    uint16_t retRecordSetIdentifier{};
+    uint8_t retRecordType{};
+    uint8_t retFieldType{};
+    uint8_t retTransferOpFlag{};
+
+    rc = decode_get_fru_record_by_option_req(
+        reqMsg, payLoadLength, &retDataTransferHandle, &retFruTableHandle,
+        &retRecordSetIdentifier, &retRecordType, &retFieldType,
+        &retTransferOpFlag);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retDataTransferHandle, dataTransferHandle);
+    EXPECT_EQ(retFruTableHandle, fruTableHandle);
+    EXPECT_EQ(retRecordSetIdentifier, recordSetIdentifier);
+    EXPECT_EQ(retRecordType, recordType);
+    EXPECT_EQ(retFieldType, fieldType);
+    EXPECT_EQ(retTransferOpFlag, transferOpFlag);
+}
+
+TEST(GetFRURecordByOption, testBadDecodeRequest)
+{
+    constexpr auto payLoadLength = sizeof(pldm_get_fru_record_by_option_req);
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> request{};
+    auto reqMsg = reinterpret_cast<pldm_msg*>(request.data());
+
+    uint32_t retDataTransferHandle{};
+    uint16_t retFruTableHandle{};
+    uint16_t retRecordSetIdentifier{};
+    uint8_t retRecordType{};
+    uint8_t retFieldType{};
+    uint8_t retTransferOpFlag{};
+
+    auto rc = decode_get_fru_record_by_option_req(
+        reqMsg, payLoadLength - 1, &retDataTransferHandle, &retFruTableHandle,
+        &retRecordSetIdentifier, &retRecordType, &retFieldType,
+        &retTransferOpFlag);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_get_fru_record_by_option_req(
+        reqMsg, payLoadLength - 1, nullptr, &retFruTableHandle,
+        &retRecordSetIdentifier, &retRecordType, &retFieldType,
+        &retTransferOpFlag);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetFruRecordByOption, testGoodEncodeResponse)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t instanceId = 2;
+    uint32_t dataTransferHandle = 3;
+    uint8_t transferFlag = 5;
+
+    std::array<uint8_t, 5> fruData = {1, 2, 3, 4, 5};
+    constexpr auto payLoadLength =
+        sizeof(pldm_get_fru_record_by_option_resp) - 1 + fruData.size();
+
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> response;
+    auto respMsg = reinterpret_cast<pldm_msg*>(response.data());
+
+    auto rc = encode_get_fru_record_by_option_resp(
+        instanceId, completionCode, dataTransferHandle, transferFlag,
+        fruData.data(), fruData.size(), respMsg, payLoadLength);
+
+    auto payLoadMsg =
+        reinterpret_cast<pldm_get_fru_record_by_option_resp*>(respMsg->payload);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(payLoadMsg->completion_code, completionCode);
+    EXPECT_EQ(payLoadMsg->next_data_transfer_handle,
+              htole32(dataTransferHandle));
+    EXPECT_EQ(payLoadMsg->transfer_flag, transferFlag);
+
+    EXPECT_EQ(std::memcmp(payLoadMsg->fru_structure_data, fruData.data(),
+                          fruData.size()),
+              0);
+}
+
+TEST(GetFruRecordByOption, testBadEncodeResponse)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t instanceId = 2;
+    uint32_t dataTransferHandle = 3;
+    uint8_t transferFlag = 5;
+
+    std::array<uint8_t, 5> fruData = {1, 2, 3, 4, 5};
+    constexpr auto payLoadLength =
+        sizeof(pldm_get_fru_record_by_option_resp) - 1 + fruData.size();
+
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> response;
+    auto respMsg = reinterpret_cast<pldm_msg*>(response.data());
+
+    auto rc = encode_get_fru_record_by_option_resp(
+        instanceId, completionCode, dataTransferHandle, transferFlag, nullptr,
+        fruData.size(), respMsg, payLoadLength);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_get_fru_record_by_option_resp(
+        instanceId, completionCode, dataTransferHandle, transferFlag,
+        fruData.data(), fruData.size(), respMsg, payLoadLength - 1);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetFruRecordByOption, testGoodDecodeResponse)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t instanceId = 2;
+    uint32_t dataTransferHandle = 3;
+    uint8_t transferFlag = 5;
+
+    std::array<uint8_t, 5> fruData = {1, 2, 3, 4, 5};
+    constexpr auto payLoadLength =
+        sizeof(pldm_get_fru_record_by_option_resp) - 1 + fruData.size();
+
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> response;
+    auto respMsg = reinterpret_cast<pldm_msg*>(response.data());
+
+    auto rc = encode_get_fru_record_by_option_resp(
+        instanceId, completionCode, dataTransferHandle, transferFlag,
+        fruData.data(), fruData.size(), respMsg, payLoadLength);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    uint8_t retCompletionCode;
+    uint32_t retDataTransferHandle;
+    uint8_t retTransferFlag;
+    variable_field retFruData;
+
+    rc = decode_get_fru_record_by_option_resp(
+        respMsg, payLoadLength, &retCompletionCode, &retDataTransferHandle,
+        &retTransferFlag, &retFruData);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retCompletionCode, completionCode);
+    EXPECT_EQ(retDataTransferHandle, dataTransferHandle);
+    EXPECT_EQ(retTransferFlag, transferFlag);
+    EXPECT_EQ(retFruData.length, fruData.size());
+    EXPECT_EQ(std::memcmp(fruData.data(), retFruData.ptr, fruData.size()), 0);
+}
+
+TEST(GetFruRecordByOption, testBadDecodeResponse)
+{
+
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t instanceId = 2;
+    uint32_t dataTransferHandle = 3;
+    uint8_t transferFlag = 5;
+
+    std::array<uint8_t, 5> fruData = {1, 2, 3, 4, 5};
+    constexpr auto payLoadLength =
+        sizeof(pldm_get_fru_record_by_option_resp) - 1 + fruData.size();
+
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> response;
+    auto respMsg = reinterpret_cast<pldm_msg*>(response.data());
+
+    auto rc = encode_get_fru_record_by_option_resp(
+        instanceId, completionCode, dataTransferHandle, transferFlag,
+        fruData.data(), fruData.size(), respMsg, payLoadLength);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    uint8_t retCompletionCode;
+    uint32_t retDataTransferHandle;
+    uint8_t retTransferFlag;
+    variable_field retFruData;
+
+    rc = decode_get_fru_record_by_option_resp(respMsg, payLoadLength, nullptr,
+                                              &retDataTransferHandle,
+                                              &retTransferFlag, &retFruData);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_fru_record_by_option_resp(
+        respMsg, PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES - 1,
+        &retCompletionCode, &retDataTransferHandle, &retTransferFlag,
+        &retFruData);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(SetFRURecordTable, testGoodEncodeResponse)
+{
+    uint8_t instanceId = 2;
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint32_t nextDataTransferHandle = 32;
+
+    std::array<uint8_t,
+               sizeof(pldm_msg_hdr) + PLDM_SET_FRU_RECORD_TABLE_RESP_BYTES>
+        responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+    auto rc = encode_set_fru_record_table_resp(
+        instanceId, completionCode, nextDataTransferHandle,
+        responseMsg.size() - sizeof(pldm_msg_hdr), response);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_set_fru_record_table_resp* resp =
+        reinterpret_cast<struct pldm_set_fru_record_table_resp*>(
+            response->payload);
+    EXPECT_EQ(completionCode, resp->completion_code);
+    EXPECT_EQ(htole32(nextDataTransferHandle), resp->next_data_transfer_handle);
+}
+
+TEST(SetFRURecordTable, testBadEncodeResponse)
+{
+    uint8_t instanceId = 0;
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint32_t nextDataTransferHandle = 1;
+
+    std::array<uint8_t,
+               sizeof(pldm_msg_hdr) + PLDM_SET_FRU_RECORD_TABLE_RESP_BYTES>
+        responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+
+    auto rc = encode_set_fru_record_table_resp(
+        instanceId, completionCode, nextDataTransferHandle,
+        responseMsg.size() - sizeof(pldm_msg_hdr), NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_set_fru_record_table_resp(
+        instanceId, completionCode, nextDataTransferHandle,
+        responseMsg.size() - sizeof(pldm_msg_hdr) - 1, response);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(SetFRURecordTable, testGoodDecodeRequest)
+{
+    uint32_t transferHandle = 1;
+    uint8_t transferFlag = PLDM_GET_FIRSTPART;
+    uint32_t tableData = 44;
+
+    std::array<uint8_t, sizeof(pldm_msg_hdr) +
+                            PLDM_SET_FRU_RECORD_TABLE_MIN_REQ_BYTES +
+                            sizeof(tableData)>
+        requestMsg{};
+    auto request = reinterpret_cast<struct pldm_msg*>(requestMsg.data());
+    struct pldm_set_fru_record_table_req* req =
+        reinterpret_cast<struct pldm_set_fru_record_table_req*>(
+            request->payload);
+    req->data_transfer_handle = htole32(transferHandle);
+    req->transfer_flag = transferFlag;
+    memcpy(req->fru_record_table_data, &tableData, sizeof(tableData));
+
+    uint32_t retTransferHandle;
+    uint8_t retTransferFlag;
+    struct variable_field table;
+
+    auto rc = decode_set_fru_record_table_req(
+        request, requestMsg.size() - sizeof(pldm_msg_hdr), &retTransferHandle,
+        &retTransferFlag, &table);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retTransferHandle, transferHandle);
+    EXPECT_EQ(retTransferFlag, transferFlag);
+    EXPECT_EQ(table.length, sizeof(tableData));
+    EXPECT_EQ(0, memcmp(table.ptr, &tableData, sizeof(tableData)));
+}
+
+TEST(SetFRURecordTable, testBadDecodeRequest)
+{
+    uint32_t transferHandle = 1;
+    uint8_t transferFlag = PLDM_GET_FIRSTPART;
+    uint32_t tableData = 44;
+
+    std::array<uint8_t, sizeof(pldm_msg_hdr) +
+                            PLDM_SET_FRU_RECORD_TABLE_MIN_REQ_BYTES +
+                            sizeof(tableData)>
+        requestMsg{};
+    auto request = reinterpret_cast<struct pldm_msg*>(requestMsg.data());
+    struct pldm_set_fru_record_table_req* req =
+        reinterpret_cast<struct pldm_set_fru_record_table_req*>(
+            request->payload);
+    req->data_transfer_handle = htole32(transferHandle);
+    req->transfer_flag = transferFlag;
+    memcpy(req->fru_record_table_data, &tableData, sizeof(tableData));
+
+    uint32_t retTransferHandle;
+    uint8_t retTransferFlag;
+
+    auto rc = decode_set_fru_record_table_req(
+        request, requestMsg.size() - sizeof(pldm_msg_hdr), &retTransferHandle,
+        &retTransferFlag, NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    struct variable_field table;
+    rc = decode_set_fru_record_table_req(
+        request,
+        requestMsg.size() - sizeof(pldm_msg_hdr) - sizeof(tableData) - 1,
+        &retTransferHandle, &retTransferFlag, &table);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
diff --git a/tests/dsp/meson.build b/tests/dsp/meson.build
new file mode 100644
index 0000000..c457260
--- /dev/null
+++ b/tests/dsp/meson.build
@@ -0,0 +1,15 @@
+tests += [
+  'dsp/base',
+  'dsp/bios_table',
+  'dsp/bios',
+  'dsp/firmware_update',
+  'dsp/fru',
+  'dsp/pdr',
+  'dsp/platform',
+]
+
+test('dsp/bios_table_iter',
+  executable('bios_table_iter',
+             'bios_table_iter.c',
+             implicit_include_directories: false,
+             include_directories: test_include_dirs))
diff --git a/tests/dsp/pdr.cpp b/tests/dsp/pdr.cpp
new file mode 100644
index 0000000..f98f21f
--- /dev/null
+++ b/tests/dsp/pdr.cpp
@@ -0,0 +1,2056 @@
+#include <endian.h>
+#include <libpldm/pdr.h>
+#include <libpldm/platform.h>
+
+#include <array>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+TEST(PDRAccess, testInit)
+{
+    auto repo = pldm_pdr_init();
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
+    EXPECT_EQ(pldm_pdr_get_repo_size(repo), 0u);
+    pldm_pdr_destroy(repo);
+}
+
+TEST(PDRUpdate, testAdd)
+{
+    auto repo = pldm_pdr_init();
+
+    std::array<uint8_t, 10> data{};
+    uint32_t handle = 0;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, &handle),
+        0);
+    EXPECT_EQ(handle, 1u);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    EXPECT_EQ(pldm_pdr_get_repo_size(repo), data.size());
+
+    handle = 0;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, &handle),
+        0);
+    EXPECT_EQ(handle, 2u);
+
+    handle = 0;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, &handle),
+        0);
+    EXPECT_EQ(handle, 3u);
+
+    handle = 0xdeeddeedu;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, &handle),
+        0);
+    EXPECT_EQ(handle, 0xdeeddeed);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
+    EXPECT_EQ(pldm_pdr_get_repo_size(repo), data.size() * 4u);
+
+    pldm_pdr_destroy(repo);
+}
+
+TEST(PDRRemoveByTerminus, testRemoveByTerminus)
+{
+    std::array<uint8_t, 10> data{};
+
+    auto repo = pldm_pdr_init();
+
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    pldm_pdr_remove_pdrs_by_terminus_handle(repo, 1);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 2, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
+    pldm_pdr_remove_pdrs_by_terminus_handle(repo, 1);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 2, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 2, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
+    pldm_pdr_remove_pdrs_by_terminus_handle(repo, 2);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 2, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    pldm_pdr_remove_pdrs_by_terminus_handle(repo, 1);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    pldm_pdr_remove_pdrs_by_terminus_handle(repo, 2);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
+    pldm_pdr_destroy(repo);
+}
+
+TEST(PDRUpdate, testRemove)
+{
+    std::array<uint8_t, 10> data{};
+
+    auto repo = pldm_pdr_init();
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 6u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 5u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 5u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 5u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
+    pldm_pdr_destroy(repo);
+
+    repo = pldm_pdr_init();
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, NULL), 0);
+    EXPECT_EQ(pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, NULL),
+              0);
+    pldm_pdr_remove_remote_pdrs(repo);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
+    uint32_t handle = 0;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, &handle),
+        0);
+    EXPECT_EQ(handle, 3u);
+    handle = 0;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, &handle),
+        0);
+    EXPECT_EQ(handle, 4u);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
+    pldm_pdr_destroy(repo);
+}
+
+TEST(PDRAccess, testGet)
+{
+    auto repo = pldm_pdr_init();
+
+    std::array<uint32_t, 10> in{100, 345, 3, 6, 89, 0, 11, 45, 23434, 123123};
+    uint32_t handle = 1;
+    EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<uint8_t*>(in.data()),
+                                 sizeof(in), false, 1, &handle),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in));
+    uint32_t size{};
+    uint32_t nextRecHdl{};
+    uint8_t* outData = nullptr;
+    auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(size, sizeof(in));
+    EXPECT_EQ(nextRecHdl, 0u);
+    EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
+    outData = nullptr;
+
+    auto hdl2 = pldm_pdr_find_record(repo, 1, &outData, &size, &nextRecHdl);
+    EXPECT_EQ(hdl, hdl2);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(size, sizeof(in));
+    EXPECT_EQ(nextRecHdl, 0u);
+    EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
+    outData = nullptr;
+
+    hdl = pldm_pdr_find_record(repo, htole32(0xdeaddead), &outData, &size,
+                               &nextRecHdl);
+    EXPECT_EQ(hdl, nullptr);
+    EXPECT_EQ(size, 0u);
+    EXPECT_EQ(nextRecHdl, 0u);
+    EXPECT_EQ(outData, nullptr);
+    outData = nullptr;
+
+    std::array<uint32_t, 10> in2{1000, 3450, 30,  60,     890,
+                                 0,    110,  450, 234034, 123123};
+    handle = 2;
+    EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<uint8_t*>(in2.data()),
+                                 sizeof(in2), false, 1, &handle),
+              0);
+    handle = 3;
+    EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<uint8_t*>(in2.data()),
+                                 sizeof(in2), false, 1, &handle),
+              0);
+    handle = 4;
+    EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<uint8_t*>(in2.data()),
+                                 sizeof(in2), true, 1, &handle),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
+    EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in2) * 4);
+    hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(size, sizeof(in));
+    EXPECT_EQ(nextRecHdl, 2u);
+    EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
+    outData = nullptr;
+    hdl2 = pldm_pdr_find_record(repo, 1, &outData, &size, &nextRecHdl);
+    EXPECT_EQ(hdl, hdl2);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(size, sizeof(in));
+    EXPECT_EQ(nextRecHdl, 2u);
+    EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
+    outData = nullptr;
+    hdl = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(size, sizeof(in2));
+    EXPECT_EQ(nextRecHdl, 3u);
+    EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
+    outData = nullptr;
+    hdl = pldm_pdr_find_record(repo, 3, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(pldm_pdr_record_is_remote(hdl), false);
+    EXPECT_EQ(size, sizeof(in2));
+    EXPECT_EQ(nextRecHdl, 4u);
+    EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
+    outData = nullptr;
+    hdl = pldm_pdr_find_record(repo, 4, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(pldm_pdr_record_is_remote(hdl), true);
+    EXPECT_EQ(size, sizeof(in2));
+    EXPECT_EQ(nextRecHdl, 0u);
+    EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
+    outData = nullptr;
+
+    pldm_pdr_destroy(repo);
+}
+
+TEST(PDRAccess, testGetNext)
+{
+    auto repo = pldm_pdr_init();
+
+    std::array<uint32_t, 10> in{100, 345, 3, 6, 89, 0, 11, 45, 23434, 123123};
+    uint32_t handle = 1;
+    EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<uint8_t*>(in.data()),
+                                 sizeof(in), false, 1, &handle),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in));
+    uint32_t size{};
+    uint32_t nextRecHdl{};
+    uint8_t* outData = nullptr;
+    auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(size, sizeof(in));
+    EXPECT_EQ(nextRecHdl, 0u);
+    EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
+    outData = nullptr;
+
+    std::array<uint32_t, 10> in2{1000, 3450, 30,  60,     890,
+                                 0,    110,  450, 234034, 123123};
+    handle = 2;
+    EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<uint8_t*>(in2.data()),
+                                 sizeof(in2), false, 1, &handle),
+              0);
+    handle = 3;
+    EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<uint8_t*>(in2.data()),
+                                 sizeof(in2), false, 1, &handle),
+              0);
+    handle = 4;
+    EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<uint8_t*>(in2.data()),
+                                 sizeof(in2), false, 1, &handle),
+              0);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
+    EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in2) * 4);
+    hdl = pldm_pdr_get_next_record(repo, hdl, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(size, sizeof(in2));
+    EXPECT_EQ(nextRecHdl, 3u);
+    EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
+    outData = nullptr;
+    hdl = pldm_pdr_get_next_record(repo, hdl, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(size, sizeof(in2));
+    EXPECT_EQ(nextRecHdl, 4u);
+    EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
+    outData = nullptr;
+    hdl = pldm_pdr_get_next_record(repo, hdl, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(size, sizeof(in2));
+    EXPECT_EQ(nextRecHdl, 0u);
+    EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
+    outData = nullptr;
+
+    pldm_pdr_destroy(repo);
+}
+
+TEST(PDRAccess, testFindByType)
+{
+    auto repo = pldm_pdr_init();
+
+    std::array<uint8_t, sizeof(pldm_pdr_hdr)> data{};
+    pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(data.data());
+    hdr->type = 1;
+    uint32_t first = 0;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, &first),
+        0);
+    hdr->type = 2;
+    uint32_t second = 0;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, &second),
+        0);
+    hdr->type = 3;
+    uint32_t third = 0;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, &third),
+        0);
+    hdr->type = 4;
+    uint32_t fourth = 0;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, &fourth),
+        0);
+
+    uint8_t* outData = nullptr;
+    uint32_t size{};
+    auto firstRec =
+        pldm_pdr_find_record_by_type(repo, 1, nullptr, &outData, &size);
+    EXPECT_EQ(pldm_pdr_get_record_handle(repo, firstRec), first);
+    outData = nullptr;
+    auto secondRec =
+        pldm_pdr_find_record_by_type(repo, 2, nullptr, &outData, &size);
+    EXPECT_EQ(pldm_pdr_get_record_handle(repo, secondRec), second);
+    outData = nullptr;
+    auto thirdRec =
+        pldm_pdr_find_record_by_type(repo, 3, nullptr, &outData, &size);
+    EXPECT_EQ(pldm_pdr_get_record_handle(repo, thirdRec), third);
+    outData = nullptr;
+    auto fourthRec =
+        pldm_pdr_find_record_by_type(repo, 4, nullptr, &outData, &size);
+    EXPECT_EQ(pldm_pdr_get_record_handle(repo, fourthRec), fourth);
+    outData = nullptr;
+    auto fifthRec =
+        pldm_pdr_find_record_by_type(repo, 5, nullptr, &outData, &size);
+    EXPECT_EQ(fifthRec, nullptr);
+    EXPECT_EQ(outData, nullptr);
+    EXPECT_EQ(size, 0u);
+
+    auto rec =
+        pldm_pdr_find_record_by_type(repo, 3, secondRec, &outData, &size);
+    EXPECT_EQ(pldm_pdr_get_record_handle(repo, rec), third);
+    outData = nullptr;
+    rec = pldm_pdr_find_record_by_type(repo, 4, secondRec, &outData, &size);
+    EXPECT_EQ(pldm_pdr_get_record_handle(repo, rec), fourth);
+    outData = nullptr;
+    rec = pldm_pdr_find_record_by_type(repo, 2, firstRec, &outData, &size);
+    EXPECT_EQ(pldm_pdr_get_record_handle(repo, rec), second);
+    outData = nullptr;
+
+    pldm_pdr_destroy(repo);
+}
+
+TEST(PDRUpdate, testAddFruRecordSet)
+{
+    auto repo = pldm_pdr_init();
+
+    uint32_t handle = 0;
+    EXPECT_EQ(
+        pldm_pdr_add_fru_record_set_check(repo, 1, 10, 1, 0, 100, &handle), 0);
+    EXPECT_EQ(handle, 1u);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+    EXPECT_EQ(pldm_pdr_get_repo_size(repo),
+              sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
+    uint32_t size{};
+    uint32_t nextRecHdl{};
+    uint8_t* outData = nullptr;
+    auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(size, sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
+    EXPECT_EQ(nextRecHdl, 0u);
+    pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
+    EXPECT_EQ(hdr->version, 1u);
+    EXPECT_EQ(hdr->type, PLDM_PDR_FRU_RECORD_SET);
+    EXPECT_EQ(hdr->length, htole16(sizeof(pldm_pdr_fru_record_set)));
+    EXPECT_EQ(hdr->record_handle, htole32(1));
+    pldm_pdr_fru_record_set* fru = reinterpret_cast<pldm_pdr_fru_record_set*>(
+        outData + sizeof(pldm_pdr_hdr));
+    EXPECT_EQ(fru->terminus_handle, htole16(1));
+    EXPECT_EQ(fru->fru_rsi, htole16(10));
+    EXPECT_EQ(fru->entity_type, htole16(1));
+    EXPECT_EQ(fru->entity_instance_num, htole16(0));
+    EXPECT_EQ(fru->container_id, htole16(100));
+    outData = nullptr;
+
+    handle = 0;
+    EXPECT_EQ(
+        pldm_pdr_add_fru_record_set_check(repo, 2, 11, 2, 1, 101, &handle), 0);
+    EXPECT_EQ(handle, 2u);
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
+    EXPECT_EQ(pldm_pdr_get_repo_size(repo),
+              2 * (sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set)));
+    hdl = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(size, sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
+    EXPECT_EQ(nextRecHdl, 0u);
+    hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
+    EXPECT_EQ(hdr->version, 1u);
+    EXPECT_EQ(hdr->type, PLDM_PDR_FRU_RECORD_SET);
+    EXPECT_EQ(hdr->length, htole16(sizeof(pldm_pdr_fru_record_set)));
+    EXPECT_EQ(hdr->record_handle, htole32(2));
+    fru = reinterpret_cast<pldm_pdr_fru_record_set*>(outData +
+                                                     sizeof(pldm_pdr_hdr));
+    EXPECT_EQ(fru->terminus_handle, htole16(2));
+    EXPECT_EQ(fru->fru_rsi, htole16(11));
+    EXPECT_EQ(fru->entity_type, htole16(2));
+    EXPECT_EQ(fru->entity_instance_num, htole16(1));
+    EXPECT_EQ(fru->container_id, htole16(101));
+    outData = nullptr;
+
+    hdl = pldm_pdr_find_record(repo, 1, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+    EXPECT_EQ(size, sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
+    EXPECT_EQ(nextRecHdl, 2u);
+    hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
+    EXPECT_EQ(hdr->version, 1u);
+    EXPECT_EQ(hdr->type, PLDM_PDR_FRU_RECORD_SET);
+    EXPECT_EQ(hdr->length, htole16(sizeof(pldm_pdr_fru_record_set)));
+    EXPECT_EQ(hdr->record_handle, htole32(1));
+    fru = reinterpret_cast<pldm_pdr_fru_record_set*>(outData +
+                                                     sizeof(pldm_pdr_hdr));
+    EXPECT_EQ(fru->terminus_handle, htole16(1));
+    EXPECT_EQ(fru->fru_rsi, htole16(10));
+    EXPECT_EQ(fru->entity_type, htole16(1));
+    EXPECT_EQ(fru->entity_instance_num, htole16(0));
+    EXPECT_EQ(fru->container_id, htole16(100));
+    outData = nullptr;
+
+    pldm_pdr_destroy(repo);
+}
+
+TEST(PDRUpdate, tesFindtFruRecordSet)
+{
+    auto repo = pldm_pdr_init();
+
+    uint16_t terminusHdl{};
+    uint16_t entityType{};
+    uint16_t entityInstanceNum{};
+    uint16_t containerId{};
+    uint32_t first = 1;
+    EXPECT_EQ(pldm_pdr_add_fru_record_set_check(repo, 1, 1, 1, 0, 100, &first),
+              0);
+    uint32_t second = 2;
+    EXPECT_EQ(pldm_pdr_add_fru_record_set_check(repo, 1, 2, 1, 1, 100, &second),
+              0);
+    uint32_t third = 3;
+    EXPECT_EQ(pldm_pdr_add_fru_record_set_check(repo, 1, 3, 1, 2, 100, &third),
+              0);
+    EXPECT_EQ(first, pldm_pdr_get_record_handle(
+                         repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                   repo, 1, &terminusHdl, &entityType,
+                                   &entityInstanceNum, &containerId)));
+    EXPECT_EQ(second, pldm_pdr_get_record_handle(
+                          repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                    repo, 2, &terminusHdl, &entityType,
+                                    &entityInstanceNum, &containerId)));
+    EXPECT_EQ(third, pldm_pdr_get_record_handle(
+                         repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                   repo, 3, &terminusHdl, &entityType,
+                                   &entityInstanceNum, &containerId)));
+    EXPECT_EQ(terminusHdl, 1u);
+    EXPECT_EQ(entityType, 1u);
+    EXPECT_EQ(entityInstanceNum, 2u);
+    EXPECT_EQ(containerId, 100u);
+    EXPECT_EQ(nullptr, pldm_pdr_fru_record_set_find_by_rsi(
+                           repo, 4, &terminusHdl, &entityType,
+                           &entityInstanceNum, &containerId));
+
+    pldm_pdr_destroy(repo);
+}
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PDRUpdate, testFindLastInRange)
+{
+    auto repo = pldm_pdr_init();
+
+    std::array<uint8_t, 10> data{};
+    uint32_t handle1 = 0;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, &handle1),
+        0);
+    uint32_t handle2 = 23;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, &handle2),
+        0);
+    uint32_t handle3 = 77;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), false, 1, &handle3),
+        0);
+    uint32_t handle4 = 16777325;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, &handle4),
+        0);
+    uint32_t handle5 = 16777344;
+    EXPECT_EQ(
+        pldm_pdr_add_check(repo, data.data(), data.size(), true, 1, &handle5),
+        0);
+
+    auto rec1 = pldm_pdr_find_last_in_range(repo, 0, 100);
+    auto rec2 = pldm_pdr_find_last_in_range(repo, 16777300, 33554431);
+    EXPECT_NE(rec1, nullptr);
+    EXPECT_NE(rec2, nullptr);
+    EXPECT_NE(handle1, pldm_pdr_get_record_handle(repo, rec1));
+    EXPECT_NE(handle2, pldm_pdr_get_record_handle(repo, rec1));
+    EXPECT_EQ(handle3, pldm_pdr_get_record_handle(repo, rec1));
+    EXPECT_NE(handle4, pldm_pdr_get_record_handle(repo, rec2));
+    EXPECT_EQ(handle5, pldm_pdr_get_record_handle(repo, rec2));
+
+    pldm_pdr_destroy(repo);
+}
+#endif
+
+TEST(EntityAssociationPDR, testInit)
+{
+    auto tree = pldm_entity_association_tree_init();
+    EXPECT_NE(tree, nullptr);
+    pldm_entity_association_tree_destroy(tree);
+}
+
+TEST(EntityAssociationPDR, testBuild)
+{
+    //        1
+    //        |
+    //        2--3--4
+    //        |
+    //        5--6--7
+    //        |  |
+    //        9  8
+
+    pldm_entity entities[9]{};
+
+    entities[0].entity_type = 1;
+    entities[1].entity_type = 2;
+    entities[2].entity_type = 2;
+    entities[3].entity_type = 3;
+    entities[4].entity_type = 4;
+    entities[5].entity_type = 5;
+    entities[6].entity_type = 5;
+    entities[7].entity_type = 6;
+    entities[8].entity_type = 7;
+
+    auto tree = pldm_entity_association_tree_init();
+
+    auto l1 = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l1, nullptr);
+    auto l2a = pldm_entity_association_tree_add(
+        tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2a, nullptr);
+    auto l2b = pldm_entity_association_tree_add(
+        tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2b, nullptr);
+    auto l2c = pldm_entity_association_tree_add(
+        tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2c, nullptr);
+    auto l3a = pldm_entity_association_tree_add(
+        tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l3a, nullptr);
+    auto l3b = pldm_entity_association_tree_add(
+        tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l3b, nullptr);
+    auto l3c = pldm_entity_association_tree_add(
+        tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l3b, nullptr);
+    auto l4a = pldm_entity_association_tree_add(
+        tree, &entities[7], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l4a, nullptr);
+    auto l4b = pldm_entity_association_tree_add(
+        tree, &entities[8], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l4b, nullptr);
+
+    EXPECT_EQ(pldm_entity_is_node_parent(l1), true);
+    EXPECT_EQ(pldm_entity_is_node_parent(l2a), true);
+    EXPECT_EQ(pldm_entity_is_node_parent(l3a), true);
+    EXPECT_EQ(pldm_entity_is_node_parent(l3b), true);
+
+    EXPECT_EQ(pldm_entity_is_node_parent(l2b), false);
+    EXPECT_EQ(pldm_entity_is_node_parent(l2c), false);
+    EXPECT_EQ(pldm_entity_is_node_parent(l3c), false);
+    EXPECT_EQ(pldm_entity_is_node_parent(l4a), false);
+    EXPECT_EQ(pldm_entity_is_node_parent(l4b), false);
+
+    EXPECT_EQ(pldm_entity_is_exist_parent(l1), false);
+
+    pldm_entity nodeL1 = pldm_entity_extract(l1);
+    pldm_entity parentL2a = pldm_entity_get_parent(l2a);
+    pldm_entity parentL2b = pldm_entity_get_parent(l2b);
+    pldm_entity parentL2c = pldm_entity_get_parent(l2c);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l2a), true);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l2b), true);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l2c), true);
+    EXPECT_EQ(parentL2a.entity_type, nodeL1.entity_type);
+    EXPECT_EQ(parentL2a.entity_instance_num, nodeL1.entity_instance_num);
+    EXPECT_EQ(parentL2a.entity_container_id, nodeL1.entity_container_id);
+    EXPECT_EQ(parentL2b.entity_type, nodeL1.entity_type);
+    EXPECT_EQ(parentL2b.entity_instance_num, nodeL1.entity_instance_num);
+    EXPECT_EQ(parentL2b.entity_container_id, nodeL1.entity_container_id);
+    EXPECT_EQ(parentL2c.entity_type, nodeL1.entity_type);
+    EXPECT_EQ(parentL2c.entity_instance_num, nodeL1.entity_instance_num);
+    EXPECT_EQ(parentL2c.entity_container_id, nodeL1.entity_container_id);
+
+    pldm_entity nodeL2a = pldm_entity_extract(l2a);
+    pldm_entity parentL3a = pldm_entity_get_parent(l3a);
+    pldm_entity parentL3b = pldm_entity_get_parent(l3b);
+    pldm_entity parentL3c = pldm_entity_get_parent(l3c);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l3a), true);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l3b), true);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l3c), true);
+    EXPECT_EQ(parentL3a.entity_type, nodeL2a.entity_type);
+    EXPECT_EQ(parentL3a.entity_instance_num, nodeL2a.entity_instance_num);
+    EXPECT_EQ(parentL3a.entity_container_id, nodeL2a.entity_container_id);
+    EXPECT_EQ(parentL3b.entity_type, nodeL2a.entity_type);
+    EXPECT_EQ(parentL3b.entity_instance_num, nodeL2a.entity_instance_num);
+    EXPECT_EQ(parentL3b.entity_container_id, nodeL2a.entity_container_id);
+    EXPECT_EQ(parentL3c.entity_type, nodeL2a.entity_type);
+    EXPECT_EQ(parentL3c.entity_instance_num, nodeL2a.entity_instance_num);
+    EXPECT_EQ(parentL3c.entity_container_id, nodeL2a.entity_container_id);
+
+    pldm_entity nodeL3a = pldm_entity_extract(l3a);
+    pldm_entity parentL4a = pldm_entity_get_parent(l4a);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l4a), true);
+    EXPECT_EQ(parentL4a.entity_type, nodeL3a.entity_type);
+    EXPECT_EQ(parentL4a.entity_instance_num, nodeL3a.entity_instance_num);
+    EXPECT_EQ(parentL4a.entity_container_id, nodeL3a.entity_container_id);
+
+    pldm_entity nodeL3b = pldm_entity_extract(l3b);
+    pldm_entity parentL4b = pldm_entity_get_parent(l4b);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l4b), true);
+    EXPECT_EQ(parentL4b.entity_type, nodeL3b.entity_type);
+    EXPECT_EQ(parentL4b.entity_instance_num, nodeL3b.entity_instance_num);
+    EXPECT_EQ(parentL4b.entity_container_id, nodeL3b.entity_container_id);
+
+    size_t num{};
+    pldm_entity* out = nullptr;
+    pldm_entity_association_tree_visit(tree, &out, &num);
+    EXPECT_EQ(num, 9u);
+
+    EXPECT_EQ(out[0].entity_type, 1u);
+    EXPECT_EQ(out[0].entity_instance_num, 1u);
+    EXPECT_EQ(out[0].entity_container_id, 0u);
+
+    EXPECT_EQ(out[1].entity_type, 2u);
+    EXPECT_EQ(out[1].entity_instance_num, 1u);
+    EXPECT_EQ(out[1].entity_container_id, 1u);
+    EXPECT_EQ(out[2].entity_type, 2u);
+    EXPECT_EQ(out[2].entity_instance_num, 2u);
+    EXPECT_EQ(out[2].entity_container_id, 1u);
+    EXPECT_EQ(out[3].entity_type, 3u);
+    EXPECT_EQ(out[3].entity_instance_num, 1u);
+    EXPECT_EQ(out[3].entity_container_id, 1u);
+
+    EXPECT_EQ(out[4].entity_type, 4u);
+    EXPECT_EQ(out[4].entity_instance_num, 1u);
+    EXPECT_EQ(out[4].entity_container_id, 2u);
+    EXPECT_EQ(out[5].entity_type, 5u);
+    EXPECT_EQ(out[5].entity_instance_num, 1u);
+    EXPECT_EQ(out[5].entity_container_id, 2u);
+    EXPECT_EQ(out[6].entity_type, 5u);
+    EXPECT_EQ(out[6].entity_instance_num, 2u);
+    EXPECT_EQ(out[6].entity_container_id, 2u);
+
+    EXPECT_EQ(out[7].entity_type, 7u);
+    EXPECT_EQ(out[7].entity_instance_num, 1u);
+    EXPECT_EQ(out[7].entity_container_id, 4u);
+    EXPECT_EQ(out[8].entity_type, 6u);
+    EXPECT_EQ(out[8].entity_instance_num, 1u);
+    EXPECT_EQ(out[8].entity_container_id, 3u);
+
+    free(out);
+
+    pldm_entity p1 = pldm_entity_extract(l1);
+    EXPECT_EQ(p1.entity_type, 1u);
+    EXPECT_EQ(p1.entity_instance_num, 1u);
+    EXPECT_EQ(p1.entity_container_id, 0u);
+
+    pldm_entity p2a = pldm_entity_extract(l2a);
+    EXPECT_EQ(p2a.entity_type, 2u);
+    EXPECT_EQ(p2a.entity_instance_num, 1u);
+    EXPECT_EQ(p2a.entity_container_id, 1u);
+    pldm_entity p2b = pldm_entity_extract(l2b);
+    EXPECT_EQ(p2b.entity_type, 2u);
+    EXPECT_EQ(p2b.entity_instance_num, 2u);
+    EXPECT_EQ(p2b.entity_container_id, 1u);
+    pldm_entity p2c = pldm_entity_extract(l2c);
+    EXPECT_EQ(p2c.entity_type, 3u);
+    EXPECT_EQ(p2c.entity_instance_num, 1u);
+    EXPECT_EQ(p2c.entity_container_id, 1u);
+
+    pldm_entity p3a = pldm_entity_extract(l3a);
+    EXPECT_EQ(p3a.entity_type, 4u);
+    EXPECT_EQ(p3a.entity_instance_num, 1u);
+    EXPECT_EQ(p3a.entity_container_id, 2u);
+    pldm_entity p3b = pldm_entity_extract(l3b);
+    EXPECT_EQ(p3b.entity_type, 5u);
+    EXPECT_EQ(p3b.entity_instance_num, 1u);
+    EXPECT_EQ(p3b.entity_container_id, 2u);
+    pldm_entity p3c = pldm_entity_extract(l3c);
+    EXPECT_EQ(p3c.entity_type, 5u);
+    EXPECT_EQ(p3c.entity_instance_num, 2u);
+    EXPECT_EQ(p3c.entity_container_id, 2u);
+
+    pldm_entity p4a = pldm_entity_extract(l4a);
+    EXPECT_EQ(p4a.entity_type, 6u);
+    EXPECT_EQ(p4a.entity_instance_num, 1u);
+    EXPECT_EQ(p4a.entity_container_id, 3u);
+    pldm_entity p4b = pldm_entity_extract(l4b);
+    EXPECT_EQ(p4b.entity_type, 7u);
+    EXPECT_EQ(p4b.entity_instance_num, 1u);
+    EXPECT_EQ(p4b.entity_container_id, 4u);
+
+    pldm_entity_association_tree_destroy(tree);
+}
+
+#if LIBPLDM_API_TESTING
+TEST(EntityAssociationPDR, findAndAddRemotePDR)
+{
+    //         Tree - 1
+    //
+    //        11521(1,0)
+    //             |
+    //          45 (1,1)
+    //             |
+    //          64 (1,2)
+    //             |
+    //    ------------------
+    //    |                 |
+    //  67(0,3)           67(1,3)
+    //    |                 |
+    // 135(0,4)          135(0,5)
+    //    |                 |
+    // 32903(0,6)         32903(0,7)
+
+    pldm_entity entities[9]{};
+    entities[0].entity_type = 11521;
+    entities[1].entity_type = 45;
+    entities[2].entity_type = 64;
+    entities[3].entity_type = 67;
+    entities[4].entity_type = 67;
+    entities[5].entity_type = 135;
+    entities[5].entity_container_id = 2;
+    entities[6].entity_type = 135;
+    entities[6].entity_container_id = 3;
+    entities[7].entity_type = 32903;
+    entities[8].entity_type = 32903;
+    auto tree = pldm_entity_association_tree_init();
+    auto l1 = pldm_entity_association_tree_add_entity(
+        tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
+        false, true, 0xffff);
+    EXPECT_NE(l1, nullptr);
+    auto l2 = pldm_entity_association_tree_add_entity(
+        tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xffff);
+    EXPECT_NE(l2, nullptr);
+    auto l3 = pldm_entity_association_tree_add_entity(
+        tree, &entities[2], 0xffff, l2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        true, 0xffff);
+    EXPECT_NE(l3, nullptr);
+    auto l4a = pldm_entity_association_tree_add_entity(
+        tree, &entities[3], 0, l3, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xffff);
+    EXPECT_NE(l4a, nullptr);
+    auto l4b = pldm_entity_association_tree_add_entity(
+        tree, &entities[4], 1, l3, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
+        0xffff);
+    EXPECT_NE(l4b, nullptr);
+    auto l5a = pldm_entity_association_tree_add_entity(
+        tree, &entities[5], 0, l4a, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xffff);
+    EXPECT_NE(l5a, nullptr);
+    auto l5b = pldm_entity_association_tree_add_entity(
+        tree, &entities[6], 0, l4b, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xffff);
+    EXPECT_NE(l5b, nullptr);
+    pldm_entity entity{};
+    entity.entity_type = 135;
+    entity.entity_instance_num = 0;
+    entity.entity_container_id = 2;
+    auto result1 = pldm_entity_association_tree_find(tree, &entity);
+    EXPECT_EQ(result1, l5a);
+    EXPECT_EQ(entities[5].entity_container_id, 2);
+    auto l6a = pldm_entity_association_tree_add_entity(
+        tree, &entities[7], 0, result1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xffff);
+    EXPECT_NE(l6a, nullptr);
+    entity.entity_type = 135;
+    entity.entity_instance_num = 0;
+    entity.entity_container_id = 3;
+    auto result2 = pldm_entity_association_tree_find(tree, &entity);
+    EXPECT_NE(result2, l5b);
+    EXPECT_EQ(entities[6].entity_container_id, 3);
+    auto l7a = pldm_entity_association_tree_add_entity(
+        tree, &entities[8], 0, result2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xffff);
+    EXPECT_EQ(l7a, nullptr);
+    pldm_entity_association_tree_destroy(tree);
+}
+#endif
+
+TEST(EntityAssociationPDR, testSpecialTrees)
+{
+    pldm_entity entities[3]{};
+
+    entities[0].entity_type = 1;
+    entities[1].entity_type = 2;
+    entities[2].entity_type = 1;
+
+    // A
+    auto tree = pldm_entity_association_tree_init();
+    auto node = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node, nullptr);
+    size_t num{};
+    pldm_entity* out = nullptr;
+    pldm_entity_association_tree_visit(tree, &out, &num);
+    EXPECT_EQ(num, 1u);
+    EXPECT_EQ(out[0].entity_type, 1u);
+    EXPECT_EQ(out[0].entity_instance_num, 1u);
+    EXPECT_EQ(out[0].entity_container_id, 0u);
+    free(out);
+    pldm_entity_association_tree_destroy(tree);
+
+    // A-A-A
+    tree = pldm_entity_association_tree_init();
+    node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
+                                            PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node, nullptr);
+    node = pldm_entity_association_tree_add(tree, &entities[1], 0xffff, nullptr,
+                                            PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node, nullptr);
+    node = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, nullptr,
+                                            PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node, nullptr);
+    pldm_entity_association_tree_visit(tree, &out, &num);
+    EXPECT_EQ(num, 3u);
+    EXPECT_EQ(out[0].entity_type, 1u);
+    EXPECT_EQ(out[0].entity_instance_num, 1u);
+    EXPECT_EQ(out[0].entity_container_id, 0u);
+    EXPECT_EQ(out[1].entity_type, 1u);
+    EXPECT_EQ(out[1].entity_instance_num, 2u);
+    EXPECT_EQ(out[1].entity_container_id, 0u);
+    EXPECT_EQ(out[2].entity_type, 2u);
+    EXPECT_EQ(out[2].entity_instance_num, 1u);
+    EXPECT_EQ(out[2].entity_container_id, 0u);
+    free(out);
+    pldm_entity_association_tree_destroy(tree);
+
+    // A
+    // |
+    // A
+    // |
+    // A
+    tree = pldm_entity_association_tree_init();
+    node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
+                                            PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node, nullptr);
+    auto node1 = pldm_entity_association_tree_add(
+        tree, &entities[1], 0xffff, node, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node1, nullptr);
+    auto node2 = pldm_entity_association_tree_add(
+        tree, &entities[2], 0xffff, node1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node2, nullptr);
+    pldm_entity_association_tree_visit(tree, &out, &num);
+    EXPECT_EQ(num, 3u);
+    EXPECT_EQ(out[0].entity_type, 1u);
+    EXPECT_EQ(out[0].entity_instance_num, 1u);
+    EXPECT_EQ(out[0].entity_container_id, 0u);
+    EXPECT_EQ(out[1].entity_type, 2u);
+    EXPECT_EQ(out[1].entity_instance_num, 1u);
+    EXPECT_EQ(out[1].entity_container_id, 1u);
+    EXPECT_EQ(out[2].entity_type, 1u);
+    EXPECT_EQ(out[2].entity_instance_num, 1u);
+    EXPECT_EQ(out[2].entity_container_id, 2u);
+    free(out);
+    pldm_entity_association_tree_destroy(tree);
+
+    // A-A
+    //   |
+    //   A-A
+    tree = pldm_entity_association_tree_init();
+    node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
+                                            PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node, nullptr);
+    node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
+                                            PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node, nullptr);
+    node1 = pldm_entity_association_tree_add(tree, &entities[1], 0xffff, node,
+                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node1, nullptr);
+    node2 = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, node,
+                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node2, nullptr);
+    pldm_entity_association_tree_visit(tree, &out, &num);
+    EXPECT_EQ(num, 4u);
+    EXPECT_EQ(out[0].entity_type, 1u);
+    EXPECT_EQ(out[0].entity_instance_num, 1u);
+    EXPECT_EQ(out[0].entity_container_id, 0u);
+    EXPECT_EQ(out[1].entity_type, 1u);
+    EXPECT_EQ(out[1].entity_instance_num, 2u);
+    EXPECT_EQ(out[1].entity_container_id, 0u);
+    EXPECT_EQ(out[2].entity_type, 2u);
+    EXPECT_EQ(out[2].entity_instance_num, 1u);
+    EXPECT_EQ(out[2].entity_container_id, 1u);
+    EXPECT_EQ(out[3].entity_type, 1u);
+    EXPECT_EQ(out[3].entity_instance_num, 1u);
+    EXPECT_EQ(out[3].entity_container_id, 1u);
+    free(out);
+    pldm_entity_association_tree_destroy(tree);
+}
+
+TEST(EntityAssociationPDR, testPDR)
+{
+    // e = entity type, c = container id, i = instance num
+
+    //        INPUT
+    //        1(e=1)--1a(e=2)
+    //        |
+    //        2(e=2)--3(e=2)--4(e=2)--5(e=3)
+    //        |
+    //        6(e=4)--7(e=5)--8(e=5)--9(e=5)
+    //        |       |
+    //        11(e=6) 10(e=7)
+
+    //        Expected OUTPUT
+    //        1(e=1,c=0,i=1)
+    //        |
+    //        2(e=2,c=1,i=1)--3(e=2,c=1,i=2)--4(e=3,c=1,i=1)--5(e=3,c=1,i=2)
+    //        |
+    //        6(e=4,c=2,i=1)--7(e=5,c=2,i=1)--8(e=5,c=2,i=2)--9(e=5,c=2,i=3)
+    //        |               |
+    //        10(e=6,c=3,i=1) 11(e=7,c=4,i=1)
+    pldm_entity entities[11]{};
+
+    entities[0].entity_type = 1;
+    entities[1].entity_type = 2;
+    entities[2].entity_type = 3;
+    entities[3].entity_type = 2;
+    entities[4].entity_type = 3;
+    entities[5].entity_type = 4;
+    entities[6].entity_type = 5;
+    entities[7].entity_type = 5;
+    entities[8].entity_type = 5;
+    entities[9].entity_type = 6;
+    entities[10].entity_type = 7;
+
+    auto tree = pldm_entity_association_tree_init();
+
+    auto l1 = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l1, nullptr);
+    auto l1a = pldm_entity_association_tree_add(
+        tree, &entities[1], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l1a, nullptr);
+
+    auto l2a = pldm_entity_association_tree_add(
+        tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2a, nullptr);
+    auto l2b = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, l1,
+                                                PLDM_ENTITY_ASSOCIAION_LOGICAL);
+    EXPECT_NE(l2b, nullptr);
+    auto l2c = pldm_entity_association_tree_add(
+        tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2c, nullptr);
+    auto l2d = pldm_entity_association_tree_add(tree, &entities[4], 0xffff, l1,
+                                                PLDM_ENTITY_ASSOCIAION_LOGICAL);
+    EXPECT_NE(l2d, nullptr);
+
+    auto l3a = pldm_entity_association_tree_add(
+        tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l3a, nullptr);
+    auto l3b = pldm_entity_association_tree_add(
+        tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l3b, nullptr);
+    auto l3c = pldm_entity_association_tree_add(tree, &entities[7], 0xffff, l2a,
+                                                PLDM_ENTITY_ASSOCIAION_LOGICAL);
+    EXPECT_NE(l3c, nullptr);
+    auto l3d = pldm_entity_association_tree_add(tree, &entities[8], 0xffff, l2a,
+                                                PLDM_ENTITY_ASSOCIAION_LOGICAL);
+    EXPECT_NE(l3d, nullptr);
+
+    auto l4a = pldm_entity_association_tree_add(
+        tree, &entities[9], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l4a, nullptr);
+    auto l4b = pldm_entity_association_tree_add(
+        tree, &entities[10], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL);
+    EXPECT_NE(l4b, nullptr);
+
+    EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
+              2);
+    EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_LOGICAL),
+              2);
+    EXPECT_EQ(
+        pldm_entity_get_num_children(l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL), 2);
+    EXPECT_EQ(
+        pldm_entity_get_num_children(l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL), 0);
+    EXPECT_EQ(pldm_entity_get_num_children(l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL),
+              1);
+
+    auto repo = pldm_pdr_init();
+    int rc = pldm_entity_association_pdr_add_check(tree, repo, false, 1);
+    ASSERT_EQ(rc, 0);
+
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 6u);
+
+    uint32_t currRecHandle{};
+    uint32_t nextRecHandle{};
+    uint8_t* data = nullptr;
+    uint32_t size{};
+    uint32_t commonSize = sizeof(struct pldm_pdr_hdr) + sizeof(uint16_t) +
+                          sizeof(uint8_t) + sizeof(pldm_entity) +
+                          sizeof(uint8_t);
+
+    pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
+    EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
+                                      l1, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
+                                  sizeof(pldm_entity)));
+    uint8_t* start = data;
+    pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
+    EXPECT_EQ(le32toh(hdr->record_handle), 1u);
+    EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
+    EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
+    start += sizeof(pldm_pdr_hdr);
+    uint16_t* containerId = reinterpret_cast<uint16_t*>(start);
+    EXPECT_EQ(le16toh(*containerId), 1u);
+    start += sizeof(uint16_t);
+    EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
+    start += sizeof(uint8_t);
+    pldm_entity* entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 1u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 0u);
+    start += sizeof(pldm_entity);
+    EXPECT_EQ(*start,
+              pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_LOGICAL));
+    start += sizeof(uint8_t);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 3u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
+    start += sizeof(pldm_entity);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 3u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
+
+    currRecHandle = nextRecHandle;
+
+    pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
+    EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
+                                      l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
+                                  sizeof(pldm_entity)));
+    start = data;
+    hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
+    EXPECT_EQ(le32toh(hdr->record_handle), 2u);
+    EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
+    EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
+    start += sizeof(pldm_pdr_hdr);
+    containerId = reinterpret_cast<uint16_t*>(start);
+    EXPECT_EQ(le16toh(*containerId), 1u);
+    start += sizeof(uint16_t);
+    EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    start += sizeof(uint8_t);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 1u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 0u);
+    start += sizeof(pldm_entity);
+    EXPECT_EQ(*start, pldm_entity_get_num_children(
+                          l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
+    start += sizeof(uint8_t);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 2u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
+    start += sizeof(pldm_entity);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 2u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
+
+    currRecHandle = nextRecHandle;
+
+    pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
+    EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
+                                      l2a, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
+                                  sizeof(pldm_entity)));
+    start = data;
+    hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
+    EXPECT_EQ(le32toh(hdr->record_handle), 3u);
+    EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
+    EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
+    start += sizeof(pldm_pdr_hdr);
+    containerId = reinterpret_cast<uint16_t*>(start);
+    EXPECT_EQ(le16toh(*containerId), 2u);
+    start += sizeof(uint16_t);
+    EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
+    start += sizeof(uint8_t);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 2u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
+    start += sizeof(pldm_entity);
+    EXPECT_EQ(*start, pldm_entity_get_num_children(
+                          l2a, PLDM_ENTITY_ASSOCIAION_LOGICAL));
+    start += sizeof(uint8_t);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 5);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
+    start += sizeof(pldm_entity);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 5u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 3u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
+
+    currRecHandle = nextRecHandle;
+
+    pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
+    EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
+                                      l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
+                                  sizeof(pldm_entity)));
+    start = data;
+    hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
+    EXPECT_EQ(le32toh(hdr->record_handle), 4u);
+    EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
+    EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
+    start += sizeof(pldm_pdr_hdr);
+    containerId = reinterpret_cast<uint16_t*>(start);
+    EXPECT_EQ(le16toh(*containerId), 2u);
+    start += sizeof(uint16_t);
+    EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    start += sizeof(uint8_t);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 2u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
+    start += sizeof(pldm_entity);
+    EXPECT_EQ(*start, pldm_entity_get_num_children(
+                          l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
+    start += sizeof(uint8_t);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 4u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
+    start += sizeof(pldm_entity);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 5u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
+
+    currRecHandle = nextRecHandle;
+
+    pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
+    EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
+                                      l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
+                                  sizeof(pldm_entity)));
+    start = data;
+    hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
+    EXPECT_EQ(le32toh(hdr->record_handle), 5u);
+    EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
+    EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
+    start += sizeof(pldm_pdr_hdr);
+    containerId = reinterpret_cast<uint16_t*>(start);
+    EXPECT_EQ(le16toh(*containerId), 3u);
+    start += sizeof(uint16_t);
+    EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    start += sizeof(uint8_t);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 4u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
+    start += sizeof(pldm_entity);
+    EXPECT_EQ(*start, pldm_entity_get_num_children(
+                          l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
+    start += sizeof(uint8_t);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 6u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 3u);
+
+    currRecHandle = nextRecHandle;
+
+    pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
+    EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
+                                      l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
+                                  sizeof(pldm_entity)));
+    start = data;
+    hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
+    EXPECT_EQ(le32toh(hdr->record_handle), 6u);
+    EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
+    EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
+    start += sizeof(pldm_pdr_hdr);
+    containerId = reinterpret_cast<uint16_t*>(start);
+    EXPECT_EQ(le16toh(*containerId), 4u);
+    start += sizeof(uint16_t);
+    EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
+    start += sizeof(uint8_t);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 5u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
+    start += sizeof(pldm_entity);
+    EXPECT_EQ(*start, pldm_entity_get_num_children(
+                          l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL));
+    start += sizeof(uint8_t);
+    entity = reinterpret_cast<pldm_entity*>(start);
+    EXPECT_EQ(le16toh(entity->entity_type), 7u);
+    EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
+    EXPECT_EQ(le16toh(entity->entity_container_id), 4u);
+
+    EXPECT_EQ(nextRecHandle, 0u);
+
+    pldm_pdr_destroy(repo);
+    pldm_entity_association_tree_destroy(tree);
+}
+
+TEST(EntityAssociationPDR, testFind)
+{
+    //        1
+    //        |
+    //        2--3--4
+    //        |
+    //        5--6--7
+    //        |  |
+    //        8  9
+
+    pldm_entity entities[9]{};
+
+    entities[0].entity_type = 1;
+    entities[1].entity_type = 2;
+    entities[2].entity_type = 2;
+    entities[3].entity_type = 3;
+    entities[4].entity_type = 4;
+    entities[5].entity_type = 5;
+    entities[6].entity_type = 5;
+    entities[7].entity_type = 6;
+    entities[8].entity_type = 7;
+
+    auto tree = pldm_entity_association_tree_init();
+
+    auto l1 = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l1, nullptr);
+    auto l2a = pldm_entity_association_tree_add(
+        tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2a, nullptr);
+    auto l2b = pldm_entity_association_tree_add(
+        tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2b, nullptr);
+    auto l2c = pldm_entity_association_tree_add(
+        tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2c, nullptr);
+    auto l3a = pldm_entity_association_tree_add(
+        tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l3a, nullptr);
+    auto l3b = pldm_entity_association_tree_add(
+        tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l3b, nullptr);
+    auto l3c = pldm_entity_association_tree_add(
+        tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l3c, nullptr);
+    auto l4a = pldm_entity_association_tree_add(
+        tree, &entities[7], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l4a, nullptr);
+    auto l4b = pldm_entity_association_tree_add(
+        tree, &entities[8], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l4b, nullptr);
+
+    pldm_entity entity{};
+
+    entity.entity_type = 1;
+    entity.entity_instance_num = 1;
+    auto result = pldm_entity_association_tree_find(tree, &entity);
+    EXPECT_EQ(result, l1);
+    EXPECT_EQ(entity.entity_container_id, 0);
+
+    entity.entity_type = 2;
+    entity.entity_instance_num = 1;
+    result = pldm_entity_association_tree_find(tree, &entity);
+    EXPECT_EQ(result, l2a);
+    EXPECT_EQ(entity.entity_container_id, 1);
+    entity.entity_type = 2;
+    entity.entity_instance_num = 2;
+    result = pldm_entity_association_tree_find(tree, &entity);
+    EXPECT_EQ(result, l2b);
+    EXPECT_EQ(entity.entity_container_id, 1);
+    entity.entity_type = 3;
+    entity.entity_instance_num = 1;
+    result = pldm_entity_association_tree_find(tree, &entity);
+    EXPECT_EQ(result, l2c);
+    EXPECT_EQ(entity.entity_container_id, 1);
+
+    entity.entity_type = 7;
+    entity.entity_instance_num = 1;
+    result = pldm_entity_association_tree_find(tree, &entity);
+    EXPECT_EQ(result, l4b);
+    EXPECT_EQ(entity.entity_container_id, 4);
+
+    pldm_entity_association_tree_destroy(tree);
+}
+
+TEST(EntityAssociationPDR, testCopyTree)
+{
+    pldm_entity entities[4]{};
+    entities[0].entity_type = 1;
+    entities[1].entity_type = 2;
+    entities[2].entity_type = 2;
+    entities[3].entity_type = 3;
+
+    auto orgTree = pldm_entity_association_tree_init();
+    auto newTree = pldm_entity_association_tree_init();
+    auto l1 =
+        pldm_entity_association_tree_add(orgTree, &entities[0], 0xffff, nullptr,
+                                         PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l1, nullptr);
+    auto l2a = pldm_entity_association_tree_add(
+        orgTree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2a, nullptr);
+    auto l2b = pldm_entity_association_tree_add(
+        orgTree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2b, nullptr);
+    auto l2c = pldm_entity_association_tree_add(
+        orgTree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2c, nullptr);
+    size_t orgNum{};
+    pldm_entity* orgOut = nullptr;
+    pldm_entity_association_tree_visit(orgTree, &orgOut, &orgNum);
+    EXPECT_EQ(orgNum, 4u);
+
+    pldm_entity_association_tree_copy_root(orgTree, newTree);
+    size_t newNum{};
+    pldm_entity* newOut = nullptr;
+    pldm_entity_association_tree_visit(newTree, &newOut, &newNum);
+    EXPECT_EQ(newNum, orgNum);
+    EXPECT_EQ(newOut[0].entity_type, 1u);
+    EXPECT_EQ(newOut[0].entity_instance_num, 1u);
+    EXPECT_EQ(newOut[0].entity_container_id, 0u);
+    free(orgOut);
+    free(newOut);
+    pldm_entity_association_tree_destroy(orgTree);
+    pldm_entity_association_tree_destroy(newTree);
+}
+
+TEST(EntityAssociationPDR, testExtract)
+{
+    std::vector<uint8_t> pdr{};
+    pdr.resize(sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_entity_association) +
+               sizeof(pldm_entity) * 4);
+    pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
+    hdr->type = PLDM_PDR_ENTITY_ASSOCIATION;
+    hdr->length =
+        htole16(sizeof(pldm_pdr_entity_association) + sizeof(pldm_entity) * 4);
+
+    pldm_pdr_entity_association* e =
+        reinterpret_cast<pldm_pdr_entity_association*>(pdr.data() +
+                                                       sizeof(pldm_pdr_hdr));
+    e->container_id = htole16(1);
+    e->num_children = 5;
+    e->container.entity_type = htole16(1);
+    e->container.entity_instance_num = htole16(1);
+    e->container.entity_container_id = htole16(0);
+
+    pldm_entity* entity = e->children;
+    entity->entity_type = htole16(2);
+    entity->entity_instance_num = htole16(1);
+    entity->entity_container_id = htole16(1);
+    ++entity;
+    entity->entity_type = htole16(3);
+    entity->entity_instance_num = htole16(1);
+    entity->entity_container_id = htole16(1);
+    ++entity;
+    entity->entity_type = htole16(4);
+    entity->entity_instance_num = htole16(1);
+    entity->entity_container_id = htole16(1);
+    ++entity;
+    entity->entity_type = htole16(5);
+    entity->entity_instance_num = htole16(1);
+    entity->entity_container_id = htole16(1);
+    ++entity;
+    entity->entity_type = htole16(6);
+    entity->entity_instance_num = htole16(1);
+    entity->entity_container_id = htole16(1);
+
+    size_t num{};
+    pldm_entity* out = nullptr;
+    pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &num, &out);
+    EXPECT_EQ(num, (unsigned)e->num_children + 1);
+    EXPECT_EQ(out[0].entity_type, 1u);
+    EXPECT_EQ(out[0].entity_instance_num, 1u);
+    EXPECT_EQ(out[0].entity_container_id, 0u);
+    EXPECT_EQ(out[1].entity_type, 2u);
+    EXPECT_EQ(out[1].entity_instance_num, 1u);
+    EXPECT_EQ(out[1].entity_container_id, 1u);
+    EXPECT_EQ(out[2].entity_type, 3u);
+    EXPECT_EQ(out[2].entity_instance_num, 1u);
+    EXPECT_EQ(out[2].entity_container_id, 1u);
+    EXPECT_EQ(out[3].entity_type, 4u);
+    EXPECT_EQ(out[3].entity_instance_num, 1u);
+    EXPECT_EQ(out[3].entity_container_id, 1u);
+    EXPECT_EQ(out[4].entity_type, 5u);
+    EXPECT_EQ(out[4].entity_instance_num, 1u);
+    EXPECT_EQ(out[4].entity_container_id, 1u);
+    EXPECT_EQ(out[5].entity_type, 6u);
+    EXPECT_EQ(out[5].entity_instance_num, 1u);
+    EXPECT_EQ(out[5].entity_container_id, 1u);
+
+    free(out);
+}
+
+TEST(EntityAssociationPDR, testGetChildren)
+{
+    pldm_entity entities[4]{};
+    entities[0].entity_type = 1;
+    entities[1].entity_type = 2;
+    entities[2].entity_type = 2;
+    entities[3].entity_type = 3;
+
+    auto tree = pldm_entity_association_tree_init();
+    auto l1 = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l1, nullptr);
+    auto l2a = pldm_entity_association_tree_add(
+        tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2a, nullptr);
+    auto l2b = pldm_entity_association_tree_add(
+        tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2b, nullptr);
+    auto l2c = pldm_entity_association_tree_add(
+        tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2c, nullptr);
+
+    pldm_entity et1;
+    et1.entity_type = 2;
+    et1.entity_instance_num = 1;
+    EXPECT_EQ(true, pldm_is_current_parent_child(l1, &et1));
+
+    pldm_entity et2;
+    et2.entity_type = 2;
+    et2.entity_instance_num = 2;
+    EXPECT_EQ(true, pldm_is_current_parent_child(l1, &et2));
+
+    pldm_entity et3;
+    et3.entity_type = 2;
+    et3.entity_instance_num = 3;
+    EXPECT_EQ(false, pldm_is_current_parent_child(l1, &et3));
+
+    pldm_entity_association_tree_destroy(tree);
+}
+
+TEST(EntityAssociationPDR, testEntityInstanceNumber)
+{
+    pldm_entity entities[9]{};
+
+    entities[0].entity_type = 1;
+    entities[1].entity_type = 2;
+    entities[2].entity_type = 2;
+    entities[3].entity_type = 2;
+    entities[4].entity_type = 2;
+    entities[5].entity_type = 2;
+    entities[6].entity_type = 2;
+    entities[7].entity_type = 3;
+    entities[8].entity_type = 3;
+
+    auto tree = pldm_entity_association_tree_init();
+    auto repo = pldm_pdr_init();
+
+    uint16_t terminusHdl{};
+    uint16_t entityType{};
+    uint16_t entityInstanceNum{};
+    uint16_t containerId{};
+
+    auto node = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node, nullptr);
+
+    auto l1 = pldm_entity_association_tree_add(tree, &entities[1], 63, node,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    uint32_t first = 1;
+    EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
+                  repo, 1, 1, entities[1].entity_type,
+                  entities[1].entity_instance_num,
+                  entities[1].entity_container_id, &first),
+              0);
+    EXPECT_NE(l1, nullptr);
+    EXPECT_EQ(entities[1].entity_instance_num, 63);
+    EXPECT_EQ(first, pldm_pdr_get_record_handle(
+                         repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                   repo, 1, &terminusHdl, &entityType,
+                                   &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 2);
+    EXPECT_EQ(entityInstanceNum, 63);
+
+    auto l2 = pldm_entity_association_tree_add(tree, &entities[2], 37, node,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    uint32_t second = 2;
+    EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
+                  repo, 1, 2, entities[2].entity_type,
+                  entities[2].entity_instance_num,
+                  entities[2].entity_container_id, &second),
+              0);
+    EXPECT_NE(l2, nullptr);
+    EXPECT_EQ(entities[2].entity_instance_num, 37);
+    EXPECT_EQ(second, pldm_pdr_get_record_handle(
+                          repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                    repo, 2, &terminusHdl, &entityType,
+                                    &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 2);
+    EXPECT_EQ(entityInstanceNum, 37);
+
+    auto l3 = pldm_entity_association_tree_add(tree, &entities[3], 44, node,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    uint32_t third = 3;
+    EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
+                  repo, 1, 3, entities[3].entity_type,
+                  entities[3].entity_instance_num,
+                  entities[3].entity_container_id, &third),
+              0);
+    EXPECT_NE(l3, nullptr);
+    EXPECT_EQ(entities[3].entity_instance_num, 44);
+    EXPECT_EQ(third, pldm_pdr_get_record_handle(
+                         repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                   repo, 3, &terminusHdl, &entityType,
+                                   &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 2);
+    EXPECT_EQ(entityInstanceNum, 44);
+
+    auto l4 = pldm_entity_association_tree_add(tree, &entities[4], 89, node,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    uint32_t fourth = 4;
+    EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
+                  repo, 1, 4, entities[4].entity_type,
+                  entities[4].entity_instance_num,
+                  entities[4].entity_container_id, &fourth),
+              0);
+    EXPECT_NE(l4, nullptr);
+    EXPECT_EQ(entities[4].entity_instance_num, 89);
+    EXPECT_EQ(fourth, pldm_pdr_get_record_handle(
+                          repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                    repo, 4, &terminusHdl, &entityType,
+                                    &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 2);
+    EXPECT_EQ(entityInstanceNum, 89);
+
+    auto l5 = pldm_entity_association_tree_add(tree, &entities[5], 0xffff, node,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    uint32_t fifth = 5;
+    EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
+                  repo, 1, 5, entities[5].entity_type,
+                  entities[5].entity_instance_num,
+                  entities[5].entity_container_id, &fifth),
+              0);
+    EXPECT_NE(l5, nullptr);
+    EXPECT_EQ(entities[5].entity_instance_num, 90);
+    EXPECT_EQ(fifth, pldm_pdr_get_record_handle(
+                         repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                   repo, 5, &terminusHdl, &entityType,
+                                   &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 2);
+    EXPECT_EQ(entityInstanceNum, 90);
+
+    auto l6 = pldm_entity_association_tree_add(tree, &entities[6], 90, node,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_EQ(l6, nullptr);
+
+    auto l7 = pldm_entity_association_tree_add(tree, &entities[7], 100, l1,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    uint32_t seventh = 7;
+    EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
+                  repo, 1, 7, entities[7].entity_type,
+                  entities[7].entity_instance_num,
+                  entities[7].entity_container_id, &seventh),
+              0);
+    EXPECT_NE(l7, nullptr);
+    EXPECT_EQ(entities[7].entity_instance_num, 100);
+    EXPECT_EQ(seventh, pldm_pdr_get_record_handle(
+                           repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                     repo, 7, &terminusHdl, &entityType,
+                                     &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 3);
+    EXPECT_EQ(entityInstanceNum, 100);
+
+    auto l8 = pldm_entity_association_tree_add(tree, &entities[8], 100, l2,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    uint32_t eighth = 8;
+    EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
+                  repo, 1, 8, entities[8].entity_type,
+                  entities[8].entity_instance_num,
+                  entities[8].entity_container_id, &eighth),
+              0);
+    EXPECT_NE(l8, nullptr);
+    EXPECT_EQ(entities[8].entity_instance_num, 100);
+    EXPECT_EQ(eighth, pldm_pdr_get_record_handle(
+                          repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                    repo, 8, &terminusHdl, &entityType,
+                                    &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 3);
+    EXPECT_EQ(entityInstanceNum, 100);
+
+    pldm_pdr_destroy(repo);
+    pldm_entity_association_tree_destroy(tree);
+}
+
+#ifdef LIBPLDM_API_TESTING
+TEST(EntityAssociationPDR, testFindChildContainerID)
+{
+    pldm_entity entities[3]{};
+    entities[0].entity_type = 1;
+    entities[1].entity_type = 2;
+    entities[2].entity_type = 3;
+    entities[1].entity_container_id = 2;
+    entities[1].entity_instance_num = 1;
+
+    auto tree = pldm_entity_association_tree_init();
+    auto l1 = pldm_entity_association_tree_add_entity(
+        tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
+        false, true, 0xffff);
+
+    EXPECT_NE(l1, nullptr);
+    auto l2 = pldm_entity_association_tree_add_entity(
+        tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xffff);
+    EXPECT_NE(l2, nullptr);
+    auto l3 = pldm_entity_association_tree_add_entity(
+        tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        true, 0xffff);
+    EXPECT_NE(l3, nullptr);
+
+    EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
+              2);
+
+    auto repo = pldm_pdr_init();
+    int rc = pldm_entity_association_pdr_add_check(tree, repo, false, 1);
+    ASSERT_EQ(rc, 0);
+
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
+
+    uint16_t container_id{};
+    pldm_pdr_find_child_container_id_index_range_exclude(
+        repo, 1, 1, 0, 0x01000000, 0x01ffffff, &container_id);
+    EXPECT_EQ(container_id, 2);
+
+    uint16_t container_id1{};
+    pldm_pdr_find_child_container_id_index_range_exclude(
+        repo, 1, 1, 0, 0x00000001, 0x00ffffff, &container_id1);
+    EXPECT_EQ(container_id1, 0);
+
+    pldm_pdr_destroy(repo);
+    pldm_entity_association_tree_destroy(tree);
+}
+#endif
+
+TEST(EntityAssociationPDR, testNodeAddCheck)
+{
+    // pldm_entity entities[4]{};
+    pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 4);
+    entities[0].entity_type = 1;
+    entities[1].entity_type = 2;
+    entities[2].entity_type = 2;
+    entities[3].entity_type = 3;
+
+    auto tree = pldm_entity_association_tree_init();
+
+    auto l1 = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l1, nullptr);
+    auto l2a = pldm_entity_association_tree_add(
+        tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2a, nullptr);
+    auto l2b = pldm_entity_association_tree_add(
+        tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2b, nullptr);
+    auto l2c = pldm_entity_association_tree_add(
+        tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2c, nullptr);
+
+    auto repo = pldm_pdr_init();
+
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l1, repo, &entities, 4, false, 1, 0),
+              0);
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l1, repo, &entities, 4, false, 1, 2),
+              0);
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l1, repo, &entities, 4, false, 1, 23),
+              0);
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l1, repo, &entities, 4, false, 1, 34),
+              0);
+
+    EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
+
+    uint8_t* outData = nullptr;
+    uint32_t size{};
+    uint32_t nextRecHdl{};
+    auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl, nullptr);
+
+    outData = nullptr;
+    auto hdl1 = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl1, nullptr);
+    pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
+    EXPECT_EQ(hdr->record_handle, 2);
+
+    outData = nullptr;
+    auto hdl2 = pldm_pdr_find_record(repo, 23, &outData, &size, &nextRecHdl);
+    EXPECT_NE(hdl2, nullptr);
+    pldm_pdr_hdr* hdr1 = reinterpret_cast<pldm_pdr_hdr*>(outData);
+    EXPECT_EQ(hdr1->record_handle, 23);
+
+    outData = nullptr;
+    auto hdl3 = pldm_pdr_find_record(repo, 3, &outData, &size, &nextRecHdl);
+    EXPECT_EQ(hdl3, nullptr);
+
+    free(entities);
+    pldm_pdr_destroy(repo);
+    pldm_entity_association_tree_destroy(tree);
+}
+
+#ifdef LIBPLDM_API_TESTING
+TEST(EntityAssociationPDR, testAddContainedEntityRemotePDR)
+{
+    // pldm_entity entities[5]{};
+    pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 5);
+    entities[0].entity_type = 1;
+    entities[1].entity_type = 2;
+    entities[2].entity_type = 3;
+    entities[3].entity_type = 4;
+    entities[4].entity_type = 5;
+
+    auto tree = pldm_entity_association_tree_init();
+    auto l1 = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l1, nullptr);
+    auto l2a = pldm_entity_association_tree_add(
+        tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2a, nullptr);
+    auto l2b = pldm_entity_association_tree_add(
+        tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2b, nullptr);
+    auto l2c = pldm_entity_association_tree_add(
+        tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2c, nullptr);
+    auto l3a = pldm_entity_association_tree_add(
+        tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l3a, nullptr);
+
+    auto repo = pldm_pdr_init();
+
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l1, repo, &entities, 5, false, 1, 0),
+              0);
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l1, repo, &entities, 5, false, 1, 2),
+              0);
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l1, repo, &entities, 5, false, 1, 23),
+              0);
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l1, repo, &entities, 5, false, 1, 34),
+              0);
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l2a, repo, &entities, 5, false, 1, 3),
+              0);
+
+    pldm_entity entity1[1];
+    entity1[0].entity_type = 2;
+
+    EXPECT_EQ(pldm_entity_association_pdr_add_contained_entity_to_remote_pdr(
+                  repo, &entity1[0], 2),
+              0);
+
+    free(entities);
+    pldm_pdr_destroy(repo);
+    pldm_entity_association_tree_destroy(tree);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(EntityAssociationPDR, testAddContainedEntityNew)
+{
+    // pldm_entity entities[5]{};
+    pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 5);
+    entities[0].entity_type = 1;
+    entities[1].entity_type = 2;
+    entities[2].entity_type = 3;
+    entities[3].entity_type = 4;
+    entities[4].entity_type = 5;
+
+    auto tree = pldm_entity_association_tree_init();
+    auto l1 = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l1, nullptr);
+    auto l2a = pldm_entity_association_tree_add(
+        tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2a, nullptr);
+    auto l2b = pldm_entity_association_tree_add(
+        tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2b, nullptr);
+    auto l2c = pldm_entity_association_tree_add(
+        tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l2c, nullptr);
+    auto l3a = pldm_entity_association_tree_add(
+        tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(l3a, nullptr);
+
+    auto repo = pldm_pdr_init();
+
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l1, repo, &entities, 5, false, 1, 0),
+              0);
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l1, repo, &entities, 5, false, 1, 2),
+              0);
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l1, repo, &entities, 5, false, 1, 23),
+              0);
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l1, repo, &entities, 5, false, 1, 34),
+              0);
+    EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
+                  l2a, repo, &entities, 5, false, 1, 3),
+              0);
+
+    uint32_t updated_record_handle = 0;
+
+    pldm_entity entity2[1]{};
+    entity2[0].entity_type = 4;
+
+    pldm_entity entity3[1]{};
+    entity3[0].entity_type = 4;
+
+    EXPECT_EQ(pldm_entity_association_pdr_create_new(
+                  repo, 34, &entity2[0], &entity3[0], &updated_record_handle),
+              0);
+
+    EXPECT_EQ(updated_record_handle, 35);
+
+    free(entities);
+    pldm_pdr_destroy(repo);
+    pldm_entity_association_tree_destroy(tree);
+}
+#endif
diff --git a/tests/dsp/platform.cpp b/tests/dsp/platform.cpp
new file mode 100644
index 0000000..682a922
--- /dev/null
+++ b/tests/dsp/platform.cpp
@@ -0,0 +1,5033 @@
+#include <endian.h>
+#include <libpldm/base.h>
+#include <libpldm/entity.h>
+#include <libpldm/platform.h>
+#include <libpldm/pldm_types.h>
+
+#include <array>
+#include <cstdint>
+#include <cstring>
+#include <vector>
+
+#include "msgbuf.h"
+
+#include <gtest/gtest.h>
+
+constexpr auto hdrSize = sizeof(pldm_msg_hdr);
+
+TEST(SetStateEffecterStates, testEncodeResponse)
+{
+    std::array<uint8_t,
+               sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    uint8_t completionCode = 0;
+
+    auto rc = encode_set_state_effecter_states_resp(0, PLDM_SUCCESS, response);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, response->payload[0]);
+}
+
+TEST(SetStateEffecterStates, testEncodeRequest)
+{
+    std::array<uint8_t,
+               sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES>
+        requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    uint16_t effecterId = 0x0a;
+    uint8_t compEffecterCnt = 0x2;
+    std::array<set_effecter_state_field, 8> stateField{};
+    stateField[0] = {PLDM_REQUEST_SET, 2};
+    stateField[1] = {PLDM_REQUEST_SET, 3};
+
+    auto rc = encode_set_state_effecter_states_req(
+        0, effecterId, compEffecterCnt, stateField.data(), request);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(effecterId, request->payload[0]);
+    EXPECT_EQ(compEffecterCnt, request->payload[sizeof(effecterId)]);
+    EXPECT_EQ(stateField[0].set_request,
+              request->payload[sizeof(effecterId) + sizeof(compEffecterCnt)]);
+    EXPECT_EQ(stateField[0].effecter_state,
+              request->payload[sizeof(effecterId) + sizeof(compEffecterCnt) +
+                               sizeof(stateField[0].set_request)]);
+    EXPECT_EQ(stateField[1].set_request,
+              request->payload[sizeof(effecterId) + sizeof(compEffecterCnt) +
+                               sizeof(stateField[0])]);
+    EXPECT_EQ(stateField[1].effecter_state,
+              request->payload[sizeof(effecterId) + sizeof(compEffecterCnt) +
+                               sizeof(stateField[0]) +
+                               sizeof(stateField[1].set_request)]);
+}
+
+TEST(SetStateEffecterStates, testGoodDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES>
+        responseMsg{};
+
+    uint8_t retcompletion_code = 0;
+
+    responseMsg[hdrSize] = PLDM_SUCCESS;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_set_state_effecter_states_resp(
+        response, responseMsg.size() - hdrSize, &retcompletion_code);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(PLDM_SUCCESS, retcompletion_code);
+}
+
+TEST(SetStateEffecterStates, testGoodDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES>
+        requestMsg{};
+
+    uint16_t effecterId = 0x32;
+    uint16_t effecterIdLE = htole16(effecterId);
+    uint8_t compEffecterCnt = 0x2;
+
+    std::array<set_effecter_state_field, 8> stateField{};
+    stateField[0] = {PLDM_REQUEST_SET, 3};
+    stateField[1] = {PLDM_REQUEST_SET, 4};
+
+    uint16_t retEffecterId = 0;
+    uint8_t retCompEffecterCnt = 0;
+
+    std::array<set_effecter_state_field, 8> retStateField{};
+
+    memcpy(requestMsg.data() + hdrSize, &effecterIdLE, sizeof(effecterIdLE));
+    memcpy(requestMsg.data() + sizeof(effecterIdLE) + hdrSize, &compEffecterCnt,
+           sizeof(compEffecterCnt));
+    memcpy(requestMsg.data() + sizeof(effecterIdLE) + sizeof(compEffecterCnt) +
+               hdrSize,
+           &stateField, sizeof(stateField));
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = decode_set_state_effecter_states_req(
+        request, requestMsg.size() - hdrSize, &retEffecterId,
+        &retCompEffecterCnt, retStateField.data());
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(effecterId, retEffecterId);
+    EXPECT_EQ(retCompEffecterCnt, compEffecterCnt);
+    EXPECT_EQ(retStateField[0].set_request, stateField[0].set_request);
+    EXPECT_EQ(retStateField[0].effecter_state, stateField[0].effecter_state);
+    EXPECT_EQ(retStateField[1].set_request, stateField[1].set_request);
+    EXPECT_EQ(retStateField[1].effecter_state, stateField[1].effecter_state);
+}
+
+TEST(SetStateEffecterStates, testBadDecodeRequest)
+{
+    const struct pldm_msg* msg = NULL;
+
+    auto rc = decode_set_state_effecter_states_req(msg, sizeof(*msg), NULL,
+                                                   NULL, NULL);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(SetStateEffecterStates, testBadDecodeResponse)
+{
+    std::array<uint8_t, PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES>
+        responseMsg{};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_set_state_effecter_states_resp(response,
+                                                    responseMsg.size(), NULL);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetPDR, testGoodEncodeResponse)
+{
+    uint8_t completionCode = 0;
+    uint32_t nextRecordHndl = 0x12;
+    uint32_t nextDataTransferHndl = 0x13;
+    uint8_t transferFlag = PLDM_END;
+    uint16_t respCnt = 0x5;
+    std::vector<uint8_t> recordData{1, 2, 3, 4, 5};
+    uint8_t transferCRC = 6;
+
+    // + size of record data and transfer CRC
+    std::vector<uint8_t> responseMsg(hdrSize + PLDM_GET_PDR_MIN_RESP_BYTES +
+                                     recordData.size() + 1);
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = encode_get_pdr_resp(0, PLDM_SUCCESS, nextRecordHndl,
+                                  nextDataTransferHndl, transferFlag, respCnt,
+                                  recordData.data(), transferCRC, response);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    struct pldm_get_pdr_resp* resp =
+        reinterpret_cast<struct pldm_get_pdr_resp*>(response->payload);
+
+    EXPECT_EQ(completionCode, resp->completion_code);
+    EXPECT_EQ(nextRecordHndl, le32toh(resp->next_record_handle));
+    EXPECT_EQ(nextDataTransferHndl, le32toh(resp->next_data_transfer_handle));
+    EXPECT_EQ(transferFlag, resp->transfer_flag);
+    EXPECT_EQ(respCnt, le16toh(resp->response_count));
+    EXPECT_EQ(0,
+              memcmp(recordData.data(), resp->record_data, recordData.size()));
+    EXPECT_EQ(*(response->payload + sizeof(pldm_get_pdr_resp) - 1 +
+                recordData.size()),
+              transferCRC);
+
+    transferFlag = PLDM_START_AND_END; // No CRC in this case
+    responseMsg.resize(responseMsg.size() - sizeof(transferCRC));
+    rc = encode_get_pdr_resp(0, PLDM_SUCCESS, nextRecordHndl,
+                             nextDataTransferHndl, transferFlag, respCnt,
+                             recordData.data(), transferCRC, response);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+}
+
+TEST(GetPDR, testBadEncodeResponse)
+{
+    uint32_t nextRecordHndl = 0x12;
+    uint32_t nextDataTransferHndl = 0x13;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    uint16_t respCnt = 0x5;
+    std::vector<uint8_t> recordData{1, 2, 3, 4, 5};
+    uint8_t transferCRC = 0;
+
+    auto rc = encode_get_pdr_resp(0, PLDM_SUCCESS, nextRecordHndl,
+                                  nextDataTransferHndl, transferFlag, respCnt,
+                                  recordData.data(), transferCRC, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetPDR, testGoodDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_PDR_REQ_BYTES> requestMsg{};
+
+    uint32_t recordHndl = 0x32;
+    uint32_t dataTransferHndl = 0x11;
+    uint8_t transferOpFlag = PLDM_GET_FIRSTPART;
+    uint16_t requestCnt = 0x5;
+    uint16_t recordChangeNum = 0x01;
+
+    uint32_t retRecordHndl = 0;
+    uint32_t retDataTransferHndl = 0;
+    uint8_t retTransferOpFlag = 0;
+    uint16_t retRequestCnt = 0;
+    uint16_t retRecordChangeNum = 0;
+
+    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_get_pdr_req* request =
+        reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
+
+    request->record_handle = htole32(recordHndl);
+    request->data_transfer_handle = htole32(dataTransferHndl);
+    request->transfer_op_flag = transferOpFlag;
+    request->request_count = htole16(requestCnt);
+    request->record_change_number = htole16(recordChangeNum);
+
+    auto rc = decode_get_pdr_req(
+        req, requestMsg.size() - hdrSize, &retRecordHndl, &retDataTransferHndl,
+        &retTransferOpFlag, &retRequestCnt, &retRecordChangeNum);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retRecordHndl, recordHndl);
+    EXPECT_EQ(retDataTransferHndl, dataTransferHndl);
+    EXPECT_EQ(retTransferOpFlag, transferOpFlag);
+    EXPECT_EQ(retRequestCnt, requestCnt);
+    EXPECT_EQ(retRecordChangeNum, recordChangeNum);
+}
+
+TEST(GetPDR, testBadDecodeRequest)
+{
+    std::array<uint8_t, PLDM_GET_PDR_REQ_BYTES> requestMsg{};
+    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = decode_get_pdr_req(req, requestMsg.size(), NULL, NULL, NULL, NULL,
+                                 NULL);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetPDR, testGoodEncodeRequest)
+{
+    uint32_t record_hndl = 0;
+    uint32_t data_transfer_hndl = 0;
+    uint8_t transfer_op_flag = PLDM_GET_FIRSTPART;
+    uint16_t request_cnt = 20;
+    uint16_t record_chg_num = 0;
+
+    std::vector<uint8_t> requestMsg(hdrSize + PLDM_GET_PDR_REQ_BYTES);
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_get_pdr_req(0, record_hndl, data_transfer_hndl,
+                                 transfer_op_flag, request_cnt, record_chg_num,
+                                 request, PLDM_GET_PDR_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    struct pldm_get_pdr_req* req =
+        reinterpret_cast<struct pldm_get_pdr_req*>(request->payload);
+    EXPECT_EQ(record_hndl, le32toh(req->record_handle));
+    EXPECT_EQ(data_transfer_hndl, le32toh(req->data_transfer_handle));
+    EXPECT_EQ(transfer_op_flag, req->transfer_op_flag);
+    EXPECT_EQ(request_cnt, le16toh(req->request_count));
+    EXPECT_EQ(record_chg_num, le16toh(req->record_change_number));
+}
+
+TEST(GetPDR, testBadEncodeRequest)
+{
+    uint32_t record_hndl = 0;
+    uint32_t data_transfer_hndl = 0;
+    uint8_t transfer_op_flag = PLDM_GET_FIRSTPART;
+    uint16_t request_cnt = 32;
+    uint16_t record_chg_num = 0;
+
+    std::vector<uint8_t> requestMsg(hdrSize + PLDM_GET_PDR_REQ_BYTES);
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_get_pdr_req(0, record_hndl, data_transfer_hndl,
+                                 transfer_op_flag, request_cnt, record_chg_num,
+                                 nullptr, PLDM_GET_PDR_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_get_pdr_req(0, record_hndl, data_transfer_hndl,
+                            transfer_op_flag, request_cnt, record_chg_num,
+                            request, PLDM_GET_PDR_REQ_BYTES + 1);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetPDR, testGoodDecodeResponse)
+{
+    const char* recordData = "123456789";
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint32_t nextRecordHndl = 0;
+    uint32_t nextDataTransferHndl = 0;
+    uint8_t transferFlag = PLDM_END;
+    constexpr uint16_t respCnt = 9;
+    uint8_t transferCRC = 96;
+    size_t recordDataLength = 32;
+    std::array<uint8_t, hdrSize + PLDM_GET_PDR_MIN_RESP_BYTES + respCnt +
+                            sizeof(transferCRC)>
+        responseMsg{};
+
+    uint8_t retCompletionCode = 0;
+    uint8_t retRecordData[32] = {0};
+    uint32_t retNextRecordHndl = 0;
+    uint32_t retNextDataTransferHndl = 0;
+    uint8_t retTransferFlag = 0;
+    uint16_t retRespCnt = 0;
+    uint8_t retTransferCRC = 0;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_get_pdr_resp* resp =
+        reinterpret_cast<struct pldm_get_pdr_resp*>(response->payload);
+    resp->completion_code = completionCode;
+    resp->next_record_handle = htole32(nextRecordHndl);
+    resp->next_data_transfer_handle = htole32(nextDataTransferHndl);
+    resp->transfer_flag = transferFlag;
+    resp->response_count = htole16(respCnt);
+    memcpy(resp->record_data, recordData, respCnt);
+    response->payload[PLDM_GET_PDR_MIN_RESP_BYTES + respCnt] = transferCRC;
+
+    auto rc = decode_get_pdr_resp(
+        response, responseMsg.size() - hdrSize, &retCompletionCode,
+        &retNextRecordHndl, &retNextDataTransferHndl, &retTransferFlag,
+        &retRespCnt, retRecordData, recordDataLength, &retTransferCRC);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retCompletionCode, completionCode);
+    EXPECT_EQ(retNextRecordHndl, nextRecordHndl);
+    EXPECT_EQ(retNextDataTransferHndl, nextDataTransferHndl);
+    EXPECT_EQ(retTransferFlag, transferFlag);
+    EXPECT_EQ(retRespCnt, respCnt);
+    EXPECT_EQ(retTransferCRC, transferCRC);
+    EXPECT_EQ(0, memcmp(recordData, resp->record_data, respCnt));
+}
+
+TEST(GetPDR, testBadDecodeResponse)
+{
+    const char* recordData = "123456789";
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint32_t nextRecordHndl = 0;
+    uint32_t nextDataTransferHndl = 0;
+    uint8_t transferFlag = PLDM_END;
+    constexpr uint16_t respCnt = 9;
+    uint8_t transferCRC = 96;
+    size_t recordDataLength = respCnt - 1;
+    std::array<uint8_t, hdrSize + PLDM_GET_PDR_MIN_RESP_BYTES + respCnt +
+                            sizeof(transferCRC)>
+        responseMsg{};
+
+    uint8_t retCompletionCode = 0;
+    uint8_t retRecordData[32] = {0};
+    uint32_t retNextRecordHndl = 0;
+    uint32_t retNextDataTransferHndl = 0;
+    uint8_t retTransferFlag = 0;
+    uint16_t retRespCnt = 0;
+    uint8_t retTransferCRC = 0;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_get_pdr_resp* resp =
+        reinterpret_cast<struct pldm_get_pdr_resp*>(response->payload);
+    resp->completion_code = completionCode;
+    resp->next_record_handle = htole32(nextRecordHndl);
+    resp->next_data_transfer_handle = htole32(nextDataTransferHndl);
+    resp->transfer_flag = transferFlag;
+    resp->response_count = htole16(respCnt);
+    memcpy(resp->record_data, recordData, respCnt);
+    response->payload[PLDM_GET_PDR_MIN_RESP_BYTES + respCnt] = transferCRC;
+
+    auto rc = decode_get_pdr_resp(response, responseMsg.size() - hdrSize, NULL,
+                                  NULL, NULL, NULL, NULL, NULL, 0, NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_pdr_resp(
+        response, responseMsg.size() - hdrSize - 1, &retCompletionCode,
+        &retNextRecordHndl, &retNextDataTransferHndl, &retTransferFlag,
+        &retRespCnt, retRecordData, recordDataLength, &retTransferCRC);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetPDRRepositoryInfo, testGoodEncodeResponse)
+{
+    uint8_t completionCode = 0;
+    uint8_t repositoryState = PLDM_AVAILABLE;
+    uint8_t updateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint8_t oemUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint32_t recordCount = 100;
+    uint32_t repositorySize = 100;
+    uint32_t largestRecordSize = UINT32_MAX;
+    uint8_t dataTransferHandleTimeout = PLDM_NO_TIMEOUT;
+
+    std::vector<uint8_t> responseMsg(hdrSize +
+                                     PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES);
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = encode_get_pdr_repository_info_resp(
+        0, PLDM_SUCCESS, repositoryState, updateTime, oemUpdateTime,
+        recordCount, repositorySize, largestRecordSize,
+        dataTransferHandleTimeout, response);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    struct pldm_pdr_repository_info_resp* resp =
+        reinterpret_cast<struct pldm_pdr_repository_info_resp*>(
+            response->payload);
+
+    EXPECT_EQ(completionCode, resp->completion_code);
+    EXPECT_EQ(repositoryState, resp->repository_state);
+    EXPECT_EQ(0, memcmp(updateTime, resp->update_time, PLDM_TIMESTAMP104_SIZE));
+    EXPECT_EQ(0, memcmp(oemUpdateTime, resp->oem_update_time,
+                        PLDM_TIMESTAMP104_SIZE));
+    EXPECT_EQ(recordCount, le32toh(resp->record_count));
+    EXPECT_EQ(repositorySize, le32toh(resp->repository_size));
+    EXPECT_EQ(largestRecordSize, le32toh(resp->largest_record_size));
+    EXPECT_EQ(dataTransferHandleTimeout, resp->data_transfer_handle_timeout);
+}
+
+TEST(GetPDRRepositoryInfo, testBadEncodeResponse)
+{
+    uint8_t repositoryState = PLDM_AVAILABLE;
+    uint8_t updateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint8_t oemUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint32_t recordCount = 100;
+    uint32_t repositorySize = 100;
+    uint32_t largestRecordSize = UINT32_MAX;
+    uint8_t dataTransferHandleTimeout = PLDM_NO_TIMEOUT;
+
+    auto rc = encode_get_pdr_repository_info_resp(
+        0, PLDM_SUCCESS, repositoryState, updateTime, oemUpdateTime,
+        recordCount, repositorySize, largestRecordSize,
+        dataTransferHandleTimeout, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetPDRRepositoryInfo, testGoodDecodeResponse)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t repositoryState = PLDM_AVAILABLE;
+    uint8_t updateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint8_t oemUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint32_t recordCount = 100;
+    uint32_t repositorySize = 100;
+    uint32_t largestRecordSize = UINT32_MAX;
+    uint8_t dataTransferHandleTimeout = PLDM_NO_TIMEOUT;
+
+    std::array<uint8_t, hdrSize + PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_pdr_repository_info_resp* resp =
+        reinterpret_cast<struct pldm_pdr_repository_info_resp*>(
+            response->payload);
+    resp->completion_code = completionCode;
+    resp->repository_state = repositoryState;
+    memcpy(resp->update_time, updateTime, PLDM_TIMESTAMP104_SIZE);
+    memcpy(resp->oem_update_time, oemUpdateTime, PLDM_TIMESTAMP104_SIZE);
+    resp->record_count = htole32(recordCount);
+    resp->repository_size = htole32(repositorySize);
+    resp->largest_record_size = htole32(largestRecordSize);
+    resp->data_transfer_handle_timeout = dataTransferHandleTimeout;
+
+    uint8_t retCompletionCode = 0;
+    uint8_t retRepositoryState = 0;
+    uint8_t retUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint8_t retOemUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint32_t retRecordCount = 0;
+    uint32_t retRepositorySize = 0;
+    uint32_t retLargestRecordSize = 0;
+    uint8_t retDataTransferHandleTimeout = 0;
+
+    auto rc = decode_get_pdr_repository_info_resp(
+        response, responseMsg.size() - hdrSize, &retCompletionCode,
+        &retRepositoryState, retUpdateTime, retOemUpdateTime, &retRecordCount,
+        &retRepositorySize, &retLargestRecordSize,
+        &retDataTransferHandleTimeout);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, retCompletionCode);
+    EXPECT_EQ(repositoryState, retRepositoryState);
+    EXPECT_EQ(0, memcmp(updateTime, retUpdateTime, PLDM_TIMESTAMP104_SIZE));
+    EXPECT_EQ(0,
+              memcmp(oemUpdateTime, retOemUpdateTime, PLDM_TIMESTAMP104_SIZE));
+    EXPECT_EQ(recordCount, recordCount);
+    EXPECT_EQ(repositorySize, repositorySize);
+    EXPECT_EQ(largestRecordSize, largestRecordSize);
+    EXPECT_EQ(dataTransferHandleTimeout, dataTransferHandleTimeout);
+}
+
+TEST(GetPDRRepositoryInfo, testBadDecodeResponse)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t repositoryState = PLDM_AVAILABLE;
+    uint8_t updateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint8_t oemUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint32_t recordCount = htole32(100);
+    uint32_t repositorySize = htole32(100);
+    uint32_t largestRecordSize = htole32(UINT32_MAX);
+    uint8_t dataTransferHandleTimeout = PLDM_NO_TIMEOUT;
+
+    std::array<uint8_t, hdrSize + PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_pdr_repository_info_resp* resp =
+        reinterpret_cast<struct pldm_pdr_repository_info_resp*>(
+            response->payload);
+    resp->completion_code = completionCode;
+    resp->repository_state = repositoryState;
+    memcpy(resp->update_time, updateTime, PLDM_TIMESTAMP104_SIZE);
+    memcpy(resp->oem_update_time, oemUpdateTime, PLDM_TIMESTAMP104_SIZE);
+    resp->record_count = recordCount;
+    resp->repository_size = repositorySize;
+    resp->largest_record_size = largestRecordSize;
+    resp->data_transfer_handle_timeout = dataTransferHandleTimeout;
+
+    uint8_t retCompletionCode = 0;
+    uint8_t retRepositoryState = 0;
+    uint8_t retUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint8_t retOemUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint32_t retRecordCount = 0;
+    uint32_t retRepositorySize = 0;
+    uint32_t retLargestRecordSize = 0;
+    uint8_t retDataTransferHandleTimeout = 0;
+
+    auto rc = decode_get_pdr_repository_info_resp(
+        response, responseMsg.size() - hdrSize, NULL, NULL, NULL, NULL, NULL,
+        NULL, NULL, NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_pdr_repository_info_resp(
+        response, responseMsg.size() - hdrSize - 1, &retCompletionCode,
+        &retRepositoryState, retUpdateTime, retOemUpdateTime, &retRecordCount,
+        &retRepositorySize, &retLargestRecordSize,
+        &retDataTransferHandleTimeout);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    resp->repository_state = PLDM_FAILED + 1;
+    rc = decode_get_pdr_repository_info_resp(
+        response, responseMsg.size() - hdrSize, &retCompletionCode,
+        &retRepositoryState, retUpdateTime, retOemUpdateTime, &retRecordCount,
+        &retRepositorySize, &retLargestRecordSize,
+        &retDataTransferHandleTimeout);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(SetNumericEffecterValue, testGoodDecodeRequest)
+{
+    std::array<uint8_t,
+               hdrSize + PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3>
+        requestMsg{};
+
+    uint16_t effecter_id = 32768;
+    uint8_t effecter_data_size = PLDM_EFFECTER_DATA_SIZE_UINT32;
+    uint32_t effecter_value = 123456789;
+
+    uint16_t reteffecter_id;
+    uint8_t reteffecter_data_size;
+    uint8_t reteffecter_value[4];
+
+    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_set_numeric_effecter_value_req* request =
+        reinterpret_cast<struct pldm_set_numeric_effecter_value_req*>(
+            req->payload);
+
+    request->effecter_id = htole16(effecter_id);
+    request->effecter_data_size = effecter_data_size;
+    uint32_t effecter_value_le = htole32(effecter_value);
+    memcpy(request->effecter_value, &effecter_value_le,
+           sizeof(effecter_value_le));
+
+    auto rc = decode_set_numeric_effecter_value_req(
+        req, requestMsg.size() - hdrSize, &reteffecter_id,
+        &reteffecter_data_size, reteffecter_value);
+
+    uint32_t value = *(reinterpret_cast<uint32_t*>(reteffecter_value));
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(reteffecter_id, effecter_id);
+    EXPECT_EQ(reteffecter_data_size, effecter_data_size);
+    EXPECT_EQ(value, effecter_value);
+}
+
+TEST(SetNumericEffecterValue, testBadDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES>
+        requestMsg{};
+
+    auto rc = decode_set_numeric_effecter_value_req(
+        NULL, requestMsg.size() - hdrSize, NULL, NULL, NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint16_t effecter_id = 0x10;
+    uint8_t effecter_data_size = PLDM_EFFECTER_DATA_SIZE_UINT8;
+    uint8_t effecter_value = 1;
+
+    uint16_t reteffecter_id;
+    uint8_t reteffecter_data_size;
+    uint8_t reteffecter_value[4];
+
+    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_set_numeric_effecter_value_req* request =
+        reinterpret_cast<struct pldm_set_numeric_effecter_value_req*>(
+            req->payload);
+
+    request->effecter_id = effecter_id;
+    request->effecter_data_size = effecter_data_size;
+    memcpy(request->effecter_value, &effecter_value, sizeof(effecter_value));
+
+    rc = decode_set_numeric_effecter_value_req(
+        req, requestMsg.size() - hdrSize - 1, &reteffecter_id,
+        &reteffecter_data_size, reinterpret_cast<uint8_t*>(&reteffecter_value));
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(SetNumericEffecterValue, testGoodEncodeRequest)
+{
+    uint16_t effecter_id = 0;
+    uint8_t effecter_data_size = PLDM_EFFECTER_DATA_SIZE_UINT16;
+    uint16_t effecter_value = 65534;
+
+    std::vector<uint8_t> requestMsg(
+        hdrSize + PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1);
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_set_numeric_effecter_value_req(
+        0, effecter_id, effecter_data_size,
+        reinterpret_cast<uint8_t*>(&effecter_value), request,
+        PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_set_numeric_effecter_value_req* req =
+        reinterpret_cast<struct pldm_set_numeric_effecter_value_req*>(
+            request->payload);
+    EXPECT_EQ(effecter_id, req->effecter_id);
+    EXPECT_EQ(effecter_data_size, req->effecter_data_size);
+    uint16_t* val = (uint16_t*)req->effecter_value;
+    *val = le16toh(*val);
+    EXPECT_EQ(effecter_value, *val);
+}
+
+TEST(SetNumericEffecterValue, testBadEncodeRequest)
+{
+    std::vector<uint8_t> requestMsg(
+        hdrSize + PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES);
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_set_numeric_effecter_value_req(
+        0, 0, 0, NULL, NULL, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint16_t effecter_value;
+    rc = encode_set_numeric_effecter_value_req(
+        0, 0, 6, reinterpret_cast<uint8_t*>(&effecter_value), request,
+        PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(SetNumericEffecterValue, testGoodDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES>
+        responseMsg{};
+
+    uint8_t completion_code = 0xa0;
+
+    uint8_t retcompletion_code;
+
+    memcpy(responseMsg.data() + hdrSize, &completion_code,
+           sizeof(completion_code));
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_set_numeric_effecter_value_resp(
+        response, responseMsg.size() - hdrSize, &retcompletion_code);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completion_code, retcompletion_code);
+}
+
+TEST(SetNumericEffecterValue, testBadDecodeResponse)
+{
+    std::array<uint8_t, PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES>
+        responseMsg{};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_set_numeric_effecter_value_resp(response,
+                                                     responseMsg.size(), NULL);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(SetNumericEffecterValue, testGoodEncodeResponse)
+{
+    std::array<uint8_t, sizeof(pldm_msg_hdr) +
+                            PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    uint8_t completionCode = 0;
+
+    auto rc = encode_set_numeric_effecter_value_resp(
+        0, PLDM_SUCCESS, response, PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, response->payload[0]);
+}
+
+TEST(SetNumericEffecterValue, testBadEncodeResponse)
+{
+    auto rc = encode_set_numeric_effecter_value_resp(
+        0, PLDM_SUCCESS, NULL, PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetStateSensorReadings, testGoodEncodeResponse)
+{
+    std::array<uint8_t, hdrSize +
+                            PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
+                            sizeof(get_sensor_state_field) * 2>
+        responseMsg{};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    uint8_t completionCode = 0;
+    uint8_t comp_sensorCnt = 0x2;
+
+    std::array<get_sensor_state_field, 2> stateField{};
+    stateField[0] = {PLDM_SENSOR_ENABLED, PLDM_SENSOR_NORMAL,
+                     PLDM_SENSOR_WARNING, PLDM_SENSOR_UNKNOWN};
+    stateField[1] = {PLDM_SENSOR_FAILED, PLDM_SENSOR_UPPERFATAL,
+                     PLDM_SENSOR_UPPERCRITICAL, PLDM_SENSOR_FATAL};
+
+    auto rc = encode_get_state_sensor_readings_resp(
+        0, PLDM_SUCCESS, comp_sensorCnt, stateField.data(), response);
+
+    struct pldm_get_state_sensor_readings_resp* resp =
+        reinterpret_cast<struct pldm_get_state_sensor_readings_resp*>(
+            response->payload);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, resp->completion_code);
+    EXPECT_EQ(comp_sensorCnt, resp->comp_sensor_count);
+    EXPECT_EQ(stateField[0].sensor_op_state, resp->field->sensor_op_state);
+    EXPECT_EQ(stateField[0].present_state, resp->field->present_state);
+    EXPECT_EQ(stateField[0].previous_state, resp->field->previous_state);
+    EXPECT_EQ(stateField[0].event_state, resp->field->event_state);
+    EXPECT_EQ(stateField[1].sensor_op_state, resp->field[1].sensor_op_state);
+    EXPECT_EQ(stateField[1].present_state, resp->field[1].present_state);
+    EXPECT_EQ(stateField[1].previous_state, resp->field[1].previous_state);
+    EXPECT_EQ(stateField[1].event_state, resp->field[1].event_state);
+}
+
+TEST(GetStateSensorReadings, testBadEncodeResponse)
+{
+    auto rc = encode_get_state_sensor_readings_resp(0, PLDM_SUCCESS, 0, nullptr,
+                                                    nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetStateSensorReadings, testGoodDecodeResponse)
+{
+    std::array<uint8_t, hdrSize +
+                            PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
+                            sizeof(get_sensor_state_field) * 2>
+        responseMsg{};
+
+    uint8_t completionCode = 0;
+    uint8_t comp_sensorCnt = 2;
+
+    std::array<get_sensor_state_field, 2> stateField{};
+    stateField[0] = {PLDM_SENSOR_DISABLED, PLDM_SENSOR_UNKNOWN,
+                     PLDM_SENSOR_UNKNOWN, PLDM_SENSOR_UNKNOWN};
+    stateField[1] = {PLDM_SENSOR_ENABLED, PLDM_SENSOR_LOWERFATAL,
+                     PLDM_SENSOR_LOWERCRITICAL, PLDM_SENSOR_WARNING};
+
+    uint8_t retcompletion_code = 0;
+    uint8_t retcomp_sensorCnt = 0;
+    std::array<get_sensor_state_field, 2> retstateField{};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_get_state_sensor_readings_resp* resp =
+        reinterpret_cast<struct pldm_get_state_sensor_readings_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->comp_sensor_count = comp_sensorCnt;
+    memcpy(resp->field, &stateField,
+           (sizeof(get_sensor_state_field) * comp_sensorCnt));
+
+    auto rc = decode_get_state_sensor_readings_resp(
+        response, responseMsg.size() - hdrSize, &retcompletion_code,
+        &retcomp_sensorCnt, retstateField.data());
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, retcompletion_code);
+    EXPECT_EQ(comp_sensorCnt, retcomp_sensorCnt);
+    EXPECT_EQ(stateField[0].sensor_op_state, retstateField[0].sensor_op_state);
+    EXPECT_EQ(stateField[0].present_state, retstateField[0].present_state);
+    EXPECT_EQ(stateField[0].previous_state, retstateField[0].previous_state);
+    EXPECT_EQ(stateField[0].event_state, retstateField[0].event_state);
+    EXPECT_EQ(stateField[1].sensor_op_state, retstateField[1].sensor_op_state);
+    EXPECT_EQ(stateField[1].present_state, retstateField[1].present_state);
+    EXPECT_EQ(stateField[1].previous_state, retstateField[1].previous_state);
+    EXPECT_EQ(stateField[1].event_state, retstateField[1].event_state);
+}
+
+TEST(GetStateSensorReadings, testBadDecodeResponse)
+{
+    std::array<uint8_t, hdrSize +
+                            PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
+                            sizeof(get_sensor_state_field) * 2>
+        responseMsg{};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_get_state_sensor_readings_resp(
+        response, responseMsg.size() - hdrSize, nullptr, nullptr, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint8_t completionCode = 0;
+    uint8_t comp_sensorCnt = 1;
+
+    std::array<get_sensor_state_field, 1> stateField{};
+    stateField[0] = {PLDM_SENSOR_ENABLED, PLDM_SENSOR_UPPERFATAL,
+                     PLDM_SENSOR_UPPERCRITICAL, PLDM_SENSOR_WARNING};
+
+    uint8_t retcompletion_code = 0;
+    uint8_t retcomp_sensorCnt = 0;
+    std::array<get_sensor_state_field, 1> retstateField{};
+
+    struct pldm_get_state_sensor_readings_resp* resp =
+        reinterpret_cast<struct pldm_get_state_sensor_readings_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->comp_sensor_count = comp_sensorCnt;
+    memcpy(resp->field, &stateField,
+           (sizeof(get_sensor_state_field) * comp_sensorCnt));
+
+    rc = decode_get_state_sensor_readings_resp(
+        response, responseMsg.size() - hdrSize, &retcompletion_code,
+        &retcomp_sensorCnt, retstateField.data());
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetStateSensorReadings, testGoodEncodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES>
+        requestMsg{};
+
+    uint16_t sensorId = 0xab;
+    bitfield8_t sensorRearm;
+    sensorRearm.byte = 0x03;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto rc = encode_get_state_sensor_readings_req(0, sensorId, sensorRearm, 0,
+                                                   request);
+
+    struct pldm_get_state_sensor_readings_req* req =
+        reinterpret_cast<struct pldm_get_state_sensor_readings_req*>(
+            request->payload);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(sensorId, le16toh(req->sensor_id));
+    EXPECT_EQ(sensorRearm.byte, req->sensor_rearm.byte);
+}
+
+TEST(GetStateSensorReadings, testBadEncodeRequest)
+{
+    bitfield8_t sensorRearm;
+    sensorRearm.byte = 0x0;
+
+    auto rc =
+        encode_get_state_sensor_readings_req(0, 0, sensorRearm, 0, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetStateSensorReadings, testGoodDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES>
+        requestMsg{};
+
+    uint16_t sensorId = 0xcd;
+    bitfield8_t sensorRearm;
+    sensorRearm.byte = 0x10;
+
+    uint16_t retsensorId;
+    bitfield8_t retsensorRearm;
+    uint8_t retreserved;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    struct pldm_get_state_sensor_readings_req* req =
+        reinterpret_cast<struct pldm_get_state_sensor_readings_req*>(
+            request->payload);
+
+    req->sensor_id = htole16(sensorId);
+    req->sensor_rearm.byte = sensorRearm.byte;
+
+    auto rc = decode_get_state_sensor_readings_req(
+        request, requestMsg.size() - hdrSize, &retsensorId, &retsensorRearm,
+        &retreserved);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(sensorId, retsensorId);
+    EXPECT_EQ(sensorRearm.byte, retsensorRearm.byte);
+    EXPECT_EQ(0, retreserved);
+}
+
+TEST(GetStateSensorReadings, testBadDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES>
+        requestMsg{};
+
+    auto rc = decode_get_state_sensor_readings_req(
+        nullptr, requestMsg.size() - hdrSize, nullptr, nullptr, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    uint16_t sensorId = 0x11;
+    bitfield8_t sensorRearm;
+    sensorRearm.byte = 0x04;
+
+    uint16_t retsensorId;
+    bitfield8_t retsensorRearm;
+    uint8_t retreserved;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    struct pldm_get_state_sensor_readings_req* req =
+        reinterpret_cast<struct pldm_get_state_sensor_readings_req*>(
+            request->payload);
+
+    req->sensor_id = htole16(sensorId);
+    req->sensor_rearm.byte = sensorRearm.byte;
+
+    rc = decode_get_state_sensor_readings_req(
+        request, requestMsg.size() - hdrSize - 1, &retsensorId, &retsensorRearm,
+        &retreserved);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(EventMessageBufferSize, testGoodEventMessageBufferSizeRequest)
+{
+    uint8_t eventBufferSize = 32;
+
+    std::array<uint8_t, hdrSize + PLDM_EVENT_MESSAGE_BUFFER_SIZE_REQ_BYTES>
+        requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_event_message_buffer_size_req(0, eventBufferSize, request);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+}
+
+TEST(EventMessageBufferSize, testGoodEventMessageBufferSizeResponse)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint16_t terminusMaxBufferSize = 256;
+
+    std::array<uint8_t, hdrSize + PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES>
+        responseMsg{};
+
+    uint8_t retCompletionCode;
+    uint16_t retMaxBufferSize = 0;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_event_message_buffer_size_resp* resp =
+        reinterpret_cast<struct pldm_event_message_buffer_size_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->terminus_max_buffer_size = terminusMaxBufferSize;
+
+    auto rc = decode_event_message_buffer_size_resp(
+        response, responseMsg.size() - hdrSize, &retCompletionCode,
+        &retMaxBufferSize);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retCompletionCode, completionCode);
+    EXPECT_EQ(terminusMaxBufferSize, retMaxBufferSize);
+}
+
+TEST(EventMessageBufferSize, testBadEventMessageBufferSizeResponse)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint16_t terminusMaxBufferSize = 256;
+
+    std::array<uint8_t, hdrSize + PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES>
+        responseMsg{};
+
+    uint8_t retCompletionCode;
+    uint16_t retMaxBufferSize = 0;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_event_message_buffer_size_resp* resp =
+        reinterpret_cast<struct pldm_event_message_buffer_size_resp*>(
+            response->payload);
+    resp->completion_code = completionCode;
+    resp->terminus_max_buffer_size = terminusMaxBufferSize;
+
+    auto rc =
+        decode_event_message_buffer_size_resp(response, 0, nullptr, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_event_message_buffer_size_resp(
+        response, responseMsg.size(), &retCompletionCode, &retMaxBufferSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(PlatformEventMessageSupported, testGoodEncodeRequest)
+{
+    uint8_t formatVersion = 0x01;
+
+    std::array<uint8_t, hdrSize + PLDM_EVENT_MESSAGE_SUPPORTED_REQ_BYTES>
+        requestMsg{};
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_event_message_supported_req(0, formatVersion, request);
+
+    struct pldm_event_message_supported_req* req =
+        reinterpret_cast<struct pldm_event_message_supported_req*>(
+            request->payload);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(formatVersion, req->format_version);
+}
+
+TEST(PlatformEventMessageSupported, testBadEncodeRequest)
+{
+    uint8_t eventData = 34;
+    uint8_t formatVersion = 0x0;
+
+    std::array<uint8_t, hdrSize + PLDM_EVENT_MESSAGE_SUPPORTED_REQ_BYTES +
+                            sizeof(eventData)>
+        requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_event_message_supported_req(0, formatVersion, request);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_event_message_supported_req(0, formatVersion, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(PlatformEventMessageSupported, testGoodDecodeRespond)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t synchConfiguration = PLDM_MESSAGE_TYPE_SYNCHRONOUS;
+    bitfield8_t synchConfigSupported;
+    synchConfigSupported.byte = 0xe;
+    uint8_t numberEventClassReturned = 0x3;
+    std::vector<uint8_t> eventClass{0x0, 0x5, 0xfa};
+    constexpr uint8_t eventClassCount = 3;
+
+    std::array<uint8_t, hdrSize + PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES +
+                            eventClassCount>
+        responseMsg{};
+
+    uint8_t retCompletionCode;
+    uint8_t retSynchConfig = 0;
+    uint8_t retNumberEventClass = 0;
+    bitfield8_t retSynchConfigSupport;
+    uint8_t retEventClass[eventClassCount] = {0};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_event_message_supported_resp* resp =
+        reinterpret_cast<struct pldm_event_message_supported_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->synchrony_configuration = synchConfiguration;
+    resp->synchrony_configuration_supported.byte = synchConfigSupported.byte;
+    resp->number_event_class_returned = numberEventClassReturned;
+    memcpy(resp->event_class, eventClass.data(), numberEventClassReturned);
+
+    auto rc = decode_event_message_supported_resp(
+        response, responseMsg.size() - hdrSize, &retCompletionCode,
+        &retSynchConfig, &retSynchConfigSupport, &retNumberEventClass,
+        retEventClass, eventClassCount);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retCompletionCode, completionCode);
+    EXPECT_EQ(retSynchConfig, synchConfiguration);
+    EXPECT_EQ(retNumberEventClass, numberEventClassReturned);
+    EXPECT_EQ(retSynchConfigSupport.byte, synchConfigSupported.byte);
+    EXPECT_EQ(0, memcmp(eventClass.data(), resp->event_class,
+                        numberEventClassReturned));
+}
+
+TEST(PlatformEventMessageSupported, testBadSynchConfiguration)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t synchConfiguration = 0x4;
+    bitfield8_t synchConfigSupported;
+    synchConfigSupported.byte = 0xe;
+    uint8_t numberEventClassReturned = 0x3;
+    std::vector<uint8_t> eventClass{0x0, 0x5, 0xfa};
+    constexpr uint8_t eventClassCount = 3;
+
+    std::array<uint8_t, hdrSize + PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES +
+                            eventClassCount>
+        responseMsg{};
+
+    uint8_t retCompletionCode;
+    uint8_t retSynchConfig = 0;
+    uint8_t retNumberEventClass = 0;
+    bitfield8_t retSynchConfigSupport;
+    uint8_t retEventClass[eventClassCount] = {0};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_event_message_supported_resp* resp =
+        reinterpret_cast<struct pldm_event_message_supported_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->synchrony_configuration = synchConfiguration;
+    resp->synchrony_configuration_supported.byte = synchConfigSupported.byte;
+    resp->number_event_class_returned = numberEventClassReturned;
+    memcpy(resp->event_class, eventClass.data(), numberEventClassReturned);
+
+    auto rc = decode_event_message_supported_resp(
+        response, responseMsg.size() - hdrSize, &retCompletionCode,
+        &retSynchConfig, &retSynchConfigSupport, &retNumberEventClass,
+        retEventClass, eventClassCount);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(PlatformEventMessageSupported, testBadDecodeRespond)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t synchConfiguration = PLDM_MESSAGE_TYPE_SYNCHRONOUS;
+    bitfield8_t synchConfigSupported;
+    synchConfigSupported.byte = 0xe;
+    uint8_t numberEventClassReturned = 0x3;
+    std::vector<uint8_t> eventClass{0x0, 0x5, 0xfa};
+    constexpr uint8_t eventClassCount = 3;
+
+    std::array<uint8_t, hdrSize + PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES +
+                            eventClassCount>
+        responseMsg{};
+
+    uint8_t retCompletionCode;
+    uint8_t retSynchConfig = 0;
+    uint8_t retNumberEventClass = 0;
+    bitfield8_t retSynchConfigSupport;
+    uint8_t retEventClass[eventClassCount] = {0};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_event_message_supported_resp* resp =
+        reinterpret_cast<struct pldm_event_message_supported_resp*>(
+            response->payload);
+    resp->completion_code = completionCode;
+    resp->synchrony_configuration = synchConfiguration;
+    resp->synchrony_configuration_supported.byte = synchConfigSupported.byte;
+    resp->number_event_class_returned = numberEventClassReturned;
+    memcpy(resp->event_class, eventClass.data(), numberEventClassReturned);
+
+    auto rc = decode_event_message_supported_resp(response, 0, nullptr, nullptr,
+                                                  nullptr, nullptr, nullptr, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_event_message_supported_resp(
+        response, PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES - 1,
+        &retCompletionCode, &retSynchConfig, &retSynchConfigSupport,
+        &retNumberEventClass, retEventClass, eventClassCount);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_event_message_supported_resp(
+        response, responseMsg.size() - hdrSize, &retCompletionCode,
+        &retSynchConfig, &retSynchConfigSupport, &retNumberEventClass,
+        retEventClass, 1);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(PollForPlatformEventMessage, testGoodEncodeRequest)
+{
+    uint8_t formatVersion = 0x01;
+    uint8_t transferOperationFlag = 0x1;
+    uint32_t dataTransferHandle = 0xffffffff;
+    uint16_t eventIdToAcknowledge = 0x0;
+
+    std::array<uint8_t,
+               hdrSize + PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES>
+        requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_poll_for_platform_event_message_req(
+        0, formatVersion, transferOperationFlag, dataTransferHandle,
+        eventIdToAcknowledge, request,
+        PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    rc = pldm_msgbuf_init_cc(
+        buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES, request->payload,
+        PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    uint8_t retFormatVersion;
+    uint8_t retTransferOperationFlag;
+    uint32_t retDataTransferHandle;
+    uint16_t retEventIdToAcknowledge;
+
+    pldm_msgbuf_extract_uint8(buf, &retFormatVersion);
+    pldm_msgbuf_extract_uint8(buf, &retTransferOperationFlag);
+    pldm_msgbuf_extract_uint32(buf, &retDataTransferHandle);
+    pldm_msgbuf_extract_uint16(buf, &retEventIdToAcknowledge);
+
+    EXPECT_EQ(retFormatVersion, formatVersion);
+    EXPECT_EQ(retTransferOperationFlag, transferOperationFlag);
+    EXPECT_EQ(retDataTransferHandle, dataTransferHandle);
+    EXPECT_EQ(retEventIdToAcknowledge, eventIdToAcknowledge);
+    EXPECT_EQ(pldm_msgbuf_destroy(buf), PLDM_SUCCESS);
+}
+
+TEST(PollForPlatformEventMessage, testBadEncodeRequest)
+{
+    uint8_t formatVersion = 0x01;
+    uint8_t transferOperationFlag = 0x1;
+    uint32_t dataTransferHandle = 0xffffffff;
+    uint16_t eventIdToAcknowledge = 0x0;
+
+    std::array<uint8_t,
+               hdrSize + PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES>
+        requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_poll_for_platform_event_message_req(
+        0, formatVersion, transferOperationFlag, dataTransferHandle,
+        eventIdToAcknowledge, nullptr,
+        PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    encode_poll_for_platform_event_message_req(
+        0, formatVersion, transferOperationFlag, dataTransferHandle,
+        eventIdToAcknowledge, request, hdrSize);
+}
+
+TEST(PollForPlatformEventMessage, testGoodDecodeRespond)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t tId = 0x9;
+    uint16_t eventId = 159;
+    uint32_t nextDataTransferHandle = 0x11223344;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    uint8_t eventClass = 0x5;
+    uint8_t eventData[5] = {0x55, 0x44, 0x33, 0x22, 0x11};
+    constexpr uint32_t eventDataSize = 0x00000005;
+    uint32_t eventDataIntegrityChecksum = 0x66778899;
+
+    std::vector<uint8_t> responseMsg{
+        0x1,
+        0x0,
+        0x0,
+        PLDM_SUCCESS,
+        0x9, // tid
+        159,
+        0x0, // event id
+        0x44,
+        0x33,
+        0x22,
+        0x11,               // next_data_transfer_handle
+        PLDM_START_AND_END, // transfer_flag
+        0x05,               // event class
+        0x05,
+        0x00,
+        0x00,
+        0x00, // event_data_size
+        0x55,
+        0x44,
+        0x33,
+        0x22,
+        0x11, // event_data[5]
+        0x99,
+        0x88,
+        0x77,
+        0x66 // event_data_integrity_checksum
+    };
+    const uint32_t respMsgLen = 23;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    uint8_t retCompletionCode;
+    uint8_t retTid = 0;
+    uint16_t retEventId = 0;
+    uint32_t retNextDataTransferHandle = 0;
+    uint8_t retTransferFlag = 0;
+    uint8_t retEventClass = 0;
+    uint32_t retEventDataSize = 0;
+    uint8_t* retEventData = nullptr;
+    uint32_t retEventDataIntegrityChecksum = 0;
+
+    auto rc = decode_poll_for_platform_event_message_resp(
+        response, respMsgLen, &retCompletionCode, &retTid, &retEventId,
+        &retNextDataTransferHandle, &retTransferFlag, &retEventClass,
+        &retEventDataSize, (void**)&retEventData,
+        &retEventDataIntegrityChecksum);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retCompletionCode, completionCode);
+    EXPECT_EQ(retTid, tId);
+    EXPECT_EQ(retEventId, eventId);
+    EXPECT_EQ(retNextDataTransferHandle, nextDataTransferHandle);
+    EXPECT_EQ(retTransferFlag, transferFlag);
+    EXPECT_EQ(retEventClass, eventClass);
+    EXPECT_EQ(retEventDataSize, eventDataSize);
+    EXPECT_EQ(retEventDataIntegrityChecksum, eventDataIntegrityChecksum);
+    EXPECT_EQ(0, memcmp(eventData, retEventData, eventDataSize));
+}
+
+TEST(PollForPlatformEventMessage, testGoodDecodeAckOnlyRespond)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t tId = 0x9;
+    uint16_t eventId = 0xffff;
+
+    std::vector<uint8_t> responseMsg{
+        0x1,  0x0, 0x0, PLDM_SUCCESS,
+        0x9, // tid
+        0xff,
+        0xff // event id
+    };
+    const uint32_t respMsgLen = 4;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    uint8_t retCompletionCode;
+    uint8_t retTid = 0;
+    uint16_t retEventId = 0;
+    uint32_t retNextDataTransferHandle = 0;
+    uint8_t retTransferFlag = 0;
+    uint8_t retEventClass = 0;
+    uint32_t retEventDataSize = 0;
+    uint8_t* retEventData = nullptr;
+    uint32_t retEventDataIntegrityChecksum = 0;
+
+    auto rc = decode_poll_for_platform_event_message_resp(
+        response, respMsgLen, &retCompletionCode, &retTid, &retEventId,
+        &retNextDataTransferHandle, &retTransferFlag, &retEventClass,
+        &retEventDataSize, (void**)&retEventData,
+        &retEventDataIntegrityChecksum);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retCompletionCode, completionCode);
+    EXPECT_EQ(retTid, tId);
+    EXPECT_EQ(retEventId, eventId);
+
+    eventId = 0x0000;
+    responseMsg[5] = 0x00;
+    responseMsg[6] = 0x00;
+    response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    rc = decode_poll_for_platform_event_message_resp(
+        response, respMsgLen, &retCompletionCode, &retTid, &retEventId,
+        &retNextDataTransferHandle, &retTransferFlag, &retEventClass,
+        &retEventDataSize, (void**)&retEventData,
+        &retEventDataIntegrityChecksum);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retCompletionCode, completionCode);
+    EXPECT_EQ(retTid, tId);
+    EXPECT_EQ(retEventId, eventId);
+}
+
+TEST(PollForPlatformEventMessage, testBadDecodeRespond)
+{
+    std::vector<uint8_t> responseMsg{
+        0x1,
+        0x0,
+        0x0,
+        PLDM_SUCCESS,
+        0x9, // tid
+        159,
+        0x0, // event id
+        0x44,
+        0x33,
+        0x22,
+        0x11,               // next_data_transfer_handle
+        PLDM_START_AND_END, // transfer_flag
+        0x05,               // event class
+        0x05,
+        0x00,
+        0x00,
+        0x00, // event_data_size
+        0x55,
+        0x44,
+        0x33,
+        0x22,
+        0x11, // event_data[5]
+        0x99,
+        0x88,
+        0x77,
+        0x66 // event_data_integrity_checksum
+    };
+    // const uint32_t respMsgLen = 23;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_poll_for_platform_event_message_resp(
+        nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+        nullptr, nullptr, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint8_t retCompletionCode;
+    uint8_t retTid = 0;
+    uint16_t retEventId = 0;
+    uint32_t retNextDataTransferHandle = 0;
+    uint8_t retTransferFlag = 0;
+    uint8_t retEventClass = 0;
+    uint32_t retEventDataSize = 0;
+    uint8_t* retEventData = nullptr;
+    uint32_t retEventDataIntegrityChecksum = 0;
+
+    rc = decode_poll_for_platform_event_message_resp(
+        response, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES - 1,
+        &retCompletionCode, &retTid, &retEventId, &retNextDataTransferHandle,
+        &retTransferFlag, &retEventClass, &retEventDataSize,
+        (void**)&retEventData, &retEventDataIntegrityChecksum);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(PollForPlatformEventMessage, testGoodDecodeRequestFirstPart)
+{
+    uint8_t formatVersion = 0x1;
+    uint8_t transferOperationFlag = PLDM_GET_FIRSTPART;
+    uint32_t dataTransferHandle = 0x11223344;
+    uint16_t eventIdToAcknowledge = 0x0;
+    std::vector<uint8_t> requestMsg{0x1,  0x0,  0x0,  0x1,  PLDM_GET_FIRSTPART,
+                                    0x44, 0x33, 0x22, 0x11, 0x00,
+                                    0x00};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    uint8_t retFormatVersion;
+    uint8_t retTransferOperationFlag;
+    uint32_t retDataTransferHandle;
+    uint16_t retEventIdToAcknowledge;
+
+    auto rc = decode_poll_for_platform_event_message_req(
+        request, requestMsg.size() - hdrSize, &retFormatVersion,
+        &retTransferOperationFlag, &retDataTransferHandle,
+        &retEventIdToAcknowledge);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retFormatVersion, formatVersion);
+    EXPECT_EQ(retTransferOperationFlag, transferOperationFlag);
+    EXPECT_EQ(retDataTransferHandle, dataTransferHandle);
+    EXPECT_EQ(retEventIdToAcknowledge, eventIdToAcknowledge);
+}
+
+TEST(PollForPlatformEventMessage, testGoodDecodeRequestNextPart)
+{
+    uint8_t formatVersion = 0x1;
+    uint8_t transferOperationFlag = PLDM_GET_NEXTPART;
+    uint32_t dataTransferHandle = 0x11223344;
+    uint16_t eventIdToAcknowledge = 0xffff;
+    std::vector<uint8_t> requestMsg{0x1,  0x0,  0x0,  0x1,  PLDM_GET_NEXTPART,
+                                    0x44, 0x33, 0x22, 0x11, 0xff,
+                                    0xff};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    uint8_t retFormatVersion;
+    uint8_t retTransferOperationFlag;
+    uint32_t retDataTransferHandle;
+    uint16_t retEventIdToAcknowledge;
+
+    auto rc = decode_poll_for_platform_event_message_req(
+        request, requestMsg.size() - hdrSize, &retFormatVersion,
+        &retTransferOperationFlag, &retDataTransferHandle,
+        &retEventIdToAcknowledge);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retFormatVersion, formatVersion);
+    EXPECT_EQ(retTransferOperationFlag, transferOperationFlag);
+    EXPECT_EQ(retDataTransferHandle, dataTransferHandle);
+    EXPECT_EQ(retEventIdToAcknowledge, eventIdToAcknowledge);
+}
+
+TEST(PollForPlatformEventMessage, testGoodDecodeRequestAck)
+{
+    uint8_t formatVersion = 0x1;
+    uint8_t transferOperationFlag = PLDM_ACKNOWLEDGEMENT_ONLY;
+    uint32_t dataTransferHandle = 0x11223344;
+    uint16_t eventIdToAcknowledge = 0xffff;
+    std::vector<uint8_t> requestMsg{
+        0x1,  0x0,  0x0,  0x1, PLDM_ACKNOWLEDGEMENT_ONLY, 0x44, 0x33,
+        0x22, 0x11, 0xff, 0xff};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    uint8_t retFormatVersion;
+    uint8_t retTransferOperationFlag;
+    uint32_t retDataTransferHandle;
+    uint16_t retEventIdToAcknowledge;
+
+    auto rc = decode_poll_for_platform_event_message_req(
+        request, requestMsg.size() - hdrSize, &retFormatVersion,
+        &retTransferOperationFlag, &retDataTransferHandle,
+        &retEventIdToAcknowledge);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retFormatVersion, formatVersion);
+    EXPECT_EQ(retTransferOperationFlag, transferOperationFlag);
+    EXPECT_EQ(retDataTransferHandle, dataTransferHandle);
+    EXPECT_EQ(retEventIdToAcknowledge, eventIdToAcknowledge);
+}
+
+TEST(PollForPlatformEventMessage, testBadDecodeRequest)
+{
+    std::vector<uint8_t> requestMsg{0x1,  0x0,  0x0,  0x1,  PLDM_GET_FIRSTPART,
+                                    0x44, 0x33, 0x22, 0x11, 0x66,
+                                    0x55};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    uint8_t retFormatVersion;
+    uint8_t retTransferOperationFlag;
+    uint32_t retDataTransferHandle;
+    uint16_t retEventIdToAcknowledge;
+
+    auto rc = decode_poll_for_platform_event_message_req(
+        NULL, requestMsg.size() - hdrSize, &retFormatVersion,
+        &retTransferOperationFlag, &retDataTransferHandle,
+        &retEventIdToAcknowledge);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    /*
+     * transfer_operation_flag is not PLDM_GET_FIRSTPART or PLDM_GET_NEXTPART or
+     * PLDM_ACKNOWLEDGEMENT_ONLY
+     */
+
+    requestMsg[4] = PLDM_ACKNOWLEDGEMENT_ONLY + 1;
+
+    rc = decode_poll_for_platform_event_message_req(
+        request, requestMsg.size() - hdrSize, &retFormatVersion,
+        &retTransferOperationFlag, &retDataTransferHandle,
+        &retEventIdToAcknowledge);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    /*
+     * transfer_operation_flag is PLDM_GET_FIRSTPART and
+     * event_id_to_acknowledge not 0x0000
+     */
+    requestMsg[4] = PLDM_GET_FIRSTPART;
+    requestMsg[9] = 0x0;
+    requestMsg[10] = 0x1;
+
+    rc = decode_poll_for_platform_event_message_req(
+        request, requestMsg.size() - hdrSize, &retFormatVersion,
+        &retTransferOperationFlag, &retDataTransferHandle,
+        &retEventIdToAcknowledge);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    /*
+     * transfer_operation_flag is not PLDM_GET_FIRSTPART and
+     * event_id_to_acknowledge is 0x0000
+     */
+    requestMsg[4] = PLDM_GET_NEXTPART;
+    requestMsg[9] = 0x0;
+    requestMsg[10] = 0x0;
+
+    rc = decode_poll_for_platform_event_message_req(
+        request, requestMsg.size() - hdrSize, &retFormatVersion,
+        &retTransferOperationFlag, &retDataTransferHandle,
+        &retEventIdToAcknowledge);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    /*
+     * transfer_operation_flag is PLDM_GET_NEXTPART and
+     * event_id_to_acknowledge not 0xffff
+     */
+    requestMsg[4] = PLDM_GET_NEXTPART;
+    requestMsg[9] = 0x0;
+    requestMsg[10] = 0x1;
+
+    rc = decode_poll_for_platform_event_message_req(
+        request, requestMsg.size() - hdrSize, &retFormatVersion,
+        &retTransferOperationFlag, &retDataTransferHandle,
+        &retEventIdToAcknowledge);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    /*
+     * transfer_operation_flag is not PLDM_GET_NEXTPART and
+     * event_id_to_acknowledge is 0xffff
+     */
+    requestMsg[4] = PLDM_GET_FIRSTPART;
+    requestMsg[9] = 0xff;
+    requestMsg[10] = 0xff;
+
+    rc = decode_poll_for_platform_event_message_req(
+        request, requestMsg.size() - hdrSize, &retFormatVersion,
+        &retTransferOperationFlag, &retDataTransferHandle,
+        &retEventIdToAcknowledge);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(PollForPlatformEventMessage, testGoodEncodeResposeP1)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t instance_id = 0;
+    uint8_t tId = 0x9;
+    uint16_t eventId = 0x1;
+    uint32_t nextDataTransferHandle = 0xffff;
+    uint8_t transferFlag = PLDM_END;
+    uint8_t eventClass = 0x5;
+    constexpr uint32_t eventDataSize = 9;
+    uint8_t pEventData[eventDataSize] = {0x31, 0x32, 0x33, 0x34, 0x35,
+                                         0x36, 0x37, 0x38, 0x39};
+    uint32_t eventDataIntegrityChecksum = 0x11223344;
+    constexpr size_t payloadLength =
+        PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_RESP_BYTES + eventDataSize + 4;
+
+    std::array<uint8_t, hdrSize + payloadLength> responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = encode_poll_for_platform_event_message_resp(
+        instance_id, completionCode, tId, eventId, nextDataTransferHandle,
+        transferFlag, eventClass, eventDataSize, pEventData,
+        eventDataIntegrityChecksum, response, payloadLength);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    rc = pldm_msgbuf_init_cc(
+        buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
+        response->payload, payloadLength);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    uint8_t retCompletionCode;
+    uint8_t retTid = 0;
+    uint16_t retEventId = 0;
+    uint32_t retNextDataTransferHandle = 0;
+    uint8_t retTransferFlag = 0;
+    uint8_t retEventClass = 0;
+    uint32_t retEventDataSize = 0;
+    uint8_t retEventData[payloadLength] = {0};
+    uint32_t retEventDataIntegrityChecksum = 0;
+
+    pldm_msgbuf_extract_uint8(buf, &retCompletionCode);
+    pldm_msgbuf_extract_uint8(buf, &retTid);
+    pldm_msgbuf_extract_uint16(buf, &retEventId);
+    pldm_msgbuf_extract_uint32(buf, &retNextDataTransferHandle);
+    pldm_msgbuf_extract_uint8(buf, &retTransferFlag);
+    pldm_msgbuf_extract_uint8(buf, &retEventClass);
+    pldm_msgbuf_extract_uint32(buf, &retEventDataSize);
+    pldm_msgbuf_extract_array_uint8(buf, retEventData, retEventDataSize);
+    pldm_msgbuf_extract_uint32(buf, &retEventDataIntegrityChecksum);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retCompletionCode, completionCode);
+    EXPECT_EQ(retTid, tId);
+    EXPECT_EQ(retEventId, eventId);
+    EXPECT_EQ(retNextDataTransferHandle, nextDataTransferHandle);
+    EXPECT_EQ(retTransferFlag, transferFlag);
+    EXPECT_EQ(retEventClass, eventClass);
+    EXPECT_EQ(retEventDataSize, eventDataSize);
+    EXPECT_EQ(retEventDataIntegrityChecksum, eventDataIntegrityChecksum);
+    EXPECT_EQ(0, memcmp(pEventData, retEventData, eventDataSize));
+
+    EXPECT_EQ(pldm_msgbuf_destroy(buf), PLDM_SUCCESS);
+}
+
+TEST(PollForPlatformEventMessage, testGoodEncodeResposeP2)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t instance_id = 0;
+    uint8_t tId = 0x9;
+    uint16_t eventId = 0x0000;
+    constexpr size_t payloadLength =
+        PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES;
+
+    std::array<uint8_t, hdrSize + payloadLength> responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = encode_poll_for_platform_event_message_resp(
+        instance_id, completionCode, tId, eventId, 0, 0, 0, 0, NULL, 0,
+        response, payloadLength);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    rc = pldm_msgbuf_init_cc(
+        buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
+        response->payload, payloadLength);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    uint8_t retCompletionCode;
+    uint8_t retTid = 0;
+    uint16_t retEventId = 0;
+
+    pldm_msgbuf_extract_uint8(buf, &retCompletionCode);
+    pldm_msgbuf_extract_uint8(buf, &retTid);
+    pldm_msgbuf_extract_uint16(buf, &retEventId);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retCompletionCode, completionCode);
+    EXPECT_EQ(retTid, tId);
+    EXPECT_EQ(retEventId, eventId);
+    EXPECT_EQ(pldm_msgbuf_destroy(buf), PLDM_SUCCESS);
+}
+
+TEST(PollForPlatformEventMessage, testGoodEncodeResposeP3)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t instance_id = 0;
+    uint8_t tId = 0x9;
+    uint16_t eventId = 0xffff;
+    constexpr size_t payloadLength =
+        PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES;
+
+    std::array<uint8_t, hdrSize + payloadLength> responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = encode_poll_for_platform_event_message_resp(
+        instance_id, completionCode, tId, eventId, 0, 0, 0, 0, NULL, 0,
+        response, payloadLength);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    rc = pldm_msgbuf_init_cc(
+        buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
+        response->payload, payloadLength);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    uint8_t retCompletionCode;
+    uint8_t retTid = 0;
+    uint16_t retEventId = 0;
+
+    pldm_msgbuf_extract_uint8(buf, &retCompletionCode);
+    pldm_msgbuf_extract_uint8(buf, &retTid);
+    pldm_msgbuf_extract_uint16(buf, &retEventId);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retCompletionCode, completionCode);
+    EXPECT_EQ(retTid, tId);
+    EXPECT_EQ(retEventId, eventId);
+    EXPECT_EQ(pldm_msgbuf_destroy(buf), PLDM_SUCCESS);
+}
+
+TEST(PollForPlatformEventMessage, testGoodEncodeResposeP4)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t instance_id = 0;
+    uint8_t tId = 0x9;
+    uint16_t eventId = 0x1;
+    uint32_t nextDataTransferHandle = 0xffff;
+    uint8_t transferFlag = PLDM_END;
+    uint8_t eventClass = 0x5;
+    constexpr uint32_t eventDataSize = 0;
+    uint32_t eventDataIntegrityChecksum = 0x11223344;
+    size_t payloadLength =
+        PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_RESP_BYTES + eventDataSize + 4;
+
+    std::array<uint8_t, hdrSize +
+                            PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_RESP_BYTES +
+                            eventDataSize + 4>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = encode_poll_for_platform_event_message_resp(
+        instance_id, completionCode, tId, eventId, nextDataTransferHandle,
+        transferFlag, eventClass, eventDataSize, NULL,
+        eventDataIntegrityChecksum, response, payloadLength);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    rc = pldm_msgbuf_init_cc(
+        buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
+        response->payload, payloadLength);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    uint8_t retCompletionCode;
+    uint8_t retTid = 0;
+    uint16_t retEventId = 0;
+    uint32_t retNextDataTransferHandle = 0;
+    uint8_t retTransferFlag = 0;
+    uint8_t retEventClass = 0;
+    uint32_t retEventDataSize = 0;
+    uint32_t retEventDataIntegrityChecksum = 0;
+
+    pldm_msgbuf_extract_uint8(buf, &retCompletionCode);
+    pldm_msgbuf_extract_uint8(buf, &retTid);
+    pldm_msgbuf_extract_uint16(buf, &retEventId);
+    pldm_msgbuf_extract_uint32(buf, &retNextDataTransferHandle);
+    pldm_msgbuf_extract_uint8(buf, &retTransferFlag);
+    pldm_msgbuf_extract_uint8(buf, &retEventClass);
+    pldm_msgbuf_extract_uint32(buf, &retEventDataSize);
+    pldm_msgbuf_extract_uint32(buf, &retEventDataIntegrityChecksum);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retCompletionCode, completionCode);
+    EXPECT_EQ(retTid, tId);
+    EXPECT_EQ(retEventId, eventId);
+    EXPECT_EQ(retNextDataTransferHandle, nextDataTransferHandle);
+    EXPECT_EQ(retTransferFlag, transferFlag);
+    EXPECT_EQ(retEventClass, eventClass);
+    EXPECT_EQ(retEventDataSize, eventDataSize);
+    EXPECT_EQ(retEventDataIntegrityChecksum, eventDataIntegrityChecksum);
+
+    EXPECT_EQ(pldm_msgbuf_destroy(buf), PLDM_SUCCESS);
+}
+
+TEST(PollForPlatformEventMessage, testBadEncodeResponse)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t instance_id = 0;
+    uint8_t tId = 0x9;
+    uint16_t eventId = 0x1;
+    uint32_t nextDataTransferHandle = 0xffff;
+    uint8_t transferFlag = 0x0;
+    uint8_t eventClass = 0x5;
+    const uint32_t eventDataSize = 0;
+    uint32_t eventDataIntegrityChecksum = 0x11223344;
+    constexpr size_t payloadLength =
+        PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_RESP_BYTES + eventDataSize + 4;
+
+    std::array<uint8_t, hdrSize + payloadLength> responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = encode_poll_for_platform_event_message_resp(
+        instance_id, completionCode, tId, eventId, nextDataTransferHandle,
+        transferFlag, eventClass, eventDataSize, NULL,
+        eventDataIntegrityChecksum, NULL, payloadLength);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_poll_for_platform_event_message_resp(
+        instance_id, completionCode, tId, eventId, nextDataTransferHandle,
+        transferFlag, eventClass, 1, NULL, eventDataIntegrityChecksum, response,
+        payloadLength);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(PlatformEventMessage, testGoodStateSensorDecodeRequest)
+{
+    std::array<uint8_t,
+               hdrSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
+                   PLDM_PLATFORM_EVENT_MESSAGE_STATE_SENSOR_STATE_REQ_BYTES>
+        requestMsg{};
+
+    uint8_t retFormatVersion = 0;
+    uint8_t retTid = 0;
+    uint8_t retEventClass = 0;
+    size_t retEventDataOffset = 0;
+
+    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_platform_event_message_req* request =
+        reinterpret_cast<struct pldm_platform_event_message_req*>(req->payload);
+
+    uint8_t formatVersion = 0x01;
+    uint8_t tid = 0x02;
+    // Sensor Event
+    uint8_t eventClass = 0x00;
+
+    request->format_version = formatVersion;
+    request->tid = tid;
+    request->event_class = eventClass;
+    size_t eventDataOffset =
+        sizeof(formatVersion) + sizeof(tid) + sizeof(eventClass);
+
+    auto rc = decode_platform_event_message_req(
+        req, requestMsg.size() - hdrSize, &retFormatVersion, &retTid,
+        &retEventClass, &retEventDataOffset);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retFormatVersion, formatVersion);
+    EXPECT_EQ(retTid, tid);
+    EXPECT_EQ(retEventClass, eventClass);
+    EXPECT_EQ(retEventDataOffset, eventDataOffset);
+}
+
+TEST(PlatformEventMessage, testBadDecodeRequest)
+{
+    const struct pldm_msg* msg = NULL;
+    std::array<uint8_t,
+               hdrSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
+                   PLDM_PLATFORM_EVENT_MESSAGE_STATE_SENSOR_STATE_REQ_BYTES - 1>
+        requestMsg{};
+    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    uint8_t retFormatVersion;
+    uint8_t retTid = 0;
+    uint8_t retEventClass = 0;
+    size_t retEventDataOffset;
+
+    auto rc = decode_platform_event_message_req(msg, sizeof(*msg), NULL, NULL,
+                                                NULL, NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_platform_event_message_req(
+        req,
+        requestMsg.size() - hdrSize -
+            PLDM_PLATFORM_EVENT_MESSAGE_STATE_SENSOR_STATE_REQ_BYTES,
+        &retFormatVersion, &retTid, &retEventClass, &retEventDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(PlatformEventMessage, testGoodEncodeResponse)
+{
+    std::array<uint8_t,
+               hdrSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
+                   PLDM_PLATFORM_EVENT_MESSAGE_STATE_SENSOR_STATE_REQ_BYTES - 1>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    uint8_t completionCode = 0;
+    uint8_t instanceId = 0x01;
+    uint8_t platformEventStatus = 0x01;
+
+    auto rc = encode_platform_event_message_resp(instanceId, PLDM_SUCCESS,
+                                                 platformEventStatus, response);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, response->payload[0]);
+    EXPECT_EQ(platformEventStatus, response->payload[1]);
+}
+
+TEST(PlatformEventMessage, testBadEncodeResponse)
+{
+    auto rc = encode_platform_event_message_resp(0, PLDM_SUCCESS, 1, NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(PlatformEventMessage, testGoodEncodeRequest)
+{
+    uint8_t formatVersion = 0x01;
+    uint8_t Tid = 0x03;
+    uint8_t eventClass = 0x00;
+    uint8_t eventData = 34;
+
+    std::array<uint8_t, hdrSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
+                            sizeof(eventData)>
+        requestMsg{};
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto rc = encode_platform_event_message_req(
+        0, formatVersion, Tid, eventClass,
+        reinterpret_cast<uint8_t*>(&eventData), sizeof(eventData), request,
+        sizeof(eventData) + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
+
+    struct pldm_platform_event_message_req* req =
+        reinterpret_cast<struct pldm_platform_event_message_req*>(
+            request->payload);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(formatVersion, req->format_version);
+    EXPECT_EQ(Tid, req->tid);
+    EXPECT_EQ(eventClass, req->event_class);
+    EXPECT_EQ(0, memcmp(&eventData, req->event_data, sizeof(eventData)));
+}
+
+TEST(PlatformEventMessage, testBadEncodeRequest)
+{
+    uint8_t Tid = 0x03;
+    uint8_t eventClass = 0x00;
+    uint8_t eventData = 34;
+    size_t sz_eventData = sizeof(eventData);
+    size_t payloadLen =
+        sz_eventData + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
+    uint8_t formatVersion = 0x01;
+
+    std::array<uint8_t, hdrSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
+                            sizeof(eventData)>
+        requestMsg{};
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_platform_event_message_req(
+        0, formatVersion, Tid, eventClass,
+        reinterpret_cast<uint8_t*>(&eventData), sz_eventData, nullptr,
+        payloadLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc = encode_platform_event_message_req(
+        0, 0, Tid, eventClass, reinterpret_cast<uint8_t*>(&eventData),
+        sz_eventData, request, payloadLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc = encode_platform_event_message_req(0, formatVersion, Tid, eventClass,
+                                           nullptr, 0, request, payloadLen);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    rc = encode_platform_event_message_req(
+        0, formatVersion, Tid, eventClass,
+        reinterpret_cast<uint8_t*>(&eventData), sz_eventData, request, 0);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(PlatformEventMessage, testGoodDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES>
+        responseMsg{};
+
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t platformEventStatus = 0x01;
+
+    uint8_t retcompletionCode;
+    uint8_t retplatformEventStatus;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_platform_event_message_resp* resp =
+        reinterpret_cast<struct pldm_platform_event_message_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->platform_event_status = platformEventStatus;
+
+    auto rc = decode_platform_event_message_resp(
+        response, responseMsg.size() - hdrSize, &retcompletionCode,
+        &retplatformEventStatus);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, retcompletionCode);
+    EXPECT_EQ(platformEventStatus, retplatformEventStatus);
+}
+
+TEST(PlatformEventMessage, testBadDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES>
+        responseMsg{};
+
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t platformEventStatus = 0x01;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_platform_event_message_resp* resp =
+        reinterpret_cast<struct pldm_platform_event_message_resp*>(
+            response->payload);
+    resp->completion_code = completionCode;
+    resp->platform_event_status = platformEventStatus;
+
+    auto rc = decode_platform_event_message_resp(
+        nullptr, responseMsg.size() - hdrSize, nullptr, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_platform_event_message_resp(
+        response, responseMsg.size() - hdrSize - 1, &completionCode,
+        &platformEventStatus);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(PlatformEventMessage, testGoodSensorEventDataDecodeRequest)
+{
+    std::array<uint8_t, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH +
+                            PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES>
+        eventDataArr{};
+    uint16_t sensorId = 0x1234;
+    uint8_t sensorEventClassType = PLDM_SENSOR_OP_STATE;
+
+    struct pldm_sensor_event_data* eventData =
+        (struct pldm_sensor_event_data*)eventDataArr.data();
+    eventData->sensor_id = sensorId;
+    eventData->sensor_event_class_type = sensorEventClassType;
+
+    size_t retSensorOpDataOffset;
+    uint16_t retSensorId = 0;
+    uint8_t retSensorEventClassType;
+    size_t sensorOpDataOffset = sizeof(sensorId) + sizeof(sensorEventClassType);
+    auto rc = decode_sensor_event_data(
+        reinterpret_cast<uint8_t*>(eventData), eventDataArr.size(),
+        &retSensorId, &retSensorEventClassType, &retSensorOpDataOffset);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retSensorId, sensorId);
+    EXPECT_EQ(retSensorEventClassType, sensorEventClassType);
+    EXPECT_EQ(retSensorOpDataOffset, sensorOpDataOffset);
+}
+
+TEST(PlatformEventMessage, testBadSensorEventDataDecodeRequest)
+{
+
+    std::array<uint8_t, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH +
+                            PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES>
+        eventDataArr{};
+
+    struct pldm_sensor_event_data* eventData =
+        (struct pldm_sensor_event_data*)eventDataArr.data();
+
+    size_t retSensorOpDataOffset;
+    uint16_t retSensorId = 0;
+    uint8_t retSensorEventClassType;
+    auto rc = decode_sensor_event_data(NULL, eventDataArr.size(), &retSensorId,
+                                       &retSensorEventClassType,
+                                       &retSensorOpDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_sensor_event_data(
+        reinterpret_cast<uint8_t*>(eventDataArr.data()),
+        eventDataArr.size() -
+            PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH,
+        &retSensorId, &retSensorEventClassType, &retSensorOpDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    eventData->sensor_event_class_type = PLDM_SENSOR_OP_STATE;
+
+    rc = decode_sensor_event_data(
+        reinterpret_cast<uint8_t*>(eventDataArr.data()), eventDataArr.size(),
+        &retSensorId, &retSensorEventClassType, &retSensorOpDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    eventData->sensor_event_class_type = PLDM_STATE_SENSOR_STATE;
+    rc = decode_sensor_event_data(
+        reinterpret_cast<uint8_t*>(eventDataArr.data()), eventDataArr.size(),
+        &retSensorId, &retSensorEventClassType, &retSensorOpDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    eventData->sensor_event_class_type = PLDM_NUMERIC_SENSOR_STATE;
+    rc = decode_sensor_event_data(
+        reinterpret_cast<uint8_t*>(eventDataArr.data()),
+        eventDataArr.size() + 1, &retSensorId, &retSensorEventClassType,
+        &retSensorOpDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PlatformEventMessage, testGoodPldmMsgPollEventDataDecodeRequest)
+{
+    std::array<uint8_t, PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION +
+                            PLDM_PLATFORM_EVENT_MESSAGE_EVENT_ID +
+                            PLDM_PLATFORM_EVENT_MESSAGE_TRANFER_HANDLE>
+        eventData{
+            0x1,                   // version
+            0x88, 0x77,            // Event Id
+            0x44, 0x33, 0x22, 0x11 // Tranfer Handle
+        };
+
+    uint8_t formatVersion = 0x01;
+    uint16_t eventID = 0x7788;
+    uint32_t dataTransferHandle = 0x11223344;
+
+    uint8_t retFormatVersion;
+    uint16_t reteventID;
+    uint32_t retDataTransferHandle;
+
+    auto rc = decode_pldm_message_poll_event_data(
+        reinterpret_cast<uint8_t*>(eventData.data()), eventData.size(),
+        &retFormatVersion, &reteventID, &retDataTransferHandle);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retFormatVersion, formatVersion);
+    EXPECT_EQ(reteventID, eventID);
+    EXPECT_EQ(retDataTransferHandle, dataTransferHandle);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PlatformEventMessage, testBadPldmMsgPollEventDataDecodeRequest)
+{
+
+    std::array<uint8_t, PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION +
+                            PLDM_PLATFORM_EVENT_MESSAGE_EVENT_ID +
+                            PLDM_PLATFORM_EVENT_MESSAGE_TRANFER_HANDLE>
+        eventData{
+            0x1,                   // version
+            0x88, 0x77,            // Event Id
+            0x44, 0x33, 0x22, 0x11 // Tranfer Handle
+        };
+
+    uint8_t retFormatVersion;
+    uint16_t reteventID;
+    uint32_t retDataTransferHandle;
+
+    auto rc = decode_pldm_message_poll_event_data(
+        NULL, eventData.size(), &retFormatVersion, &reteventID,
+        &retDataTransferHandle);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_pldm_message_poll_event_data(
+        reinterpret_cast<uint8_t*>(eventData.data()), eventData.size() - 1,
+        &retFormatVersion, &reteventID, &retDataTransferHandle);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    // Event id is 0x0000
+    eventData[1] = 0x00;
+    eventData[2] = 0x00;
+    rc = decode_pldm_message_poll_event_data(
+        reinterpret_cast<uint8_t*>(eventData.data()), eventData.size(),
+        &retFormatVersion, &reteventID, &retDataTransferHandle);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    // Event id is 0xffff
+    eventData[1] = 0xff;
+    eventData[2] = 0xff;
+    rc = decode_pldm_message_poll_event_data(
+        reinterpret_cast<uint8_t*>(eventData.data()), eventData.size(),
+        &retFormatVersion, &reteventID, &retDataTransferHandle);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PlatformEventMessage, testGoodPldmMsgPollEventDataEncode)
+{
+    std::array<uint8_t, PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION +
+                            PLDM_PLATFORM_EVENT_MESSAGE_EVENT_ID +
+                            PLDM_PLATFORM_EVENT_MESSAGE_TRANFER_HANDLE>
+        eventData{};
+
+    uint8_t formatVersion = 0x01;
+    uint16_t eventID = 0x7788;
+    uint32_t dataTransferHandle = 0x11223344;
+
+    int rc = encode_pldm_message_poll_event_data(
+        formatVersion, eventID, dataTransferHandle,
+        reinterpret_cast<uint8_t*>(eventData.data()), eventData.size());
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+
+    rc = pldm_msgbuf_init_cc(buf, PLDM_MSG_POLL_EVENT_LENGTH,
+                             reinterpret_cast<uint8_t*>(eventData.data()),
+                             eventData.size());
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+
+    uint8_t retFormatVersion;
+    uint16_t reteventID;
+    uint32_t retDataTransferHandle;
+
+    EXPECT_EQ(pldm_msgbuf_extract_uint8(buf, &retFormatVersion), PLDM_SUCCESS);
+    EXPECT_EQ(pldm_msgbuf_extract_uint16(buf, &reteventID), PLDM_SUCCESS);
+    EXPECT_EQ(pldm_msgbuf_extract_uint32(buf, &retDataTransferHandle),
+              PLDM_SUCCESS);
+    EXPECT_EQ(retFormatVersion, formatVersion);
+    EXPECT_EQ(reteventID, eventID);
+    EXPECT_EQ(retDataTransferHandle, dataTransferHandle);
+    EXPECT_EQ(pldm_msgbuf_destroy_consumed(buf), PLDM_SUCCESS);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PlatformEventMessage, testBadPldmMsgPollEventDataEncode)
+{
+    std::array<uint8_t, PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION +
+                            PLDM_PLATFORM_EVENT_MESSAGE_EVENT_ID +
+                            PLDM_PLATFORM_EVENT_MESSAGE_TRANFER_HANDLE>
+        eventData{};
+
+    uint8_t formatVersion = 0x01;
+    uint16_t eventID = 0x7788;
+    uint32_t dataTransferHandle = 0x11223344;
+
+    int rc = encode_pldm_message_poll_event_data(
+        formatVersion, eventID, dataTransferHandle, NULL, eventData.size());
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    eventID = 0x0000;
+    rc = encode_pldm_message_poll_event_data(
+        formatVersion, eventID, dataTransferHandle,
+        reinterpret_cast<uint8_t*>(eventData.data()), eventData.size());
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    eventID = 0xffff;
+    rc = encode_pldm_message_poll_event_data(
+        formatVersion, eventID, dataTransferHandle,
+        reinterpret_cast<uint8_t*>(eventData.data()), eventData.size());
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+#endif
+
+TEST(PlatformEventMessage, testGoodSensorOpEventDataDecodeRequest)
+{
+    std::array<uint8_t, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH>
+        eventDataArr{};
+
+    struct pldm_sensor_event_sensor_op_state* sensorData =
+        (struct pldm_sensor_event_sensor_op_state*)eventDataArr.data();
+    uint8_t presentState = PLDM_SENSOR_ENABLED;
+    uint8_t previousState = PLDM_SENSOR_INITIALIZING;
+    sensorData->present_op_state = presentState;
+    sensorData->previous_op_state = previousState;
+
+    uint8_t retPresentState;
+    uint8_t retPreviousState;
+    auto rc = decode_sensor_op_data(reinterpret_cast<uint8_t*>(sensorData),
+                                    eventDataArr.size(), &retPresentState,
+                                    &retPreviousState);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retPresentState, presentState);
+    EXPECT_EQ(retPreviousState, previousState);
+}
+
+TEST(PlatformEventMessage, testBadSensorOpEventDataDecodeRequest)
+{
+    uint8_t presentOpState;
+    uint8_t previousOpState;
+    size_t sensorDataLength = PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH;
+    auto rc = decode_sensor_op_data(NULL, sensorDataLength, &presentOpState,
+                                    &previousOpState);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    std::array<uint8_t, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH>
+        sensorData{};
+    rc = decode_sensor_op_data(reinterpret_cast<uint8_t*>(sensorData.data()),
+                               sensorDataLength + 1, &presentOpState,
+                               &previousOpState);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_sensor_op_data(reinterpret_cast<uint8_t*>(sensorData.data()),
+                               sensorDataLength, nullptr, &previousOpState);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(PlatformEventMessage, testGoodSensorStateEventDataDecodeRequest)
+{
+    std::array<uint8_t, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH>
+        eventDataArr{};
+
+    struct pldm_sensor_event_state_sensor_state* sensorData =
+        (struct pldm_sensor_event_state_sensor_state*)eventDataArr.data();
+    uint8_t sensorOffset = 0x02;
+    uint8_t eventState = PLDM_SENSOR_SHUTTINGDOWN;
+    uint8_t previousEventState = PLDM_SENSOR_INTEST;
+    sensorData->sensor_offset = sensorOffset;
+    sensorData->event_state = eventState;
+    sensorData->previous_event_state = previousEventState;
+
+    uint8_t retSensorOffset;
+    uint8_t retEventState;
+    uint8_t retPreviousState;
+    auto rc = decode_state_sensor_data(reinterpret_cast<uint8_t*>(sensorData),
+                                       eventDataArr.size(), &retSensorOffset,
+                                       &retEventState, &retPreviousState);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retSensorOffset, sensorOffset);
+    EXPECT_EQ(retEventState, eventState);
+    EXPECT_EQ(retPreviousState, previousEventState);
+}
+
+TEST(PlatformEventMessage, testBadStateSensorEventDataDecodeRequest)
+{
+    uint8_t sensorOffset;
+    uint8_t eventState;
+    uint8_t previousEventState;
+    size_t sensorDataLength = PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH;
+    auto rc = decode_state_sensor_data(NULL, sensorDataLength, &sensorOffset,
+                                       &eventState, &previousEventState);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    std::array<uint8_t, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH>
+        sensorData{};
+    rc = decode_state_sensor_data(reinterpret_cast<uint8_t*>(sensorData.data()),
+                                  sensorDataLength - 1, &sensorOffset,
+                                  &eventState, &previousEventState);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_state_sensor_data(reinterpret_cast<uint8_t*>(sensorData.data()),
+                                  sensorDataLength, &sensorOffset, nullptr,
+                                  &previousEventState);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(PlatformEventMessage, testGoodNumericSensorEventDataDecodeRequest)
+{
+    std::array<uint8_t, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH>
+        eventDataArr{};
+    struct pldm_sensor_event_numeric_sensor_state* sensorData =
+        (struct pldm_sensor_event_numeric_sensor_state*)eventDataArr.data();
+
+    size_t sensorDataLength =
+        PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_32BIT_DATA_LENGTH;
+    uint8_t eventState = PLDM_SENSOR_SHUTTINGDOWN;
+    uint8_t previousEventState = PLDM_SENSOR_INTEST;
+    uint8_t sensorDataSize = PLDM_SENSOR_DATA_SIZE_UINT32;
+    uint32_t presentReading = 305441741;
+    sensorData->event_state = eventState;
+    sensorData->previous_event_state = previousEventState;
+    sensorData->sensor_data_size = sensorDataSize;
+    {
+        uint32_t presentReadingLE = htole32(presentReading);
+        memcpy(&sensorData->present_reading, &presentReadingLE,
+               sizeof(presentReadingLE));
+    }
+
+    uint8_t retEventState;
+    uint8_t retPreviousEventState;
+    uint8_t retSensorDataSize;
+    uint32_t retPresentReading;
+
+    auto rc = decode_numeric_sensor_data(
+        reinterpret_cast<uint8_t*>(sensorData), sensorDataLength,
+        &retEventState, &retPreviousEventState, &retSensorDataSize,
+        &retPresentReading);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retEventState, eventState);
+    EXPECT_EQ(retPreviousEventState, previousEventState);
+    EXPECT_EQ(retSensorDataSize, sensorDataSize);
+    EXPECT_EQ(retPresentReading, presentReading);
+
+    int16_t presentReadingNew = -31432;
+    {
+        int16_t presentReadingNewLE = htole16(presentReadingNew);
+        memcpy(&sensorData->present_reading, &presentReadingNewLE,
+               sizeof(presentReadingNewLE));
+    }
+    sensorDataSize = PLDM_SENSOR_DATA_SIZE_SINT16;
+    sensorData->sensor_data_size = sensorDataSize;
+    sensorDataLength = PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_16BIT_DATA_LENGTH;
+
+    rc = decode_numeric_sensor_data(reinterpret_cast<uint8_t*>(sensorData),
+                                    sensorDataLength, &retEventState,
+                                    &retPreviousEventState, &retSensorDataSize,
+                                    &retPresentReading);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retEventState, eventState);
+    EXPECT_EQ(retPreviousEventState, previousEventState);
+    EXPECT_EQ(retSensorDataSize, sensorDataSize);
+    EXPECT_EQ(static_cast<int16_t>(retPresentReading), presentReadingNew);
+}
+
+TEST(PlatformEventMessage, testBadNumericSensorEventDataDecodeRequest)
+{
+    uint8_t eventState;
+    uint8_t previousEventState;
+    uint8_t sensorDataSize;
+    uint32_t presentReading;
+    size_t sensorDataLength =
+        PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH;
+    auto rc = decode_numeric_sensor_data(NULL, sensorDataLength, &eventState,
+                                         &previousEventState, &sensorDataSize,
+                                         &presentReading);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    std::array<uint8_t, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH>
+        sensorData{};
+    rc = decode_numeric_sensor_data(
+        reinterpret_cast<uint8_t*>(sensorData.data()), sensorDataLength - 1,
+        &eventState, &previousEventState, &sensorDataSize, &presentReading);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    struct pldm_sensor_event_numeric_sensor_state* numericSensorData =
+        (struct pldm_sensor_event_numeric_sensor_state*)sensorData.data();
+    numericSensorData->sensor_data_size = PLDM_SENSOR_DATA_SIZE_UINT8;
+    rc = decode_numeric_sensor_data(
+        reinterpret_cast<uint8_t*>(sensorData.data()), sensorDataLength,
+        &eventState, &previousEventState, &sensorDataSize, &presentReading);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    numericSensorData->sensor_data_size = PLDM_SENSOR_DATA_SIZE_UINT16;
+    rc = decode_numeric_sensor_data(
+        reinterpret_cast<uint8_t*>(sensorData.data()), sensorDataLength,
+        &eventState, &previousEventState, &sensorDataSize, &presentReading);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetNumericEffecterValue, testGoodEncodeRequest)
+{
+    std::vector<uint8_t> requestMsg(hdrSize +
+                                    PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES);
+
+    uint16_t effecter_id = 0xab01;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_get_numeric_effecter_value_req(0, effecter_id, request);
+
+    struct pldm_get_numeric_effecter_value_req* req =
+        reinterpret_cast<struct pldm_get_numeric_effecter_value_req*>(
+            request->payload);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(effecter_id, le16toh(req->effecter_id));
+}
+
+TEST(GetNumericEffecterValue, testBadEncodeRequest)
+{
+    std::vector<uint8_t> requestMsg(
+        hdrSize + PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES);
+
+    auto rc = encode_get_numeric_effecter_value_req(0, 0, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetNumericEffecterValue, testGoodDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES>
+        requestMsg{};
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_get_numeric_effecter_value_req* req =
+        reinterpret_cast<struct pldm_get_numeric_effecter_value_req*>(
+            request->payload);
+
+    uint16_t effecter_id = 0x12ab;
+    req->effecter_id = htole16(effecter_id);
+
+    uint16_t reteffecter_id;
+
+    auto rc = decode_get_numeric_effecter_value_req(
+        request, requestMsg.size() - hdrSize, &reteffecter_id);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(effecter_id, reteffecter_id);
+}
+
+TEST(GetNumericEffecterValue, testBadDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES>
+        requestMsg{};
+
+    auto rc = decode_get_numeric_effecter_value_req(
+        nullptr, requestMsg.size() - hdrSize, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_set_numeric_effecter_value_req* req =
+        reinterpret_cast<struct pldm_set_numeric_effecter_value_req*>(
+            request->payload);
+
+    uint16_t effecter_id = 0x1a;
+    req->effecter_id = htole16(effecter_id);
+    uint16_t reteffecter_id;
+
+    rc = decode_get_numeric_effecter_value_req(
+        request, requestMsg.size() - hdrSize - 1, &reteffecter_id);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetNumericEffecterValue, testGoodEncodeResponse)
+{
+    uint8_t completionCode = 0;
+    uint8_t effecter_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT32;
+    uint8_t effecter_operState = EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING;
+    uint32_t pendingValue = 0x12345678;
+    uint32_t presentValue = 0xabcdef11;
+    uint32_t val_pending;
+    uint32_t val_present;
+
+    std::array<uint8_t,
+               hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = encode_get_numeric_effecter_value_resp(
+        0, completionCode, effecter_dataSize, effecter_operState,
+        reinterpret_cast<uint8_t*>(&pendingValue),
+        reinterpret_cast<uint8_t*>(&presentValue), response,
+        responseMsg.size() - hdrSize);
+
+    struct pldm_get_numeric_effecter_value_resp* resp =
+        reinterpret_cast<struct pldm_get_numeric_effecter_value_resp*>(
+            response->payload);
+
+    memcpy(&val_pending, &resp->pending_and_present_values[0],
+           sizeof(val_pending));
+    val_pending = le32toh(val_pending);
+    memcpy(&val_present, &resp->pending_and_present_values[4],
+           sizeof(val_present));
+    val_present = le32toh(val_present);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(effecter_dataSize, resp->effecter_data_size);
+    EXPECT_EQ(effecter_operState, resp->effecter_oper_state);
+    EXPECT_EQ(pendingValue, val_pending);
+    EXPECT_EQ(presentValue, val_present);
+}
+
+TEST(GetNumericEffecterValue, testBadEncodeResponse)
+{
+    std::array<uint8_t,
+               hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    uint8_t pendingValue = 0x01;
+    uint8_t presentValue = 0x02;
+
+    auto rc = encode_get_numeric_effecter_value_resp(
+        0, PLDM_SUCCESS, 0, 0, nullptr, nullptr, nullptr,
+        responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_get_numeric_effecter_value_resp(
+        0, PLDM_SUCCESS, 6, 9, reinterpret_cast<uint8_t*>(&pendingValue),
+        reinterpret_cast<uint8_t*>(&presentValue), response,
+        responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint8_t effecter_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT8;
+    uint8_t effecter_operState = EFFECTER_OPER_STATE_FAILED;
+
+    rc = encode_get_numeric_effecter_value_resp(
+        0, PLDM_SUCCESS, effecter_dataSize, effecter_operState,
+        reinterpret_cast<uint8_t*>(&pendingValue),
+        reinterpret_cast<uint8_t*>(&presentValue), response,
+        responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetNumericEffecterValue, testGoodDecodeResponse)
+{
+    std::array<uint8_t,
+               hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2>
+        responseMsg{};
+
+    uint8_t completionCode = 0;
+    uint8_t effecter_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT16;
+    uint8_t effecter_operState = EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING;
+    uint16_t pendingValue = 0x4321;
+    uint16_t presentValue = 0xdcba;
+
+    uint8_t retcompletionCode;
+    uint8_t reteffecter_dataSize;
+    uint8_t reteffecter_operState;
+    uint8_t retpendingValue[2];
+    uint8_t retpresentValue[2];
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_get_numeric_effecter_value_resp* resp =
+        reinterpret_cast<struct pldm_get_numeric_effecter_value_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->effecter_data_size = effecter_dataSize;
+    resp->effecter_oper_state = effecter_operState;
+
+    uint16_t pendingValue_le = htole16(pendingValue);
+    memcpy(resp->pending_and_present_values, &pendingValue_le,
+           sizeof(pendingValue_le));
+    uint16_t presentValue_le = htole16(presentValue);
+    memcpy(&resp->pending_and_present_values[2], &presentValue_le,
+           sizeof(presentValue_le));
+
+    auto rc = decode_get_numeric_effecter_value_resp(
+        response, responseMsg.size() - hdrSize, &retcompletionCode,
+        &reteffecter_dataSize, &reteffecter_operState, retpendingValue,
+        retpresentValue);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, retcompletionCode);
+    EXPECT_EQ(effecter_dataSize, reteffecter_dataSize);
+    EXPECT_EQ(effecter_operState, reteffecter_operState);
+    EXPECT_EQ(pendingValue, *(reinterpret_cast<uint16_t*>(retpendingValue)));
+    EXPECT_EQ(presentValue, *(reinterpret_cast<uint16_t*>(retpresentValue)));
+}
+
+TEST(GetNumericEffecterValue, testBadDecodeResponse)
+{
+    std::array<uint8_t,
+               hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6>
+        responseMsg{};
+
+    auto rc = decode_get_numeric_effecter_value_resp(
+        nullptr, responseMsg.size() - hdrSize, nullptr, nullptr, nullptr,
+        nullptr, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint8_t completionCode = 0;
+    uint8_t effecter_dataSize = PLDM_EFFECTER_DATA_SIZE_SINT16;
+    uint8_t effecter_operState = EFFECTER_OPER_STATE_DISABLED;
+    uint16_t pendingValue = 0x5678;
+    uint16_t presentValue = 0xcdef;
+
+    uint8_t retcompletionCode;
+    uint8_t reteffecter_dataSize;
+    uint8_t reteffecter_operState;
+    uint8_t retpendingValue[2];
+    uint8_t retpresentValue[2];
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_get_numeric_effecter_value_resp* resp =
+        reinterpret_cast<struct pldm_get_numeric_effecter_value_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->effecter_data_size = effecter_dataSize;
+    resp->effecter_oper_state = effecter_operState;
+
+    uint16_t pendingValue_le = htole16(pendingValue);
+    memcpy(resp->pending_and_present_values, &pendingValue_le,
+           sizeof(pendingValue_le));
+    uint16_t presentValue_le = htole16(presentValue);
+    memcpy(&resp->pending_and_present_values[2], &presentValue_le,
+           sizeof(presentValue_le));
+
+    rc = decode_get_numeric_effecter_value_resp(
+        response, responseMsg.size() - hdrSize, &retcompletionCode,
+        &reteffecter_dataSize, &reteffecter_operState, retpendingValue,
+        retpresentValue);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(PldmPDRRepositoryChgEventEvent, testGoodDecodeRequest)
+{
+    const uint8_t eventDataFormat = FORMAT_IS_PDR_HANDLES;
+    const uint8_t numberOfChangeRecords = 2;
+    uint8_t eventDataOperation1 = PLDM_RECORDS_DELETED;
+    const uint8_t numberOfChangeEntries1 = 2;
+    std::array<uint32_t, numberOfChangeEntries1> changeRecordArr1{
+        {0x00000000, 0x12345678}};
+    uint8_t eventDataOperation2 = PLDM_RECORDS_ADDED;
+    const uint8_t numberOfChangeEntries2 = 5;
+    std::array<uint32_t, numberOfChangeEntries2> changeRecordArr2{
+        {0x01234567, 0x11223344, 0x45678901, 0x21222324, 0x98765432}};
+    std::array<uint8_t, PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
+                            PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH *
+                                numberOfChangeRecords +
+                            (numberOfChangeEntries1 + numberOfChangeEntries2) *
+                                sizeof(uint32_t)>
+        eventDataArr{};
+
+    struct pldm_pdr_repository_chg_event_data* eventData =
+        reinterpret_cast<struct pldm_pdr_repository_chg_event_data*>(
+            eventDataArr.data());
+    eventData->event_data_format = eventDataFormat;
+    eventData->number_of_change_records = numberOfChangeRecords;
+    struct pldm_pdr_repository_change_record_data* changeRecord1 =
+        reinterpret_cast<struct pldm_pdr_repository_change_record_data*>(
+            eventData->change_records);
+    changeRecord1->event_data_operation = eventDataOperation1;
+    changeRecord1->number_of_change_entries = numberOfChangeEntries1;
+    memcpy(changeRecord1->change_entry, &changeRecordArr1[0],
+           changeRecordArr1.size() * sizeof(uint32_t));
+    struct pldm_pdr_repository_change_record_data* changeRecord2 =
+        reinterpret_cast<struct pldm_pdr_repository_change_record_data*>(
+            eventData->change_records +
+            PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
+            (changeRecordArr1.size() * sizeof(uint32_t)));
+    changeRecord2->event_data_operation = eventDataOperation2;
+    changeRecord2->number_of_change_entries = numberOfChangeEntries2;
+    memcpy(changeRecord2->change_entry, &changeRecordArr2[0],
+           changeRecordArr2.size() * sizeof(uint32_t));
+
+    uint8_t retEventDataFormat{};
+    uint8_t retNumberOfChangeRecords{};
+    size_t retChangeRecordDataOffset{0};
+    auto rc = decode_pldm_pdr_repository_chg_event_data(
+        reinterpret_cast<const uint8_t*>(eventData), eventDataArr.size(),
+        &retEventDataFormat, &retNumberOfChangeRecords,
+        &retChangeRecordDataOffset);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retEventDataFormat, FORMAT_IS_PDR_HANDLES);
+    EXPECT_EQ(retNumberOfChangeRecords, numberOfChangeRecords);
+
+    const uint8_t* changeRecordData =
+        reinterpret_cast<const uint8_t*>(changeRecord1);
+    size_t changeRecordDataSize =
+        eventDataArr.size() - PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH;
+    uint8_t retEventDataOperation;
+    uint8_t retNumberOfChangeEntries;
+    size_t retChangeEntryDataOffset;
+
+    rc = decode_pldm_pdr_repository_change_record_data(
+        reinterpret_cast<const uint8_t*>(changeRecordData),
+        changeRecordDataSize, &retEventDataOperation, &retNumberOfChangeEntries,
+        &retChangeEntryDataOffset);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retEventDataOperation, eventDataOperation1);
+    EXPECT_EQ(retNumberOfChangeEntries, numberOfChangeEntries1);
+    changeRecordData += retChangeEntryDataOffset;
+    EXPECT_EQ(0, memcmp(changeRecordData, &changeRecordArr1[0],
+                        sizeof(uint32_t) * retNumberOfChangeEntries));
+
+    changeRecordData += sizeof(uint32_t) * retNumberOfChangeEntries;
+    changeRecordDataSize -= sizeof(uint32_t) * retNumberOfChangeEntries -
+                            PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH;
+    rc = decode_pldm_pdr_repository_change_record_data(
+        reinterpret_cast<const uint8_t*>(changeRecordData),
+        changeRecordDataSize, &retEventDataOperation, &retNumberOfChangeEntries,
+        &retChangeEntryDataOffset);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retEventDataOperation, eventDataOperation2);
+    EXPECT_EQ(retNumberOfChangeEntries, numberOfChangeEntries2);
+    changeRecordData += retChangeEntryDataOffset;
+    EXPECT_EQ(0, memcmp(changeRecordData, &changeRecordArr2[0],
+                        sizeof(uint32_t) * retNumberOfChangeEntries));
+}
+
+TEST(PldmPDRRepositoryChgEventEvent, testBadDecodeRequest)
+{
+    uint8_t eventDataFormat{};
+    uint8_t numberOfChangeRecords{};
+    size_t changeRecordDataOffset{};
+    auto rc = decode_pldm_pdr_repository_chg_event_data(
+        NULL, 0, &eventDataFormat, &numberOfChangeRecords,
+        &changeRecordDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    std::array<uint8_t, 2> eventData{};
+    rc = decode_pldm_pdr_repository_chg_event_data(
+        reinterpret_cast<const uint8_t*>(eventData.data()), 0, &eventDataFormat,
+        &numberOfChangeRecords, &changeRecordDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    uint8_t eventDataOperation{};
+    uint8_t numberOfChangeEntries{};
+    size_t changeEntryDataOffset{};
+    rc = decode_pldm_pdr_repository_change_record_data(
+        NULL, 0, &eventDataOperation, &numberOfChangeEntries,
+        &changeEntryDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    std::array<uint8_t, 2> changeRecord{};
+    rc = decode_pldm_pdr_repository_change_record_data(
+        reinterpret_cast<const uint8_t*>(changeRecord.data()), 0,
+        &eventDataOperation, &numberOfChangeEntries, &changeEntryDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetSensorReading, testGoodEncodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_REQ_BYTES>
+        requestMsg{};
+
+    uint16_t sensorId = 0x1234;
+    bool8_t rearmEventState = 0x01;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto rc =
+        encode_get_sensor_reading_req(0, sensorId, rearmEventState, request);
+
+    struct pldm_get_sensor_reading_req* req =
+        reinterpret_cast<struct pldm_get_sensor_reading_req*>(request->payload);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(sensorId, le16toh(req->sensor_id));
+    EXPECT_EQ(rearmEventState, req->rearm_event_state);
+}
+
+TEST(GetSensorReading, testBadEncodeRequest)
+{
+    auto rc = encode_get_sensor_reading_req(0, 0, 0, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetSensorReading, testGoodDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_REQ_BYTES>
+        requestMsg{};
+
+    uint16_t sensorId = 0xabcd;
+    bool8_t rearmEventState = 0xa;
+
+    uint16_t retsensorId;
+    bool8_t retrearmEventState;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    struct pldm_get_sensor_reading_req* req =
+        reinterpret_cast<struct pldm_get_sensor_reading_req*>(request->payload);
+
+    req->sensor_id = htole16(sensorId);
+    req->rearm_event_state = rearmEventState;
+
+    auto rc =
+        decode_get_sensor_reading_req(request, requestMsg.size() - hdrSize,
+                                      &retsensorId, &retrearmEventState);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(sensorId, retsensorId);
+    EXPECT_EQ(rearmEventState, retrearmEventState);
+}
+
+TEST(GetSensorReading, testBadDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_REQ_BYTES>
+        requestMsg{};
+
+    auto rc = decode_get_sensor_reading_req(
+        nullptr, requestMsg.size() - hdrSize, nullptr, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint16_t sensorId = 0xabcd;
+    bool8_t rearmEventState = 0xa;
+
+    uint16_t retsensorId;
+    bool8_t retrearmEventState;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    struct pldm_get_sensor_reading_req* req =
+        reinterpret_cast<struct pldm_get_sensor_reading_req*>(request->payload);
+
+    req->sensor_id = htole16(sensorId);
+    req->rearm_event_state = rearmEventState;
+
+    rc = decode_get_sensor_reading_req(request, requestMsg.size() - hdrSize - 1,
+                                       &retsensorId, &retrearmEventState);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetSensorReading, testGoodEncodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_MIN_RESP_BYTES>
+        responseMsg{};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    uint8_t completionCode = 0;
+    uint8_t sensor_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT8;
+    uint8_t sensor_operationalState = PLDM_SENSOR_ENABLED;
+    uint8_t sensor_event_messageEnable = PLDM_NO_EVENT_GENERATION;
+    uint8_t presentState = PLDM_SENSOR_NORMAL;
+    uint8_t previousState = PLDM_SENSOR_WARNING;
+    uint8_t eventState = PLDM_SENSOR_UPPERWARNING;
+    uint8_t presentReading = 0x21;
+
+    auto rc = encode_get_sensor_reading_resp(
+        0, completionCode, sensor_dataSize, sensor_operationalState,
+        sensor_event_messageEnable, presentState, previousState, eventState,
+        reinterpret_cast<uint8_t*>(&presentReading), response,
+        responseMsg.size() - hdrSize);
+
+    struct pldm_get_sensor_reading_resp* resp =
+        reinterpret_cast<struct pldm_get_sensor_reading_resp*>(
+            response->payload);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, resp->completion_code);
+    EXPECT_EQ(sensor_dataSize, resp->sensor_data_size);
+    EXPECT_EQ(sensor_operationalState, resp->sensor_operational_state);
+    EXPECT_EQ(sensor_event_messageEnable, resp->sensor_event_message_enable);
+    EXPECT_EQ(presentState, resp->present_state);
+    EXPECT_EQ(previousState, resp->previous_state);
+    EXPECT_EQ(eventState, resp->event_state);
+    EXPECT_EQ(presentReading,
+              *(reinterpret_cast<uint8_t*>(&resp->present_reading[0])));
+}
+
+TEST(GetSensorReading, testBadEncodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3>
+        responseMsg{};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    uint8_t presentReading = 0x1;
+
+    auto rc = encode_get_sensor_reading_resp(0, PLDM_SUCCESS, 0, 0, 0, 0, 0, 0,
+                                             nullptr, nullptr,
+                                             responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_get_sensor_reading_resp(
+        0, PLDM_SUCCESS, 6, 1, 1, 1, 1, 1,
+        reinterpret_cast<uint8_t*>(&presentReading), response,
+        responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint8_t sensor_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT8;
+
+    rc = encode_get_sensor_reading_resp(
+        0, PLDM_SUCCESS, sensor_dataSize, 1, 1, 1, 1, 1,
+        reinterpret_cast<uint8_t*>(&presentReading), response,
+        responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetSensorReading, testGoodDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3>
+        responseMsg{};
+
+    uint8_t completionCode = 0;
+    uint8_t sensor_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT32;
+    uint8_t sensor_operationalState = PLDM_SENSOR_STATUSUNKOWN;
+    uint8_t sensor_event_messageEnable = PLDM_EVENTS_ENABLED;
+    uint8_t presentState = PLDM_SENSOR_CRITICAL;
+    uint8_t previousState = PLDM_SENSOR_UPPERCRITICAL;
+    uint8_t eventState = PLDM_SENSOR_WARNING;
+    uint32_t presentReading = 0xabcdef11;
+
+    uint8_t retcompletionCode;
+    uint8_t retsensor_dataSize = PLDM_SENSOR_DATA_SIZE_UINT32;
+    uint8_t retsensor_operationalState;
+    uint8_t retsensor_event_messageEnable;
+    uint8_t retpresentState;
+    uint8_t retpreviousState;
+    uint8_t reteventState;
+    uint8_t retpresentReading[4];
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_get_sensor_reading_resp* resp =
+        reinterpret_cast<struct pldm_get_sensor_reading_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->sensor_data_size = sensor_dataSize;
+    resp->sensor_operational_state = sensor_operationalState;
+    resp->sensor_event_message_enable = sensor_event_messageEnable;
+    resp->present_state = presentState;
+    resp->previous_state = previousState;
+    resp->event_state = eventState;
+
+    uint32_t presentReading_le = htole32(presentReading);
+    memcpy(resp->present_reading, &presentReading_le,
+           sizeof(presentReading_le));
+
+    auto rc = decode_get_sensor_reading_resp(
+        response, responseMsg.size() - hdrSize, &retcompletionCode,
+        &retsensor_dataSize, &retsensor_operationalState,
+        &retsensor_event_messageEnable, &retpresentState, &retpreviousState,
+        &reteventState, retpresentReading);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, retcompletionCode);
+    EXPECT_EQ(sensor_dataSize, retsensor_dataSize);
+    EXPECT_EQ(sensor_operationalState, retsensor_operationalState);
+    EXPECT_EQ(sensor_event_messageEnable, retsensor_event_messageEnable);
+    EXPECT_EQ(presentState, retpresentState);
+    EXPECT_EQ(previousState, retpreviousState);
+    EXPECT_EQ(eventState, reteventState);
+    EXPECT_EQ(presentReading,
+              *(reinterpret_cast<uint32_t*>(retpresentReading)));
+}
+
+TEST(GetSensorReading, testBadDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1>
+        responseMsg{};
+
+    auto rc = decode_get_sensor_reading_resp(
+        nullptr, responseMsg.size() - hdrSize, nullptr, nullptr, nullptr,
+        nullptr, nullptr, nullptr, nullptr, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint8_t completionCode = 0;
+    uint8_t sensor_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT8;
+    uint8_t sensor_operationalState = PLDM_SENSOR_INTEST;
+    uint8_t sensor_event_messageEnable = PLDM_EVENTS_DISABLED;
+    uint8_t presentState = PLDM_SENSOR_FATAL;
+    uint8_t previousState = PLDM_SENSOR_UPPERFATAL;
+    uint8_t eventState = PLDM_SENSOR_WARNING;
+    uint8_t presentReading = 0xa;
+
+    uint8_t retcompletionCode;
+    uint8_t retsensor_dataSize = PLDM_SENSOR_DATA_SIZE_SINT16;
+    uint8_t retsensor_operationalState;
+    uint8_t retsensor_event_messageEnable;
+    uint8_t retpresent_state;
+    uint8_t retprevious_state;
+    uint8_t retevent_state;
+    uint8_t retpresentReading;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_get_sensor_reading_resp* resp =
+        reinterpret_cast<struct pldm_get_sensor_reading_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->sensor_data_size = sensor_dataSize;
+    resp->sensor_operational_state = sensor_operationalState;
+    resp->sensor_event_message_enable = sensor_event_messageEnable;
+    resp->present_state = presentState;
+    resp->previous_state = previousState;
+    resp->event_state = eventState;
+    resp->present_reading[0] = presentReading;
+
+    rc = decode_get_sensor_reading_resp(
+        response, responseMsg.size() - hdrSize, &retcompletionCode,
+        &retsensor_dataSize, &retsensor_operationalState,
+        &retsensor_event_messageEnable, &retpresent_state, &retprevious_state,
+        &retevent_state, reinterpret_cast<uint8_t*>(&retpresentReading));
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(SetEventReceiver, testGoodEncodeRequest)
+{
+    uint8_t eventMessageGlobalEnable =
+        PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE;
+    uint8_t transportProtocolType = PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP;
+    uint8_t eventReceiverAddressInfo = 0x08;
+    uint16_t heartbeatTimer = 0x78;
+
+    std::vector<uint8_t> requestMsg(hdrSize +
+                                    PLDM_SET_EVENT_RECEIVER_REQ_BYTES);
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_set_event_receiver_req(
+        0, eventMessageGlobalEnable, transportProtocolType,
+        eventReceiverAddressInfo, heartbeatTimer, request);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    struct pldm_set_event_receiver_req* req =
+        reinterpret_cast<struct pldm_set_event_receiver_req*>(request->payload);
+    EXPECT_EQ(eventMessageGlobalEnable, req->event_message_global_enable);
+    EXPECT_EQ(transportProtocolType, req->transport_protocol_type);
+    EXPECT_EQ(eventReceiverAddressInfo, req->event_receiver_address_info);
+    EXPECT_EQ(heartbeatTimer, le16toh(req->heartbeat_timer));
+}
+
+TEST(SetEventReceiver, testBadEncodeRequest)
+{
+    uint8_t eventMessageGlobalEnable =
+        PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE;
+    uint8_t transportProtocolType = PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP;
+    uint8_t eventReceiverAddressInfo = 0x08;
+    uint16_t heartbeatTimer = 0;
+
+    std::vector<uint8_t> requestMsg(hdrSize +
+                                    PLDM_SET_EVENT_RECEIVER_REQ_BYTES);
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_set_event_receiver_req(
+        0, eventMessageGlobalEnable, transportProtocolType,
+        eventReceiverAddressInfo, heartbeatTimer, request);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(SetEventReceiver, testGoodDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_SET_EVENT_RECEIVER_RESP_BYTES>
+        responseMsg{};
+
+    uint8_t retcompletion_code = 0;
+    responseMsg[hdrSize] = PLDM_SUCCESS;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    auto rc = decode_set_event_receiver_resp(
+        response, responseMsg.size() - sizeof(pldm_msg_hdr),
+        &retcompletion_code);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(PLDM_SUCCESS, retcompletion_code);
+}
+
+TEST(SetEventReceiver, testBadDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_SET_EVENT_RECEIVER_RESP_BYTES>
+        responseMsg{};
+    uint8_t retcompletion_code = 0;
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_set_event_receiver_resp(
+        response, responseMsg.size() - sizeof(pldm_msg_hdr), NULL);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_set_event_receiver_resp(
+        nullptr, responseMsg.size() - sizeof(pldm_msg_hdr),
+        &retcompletion_code);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(SetEventReceiver, testGoodEncodeResponse)
+{
+    std::array<uint8_t,
+               sizeof(pldm_msg_hdr) + PLDM_SET_EVENT_RECEIVER_RESP_BYTES>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    uint8_t completionCode = 0;
+
+    auto rc = encode_set_event_receiver_resp(0, PLDM_SUCCESS, response);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, response->payload[0]);
+}
+
+TEST(SetEventReceiver, testBadEncodeResponse)
+{
+    auto rc = encode_set_event_receiver_resp(0, PLDM_SUCCESS, NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(SetEventReceiver, testGoodDecodeRequest)
+{
+
+    std::array<uint8_t, hdrSize + PLDM_SET_EVENT_RECEIVER_REQ_BYTES>
+        requestMsg{};
+
+    uint8_t eventMessageGlobalEnable =
+        PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE;
+    uint8_t transportProtocolType = PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP;
+    uint8_t eventReceiverAddressInfo = 0x08;
+    uint16_t heartbeatTimer = 0x78;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_set_event_receiver_req* req =
+        reinterpret_cast<struct pldm_set_event_receiver_req*>(request->payload);
+
+    req->event_message_global_enable = eventMessageGlobalEnable;
+    req->transport_protocol_type = transportProtocolType;
+    req->event_receiver_address_info = eventReceiverAddressInfo;
+    req->heartbeat_timer = htole16(heartbeatTimer);
+
+    uint8_t reteventMessageGlobalEnable;
+    uint8_t rettransportProtocolType;
+    uint8_t reteventReceiverAddressInfo;
+    uint16_t retheartbeatTimer;
+    auto rc = decode_set_event_receiver_req(
+        request, requestMsg.size() - hdrSize, &reteventMessageGlobalEnable,
+        &rettransportProtocolType, &reteventReceiverAddressInfo,
+        &retheartbeatTimer);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(eventMessageGlobalEnable, reteventMessageGlobalEnable);
+    EXPECT_EQ(transportProtocolType, rettransportProtocolType);
+    EXPECT_EQ(eventReceiverAddressInfo, reteventReceiverAddressInfo);
+    EXPECT_EQ(heartbeatTimer, retheartbeatTimer);
+}
+
+TEST(SetEventReceiver, testBadDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_SET_EVENT_RECEIVER_REQ_BYTES>
+        requestMsg{};
+
+    auto rc = decode_set_event_receiver_req(NULL, requestMsg.size() - hdrSize,
+                                            NULL, NULL, NULL, NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint8_t eventMessageGlobalEnable =
+        PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE;
+    uint8_t transportProtocolType = PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP;
+    uint8_t eventReceiverAddressInfo = 0x08;
+    uint16_t heartbeatTimer = 0x78;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    struct pldm_set_event_receiver_req* req =
+        reinterpret_cast<struct pldm_set_event_receiver_req*>(request->payload);
+
+    req->event_message_global_enable = eventMessageGlobalEnable;
+    req->transport_protocol_type = transportProtocolType;
+    req->event_receiver_address_info = eventReceiverAddressInfo;
+    req->heartbeat_timer = htole16(heartbeatTimer);
+
+    uint8_t reteventMessageGlobalEnable;
+    uint8_t rettransportProtocolType;
+    uint8_t reteventReceiverAddressInfo;
+    uint16_t retheartbeatTimer;
+    rc = decode_set_event_receiver_req(
+        request, requestMsg.size() - hdrSize - 1, &reteventMessageGlobalEnable,
+        &rettransportProtocolType, &reteventReceiverAddressInfo,
+        &retheartbeatTimer);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(decodeNumericSensorPdrData, Uint8Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                     // record handle
+        0x1,                     // PDRHeaderVersion
+        PLDM_NUMERIC_SENSOR_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // sensorID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        1,
+        0,                           // containerID=1
+        PLDM_NO_INIT,                // sensorInit
+        false,                       // sensorAuxiliaryNamesPDR
+        PLDM_SENSOR_UNIT_DEGRESS_C,  // baseUint(2)=degrees C
+        0,                           // unitModifier
+        0,                           // rateUnit
+        0,                           // baseOEMUnitHandle
+        0,                           // auxUnit
+        0,                           // auxUnitModifier
+        0,                           // auxRateUnit
+        0,                           // rel
+        0,                           // auxOEMUnitHandle
+        true,                        // isLinear
+        PLDM_SENSOR_DATA_SIZE_UINT8, // sensorDataSize
+        0,
+        0,
+        0xc0,
+        0x3f, // resolution=1.5
+        0,
+        0,
+        0x80,
+        0x3f, // offset=1.0
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        3, // hysteresis = 3
+        0, // supportedThresholds
+        0, // thresholdAndHysteresisVolatility
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f,                          // updateInverval=1.0
+        255,                           // maxReadable
+        0,                             // minReadable
+        PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
+        0,                             // rangeFieldsupport
+        50,                            // nominalValue = 50
+        60,                            // normalMax = 60
+        40,                            // normalMin = 40
+        70,                            // warningHigh = 70
+        30,                            // warningLow = 30
+        80,                            // criticalHigh = 80
+        20,                            // criticalLow = 20
+        90,                            // fatalHigh = 90
+        10                             // fatalLow = 10
+    };
+
+    struct pldm_numeric_sensor_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_sensor_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+    EXPECT_EQ(1, decodedPdr.hdr.record_handle);
+    EXPECT_EQ(1, decodedPdr.hdr.version);
+    EXPECT_EQ(PLDM_NUMERIC_SENSOR_PDR, decodedPdr.hdr.type);
+    EXPECT_EQ(0, decodedPdr.hdr.record_change_num);
+    EXPECT_EQ(PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH, decodedPdr.hdr.length);
+    EXPECT_EQ(1, decodedPdr.sensor_id);
+    EXPECT_EQ(PLDM_ENTITY_POWER_SUPPLY, decodedPdr.entity_type);
+    EXPECT_EQ(1, decodedPdr.entity_instance_num);
+    EXPECT_EQ(1, decodedPdr.container_id);
+    EXPECT_EQ(PLDM_NO_INIT, decodedPdr.sensor_init);
+    EXPECT_EQ(false, decodedPdr.sensor_auxiliary_names_pdr);
+    EXPECT_EQ(PLDM_SENSOR_UNIT_DEGRESS_C, decodedPdr.base_unit);
+    EXPECT_EQ(0, decodedPdr.unit_modifier);
+    EXPECT_EQ(0, decodedPdr.rate_unit);
+    EXPECT_EQ(0, decodedPdr.base_oem_unit_handle);
+    EXPECT_EQ(0, decodedPdr.aux_unit);
+    EXPECT_EQ(0, decodedPdr.aux_unit_modifier);
+    EXPECT_EQ(0, decodedPdr.aux_rate_unit);
+    EXPECT_EQ(0, decodedPdr.rel);
+    EXPECT_EQ(0, decodedPdr.aux_oem_unit_handle);
+    EXPECT_EQ(true, decodedPdr.is_linear);
+    EXPECT_EQ(PLDM_SENSOR_DATA_SIZE_UINT8, decodedPdr.sensor_data_size);
+    EXPECT_FLOAT_EQ(1.5f, decodedPdr.resolution);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.offset);
+    EXPECT_EQ(0, decodedPdr.accuracy);
+    EXPECT_EQ(0, decodedPdr.plus_tolerance);
+    EXPECT_EQ(0, decodedPdr.minus_tolerance);
+    EXPECT_EQ(3, decodedPdr.hysteresis.value_u8);
+    EXPECT_EQ(0, decodedPdr.supported_thresholds.byte);
+    EXPECT_EQ(0, decodedPdr.threshold_and_hysteresis_volatility.byte);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.state_transition_interval);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.update_interval);
+    EXPECT_EQ(255, decodedPdr.max_readable.value_u8);
+    EXPECT_EQ(0, decodedPdr.min_readable.value_u8);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_UINT8, decodedPdr.range_field_format);
+    EXPECT_EQ(0, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(50, decodedPdr.nominal_value.value_u8);
+    EXPECT_EQ(60, decodedPdr.normal_max.value_u8);
+    EXPECT_EQ(40, decodedPdr.normal_min.value_u8);
+    EXPECT_EQ(70, decodedPdr.warning_high.value_u8);
+    EXPECT_EQ(30, decodedPdr.warning_low.value_u8);
+    EXPECT_EQ(80, decodedPdr.critical_high.value_u8);
+    EXPECT_EQ(20, decodedPdr.critical_low.value_u8);
+    EXPECT_EQ(90, decodedPdr.fatal_high.value_u8);
+    EXPECT_EQ(10, decodedPdr.fatal_low.value_u8);
+}
+
+TEST(decodeNumericSensorPdrData, Sint8Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                     // record handle
+        0x1,                     // PDRHeaderVersion
+        PLDM_NUMERIC_SENSOR_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH +
+            PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // sensorID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0,                           // containerID=1
+        PLDM_NO_INIT,                  // sensorInit
+        false,                         // sensorAuxiliaryNamesPDR
+        PLDM_SENSOR_UNIT_DEGRESS_C,    // baseUint(2)=degrees C
+        0,                             // unitModifier
+        0,                             // rateUnit
+        0,                             // baseOEMUnitHandle
+        0,                             // auxUnit
+        0,                             // auxUnitModifier
+        0,                             // auxRateUnit
+        0,                             // rel
+        0,                             // auxOEMUnitHandle
+        true,                          // isLinear
+        PLDM_RANGE_FIELD_FORMAT_SINT8, // sensorDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        3, // hysteresis = 3
+        0, // supportedThresholds
+        0, // thresholdAndHysteresisVolatility
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f,                          // updateInverval=1.0
+        0x64,                          // maxReadable = 100
+        0x9c,                          // minReadable = -100
+        PLDM_RANGE_FIELD_FORMAT_SINT8, // rangeFieldFormat
+        0,                             // rangeFieldsupport
+        0,                             // nominalValue = 0
+        5,                             // normalMax = 5
+        0xfb,                          // normalMin = -5
+        10,                            // warningHigh = 10
+        0xf6,                          // warningLow = -10
+        20,                            // criticalHigh = 20
+        0xec,                          // criticalLow = -20
+        30,                            // fatalHigh = 30
+        0xe2                           // fatalLow = -30
+    };
+
+    struct pldm_numeric_sensor_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_sensor_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_SENSOR_DATA_SIZE_SINT8, decodedPdr.sensor_data_size);
+    EXPECT_EQ(100, decodedPdr.max_readable.value_s8);
+    EXPECT_EQ(-100, decodedPdr.min_readable.value_s8);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_SINT8, decodedPdr.range_field_format);
+    EXPECT_EQ(0, decodedPdr.nominal_value.value_s8);
+    EXPECT_EQ(5, decodedPdr.normal_max.value_s8);
+    EXPECT_EQ(-5, decodedPdr.normal_min.value_s8);
+    EXPECT_EQ(10, decodedPdr.warning_high.value_s8);
+    EXPECT_EQ(-10, decodedPdr.warning_low.value_s8);
+    EXPECT_EQ(20, decodedPdr.critical_high.value_s8);
+    EXPECT_EQ(-20, decodedPdr.critical_low.value_s8);
+    EXPECT_EQ(30, decodedPdr.fatal_high.value_s8);
+    EXPECT_EQ(-30, decodedPdr.fatal_low.value_s8);
+}
+
+TEST(decodeNumericSensorPdrData, Uint16Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                     // record handle
+        0x1,                     // PDRHeaderVersion
+        PLDM_NUMERIC_SENSOR_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH * 2 +
+            PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 2,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // sensorID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0,                          // containerID=1
+        PLDM_NO_INIT,                 // sensorInit
+        false,                        // sensorAuxiliaryNamesPDR
+        PLDM_SENSOR_UNIT_DEGRESS_C,   // baseUint(2)=degrees C
+        0,                            // unitModifier
+        0,                            // rateUnit
+        0,                            // baseOEMUnitHandle
+        0,                            // auxUnit
+        0,                            // auxUnitModifier
+        0,                            // auxRateUnit
+        0,                            // rel
+        0,                            // auxOEMUnitHandle
+        true,                         // isLinear
+        PLDM_SENSOR_DATA_SIZE_UINT16, // sensorDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        3,
+        0, // hysteresis = 3
+        0, // supportedThresholds
+        0, // thresholdAndHysteresisVolatility
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // updateInverval=1.0
+        0,
+        0x10, // maxReadable = 4096
+        0,
+        0,                              // minReadable = 0
+        PLDM_RANGE_FIELD_FORMAT_UINT16, // rangeFieldFormat
+        0,                              // rangeFieldsupport
+        0x88,
+        0x13, // nominalValue = 5,000
+        0x70,
+        0x17, // normalMax = 6,000
+        0xa0,
+        0x0f, // normalMin = 4,000
+        0x58,
+        0x1b, // warningHigh = 7,000
+        0xb8,
+        0x0b, // warningLow = 3,000
+        0x40,
+        0x1f, // criticalHigh = 8,000
+        0xd0,
+        0x07, // criticalLow = 2,000
+        0x28,
+        0x23, // fatalHigh = 9,000
+        0xe8,
+        0x03 // fatalLow = 1,000
+    };
+
+    struct pldm_numeric_sensor_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_sensor_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_SENSOR_DATA_SIZE_UINT16, decodedPdr.sensor_data_size);
+    EXPECT_EQ(4096, decodedPdr.max_readable.value_u16);
+    EXPECT_EQ(0, decodedPdr.min_readable.value_u16);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_UINT16, decodedPdr.range_field_format);
+    EXPECT_EQ(5000, decodedPdr.nominal_value.value_u16);
+    EXPECT_EQ(6000, decodedPdr.normal_max.value_u16);
+    EXPECT_EQ(4000, decodedPdr.normal_min.value_u16);
+    EXPECT_EQ(7000, decodedPdr.warning_high.value_u16);
+    EXPECT_EQ(3000, decodedPdr.warning_low.value_u16);
+    EXPECT_EQ(8000, decodedPdr.critical_high.value_u16);
+    EXPECT_EQ(2000, decodedPdr.critical_low.value_u16);
+    EXPECT_EQ(9000, decodedPdr.fatal_high.value_u16);
+    EXPECT_EQ(1000, decodedPdr.fatal_low.value_u16);
+}
+
+TEST(decodeNumericSensorPdrData, Sint16Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                     // record handle
+        0x1,                     // PDRHeaderVersion
+        PLDM_NUMERIC_SENSOR_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH * 2 +
+            PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 2,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // sensorID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0,                          // containerID=1
+        PLDM_NO_INIT,                 // sensorInit
+        false,                        // sensorAuxiliaryNamesPDR
+        PLDM_SENSOR_UNIT_DEGRESS_C,   // baseUint(2)=degrees C
+        0,                            // unitModifier
+        0,                            // rateUnit
+        0,                            // baseOEMUnitHandle
+        0,                            // auxUnit
+        0,                            // auxUnitModifier
+        0,                            // auxRateUnit
+        0,                            // rel
+        0,                            // auxOEMUnitHandle
+        true,                         // isLinear
+        PLDM_SENSOR_DATA_SIZE_SINT16, // sensorDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        3,
+        0, // hysteresis
+        0, // supportedThresholds
+        0, // thresholdAndHysteresisVolatility
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // updateInverval=1.0
+        0xe8,
+        0x03, // maxReadable = 1000
+        0x18,
+        0xfc,                           // minReadable = -1000
+        PLDM_RANGE_FIELD_FORMAT_SINT16, // rangeFieldFormat
+        0,                              // rangeFieldsupport
+        0,
+        0, // nominalValue = 0
+        0xf4,
+        0x01, // normalMax = 500
+        0x0c,
+        0xfe, // normalMin = -500
+        0xe8,
+        0x03, // warningHigh = 1,000
+        0x18,
+        0xfc, // warningLow = -1,000
+        0xd0,
+        0x07, // criticalHigh = 2,000
+        0x30,
+        0xf8, // criticalLow = -2,000
+        0xb8,
+        0x0b, // fatalHigh = 3,000
+        0x48,
+        0xf4 // fatalLow = -3,000
+    };
+
+    struct pldm_numeric_sensor_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_sensor_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_SENSOR_DATA_SIZE_SINT16, decodedPdr.sensor_data_size);
+    EXPECT_EQ(1000, decodedPdr.max_readable.value_s16);
+    EXPECT_EQ(-1000, decodedPdr.min_readable.value_s16);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_SINT16, decodedPdr.range_field_format);
+    EXPECT_EQ(0, decodedPdr.nominal_value.value_s16);
+    EXPECT_EQ(500, decodedPdr.normal_max.value_s16);
+    EXPECT_EQ(-500, decodedPdr.normal_min.value_s16);
+    EXPECT_EQ(1000, decodedPdr.warning_high.value_s16);
+    EXPECT_EQ(-1000, decodedPdr.warning_low.value_s16);
+    EXPECT_EQ(2000, decodedPdr.critical_high.value_s16);
+    EXPECT_EQ(-2000, decodedPdr.critical_low.value_s16);
+    EXPECT_EQ(3000, decodedPdr.fatal_high.value_s16);
+    EXPECT_EQ(-3000, decodedPdr.fatal_low.value_s16);
+}
+
+TEST(decodeNumericSensorPdrData, Uint32Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                     // record handle
+        0x1,                     // PDRHeaderVersion
+        PLDM_NUMERIC_SENSOR_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH * 4 +
+            PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 4,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // sensorID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0,                          // containerID=1
+        PLDM_NO_INIT,                 // sensorInit
+        false,                        // sensorAuxiliaryNamesPDR
+        PLDM_SENSOR_UNIT_DEGRESS_C,   // baseUint(2)=degrees C
+        0,                            // unitModifier
+        0,                            // rateUnit
+        0,                            // baseOEMUnitHandle
+        0,                            // auxUnit
+        0,                            // auxUnitModifier
+        0,                            // auxRateUnit
+        0,                            // rel
+        0,                            // auxOEMUnitHandle
+        true,                         // isLinear
+        PLDM_SENSOR_DATA_SIZE_UINT32, // sensorDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        3,
+        0,
+        0,
+        0, // hysteresis
+        0, // supportedThresholds
+        0, // thresholdAndHysteresisVolatility
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // updateInverval=1.0
+        0,
+        0x10,
+        0,
+        0, // maxReadable = 4096
+        0,
+        0,
+        0,
+        0,                              // minReadable = 0
+        PLDM_RANGE_FIELD_FORMAT_UINT32, // rangeFieldFormat
+        0,                              // rangeFieldsupport
+        0x40,
+        0x4b,
+        0x4c,
+        0x00, // nominalValue = 5,000,000
+        0x80,
+        0x8d,
+        0x5b,
+        0x00, // normalMax = 6,000,000
+        0x00,
+        0x09,
+        0x3d,
+        0x00, // normalMin = 4,000,000
+        0xc0,
+        0xcf,
+        0x6a,
+        0x00, // warningHigh = 7,000,000
+        0xc0,
+        0xc6,
+        0x2d,
+        0x00, // warningLow = 3,000,000
+        0x00,
+        0x12,
+        0x7a,
+        0x00, // criticalHigh = 8,000,000
+        0x80,
+        0x84,
+        0x1e,
+        0x00, // criticalLow = 2,000,000
+        0x40,
+        0x54,
+        0x89,
+        0x00, // fatalHigh = 9,000,000
+        0x40,
+        0x42,
+        0x0f,
+        0x00 // fatalLow = 1,000,000
+    };
+
+    struct pldm_numeric_sensor_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_sensor_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_SENSOR_DATA_SIZE_UINT32, decodedPdr.sensor_data_size);
+    EXPECT_EQ(4096, decodedPdr.max_readable.value_u32);
+    EXPECT_EQ(0, decodedPdr.min_readable.value_u32);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_UINT32, decodedPdr.range_field_format);
+    EXPECT_EQ(5000000, decodedPdr.nominal_value.value_u32);
+    EXPECT_EQ(6000000, decodedPdr.normal_max.value_u32);
+    EXPECT_EQ(4000000, decodedPdr.normal_min.value_u32);
+    EXPECT_EQ(7000000, decodedPdr.warning_high.value_u32);
+    EXPECT_EQ(3000000, decodedPdr.warning_low.value_u32);
+    EXPECT_EQ(8000000, decodedPdr.critical_high.value_u32);
+    EXPECT_EQ(2000000, decodedPdr.critical_low.value_u32);
+    EXPECT_EQ(9000000, decodedPdr.fatal_high.value_u32);
+    EXPECT_EQ(1000000, decodedPdr.fatal_low.value_u32);
+}
+
+TEST(decodeNumericSensorPdrData, Sint32Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                     // record handle
+        0x1,                     // PDRHeaderVersion
+        PLDM_NUMERIC_SENSOR_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH * 4 +
+            PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 4,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // sensorID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0,                          // containerID=1
+        PLDM_NO_INIT,                 // sensorInit
+        false,                        // sensorAuxiliaryNamesPDR
+        PLDM_SENSOR_UNIT_DEGRESS_C,   // baseUint(2)=degrees C
+        0,                            // unitModifier
+        0,                            // rateUnit
+        0,                            // baseOEMUnitHandle
+        0,                            // auxUnit
+        0,                            // auxUnitModifier
+        0,                            // auxRateUnit
+        0,                            // rel
+        0,                            // auxOEMUnitHandle
+        true,                         // isLinear
+        PLDM_SENSOR_DATA_SIZE_SINT32, // sensorDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        3,
+        0,
+        0,
+        0, // hysteresis
+        0, // supportedThresholds
+        0, // thresholdAndHysteresisVolatility
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // updateInverval=1.0
+        0xa0,
+        0x86,
+        0x01,
+        0x00, // maxReadable = 100000
+        0x60,
+        0x79,
+        0xfe,
+        0xff,                           // minReadable = -10000
+        PLDM_RANGE_FIELD_FORMAT_SINT32, // rangeFieldFormat
+        0,                              // rangeFieldsupport
+        0,
+        0,
+        0,
+        0, // nominalValue = 0
+        0x20,
+        0xa1,
+        0x07,
+        0x00, // normalMax = 500,000
+        0xe0,
+        0x5e,
+        0xf8,
+        0xff, // normalMin = -500,000
+        0x40,
+        0x42,
+        0x0f,
+        0x00, // warningHigh = 1,000,000
+        0xc0,
+        0xbd,
+        0xf0,
+        0xff, // warningLow = -1,000,000
+        0x80,
+        0x84,
+        0x1e,
+        0x00, // criticalHigh = 2,000,000
+        0x80,
+        0x7b,
+        0xe1,
+        0xff, // criticalLow = -2,000,000
+        0xc0,
+        0xc6,
+        0x2d,
+        0x00, // fatalHigh = 3,000,000
+        0x40,
+        0x39,
+        0xd2,
+        0xff // fatalLow = -3,000,000
+    };
+
+    struct pldm_numeric_sensor_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_sensor_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_SENSOR_DATA_SIZE_SINT32, decodedPdr.sensor_data_size);
+    EXPECT_EQ(100000, decodedPdr.max_readable.value_s32);
+    EXPECT_EQ(-100000, decodedPdr.min_readable.value_s32);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_SINT32, decodedPdr.range_field_format);
+    EXPECT_EQ(0, decodedPdr.nominal_value.value_s32);
+    EXPECT_EQ(500000, decodedPdr.normal_max.value_s32);
+    EXPECT_EQ(-500000, decodedPdr.normal_min.value_s32);
+    EXPECT_EQ(1000000, decodedPdr.warning_high.value_s32);
+    EXPECT_EQ(-1000000, decodedPdr.warning_low.value_s32);
+    EXPECT_EQ(2000000, decodedPdr.critical_high.value_s32);
+    EXPECT_EQ(-2000000, decodedPdr.critical_low.value_s32);
+    EXPECT_EQ(3000000, decodedPdr.fatal_high.value_s32);
+    EXPECT_EQ(-3000000, decodedPdr.fatal_low.value_s32);
+}
+
+TEST(decodeNumericSensorPdrData, Real32Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                     // record handle
+        0x1,                     // PDRHeaderVersion
+        PLDM_NUMERIC_SENSOR_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH * 4 +
+            PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 4,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // sensorID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0,                          // containerID=1
+        PLDM_NO_INIT,                 // sensorInit
+        false,                        // sensorAuxiliaryNamesPDR
+        PLDM_SENSOR_UNIT_DEGRESS_C,   // baseUint(2)=degrees C
+        0,                            // unitModifier
+        0,                            // rateUnit
+        0,                            // baseOEMUnitHandle
+        0,                            // auxUnit
+        0,                            // auxUnitModifier
+        0,                            // auxRateUnit
+        0,                            // rel
+        0,                            // auxOEMUnitHandle
+        true,                         // isLinear
+        PLDM_SENSOR_DATA_SIZE_SINT32, // sensorDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        3,
+        0,
+        0,
+        0, // hysteresis
+        0, // supportedThresholds
+        0, // thresholdAndHysteresisVolatility
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // updateInverval=1.0
+        0xa0,
+        0x86,
+        0x01,
+        0x00, // maxReadable = 100000
+        0x60,
+        0x79,
+        0xfe,
+        0xff,                           // minReadable = -10000
+        PLDM_RANGE_FIELD_FORMAT_REAL32, // rangeFieldFormat
+        0,                              // rangeFieldsupport
+        0,
+        0,
+        0,
+        0, // nominalValue = 0.0
+        0x33,
+        0x33,
+        0x48,
+        0x42, // normalMax = 50.05
+        0x33,
+        0x33,
+        0x48,
+        0xc2, // normalMin = -50.05
+        0x83,
+        0x00,
+        0xc8,
+        0x42, // warningHigh = 100.001
+        0x83,
+        0x00,
+        0xc8,
+        0xc2, // warningLow = -100.001
+        0x83,
+        0x00,
+        0x48,
+        0x43, // criticalHigh = 200.002
+        0x83,
+        0x00,
+        0x48,
+        0xc3, // criticalLow = -200.002
+        0x62,
+        0x00,
+        0x96,
+        0x43, // fatalHigh = 300.003
+        0x62,
+        0x00,
+        0x96,
+        0xc3 // fatalLow = -300.003
+    };
+
+    struct pldm_numeric_sensor_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_sensor_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_SENSOR_DATA_SIZE_SINT32, decodedPdr.sensor_data_size);
+    EXPECT_EQ(100000, decodedPdr.max_readable.value_s32);
+    EXPECT_EQ(-100000, decodedPdr.min_readable.value_s32);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_REAL32, decodedPdr.range_field_format);
+    EXPECT_FLOAT_EQ(0, decodedPdr.nominal_value.value_f32);
+    EXPECT_FLOAT_EQ(50.05f, decodedPdr.normal_max.value_f32);
+    EXPECT_FLOAT_EQ(-50.05f, decodedPdr.normal_min.value_f32);
+    EXPECT_FLOAT_EQ(100.001f, decodedPdr.warning_high.value_f32);
+    EXPECT_FLOAT_EQ(-100.001f, decodedPdr.warning_low.value_f32);
+    EXPECT_FLOAT_EQ(200.002f, decodedPdr.critical_high.value_f32);
+    EXPECT_FLOAT_EQ(-200.002f, decodedPdr.critical_low.value_f32);
+    EXPECT_FLOAT_EQ(300.003f, decodedPdr.fatal_high.value_f32);
+    EXPECT_FLOAT_EQ(-300.003f, decodedPdr.fatal_low.value_f32);
+}
+
+TEST(decodeNumericSensorPdrDataDeathTest, InvalidSizeTest)
+{
+    // A corrupted PDR. The data after plusTolerance missed.
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                     // record handle
+        0x1,                     // PDRHeaderVersion
+        PLDM_NUMERIC_SENSOR_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // sensorID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0,                         // containerID=1
+        PLDM_NO_INIT,                // sensorInit
+        false,                       // sensorAuxiliaryNamesPDR
+        2,                           // baseUint(2)=degrees C
+        0,                           // unitModifier
+        0,                           // rateUnit
+        0,                           // baseOEMUnitHandle
+        0,                           // auxUnit
+        0,                           // auxUnitModifier
+        0,                           // auxRateUnit
+        0,                           // rel
+        0,                           // auxOEMUnitHandle
+        true,                        // isLinear
+        PLDM_SENSOR_DATA_SIZE_UINT8, // sensorDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0  // plusTolerance
+    };
+
+    struct pldm_numeric_sensor_value_pdr decodedPdr;
+    int rc =
+        decode_numeric_sensor_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+#ifdef LIBPLDM_API_TESTING
+TEST(decodeNumericEffecterPdrData, Uint8Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        1,
+        0, // containerID=1
+        0x2,
+        0x0,                           // effecter_semantic_id=2
+        PLDM_NO_INIT,                  // effecterInit
+        false,                         // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,    // baseUint(2)=degrees C
+        0,                             // unitModifier
+        0,                             // rateUnit
+        0,                             // baseOEMUnitHandle
+        0,                             // auxUnit
+        0,                             // auxUnitModifier
+        4,                             // auxRateUnit
+        0,                             // auxOEMUnitHandle
+        true,                          // isLinear
+        PLDM_EFFECTER_DATA_SIZE_UINT8, // effecterDataSize
+        0,
+        0,
+        0xc0,
+        0x3f, // resolution=1.5
+        0,
+        0,
+        0x80,
+        0x3f, // offset=1.0
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f,                          // transition_interval=1.0
+        255,                           // maxSetdable
+        0,                             // minSetable
+        PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
+        0x1f,                          // rangeFieldsupport
+        50,                            // nominalValue = 50
+        60,                            // normalMax = 60
+        40,                            // normalMin = 40
+        90,                            // rated_max = 90
+        10                             // rated_min = 10
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+    EXPECT_EQ(1, decodedPdr.hdr.record_handle);
+    EXPECT_EQ(1, decodedPdr.hdr.version);
+    EXPECT_EQ(PLDM_NUMERIC_EFFECTER_PDR, decodedPdr.hdr.type);
+    EXPECT_EQ(0, decodedPdr.hdr.record_change_num);
+    EXPECT_EQ(PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, decodedPdr.hdr.length);
+    EXPECT_EQ(1, decodedPdr.effecter_id);
+    EXPECT_EQ(PLDM_ENTITY_POWER_SUPPLY, decodedPdr.entity_type);
+    EXPECT_EQ(1, decodedPdr.entity_instance);
+    EXPECT_EQ(1, decodedPdr.container_id);
+    EXPECT_EQ(2, decodedPdr.effecter_semantic_id);
+    EXPECT_EQ(PLDM_NO_INIT, decodedPdr.effecter_init);
+    EXPECT_EQ(false, decodedPdr.effecter_auxiliary_names);
+    EXPECT_EQ(PLDM_SENSOR_UNIT_DEGRESS_C, decodedPdr.base_unit);
+    EXPECT_EQ(0, decodedPdr.unit_modifier);
+    EXPECT_EQ(0, decodedPdr.rate_unit);
+    EXPECT_EQ(0, decodedPdr.base_oem_unit_handle);
+    EXPECT_EQ(0, decodedPdr.aux_unit);
+    EXPECT_EQ(0, decodedPdr.aux_unit_modifier);
+    EXPECT_EQ(4, decodedPdr.aux_rate_unit);
+    EXPECT_EQ(0, decodedPdr.aux_oem_unit_handle);
+    EXPECT_EQ(true, decodedPdr.is_linear);
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_UINT8, decodedPdr.effecter_data_size);
+    EXPECT_FLOAT_EQ(1.5f, decodedPdr.resolution);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.offset);
+    EXPECT_EQ(0, decodedPdr.accuracy);
+    EXPECT_EQ(0, decodedPdr.plus_tolerance);
+    EXPECT_EQ(0, decodedPdr.minus_tolerance);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.state_transition_interval);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.transition_interval);
+    EXPECT_EQ(255, decodedPdr.max_settable.value_u8);
+    EXPECT_EQ(0, decodedPdr.min_settable.value_u8);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_UINT8, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(50, decodedPdr.nominal_value.value_u8);
+    EXPECT_EQ(60, decodedPdr.normal_max.value_u8);
+    EXPECT_EQ(40, decodedPdr.normal_min.value_u8);
+    EXPECT_EQ(90, decodedPdr.rated_max.value_u8);
+    EXPECT_EQ(10, decodedPdr.rated_min.value_u8);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(decodeNumericEffecterPdrData, Sint8Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_EFFECTER_DATA_SIZE_MIN_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_RANGE_FIELD_MIN_LENGTH,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0, // containerID=1
+        0x2,
+        0x0,                           // effecter_semantic_id=2
+        PLDM_NO_INIT,                  // effecterInit
+        false,                         // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,    // baseUint(2)=degrees C
+        0,                             // unitModifier
+        0,                             // rateUnit
+        0,                             // baseOEMUnitHandle
+        0,                             // auxUnit
+        0,                             // auxUnitModifier
+        0,                             // auxRateUnit
+        0,                             // auxOEMUnitHandle
+        true,                          // isLinear
+        PLDM_RANGE_FIELD_FORMAT_SINT8, // effecterDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f,                          // transition_interval=1.0
+        0x64,                          // maxSetdable = 100
+        0x9c,                          // minSetable = -100
+        PLDM_RANGE_FIELD_FORMAT_SINT8, // rangeFieldFormat
+        0x1f,                          // rangeFieldsupport
+        0,                             // nominalValue = 0
+        5,                             // normalMax = 5
+        0xfb,                          // normalMin = -5
+        30,                            // rated_max = 30
+        0xe2                           // rated_min = -30
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_SINT8, decodedPdr.effecter_data_size);
+    EXPECT_EQ(100, decodedPdr.max_settable.value_s8);
+    EXPECT_EQ(-100, decodedPdr.min_settable.value_s8);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_SINT8, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(0, decodedPdr.nominal_value.value_s8);
+    EXPECT_EQ(5, decodedPdr.normal_max.value_s8);
+    EXPECT_EQ(-5, decodedPdr.normal_min.value_s8);
+    EXPECT_EQ(30, decodedPdr.rated_max.value_s8);
+    EXPECT_EQ(-30, decodedPdr.rated_min.value_s8);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(decodeNumericEffecterPdrData, Uint16Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_EFFECTER_DATA_SIZE_MIN_LENGTH *
+                2 +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 2,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0, // containerID=1
+        0x2,
+        0x0,                            // effecter_semantic_id=2
+        PLDM_NO_INIT,                   // effecterInit
+        false,                          // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,     // baseUint(2)=degrees C
+        0,                              // unitModifier
+        0,                              // rateUnit
+        0,                              // baseOEMUnitHandle
+        0,                              // auxUnit
+        0,                              // auxUnitModifier
+        0,                              // auxRateUnit
+        0,                              // auxOEMUnitHandle
+        true,                           // isLinear
+        PLDM_EFFECTER_DATA_SIZE_UINT16, // effecterDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // transition_interval=1.0
+        0,
+        0x10, // maxSetdable = 4096
+        0,
+        0,                              // minSetable = 0
+        PLDM_RANGE_FIELD_FORMAT_UINT16, // rangeFieldFormat
+        0x1f,                           // rangeFieldsupport
+        0x88,
+        0x13, // nominalValue = 5,000
+        0x70,
+        0x17, // normalMax = 6,000
+        0xa0,
+        0x0f, // normalMin = 4,000
+        0x28,
+        0x23, // rated_max = 9,000
+        0xe8,
+        0x03 // rated_min = 1,000
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_UINT16, decodedPdr.effecter_data_size);
+    EXPECT_EQ(4096, decodedPdr.max_settable.value_u16);
+    EXPECT_EQ(0, decodedPdr.min_settable.value_u16);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_UINT16, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(5000, decodedPdr.nominal_value.value_u16);
+    EXPECT_EQ(6000, decodedPdr.normal_max.value_u16);
+    EXPECT_EQ(4000, decodedPdr.normal_min.value_u16);
+    EXPECT_EQ(9000, decodedPdr.rated_max.value_u16);
+    EXPECT_EQ(1000, decodedPdr.rated_min.value_u16);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(decodeNumericEffecterPdrData, Sint16Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_EFFECTER_DATA_SIZE_MIN_LENGTH *
+                2 +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 2,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0, // containerID=1
+        0x2,
+        0x0,                            // effecter_semantic_id=2
+        PLDM_NO_INIT,                   // effecterInit
+        false,                          // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,     // baseUint(2)=degrees C
+        0,                              // unitModifier
+        0,                              // rateUnit
+        0,                              // baseOEMUnitHandle
+        0,                              // auxUnit
+        0,                              // auxUnitModifier
+        0,                              // auxRateUnit
+        0,                              // auxOEMUnitHandle
+        true,                           // isLinear
+        PLDM_EFFECTER_DATA_SIZE_SINT16, // effecterDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // transition_interval=1.0
+        0xe8,
+        0x03, // maxSetdable = 1000
+        0x18,
+        0xfc,                           // minSetable = -1000
+        PLDM_RANGE_FIELD_FORMAT_SINT16, // rangeFieldFormat
+        0x1f,                           // rangeFieldsupport
+        0,
+        0, // nominalValue = 0
+        0xf4,
+        0x01, // normalMax = 500
+        0x0c,
+        0xfe, // normalMin = -500
+        0xb8,
+        0x0b, // rated_max = 3,000
+        0x48,
+        0xf4 // rated_min = -3,000
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_SINT16, decodedPdr.effecter_data_size);
+    EXPECT_EQ(1000, decodedPdr.max_settable.value_s16);
+    EXPECT_EQ(-1000, decodedPdr.min_settable.value_s16);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_SINT16, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(0, decodedPdr.nominal_value.value_s16);
+    EXPECT_EQ(500, decodedPdr.normal_max.value_s16);
+    EXPECT_EQ(-500, decodedPdr.normal_min.value_s16);
+    EXPECT_EQ(3000, decodedPdr.rated_max.value_s16);
+    EXPECT_EQ(-3000, decodedPdr.rated_min.value_s16);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(decodeNumericEffecterPdrData, Uint32Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_EFFECTER_DATA_SIZE_MIN_LENGTH *
+                4 +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 4,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0, // containerID=1
+        0x2,
+        0x0,                            // effecter_semantic_id=2
+        PLDM_NO_INIT,                   // effecterInit
+        false,                          // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,     // baseUint(2)=degrees C
+        0,                              // unitModifier
+        0,                              // rateUnit
+        0,                              // baseOEMUnitHandle
+        0,                              // auxUnit
+        0,                              // auxUnitModifier
+        0,                              // auxRateUnit
+        0,                              // auxOEMUnitHandle
+        true,                           // isLinear
+        PLDM_EFFECTER_DATA_SIZE_UINT32, // effecterDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // transition_interval=1.0
+        0,
+        0x10,
+        0,
+        0, // maxSetdable = 4096
+        0,
+        0,
+        0,
+        0,                              // minSetable = 0
+        PLDM_RANGE_FIELD_FORMAT_UINT32, // rangeFieldFormat
+        0x1f,                           // rangeFieldsupport
+        0x40,
+        0x4b,
+        0x4c,
+        0x00, // nominalValue = 5,000,000
+        0x80,
+        0x8d,
+        0x5b,
+        0x00, // normalMax = 6,000,000
+        0x00,
+        0x09,
+        0x3d,
+        0x00, // normalMin = 4,000,000
+        0x40,
+        0x54,
+        0x89,
+        0x00, // rated_max = 9,000,000
+        0x40,
+        0x42,
+        0x0f,
+        0x00 // rated_min = 1,000,000
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_UINT32, decodedPdr.effecter_data_size);
+    EXPECT_EQ(4096, decodedPdr.max_settable.value_u32);
+    EXPECT_EQ(0, decodedPdr.min_settable.value_u32);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_UINT32, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(5000000, decodedPdr.nominal_value.value_u32);
+    EXPECT_EQ(6000000, decodedPdr.normal_max.value_u32);
+    EXPECT_EQ(4000000, decodedPdr.normal_min.value_u32);
+    EXPECT_EQ(9000000, decodedPdr.rated_max.value_u32);
+    EXPECT_EQ(1000000, decodedPdr.rated_min.value_u32);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(decodeNumericEffecterPdrData, Sint32Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_EFFECTER_DATA_SIZE_MIN_LENGTH *
+                4 +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 4,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0, // containerID=1
+        0x2,
+        0x0,                            // effecter_semantic_id=2
+        PLDM_NO_INIT,                   // effecterInit
+        false,                          // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,     // baseUint(2)=degrees C
+        0,                              // unitModifier
+        0,                              // rateUnit
+        0,                              // baseOEMUnitHandle
+        0,                              // auxUnit
+        0,                              // auxUnitModifier
+        0,                              // auxRateUnit
+        0,                              // auxOEMUnitHandle
+        true,                           // isLinear
+        PLDM_EFFECTER_DATA_SIZE_SINT32, // effecterDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // transition_interval=1.0
+        0xa0,
+        0x86,
+        0x01,
+        0x00, // maxSetdable = 100000
+        0x60,
+        0x79,
+        0xfe,
+        0xff,                           // minSetable = -10000
+        PLDM_RANGE_FIELD_FORMAT_SINT32, // rangeFieldFormat
+        0x1f,                           // rangeFieldsupport
+        0,
+        0,
+        0,
+        0, // nominalValue = 0
+        0x20,
+        0xa1,
+        0x07,
+        0x00, // normalMax = 500,000
+        0xe0,
+        0x5e,
+        0xf8,
+        0xff, // normalMin = -500,000
+        0xc0,
+        0xc6,
+        0x2d,
+        0x00, // rated_max = 3,000,000
+        0x40,
+        0x39,
+        0xd2,
+        0xff // rated_min = -3,000,000
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_SINT32, decodedPdr.effecter_data_size);
+    EXPECT_EQ(100000, decodedPdr.max_settable.value_s32);
+    EXPECT_EQ(-100000, decodedPdr.min_settable.value_s32);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_SINT32, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(0, decodedPdr.nominal_value.value_s32);
+    EXPECT_EQ(500000, decodedPdr.normal_max.value_s32);
+    EXPECT_EQ(-500000, decodedPdr.normal_min.value_s32);
+    EXPECT_EQ(3000000, decodedPdr.rated_max.value_s32);
+    EXPECT_EQ(-3000000, decodedPdr.rated_min.value_s32);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(decodeNumericEffecterPdrData, Real32Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_EFFECTER_DATA_SIZE_MIN_LENGTH *
+                4 +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 4,
+        0, // dataLength
+        0,
+
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0, // containerID=1
+        0x2,
+        0x0,                            // effecter_semantic_id=2
+        PLDM_NO_INIT,                   // effecterInit
+        false,                          // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,     // baseUint(2)=degrees C
+        0,                              // unitModifier
+        0,                              // rateUnit
+        0,                              // baseOEMUnitHandle
+        0,                              // auxUnit
+        0,                              // auxUnitModifier
+        0,                              // auxRateUnit
+        0,                              // auxOEMUnitHandle
+        true,                           // isLinear
+        PLDM_EFFECTER_DATA_SIZE_SINT32, // effecterDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // transition_interval=1.0
+        0xa0,
+        0x86,
+        0x01,
+        0x00, // maxSetdable = 100000
+        0x60,
+        0x79,
+        0xfe,
+        0xff,                           // minSetable = -10000
+        PLDM_RANGE_FIELD_FORMAT_REAL32, // rangeFieldFormat
+        0x1f,                           // rangeFieldsupport
+        0,
+        0,
+        0,
+        0, // nominalValue = 0.0
+        0x33,
+        0x33,
+        0x48,
+        0x42, // normalMax = 50.05
+        0x33,
+        0x33,
+        0x48,
+        0xc2, // normalMin = -50.05
+        0x62,
+        0x00,
+        0x96,
+        0x43, // rated_max = 300.003
+        0x62,
+        0x00,
+        0x96,
+        0xc3 // rated_min = -300.003
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_SINT32, decodedPdr.effecter_data_size);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.state_transition_interval);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.transition_interval);
+    EXPECT_EQ(100000, decodedPdr.max_settable.value_s32);
+    EXPECT_EQ(-100000, decodedPdr.min_settable.value_s32);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_REAL32, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_FLOAT_EQ(0, decodedPdr.nominal_value.value_f32);
+    EXPECT_FLOAT_EQ(50.05f, decodedPdr.normal_max.value_f32);
+    EXPECT_FLOAT_EQ(-50.05f, decodedPdr.normal_min.value_f32);
+    EXPECT_FLOAT_EQ(300.003f, decodedPdr.rated_max.value_f32);
+    EXPECT_FLOAT_EQ(-300.003f, decodedPdr.rated_min.value_f32);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetStateEffecterStates, testEncodeAndDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES>
+        requestMsg{};
+
+    constexpr std::array<uint8_t,
+                         hdrSize + PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES>
+        expectedRequestMsg{
+            {0x80, PLDM_PLATFORM, PLDM_GET_STATE_EFFECTER_STATES, 1, 0xab}};
+
+    constexpr uint16_t effecter_id = 0xab01;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    auto rc = encode_get_state_effecter_states_req(
+        0, effecter_id, request, PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(requestMsg, expectedRequestMsg);
+
+    uint16_t ret_effecter_id;
+
+    rc = decode_get_state_effecter_states_req(
+        request, requestMsg.size() - hdrSize, &ret_effecter_id);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(effecter_id, ret_effecter_id);
+
+    // Test invalid length decode request
+
+    rc = decode_get_state_effecter_states_req(
+        request, requestMsg.size() - hdrSize - 1, &ret_effecter_id);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetStateEffecterStates, testBadEncodeRequest)
+{
+    std::vector<uint8_t> requestMsg(hdrSize +
+                                    PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES);
+
+    auto rc = encode_get_state_effecter_states_req(
+        0, 0, nullptr, PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetStateEffecterStates, testBadDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES>
+        requestMsg{};
+
+    auto rc = decode_get_state_effecter_states_req(
+        nullptr, requestMsg.size() - hdrSize, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetStateEffecterStates, testEncodeAndDecodeResponse)
+{
+    constexpr uint8_t comp_effecterCnt = 0x2;
+    constexpr uint8_t completionCode = 0;
+    std::array<uint8_t,
+               hdrSize + PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES +
+                   PLDM_GET_EFFECTER_STATE_FIELD_SIZE * comp_effecterCnt>
+        expectedResponseMsg{{0, PLDM_PLATFORM, PLDM_GET_STATE_EFFECTER_STATES,
+                             completionCode, comp_effecterCnt,
+                             EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING, 2, 2,
+                             EFFECTER_OPER_STATE_ENABLED_UPDATEPENDING, 2, 3}};
+
+    decltype(expectedResponseMsg) responseMsg{};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    std::array<get_effecter_state_field, comp_effecterCnt> stateField{
+        {{EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING, 2, 2},
+         {EFFECTER_OPER_STATE_ENABLED_UPDATEPENDING, 2, 3}}};
+
+    struct pldm_get_state_effecter_states_resp resp_fields
+    {
+        PLDM_SUCCESS, comp_effecterCnt,
+        {
+            stateField[0], stateField[1]
+        }
+    };
+
+    auto rc = encode_get_state_effecter_states_resp(
+        0, &resp_fields, response, responseMsg.size() - hdrSize);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(expectedResponseMsg, responseMsg);
+
+    struct pldm_get_state_effecter_states_resp ret_resp_fields;
+
+    rc = decode_get_state_effecter_states_resp(
+        response, responseMsg.size() - hdrSize, &ret_resp_fields);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, ret_resp_fields.completion_code);
+    EXPECT_EQ(comp_effecterCnt, ret_resp_fields.comp_effecter_count);
+    EXPECT_EQ(stateField[0].effecter_op_state,
+              ret_resp_fields.field[0].effecter_op_state);
+    EXPECT_EQ(stateField[0].pending_state,
+              ret_resp_fields.field[0].pending_state);
+    EXPECT_EQ(stateField[0].present_state,
+              ret_resp_fields.field[0].present_state);
+    EXPECT_EQ(stateField[1].effecter_op_state,
+              ret_resp_fields.field[1].effecter_op_state);
+    EXPECT_EQ(stateField[1].pending_state,
+              ret_resp_fields.field[1].pending_state);
+    EXPECT_EQ(stateField[1].present_state,
+              ret_resp_fields.field[1].present_state);
+
+    // Test invalid length decode
+
+    rc = decode_get_state_effecter_states_resp(
+        response,
+        responseMsg.size() - hdrSize + PLDM_GET_EFFECTER_STATE_FIELD_SIZE,
+        &ret_resp_fields);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetStateEffecterStates, testBadEncodeResponse)
+{
+    struct pldm_get_state_effecter_states_resp resp
+    {
+        PLDM_SUCCESS, 0,
+        {
+        }
+    };
+    auto rc = decode_get_state_effecter_states_resp(nullptr, 0, &resp);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetStateEffecterStates, testBadDecodeResponse)
+{
+    std::array<uint8_t, hdrSize +
+                            PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES +
+                            PLDM_GET_EFFECTER_STATE_FIELD_SIZE * 2>
+        responseMsg{};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    auto rc = decode_get_state_effecter_states_resp(
+        response, responseMsg.size() - hdrSize, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+#endif