blob: 2c450f457e0b89a7da3ce01e921ab5de9c7227d3 [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 {
33 blobs = {
34 {hashBlobId, &hashImageMock},
35 {staticLayoutBlobId, &staticImageMock},
Patrick Venture7c2a00e2019-07-01 17:33:03 -070036 {biosBlobId, &biosImageMock},
Patrick Venturefa06a5f2019-07-01 09:22:38 -070037 };
38
39 std::unique_ptr<TriggerableActionInterface> bmcPrepareMock =
40 std::make_unique<TriggerMock>();
41 bmcPrepareMockPtr =
42 reinterpret_cast<TriggerMock*>(bmcPrepareMock.get());
43
44 std::unique_ptr<TriggerableActionInterface> bmcVerifyMock =
45 std::make_unique<TriggerMock>();
46 bmcVerifyMockPtr = reinterpret_cast<TriggerMock*>(bmcVerifyMock.get());
47
48 std::unique_ptr<TriggerableActionInterface> bmcUpdateMock =
49 std::make_unique<TriggerMock>();
50 bmcUpdateMockPtr = reinterpret_cast<TriggerMock*>(bmcUpdateMock.get());
51
52 std::unique_ptr<TriggerableActionInterface> biosPrepareMock =
53 std::make_unique<TriggerMock>();
54 biosPrepareMockPtr =
55 reinterpret_cast<TriggerMock*>(biosPrepareMock.get());
56
57 std::unique_ptr<TriggerableActionInterface> biosVerifyMock =
58 std::make_unique<TriggerMock>();
59 biosVerifyMockPtr =
60 reinterpret_cast<TriggerMock*>(biosVerifyMock.get());
61
62 std::unique_ptr<TriggerableActionInterface> biosUpdateMock =
63 std::make_unique<TriggerMock>();
64 biosUpdateMockPtr =
65 reinterpret_cast<TriggerMock*>(biosUpdateMock.get());
66
67 ActionMap packs;
68
69 std::unique_ptr<ActionPack> bmcPack = std::make_unique<ActionPack>();
70 bmcPack->preparation = std::move(bmcPrepareMock);
71 bmcPack->verification = std::move(bmcVerifyMock);
72 bmcPack->update = std::move(bmcUpdateMock);
73
74 std::unique_ptr<ActionPack> biosPack = std::make_unique<ActionPack>();
75 biosPack->preparation = std::move(biosPrepareMock);
76 biosPack->verification = std::move(biosVerifyMock);
77 biosPack->update = std::move(biosUpdateMock);
78
79 packs[staticLayoutBlobId] = std::move(bmcPack);
Patrick Venture7c2a00e2019-07-01 17:33:03 -070080 packs[biosBlobId] = std::move(biosPack);
Patrick Venturefa06a5f2019-07-01 09:22:38 -070081
82 handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(
83 blobs, data, std::move(packs));
84 }
85
86 void expectedState(FirmwareBlobHandler::UpdateState state)
87 {
88 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
89 EXPECT_EQ(state, realHandler->getCurrentState());
90 }
91
92 ImageHandlerMock hashImageMock, staticImageMock, biosImageMock;
93
94 std::vector<HandlerPack> blobs;
95 std::vector<DataHandlerPack> data = {
96 {FirmwareFlags::UpdateFlags::ipmi, nullptr}};
97
98 std::unique_ptr<blobs::GenericBlobInterface> handler;
99
100 TriggerMock *bmcPrepareMockPtr, *bmcVerifyMockPtr, *bmcUpdateMockPtr;
101 TriggerMock *biosPrepareMockPtr, *biosVerifyMockPtr, *biosUpdateMockPtr;
102
103 std::uint16_t session = 1;
104 std::uint16_t flags =
105 blobs::OpenFlags::write | FirmwareFlags::UpdateFlags::ipmi;
Patrick Venturefa06a5f2019-07-01 09:22:38 -0700106};
107
108TEST_F(IpmiOnlyTwoFirmwaresTest, OpeningBiosAfterBlobFails)
109{
110 /* You can only have one file open at a time, and the first firmware file
111 * you open locks it down
112 */
113 EXPECT_CALL(staticImageMock, open(staticLayoutBlobId))
114 .WillOnce(Return(true));
115 EXPECT_CALL(*bmcPrepareMockPtr, trigger()).WillOnce(Return(true));
116
117 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
118 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
119
120 EXPECT_CALL(staticImageMock, close()).WillOnce(Return());
121 handler->close(session);
122
123 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
124
Patrick Venture7c2a00e2019-07-01 17:33:03 -0700125 EXPECT_CALL(biosImageMock, open(biosBlobId)).Times(0);
126 EXPECT_FALSE(handler->open(session, flags, biosBlobId));
Patrick Venturefa06a5f2019-07-01 09:22:38 -0700127}
128
129TEST_F(IpmiOnlyTwoFirmwaresTest, OpeningHashBeforeBiosSucceeds)
130{
131 /* Opening the hash blob does nothing special in this regard. */
132 EXPECT_CALL(hashImageMock, open(hashBlobId)).WillOnce(Return(true));
133 EXPECT_TRUE(handler->open(session, flags, hashBlobId));
134
135 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
136
137 EXPECT_CALL(hashImageMock, close()).WillOnce(Return());
138 handler->close(session);
139
140 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
141 ASSERT_FALSE(handler->canHandleBlob(verifyBlobId));
142
Patrick Venture7c2a00e2019-07-01 17:33:03 -0700143 EXPECT_CALL(biosImageMock, open(biosBlobId)).WillOnce(Return(true));
144 EXPECT_TRUE(handler->open(session, flags, biosBlobId));
Patrick Venturefa06a5f2019-07-01 09:22:38 -0700145
146 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
147
148 EXPECT_CALL(biosImageMock, close()).WillOnce(Return());
149 handler->close(session);
150}
151
152} // namespace
153} // namespace ipmi_flash