blob: aab3a762117d74f14023eb45c578c86b5767f1a5 [file] [log] [blame]
#include "helper.hpp"
#include "ipmi.hpp"
#include "manager_mock.hpp"
#include <cstring>
#include <string>
#include <gtest/gtest.h>
namespace blobs
{
using ::testing::_;
using ::testing::Invoke;
using ::testing::Matcher;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::StrEq;
// ipmid.hpp isn't installed where we can grab it and this value is per BMC
// SoC.
#define MAX_IPMI_BUFFER 64
TEST(BlobStatTest, InvalidRequestLengthReturnsFailure)
{
// There is a minimum blobId length of one character, this test verifies
// we check that.
ManagerMock mgr;
std::vector<uint8_t> request;
struct BmcBlobStatTx req;
std::string blobId = "abc";
req.crc = 0;
request.resize(sizeof(struct BmcBlobStatTx));
std::memcpy(request.data(), &req, sizeof(struct BmcBlobStatTx));
// Do not include the nul-terminator
request.insert(request.end(), blobId.begin(), blobId.end());
EXPECT_EQ(ipmi::responseReqDataLenInvalid(), statBlob(&mgr, request));
}
TEST(BlobStatTest, RequestRejectedReturnsFailure)
{
// The blobId is rejected for any reason.
ManagerMock mgr;
std::vector<uint8_t> request;
struct BmcBlobStatTx req;
std::string blobId = "a";
req.crc = 0;
request.resize(sizeof(struct BmcBlobStatTx));
std::memcpy(request.data(), &req, sizeof(struct BmcBlobStatTx));
request.insert(request.end(), blobId.begin(), blobId.end());
request.emplace_back('\0');
EXPECT_CALL(mgr, stat(Matcher<const std::string&>(StrEq(blobId)),
Matcher<BlobMeta*>(_)))
.WillOnce(Return(false));
EXPECT_EQ(ipmi::responseUnspecifiedError(), statBlob(&mgr, request));
}
TEST(BlobStatTest, RequestSucceedsNoMetadata)
{
// Stat request succeeeds but there were no metadata bytes.
ManagerMock mgr;
std::vector<uint8_t> request;
struct BmcBlobStatTx req;
std::string blobId = "a";
req.crc = 0;
request.resize(sizeof(struct BmcBlobStatTx));
std::memcpy(request.data(), &req, sizeof(struct BmcBlobStatTx));
request.insert(request.end(), blobId.begin(), blobId.end());
request.emplace_back('\0');
struct BmcBlobStatRx rep;
rep.crc = 0x00;
rep.blobState = 0x01;
rep.size = 0x100;
rep.metadataLen = 0x00;
uint16_t blobState = rep.blobState;
uint32_t size = rep.size;
EXPECT_CALL(mgr, stat(Matcher<const std::string&>(StrEq(blobId)),
Matcher<BlobMeta*>(NotNull())))
.WillOnce(Invoke([&](const std::string&, BlobMeta* meta) {
meta->blobState = blobState;
meta->size = size;
return true;
}));
auto result = validateReply(statBlob(&mgr, request));
EXPECT_EQ(sizeof(rep), result.size());
EXPECT_EQ(0, std::memcmp(result.data(), &rep, sizeof(rep)));
}
TEST(BlobStatTest, RequestSucceedsWithMetadata)
{
// Stat request succeeds and there were metadata bytes.
ManagerMock mgr;
std::vector<uint8_t> request;
struct BmcBlobStatTx req;
std::string blobId = "a";
req.crc = 0;
request.resize(sizeof(struct BmcBlobStatTx));
std::memcpy(request.data(), &req, sizeof(struct BmcBlobStatTx));
request.insert(request.end(), blobId.begin(), blobId.end());
request.emplace_back('\0');
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<const std::string&>(StrEq(blobId)),
Matcher<BlobMeta*>(NotNull())))
.WillOnce(Invoke([&](const std::string&, BlobMeta* meta) {
(*meta) = lmeta;
return true;
}));
auto result = validateReply(statBlob(&mgr, request));
EXPECT_EQ(sizeof(rep) + lmeta.metadata.size(), result.size());
EXPECT_EQ(0, std::memcmp(result.data(), &rep, sizeof(rep)));
EXPECT_EQ(0, std::memcmp(result.data() + sizeof(rep), lmeta.metadata.data(),
lmeta.metadata.size()));
}
} // namespace blobs