blob: 6bf515d33b3b01f5705e61042cf78d715a4f78c8 [file] [log] [blame]
#pragma once
#include "data_mock.hpp"
#include "firmware_handler.hpp"
#include "flags.hpp"
#include "image_mock.hpp"
#include "triggerable_mock.hpp"
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace ipmi_flash
{
namespace
{
using ::testing::Return;
class IpmiOnlyFirmwareStaticTest : public ::testing::Test
{
protected:
void SetUp() override
{
/* Unfortunately, since the FirmwareHandler object ends up owning the
* handlers, we can't just share handlers.
*/
std::unique_ptr<ImageHandlerInterface> image =
std::make_unique<ImageHandlerMock>();
hashImageMock = reinterpret_cast<ImageHandlerMock*>(image.get());
blobs.push_back(std::move(HandlerPack(hashBlobId, std::move(image))));
image = std::make_unique<ImageHandlerMock>();
imageMock2 = reinterpret_cast<ImageHandlerMock*>(image.get());
blobs.push_back(
std::move(HandlerPack(staticLayoutBlobId, std::move(image))));
std::unique_ptr<TriggerableActionInterface> prepareMock =
std::make_unique<TriggerMock>();
prepareMockPtr = reinterpret_cast<TriggerMock*>(prepareMock.get());
std::unique_ptr<TriggerableActionInterface> verifyMock =
std::make_unique<TriggerMock>();
verifyMockPtr = reinterpret_cast<TriggerMock*>(verifyMock.get());
std::unique_ptr<TriggerableActionInterface> updateMock =
std::make_unique<TriggerMock>();
updateMockPtr = reinterpret_cast<TriggerMock*>(updateMock.get());
std::unique_ptr<ActionPack> actionPack = std::make_unique<ActionPack>();
actionPack->preparation = std::move(prepareMock);
actionPack->verification = std::move(verifyMock);
actionPack->update = std::move(updateMock);
ActionMap packs;
packs[staticLayoutBlobId] = std::move(actionPack);
handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(
std::move(blobs), data, std::move(packs));
}
void expectedState(FirmwareBlobHandler::UpdateState state)
{
auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
EXPECT_EQ(state, realHandler->getCurrentState());
}
void openToInProgress(const std::string& blobId)
{
if (blobId == hashBlobId)
{
EXPECT_CALL(*hashImageMock, open(blobId)).WillOnce(Return(true));
}
else
{
EXPECT_CALL(*imageMock2, open(blobId)).WillOnce(Return(true));
}
if (blobId != hashBlobId)
{
EXPECT_CALL(*prepareMockPtr, trigger()).WillOnce(Return(true));
}
EXPECT_TRUE(handler->open(session, flags, blobId));
expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
}
void getToVerificationPending(const std::string& blobId)
{
openToInProgress(blobId);
if (blobId == hashBlobId)
{
EXPECT_CALL(*hashImageMock, close()).WillRepeatedly(Return());
}
else
{
EXPECT_CALL(*imageMock2, close()).WillRepeatedly(Return());
}
handler->close(session);
expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
}
void getToVerificationStarted(const std::string& blobId)
{
getToVerificationPending(blobId);
EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
EXPECT_CALL(*verifyMockPtr, trigger()).WillOnce(Return(true));
EXPECT_TRUE(handler->commit(session, {}));
expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);
}
void getToVerificationStartedWitHashBlob()
{
/* Open both static and hash to check for activeHashBlobId. */
getToVerificationPending(staticLayoutBlobId);
openToInProgress(hashBlobId);
EXPECT_CALL(*hashImageMock, close()).WillRepeatedly(Return());
handler->close(session);
expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
/* Now the hash is active AND the static image is active. */
EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
EXPECT_CALL(*verifyMockPtr, trigger()).WillOnce(Return(true));
EXPECT_TRUE(handler->commit(session, {}));
expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);
}
void getToVerificationCompleted(ActionStatus checkResponse)
{
getToVerificationStarted(staticLayoutBlobId);
EXPECT_CALL(*verifyMockPtr, status()).WillOnce(Return(checkResponse));
blobs::BlobMeta meta;
EXPECT_TRUE(handler->stat(session, &meta));
expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
}
void getToUpdatePending()
{
getToVerificationCompleted(ActionStatus::success);
handler->close(session);
expectedState(FirmwareBlobHandler::UpdateState::updatePending);
}
void getToUpdateStarted()
{
getToUpdatePending();
EXPECT_TRUE(handler->open(session, flags, updateBlobId));
EXPECT_CALL(*updateMockPtr, trigger()).WillOnce(Return(true));
EXPECT_TRUE(handler->commit(session, {}));
expectedState(FirmwareBlobHandler::UpdateState::updateStarted);
}
void getToUpdateCompleted(ActionStatus result)
{
getToUpdateStarted();
EXPECT_CALL(*updateMockPtr, status()).WillOnce(Return(result));
blobs::BlobMeta meta;
EXPECT_TRUE(handler->stat(session, &meta));
expectedState(FirmwareBlobHandler::UpdateState::updateCompleted);
}
ImageHandlerMock *hashImageMock, *imageMock2;
std::vector<HandlerPack> blobs;
std::vector<DataHandlerPack> data = {
{FirmwareFlags::UpdateFlags::ipmi, nullptr}};
std::unique_ptr<blobs::GenericBlobInterface> handler;
TriggerMock* prepareMockPtr;
TriggerMock* verifyMockPtr;
TriggerMock* updateMockPtr;
std::uint16_t session = 1;
std::uint16_t flags =
blobs::OpenFlags::write | FirmwareFlags::UpdateFlags::ipmi;
std::vector<std::string> startingBlobs = {staticLayoutBlobId, hashBlobId};
};
class IpmiOnlyFirmwareTest : public ::testing::Test
{
protected:
ImageHandlerMock *hashImageMock, *imageMock;
std::vector<HandlerPack> blobs;
std::vector<DataHandlerPack> data = {
{FirmwareFlags::UpdateFlags::ipmi, nullptr}};
std::unique_ptr<blobs::GenericBlobInterface> handler;
void SetUp() override
{
std::unique_ptr<ImageHandlerInterface> image =
std::make_unique<ImageHandlerMock>();
hashImageMock = reinterpret_cast<ImageHandlerMock*>(image.get());
blobs.push_back(std::move(HandlerPack(hashBlobId, std::move(image))));
image = std::make_unique<ImageHandlerMock>();
imageMock = reinterpret_cast<ImageHandlerMock*>(image.get());
blobs.push_back(std::move(HandlerPack("asdf", std::move(image))));
handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(
std::move(blobs), data, std::move(CreateActionMap("asdf")));
}
};
class FakeLpcFirmwareTest : public ::testing::Test
{
protected:
DataHandlerMock dataMock;
ImageHandlerMock *hashImageMock, *imageMock;
std::vector<HandlerPack> blobs;
std::vector<DataHandlerPack> data;
std::unique_ptr<blobs::GenericBlobInterface> handler;
void SetUp() override
{
std::unique_ptr<ImageHandlerInterface> image =
std::make_unique<ImageHandlerMock>();
hashImageMock = reinterpret_cast<ImageHandlerMock*>(image.get());
blobs.push_back(std::move(HandlerPack(hashBlobId, std::move(image))));
image = std::make_unique<ImageHandlerMock>();
imageMock = reinterpret_cast<ImageHandlerMock*>(image.get());
blobs.push_back(std::move(HandlerPack("asdf", std::move(image))));
data = {
{FirmwareFlags::UpdateFlags::ipmi, nullptr},
{FirmwareFlags::UpdateFlags::lpc, &dataMock},
};
handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(
std::move(blobs), data, std::move(CreateActionMap("asdf")));
}
};
} // namespace
} // namespace ipmi_flash