blob: d4b9c5866d85499af7699e62a6f79f4b50150e83 [file] [log] [blame]
#include "ipmi.hpp"
#include "manager_mock.hpp"
#include <cstring>
#include <gtest/gtest.h>
namespace blobs
{
using ::testing::_;
using ::testing::ElementsAreArray;
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(BlobCommitTest, InvalidCommitDataLengthReturnsFailure)
{
// The commit command supports an optional commit blob. This test verifies
// we sanity check the length of that blob.
ManagerMock mgr;
size_t dataLen;
uint8_t request[MAX_IPMI_BUFFER] = {0};
uint8_t reply[MAX_IPMI_BUFFER] = {0};
auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request);
req->cmd = static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobCommit);
req->crc = 0;
req->sessionId = 0x54;
req->commitDataLen =
1; // It's one byte, but that's more than the packet size.
dataLen = sizeof(struct BmcBlobCommitTx);
EXPECT_EQ(IPMI_CC_REQ_DATA_LEN_INVALID,
commitBlob(&mgr, request, reply, &dataLen));
}
TEST(BlobCommitTest, ValidCommitNoDataHandlerRejectsReturnsFailure)
{
// The commit packet is valid and the manager's commit call returns failure.
ManagerMock mgr;
size_t dataLen;
uint8_t request[MAX_IPMI_BUFFER] = {0};
uint8_t reply[MAX_IPMI_BUFFER] = {0};
auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request);
req->cmd = static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobCommit);
req->crc = 0;
req->sessionId = 0x54;
req->commitDataLen = 0;
dataLen = sizeof(struct BmcBlobCommitTx);
EXPECT_CALL(mgr, commit(req->sessionId, _)).WillOnce(Return(false));
EXPECT_EQ(IPMI_CC_UNSPECIFIED_ERROR,
commitBlob(&mgr, request, reply, &dataLen));
}
TEST(BlobCommitTest, ValidCommitNoDataHandlerAcceptsReturnsSuccess)
{
// Commit called with no data and everything returns success.
ManagerMock mgr;
size_t dataLen;
uint8_t request[MAX_IPMI_BUFFER] = {0};
uint8_t reply[MAX_IPMI_BUFFER] = {0};
auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request);
req->cmd = static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobCommit);
req->crc = 0;
req->sessionId = 0x54;
req->commitDataLen = 0;
dataLen = sizeof(struct BmcBlobCommitTx);
EXPECT_CALL(mgr, commit(req->sessionId, _)).WillOnce(Return(true));
EXPECT_EQ(IPMI_CC_OK, commitBlob(&mgr, request, reply, &dataLen));
}
TEST(BlobCommitTest, ValidCommitWithDataHandlerAcceptsReturnsSuccess)
{
// Commit called with extra data and everything returns success.
ManagerMock mgr;
size_t dataLen;
uint8_t request[MAX_IPMI_BUFFER] = {0};
uint8_t reply[MAX_IPMI_BUFFER] = {0};
auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request);
uint8_t expectedBlob[4] = {0x25, 0x33, 0x45, 0x67};
req->cmd = static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobCommit);
req->crc = 0;
req->sessionId = 0x54;
req->commitDataLen = sizeof(expectedBlob);
std::memcpy(req + 1, &expectedBlob[0], sizeof(expectedBlob));
dataLen = sizeof(struct BmcBlobCommitTx) + sizeof(expectedBlob);
EXPECT_CALL(mgr,
commit(req->sessionId,
ElementsAreArray(expectedBlob, sizeof(expectedBlob))))
.WillOnce(Return(true));
EXPECT_EQ(IPMI_CC_OK, commitBlob(&mgr, request, reply, &dataLen));
}
} // namespace blobs