1ded66d0fSJason Ling #pragma once 2ded66d0fSJason Ling 384bff8beSJason Ling #include "create_action_map.hpp" 4ded66d0fSJason Ling #include "data_mock.hpp" 5ded66d0fSJason Ling #include "firmware_handler.hpp" 6ded66d0fSJason Ling #include "flags.hpp" 7ded66d0fSJason Ling #include "image_mock.hpp" 8ded66d0fSJason Ling #include "triggerable_mock.hpp" 9ded66d0fSJason Ling #include "util.hpp" 10ded66d0fSJason Ling 11ded66d0fSJason Ling #include <memory> 12ded66d0fSJason Ling #include <string> 13ded66d0fSJason Ling #include <unordered_map> 14ded66d0fSJason Ling #include <vector> 15ded66d0fSJason Ling 16ded66d0fSJason Ling #include <gmock/gmock.h> 17ded66d0fSJason Ling #include <gtest/gtest.h> 18ded66d0fSJason Ling 19ded66d0fSJason Ling namespace ipmi_flash 20ded66d0fSJason Ling { 21ded66d0fSJason Ling namespace 22ded66d0fSJason Ling { 23ded66d0fSJason Ling 24ded66d0fSJason Ling using ::testing::Return; 25ded66d0fSJason Ling 26ded66d0fSJason Ling class IpmiOnlyFirmwareStaticTest : public ::testing::Test 27ded66d0fSJason Ling { 28ded66d0fSJason Ling protected: SetUp()29ded66d0fSJason Ling void SetUp() override 30ded66d0fSJason Ling { 31ded66d0fSJason Ling /* Unfortunately, since the FirmwareHandler object ends up owning the 32ded66d0fSJason Ling * handlers, we can't just share handlers. 33ded66d0fSJason Ling */ 34ded66d0fSJason Ling std::unique_ptr<ImageHandlerInterface> image = 35ded66d0fSJason Ling std::make_unique<ImageHandlerMock>(); 36ded66d0fSJason Ling hashImageMock = reinterpret_cast<ImageHandlerMock*>(image.get()); 37ded66d0fSJason Ling blobs.emplace_back(hashBlobId, std::move(image)); 38ded66d0fSJason Ling 39ded66d0fSJason Ling image = std::make_unique<ImageHandlerMock>(); 40ded66d0fSJason Ling imageMock2 = reinterpret_cast<ImageHandlerMock*>(image.get()); 41ded66d0fSJason Ling blobs.emplace_back(staticLayoutBlobId, std::move(image)); 42ded66d0fSJason Ling 43ded66d0fSJason Ling std::unique_ptr<TriggerableActionInterface> prepareMock = 44ded66d0fSJason Ling std::make_unique<TriggerMock>(); 45ded66d0fSJason Ling prepareMockPtr = reinterpret_cast<TriggerMock*>(prepareMock.get()); 46ded66d0fSJason Ling 47ded66d0fSJason Ling std::unique_ptr<TriggerableActionInterface> verifyMock = 48ded66d0fSJason Ling std::make_unique<TriggerMock>(); 49ded66d0fSJason Ling verifyMockPtr = reinterpret_cast<TriggerMock*>(verifyMock.get()); 50ded66d0fSJason Ling 51ded66d0fSJason Ling std::unique_ptr<TriggerableActionInterface> updateMock = 52ded66d0fSJason Ling std::make_unique<TriggerMock>(); 53ded66d0fSJason Ling updateMockPtr = reinterpret_cast<TriggerMock*>(updateMock.get()); 54ded66d0fSJason Ling 55ded66d0fSJason Ling std::unique_ptr<ActionPack> actionPack = std::make_unique<ActionPack>(); 56ded66d0fSJason Ling actionPack->preparation = std::move(prepareMock); 57ded66d0fSJason Ling actionPack->verification = std::move(verifyMock); 58ded66d0fSJason Ling actionPack->update = std::move(updateMock); 59ded66d0fSJason Ling 60ded66d0fSJason Ling ActionMap packs; 61ded66d0fSJason Ling packs[staticLayoutBlobId] = std::move(actionPack); 62ded66d0fSJason Ling 63ded66d0fSJason Ling std::vector<DataHandlerPack> data; 64ded66d0fSJason Ling data.emplace_back(FirmwareFlags::UpdateFlags::ipmi, nullptr); 65ded66d0fSJason Ling 66ded66d0fSJason Ling handler = FirmwareBlobHandler::CreateFirmwareBlobHandler( 67ded66d0fSJason Ling std::move(blobs), std::move(data), std::move(packs)); 68ded66d0fSJason Ling } 69ded66d0fSJason Ling expectedState(FirmwareBlobHandler::UpdateState state)70ded66d0fSJason Ling void expectedState(FirmwareBlobHandler::UpdateState state) 71ded66d0fSJason Ling { 72ded66d0fSJason Ling auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get()); 73ded66d0fSJason Ling EXPECT_EQ(state, realHandler->getCurrentState()); 74ded66d0fSJason Ling } 75ded66d0fSJason Ling openToInProgress(const std::string & blobId)76ded66d0fSJason Ling void openToInProgress(const std::string& blobId) 77ded66d0fSJason Ling { 78ded66d0fSJason Ling if (blobId == hashBlobId) 79ded66d0fSJason Ling { 8056a2273fSJason Ling EXPECT_CALL(*hashImageMock, open(blobId, std::ios::out)) 8156a2273fSJason Ling .WillOnce(Return(true)); 82ded66d0fSJason Ling } 83ded66d0fSJason Ling else 84ded66d0fSJason Ling { 8556a2273fSJason Ling EXPECT_CALL(*imageMock2, open(blobId, std::ios::out)) 8656a2273fSJason Ling .WillOnce(Return(true)); 87ded66d0fSJason Ling } 88ded66d0fSJason Ling 89ded66d0fSJason Ling if (blobId != hashBlobId) 90ded66d0fSJason Ling { 91ded66d0fSJason Ling EXPECT_CALL(*prepareMockPtr, trigger()).WillOnce(Return(true)); 92ded66d0fSJason Ling } 93ded66d0fSJason Ling EXPECT_TRUE(handler->open(session, flags, blobId)); 94ded66d0fSJason Ling expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress); 95ded66d0fSJason Ling } 96ded66d0fSJason Ling getToVerificationPending(const std::string & blobId)97ded66d0fSJason Ling void getToVerificationPending(const std::string& blobId) 98ded66d0fSJason Ling { 99ded66d0fSJason Ling openToInProgress(blobId); 100ded66d0fSJason Ling 101ded66d0fSJason Ling if (blobId == hashBlobId) 102ded66d0fSJason Ling { 103ded66d0fSJason Ling EXPECT_CALL(*hashImageMock, close()).WillRepeatedly(Return()); 104ded66d0fSJason Ling } 105ded66d0fSJason Ling else 106ded66d0fSJason Ling { 107ded66d0fSJason Ling EXPECT_CALL(*imageMock2, close()).WillRepeatedly(Return()); 108ded66d0fSJason Ling } 109ded66d0fSJason Ling handler->close(session); 110ded66d0fSJason Ling expectedState(FirmwareBlobHandler::UpdateState::verificationPending); 111ded66d0fSJason Ling } 112ded66d0fSJason Ling getToVerificationStarted(const std::string & blobId)113ded66d0fSJason Ling void getToVerificationStarted(const std::string& blobId) 114ded66d0fSJason Ling { 115ded66d0fSJason Ling getToVerificationPending(blobId); 116ded66d0fSJason Ling 117ded66d0fSJason Ling EXPECT_TRUE(handler->open(session, flags, verifyBlobId)); 118ded66d0fSJason Ling EXPECT_CALL(*verifyMockPtr, trigger()).WillOnce(Return(true)); 119ded66d0fSJason Ling 120ded66d0fSJason Ling EXPECT_TRUE(handler->commit(session, {})); 121ded66d0fSJason Ling expectedState(FirmwareBlobHandler::UpdateState::verificationStarted); 122ded66d0fSJason Ling } 123ded66d0fSJason Ling getToVerificationStartedWitHashBlob()124ded66d0fSJason Ling void getToVerificationStartedWitHashBlob() 125ded66d0fSJason Ling { 126ded66d0fSJason Ling /* Open both static and hash to check for activeHashBlobId. */ 127ded66d0fSJason Ling getToVerificationPending(staticLayoutBlobId); 128ded66d0fSJason Ling 129ded66d0fSJason Ling openToInProgress(hashBlobId); 130ded66d0fSJason Ling EXPECT_CALL(*hashImageMock, close()).WillRepeatedly(Return()); 131ded66d0fSJason Ling handler->close(session); 132ded66d0fSJason Ling expectedState(FirmwareBlobHandler::UpdateState::verificationPending); 133ded66d0fSJason Ling 134ded66d0fSJason Ling /* Now the hash is active AND the static image is active. */ 135ded66d0fSJason Ling EXPECT_TRUE(handler->open(session, flags, verifyBlobId)); 136ded66d0fSJason Ling EXPECT_CALL(*verifyMockPtr, trigger()).WillOnce(Return(true)); 137ded66d0fSJason Ling 138ded66d0fSJason Ling EXPECT_TRUE(handler->commit(session, {})); 139ded66d0fSJason Ling expectedState(FirmwareBlobHandler::UpdateState::verificationStarted); 140ded66d0fSJason Ling } 141ded66d0fSJason Ling getToVerificationCompleted(ActionStatus checkResponse)142ded66d0fSJason Ling void getToVerificationCompleted(ActionStatus checkResponse) 143ded66d0fSJason Ling { 144ded66d0fSJason Ling getToVerificationStarted(staticLayoutBlobId); 145ded66d0fSJason Ling 146ded66d0fSJason Ling EXPECT_CALL(*verifyMockPtr, status()).WillOnce(Return(checkResponse)); 147ded66d0fSJason Ling blobs::BlobMeta meta; 148ded66d0fSJason Ling EXPECT_TRUE(handler->stat(session, &meta)); 149ded66d0fSJason Ling expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted); 150ded66d0fSJason Ling } 151ded66d0fSJason Ling getToUpdatePending()152ded66d0fSJason Ling void getToUpdatePending() 153ded66d0fSJason Ling { 154ded66d0fSJason Ling getToVerificationCompleted(ActionStatus::success); 155ded66d0fSJason Ling 156ded66d0fSJason Ling handler->close(session); 157ded66d0fSJason Ling expectedState(FirmwareBlobHandler::UpdateState::updatePending); 158ded66d0fSJason Ling } 159ded66d0fSJason Ling getToUpdateStarted()160ded66d0fSJason Ling void getToUpdateStarted() 161ded66d0fSJason Ling { 162ded66d0fSJason Ling getToUpdatePending(); 163ded66d0fSJason Ling EXPECT_TRUE(handler->open(session, flags, updateBlobId)); 164ded66d0fSJason Ling 165ded66d0fSJason Ling EXPECT_CALL(*updateMockPtr, trigger()).WillOnce(Return(true)); 166ded66d0fSJason Ling EXPECT_TRUE(handler->commit(session, {})); 167ded66d0fSJason Ling expectedState(FirmwareBlobHandler::UpdateState::updateStarted); 168ded66d0fSJason Ling } 169ded66d0fSJason Ling getToUpdateCompleted(ActionStatus result)170ded66d0fSJason Ling void getToUpdateCompleted(ActionStatus result) 171ded66d0fSJason Ling { 172ded66d0fSJason Ling getToUpdateStarted(); 173ded66d0fSJason Ling EXPECT_CALL(*updateMockPtr, status()).WillOnce(Return(result)); 174ded66d0fSJason Ling 175ded66d0fSJason Ling blobs::BlobMeta meta; 176ded66d0fSJason Ling EXPECT_TRUE(handler->stat(session, &meta)); 177ded66d0fSJason Ling expectedState(FirmwareBlobHandler::UpdateState::updateCompleted); 178ded66d0fSJason Ling } 179ded66d0fSJason Ling 180ded66d0fSJason Ling ImageHandlerMock *hashImageMock, *imageMock2; 181ded66d0fSJason Ling 182ded66d0fSJason Ling std::vector<HandlerPack> blobs; 183ded66d0fSJason Ling 184ded66d0fSJason Ling std::unique_ptr<blobs::GenericBlobInterface> handler; 185ded66d0fSJason Ling 186ded66d0fSJason Ling TriggerMock* prepareMockPtr; 187ded66d0fSJason Ling TriggerMock* verifyMockPtr; 188ded66d0fSJason Ling TriggerMock* updateMockPtr; 189ded66d0fSJason Ling 190ded66d0fSJason Ling std::uint16_t session = 1; 191*b487eb47SWilly Tu std::uint16_t flags = static_cast<std::uint16_t>(blobs::OpenFlags::write) | 192*b487eb47SWilly Tu FirmwareFlags::UpdateFlags::ipmi; 193ded66d0fSJason Ling 194ded66d0fSJason Ling blobs::BlobMeta expectedIdleMeta = {0xff00, 0, {}}; 195ded66d0fSJason Ling 196ded66d0fSJason Ling std::vector<std::string> startingBlobs = {staticLayoutBlobId, hashBlobId}; 197ded66d0fSJason Ling }; 198ded66d0fSJason Ling 199ded66d0fSJason Ling class IpmiOnlyFirmwareTest : public ::testing::Test 200ded66d0fSJason Ling { 201ded66d0fSJason Ling protected: 202ded66d0fSJason Ling ImageHandlerMock *hashImageMock, *imageMock; 203ded66d0fSJason Ling std::vector<HandlerPack> blobs; 204ded66d0fSJason Ling std::unique_ptr<blobs::GenericBlobInterface> handler; 205ded66d0fSJason Ling SetUp()206ded66d0fSJason Ling void SetUp() override 207ded66d0fSJason Ling { 208ded66d0fSJason Ling std::unique_ptr<ImageHandlerInterface> image = 209ded66d0fSJason Ling std::make_unique<ImageHandlerMock>(); 210ded66d0fSJason Ling hashImageMock = reinterpret_cast<ImageHandlerMock*>(image.get()); 211ded66d0fSJason Ling blobs.emplace_back(hashBlobId, std::move(image)); 212ded66d0fSJason Ling 213ded66d0fSJason Ling image = std::make_unique<ImageHandlerMock>(); 214ded66d0fSJason Ling imageMock = reinterpret_cast<ImageHandlerMock*>(image.get()); 215ded66d0fSJason Ling blobs.emplace_back("asdf", std::move(image)); 216ded66d0fSJason Ling 217ded66d0fSJason Ling std::vector<DataHandlerPack> data; 218ded66d0fSJason Ling data.emplace_back(FirmwareFlags::UpdateFlags::ipmi, nullptr); 219ded66d0fSJason Ling 220ded66d0fSJason Ling handler = FirmwareBlobHandler::CreateFirmwareBlobHandler( 221ded66d0fSJason Ling std::move(blobs), std::move(data), CreateActionMap("asdf")); 222ded66d0fSJason Ling } 223ded66d0fSJason Ling }; 224ded66d0fSJason Ling 225ded66d0fSJason Ling class FakeLpcFirmwareTest : public ::testing::Test 226ded66d0fSJason Ling { 227ded66d0fSJason Ling protected: 228ded66d0fSJason Ling DataHandlerMock* dataMock; 229ded66d0fSJason Ling ImageHandlerMock *hashImageMock, *imageMock; 230ded66d0fSJason Ling std::vector<HandlerPack> blobs; 231ded66d0fSJason Ling std::unique_ptr<blobs::GenericBlobInterface> handler; 232ded66d0fSJason Ling SetUp()233ded66d0fSJason Ling void SetUp() override 234ded66d0fSJason Ling { 235ded66d0fSJason Ling std::unique_ptr<ImageHandlerInterface> image = 236ded66d0fSJason Ling std::make_unique<ImageHandlerMock>(); 237ded66d0fSJason Ling hashImageMock = reinterpret_cast<ImageHandlerMock*>(image.get()); 238ded66d0fSJason Ling blobs.emplace_back(hashBlobId, std::move(image)); 239ded66d0fSJason Ling 240ded66d0fSJason Ling image = std::make_unique<ImageHandlerMock>(); 241ded66d0fSJason Ling imageMock = reinterpret_cast<ImageHandlerMock*>(image.get()); 242ded66d0fSJason Ling blobs.emplace_back("asdf", std::move(image)); 243ded66d0fSJason Ling 244ded66d0fSJason Ling auto dataMockInstance = std::make_unique<DataHandlerMock>(); 245ded66d0fSJason Ling dataMock = dataMockInstance.get(); 246ded66d0fSJason Ling 247ded66d0fSJason Ling std::vector<DataHandlerPack> data; 248ded66d0fSJason Ling data.emplace_back(FirmwareFlags::UpdateFlags::ipmi, nullptr); 249ded66d0fSJason Ling data.emplace_back(FirmwareFlags::UpdateFlags::lpc, 250ded66d0fSJason Ling std::move(dataMockInstance)); 251ded66d0fSJason Ling handler = FirmwareBlobHandler::CreateFirmwareBlobHandler( 252ded66d0fSJason Ling std::move(blobs), std::move(data), CreateActionMap("asdf")); 253ded66d0fSJason Ling } 254ded66d0fSJason Ling }; 255ded66d0fSJason Ling 256ded66d0fSJason Ling } // namespace 257ded66d0fSJason Ling } // namespace ipmi_flash 258