blob: a2984b7455e21e145a391c8d339a4c519e4abf39 [file] [log] [blame]
Patrick Venturefa06a5f2019-07-01 09:22:38 -07001/* The goal of these tests is to verify that once a host-client has started the
2 * process with one blob bundle, they cannot pivot to upload data to another.
3 *
4 * This prevent someone from starting to upload a BMC firmware, and then midway
5 * through start uploading a BIOS image.
6 */
7#include "firmware_handler.hpp"
8#include "flags.hpp"
9#include "image_mock.hpp"
10#include "status.hpp"
11#include "triggerable_mock.hpp"
12#include "util.hpp"
13
14#include <memory>
15#include <string>
16#include <unordered_map>
17#include <vector>
18
19#include <gtest/gtest.h>
20
21namespace ipmi_flash
22{
23namespace
24{
25
26using ::testing::Return;
27
28class IpmiOnlyTwoFirmwaresTest : public ::testing::Test
29{
30 protected:
31 void SetUp() override
32 {
Patrick Ventured4e20de2019-07-18 12:48:05 -070033 std::unique_ptr<ImageHandlerInterface> image =
34 std::make_unique<ImageHandlerMock>();
35 hashImageMock = reinterpret_cast<ImageHandlerMock*>(image.get());
36 blobs.push_back(std::move(HandlerPack(hashBlobId, std::move(image))));
37
38 image = std::make_unique<ImageHandlerMock>();
39 staticImageMock = reinterpret_cast<ImageHandlerMock*>(image.get());
40 blobs.push_back(
41 std::move(HandlerPack(staticLayoutBlobId, std::move(image))));
42
43 image = std::make_unique<ImageHandlerMock>();
44 biosImageMock = reinterpret_cast<ImageHandlerMock*>(image.get());
45 blobs.push_back(std::move(HandlerPack(biosBlobId, std::move(image))));
Patrick Venturefa06a5f2019-07-01 09:22:38 -070046
47 std::unique_ptr<TriggerableActionInterface> bmcPrepareMock =
48 std::make_unique<TriggerMock>();
49 bmcPrepareMockPtr =
50 reinterpret_cast<TriggerMock*>(bmcPrepareMock.get());
51
52 std::unique_ptr<TriggerableActionInterface> bmcVerifyMock =
53 std::make_unique<TriggerMock>();
54 bmcVerifyMockPtr = reinterpret_cast<TriggerMock*>(bmcVerifyMock.get());
55
56 std::unique_ptr<TriggerableActionInterface> bmcUpdateMock =
57 std::make_unique<TriggerMock>();
58 bmcUpdateMockPtr = reinterpret_cast<TriggerMock*>(bmcUpdateMock.get());
59
60 std::unique_ptr<TriggerableActionInterface> biosPrepareMock =
61 std::make_unique<TriggerMock>();
62 biosPrepareMockPtr =
63 reinterpret_cast<TriggerMock*>(biosPrepareMock.get());
64
65 std::unique_ptr<TriggerableActionInterface> biosVerifyMock =
66 std::make_unique<TriggerMock>();
67 biosVerifyMockPtr =
68 reinterpret_cast<TriggerMock*>(biosVerifyMock.get());
69
70 std::unique_ptr<TriggerableActionInterface> biosUpdateMock =
71 std::make_unique<TriggerMock>();
72 biosUpdateMockPtr =
73 reinterpret_cast<TriggerMock*>(biosUpdateMock.get());
74
75 ActionMap packs;
76
77 std::unique_ptr<ActionPack> bmcPack = std::make_unique<ActionPack>();
78 bmcPack->preparation = std::move(bmcPrepareMock);
79 bmcPack->verification = std::move(bmcVerifyMock);
80 bmcPack->update = std::move(bmcUpdateMock);
81
82 std::unique_ptr<ActionPack> biosPack = std::make_unique<ActionPack>();
83 biosPack->preparation = std::move(biosPrepareMock);
84 biosPack->verification = std::move(biosVerifyMock);
85 biosPack->update = std::move(biosUpdateMock);
86
87 packs[staticLayoutBlobId] = std::move(bmcPack);
Patrick Venture7c2a00e2019-07-01 17:33:03 -070088 packs[biosBlobId] = std::move(biosPack);
Patrick Venturefa06a5f2019-07-01 09:22:38 -070089
90 handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(
Patrick Venture7b783432020-09-22 15:55:08 -070091 std::move(blobs), std::move(data), std::move(packs));
Patrick Venturefa06a5f2019-07-01 09:22:38 -070092 }
93
94 void expectedState(FirmwareBlobHandler::UpdateState state)
95 {
96 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
97 EXPECT_EQ(state, realHandler->getCurrentState());
98 }
99
Patrick Ventured4e20de2019-07-18 12:48:05 -0700100 ImageHandlerMock *hashImageMock, *staticImageMock, *biosImageMock;
Patrick Venturefa06a5f2019-07-01 09:22:38 -0700101
102 std::vector<HandlerPack> blobs;
103 std::vector<DataHandlerPack> data = {
104 {FirmwareFlags::UpdateFlags::ipmi, nullptr}};
105
106 std::unique_ptr<blobs::GenericBlobInterface> handler;
107
108 TriggerMock *bmcPrepareMockPtr, *bmcVerifyMockPtr, *bmcUpdateMockPtr;
109 TriggerMock *biosPrepareMockPtr, *biosVerifyMockPtr, *biosUpdateMockPtr;
110
111 std::uint16_t session = 1;
112 std::uint16_t flags =
113 blobs::OpenFlags::write | FirmwareFlags::UpdateFlags::ipmi;
Patrick Venturefa06a5f2019-07-01 09:22:38 -0700114};
115
116TEST_F(IpmiOnlyTwoFirmwaresTest, OpeningBiosAfterBlobFails)
117{
118 /* You can only have one file open at a time, and the first firmware file
119 * you open locks it down
120 */
Patrick Ventured4e20de2019-07-18 12:48:05 -0700121 EXPECT_CALL(*staticImageMock, open(staticLayoutBlobId))
Patrick Venturefa06a5f2019-07-01 09:22:38 -0700122 .WillOnce(Return(true));
123 EXPECT_CALL(*bmcPrepareMockPtr, trigger()).WillOnce(Return(true));
124
125 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
126 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
127
Patrick Ventured4e20de2019-07-18 12:48:05 -0700128 EXPECT_CALL(*staticImageMock, close()).WillOnce(Return());
Patrick Venturefa06a5f2019-07-01 09:22:38 -0700129 handler->close(session);
130
131 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
132
Patrick Ventured4e20de2019-07-18 12:48:05 -0700133 EXPECT_CALL(*biosImageMock, open(biosBlobId)).Times(0);
Patrick Venture7c2a00e2019-07-01 17:33:03 -0700134 EXPECT_FALSE(handler->open(session, flags, biosBlobId));
Patrick Venturefa06a5f2019-07-01 09:22:38 -0700135}
136
137TEST_F(IpmiOnlyTwoFirmwaresTest, OpeningHashBeforeBiosSucceeds)
138{
139 /* Opening the hash blob does nothing special in this regard. */
Patrick Ventured4e20de2019-07-18 12:48:05 -0700140 EXPECT_CALL(*hashImageMock, open(hashBlobId)).WillOnce(Return(true));
Patrick Venturefa06a5f2019-07-01 09:22:38 -0700141 EXPECT_TRUE(handler->open(session, flags, hashBlobId));
142
143 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
144
Patrick Ventured4e20de2019-07-18 12:48:05 -0700145 EXPECT_CALL(*hashImageMock, close()).WillOnce(Return());
Patrick Venturefa06a5f2019-07-01 09:22:38 -0700146 handler->close(session);
147
148 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
149 ASSERT_FALSE(handler->canHandleBlob(verifyBlobId));
150
Patrick Ventured4e20de2019-07-18 12:48:05 -0700151 EXPECT_CALL(*biosImageMock, open(biosBlobId)).WillOnce(Return(true));
Patrick Venture7c2a00e2019-07-01 17:33:03 -0700152 EXPECT_TRUE(handler->open(session, flags, biosBlobId));
Patrick Venturefa06a5f2019-07-01 09:22:38 -0700153
154 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
155
Patrick Ventured4e20de2019-07-18 12:48:05 -0700156 EXPECT_CALL(*biosImageMock, close()).WillOnce(Return());
Patrick Venturefa06a5f2019-07-01 09:22:38 -0700157 handler->close(session);
158}
159
160} // namespace
161} // namespace ipmi_flash