#include "ipmi.hpp" #include "manager_mock.hpp" #include #include namespace blobs { using ::testing::_; using ::testing::Invoke; using ::testing::Matcher; using ::testing::NotNull; using ::testing::Return; // ipmid.hpp isn't installed where we can grab it and this value is per BMC // SoC. #define MAX_IPMI_BUFFER 64 TEST(BlobSessionStatTest, RequestRejectedByManagerReturnsFailure) { // If the session ID is invalid, the request must fail. ManagerMock mgr; size_t dataLen; uint8_t request[MAX_IPMI_BUFFER] = {0}; uint8_t reply[MAX_IPMI_BUFFER] = {0}; auto req = reinterpret_cast(request); req->cmd = BlobOEMCommands::bmcBlobSessionStat; req->crc = 0; req->sessionId = 0x54; dataLen = sizeof(struct BmcBlobSessionStatTx); EXPECT_CALL(mgr, stat(Matcher(req->sessionId), Matcher(_))) .WillOnce(Return(false)); EXPECT_EQ(IPMI_CC_INVALID, sessionStatBlob(&mgr, request, reply, &dataLen)); } TEST(BlobSessionStatTest, RequestSucceedsNoMetadata) { // Stat request succeeeds but there were no metadata bytes. ManagerMock mgr; size_t dataLen; uint8_t request[MAX_IPMI_BUFFER] = {0}; uint8_t reply[MAX_IPMI_BUFFER] = {0}; auto req = reinterpret_cast(request); req->cmd = BlobOEMCommands::bmcBlobSessionStat; req->crc = 0; req->sessionId = 0x54; dataLen = sizeof(struct BmcBlobSessionStatTx); struct BmcBlobStatRx rep; rep.crc = 0x00; rep.blobState = 0x01; rep.size = 0x100; rep.metadataLen = 0x00; EXPECT_CALL(mgr, stat(Matcher(req->sessionId), Matcher(NotNull()))) .WillOnce(Invoke([&](uint16_t session, struct BlobMeta* meta) { meta->blobState = rep.blobState; meta->size = rep.size; return true; })); EXPECT_EQ(IPMI_CC_OK, sessionStatBlob(&mgr, request, reply, &dataLen)); EXPECT_EQ(sizeof(rep), dataLen); EXPECT_EQ(0, std::memcmp(reply, &rep, sizeof(rep))); } TEST(BlobSessionStatTest, RequestSucceedsWithMetadata) { // Stat request succeeds and there were metadata bytes. ManagerMock mgr; size_t dataLen; uint8_t request[MAX_IPMI_BUFFER] = {0}; uint8_t reply[MAX_IPMI_BUFFER] = {0}; auto req = reinterpret_cast(request); req->cmd = BlobOEMCommands::bmcBlobSessionStat; req->crc = 0; req->sessionId = 0x54; dataLen = sizeof(struct BmcBlobSessionStatTx); struct BlobMeta lmeta; lmeta.blobState = 0x01; lmeta.size = 0x100; lmeta.metadata.push_back(0x01); lmeta.metadata.push_back(0x02); lmeta.metadata.push_back(0x03); lmeta.metadata.push_back(0x04); struct BmcBlobStatRx rep; rep.crc = 0x00; rep.blobState = lmeta.blobState; rep.size = lmeta.size; rep.metadataLen = lmeta.metadata.size(); EXPECT_CALL(mgr, stat(Matcher(req->sessionId), Matcher(NotNull()))) .WillOnce(Invoke([&](uint16_t session, struct BlobMeta* meta) { (*meta) = lmeta; return true; })); EXPECT_EQ(IPMI_CC_OK, sessionStatBlob(&mgr, request, reply, &dataLen)); EXPECT_EQ(sizeof(rep) + lmeta.metadata.size(), dataLen); EXPECT_EQ(0, std::memcmp(reply, &rep, sizeof(rep))); EXPECT_EQ(0, std::memcmp(reply + sizeof(rep), lmeta.metadata.data(), lmeta.metadata.size())); } } // namespace blobs