blob: 92b6a2aa1fc01973d5d33051c9a2990170c8c050 [file] [log] [blame]
Patrick Venture61d2ed42019-05-23 18:16:31 -07001/**
2 * The goal of these tests is to verify the behavior of all blob commands given
3 * the current state is verificationPending. This state is achieved as a
4 * transition out of uploadInProgress.
5 */
6#include "firmware_handler.hpp"
7#include "firmware_unittest.hpp"
Patrick Venture01a33272019-05-23 19:48:22 -07008#include "status.hpp"
Patrick Venture61d2ed42019-05-23 18:16:31 -07009#include "util.hpp"
10
Patrick Venture930c7b72019-05-24 11:11:08 -070011#include <algorithm>
Patrick Venture61d2ed42019-05-23 18:16:31 -070012#include <cstdint>
13#include <string>
14#include <vector>
15
16#include <gtest/gtest.h>
17
18namespace ipmi_flash
19{
20namespace
21{
22
Patrick Venture2567ebc2019-05-24 10:02:53 -070023using ::testing::IsEmpty;
Patrick Venture61d2ed42019-05-23 18:16:31 -070024using ::testing::Return;
Patrick Ventureefba42d2019-05-24 10:48:16 -070025using ::testing::UnorderedElementsAreArray;
Patrick Venture61d2ed42019-05-23 18:16:31 -070026
27/*
28 * There are the following calls (parameters may vary):
29 * canHandleBlob(blob)
30 * getBlobIds
31 * deleteBlob(blob)
32 * stat(blob)
33 * stat(session)
34 * open(blob)
35 * close(session)
36 * writemeta(session)
37 * write(session)
38 * read(session)
39 * commit(session)
40 *
41 * Testing canHandleBlob is uninteresting in this state. Getting the BlobIDs
42 * will inform what canHandleBlob will return.
43 */
44
45class FirmwareHandlerVerificationPendingTest : public IpmiOnlyFirmwareStaticTest
46{
47 protected:
48 void getToVerificationPending(const std::string& blobId)
49 {
50 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
51 EXPECT_CALL(imageMock, open(blobId)).WillOnce(Return(true));
52 EXPECT_TRUE(handler->open(session, flags, blobId));
53 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
54 realHandler->getCurrentState());
55 EXPECT_CALL(imageMock, close()).WillRepeatedly(Return());
56 handler->close(session);
57 EXPECT_EQ(FirmwareBlobHandler::UpdateState::verificationPending,
58 realHandler->getCurrentState());
59 }
60
61 std::uint16_t session = 1;
62 std::uint16_t flags =
63 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
64};
65
66/*
67 * getBlobIds
Patrick Venture61d2ed42019-05-23 18:16:31 -070068 */
Patrick Venture61d2ed42019-05-23 18:16:31 -070069TEST_F(FirmwareHandlerVerificationPendingTest, VerifyBlobIdAvailableInState)
70{
71 /* Only in the verificationPending state (and later), should the
72 * verifyBlobId be present. */
73
Patrick Venture930c7b72019-05-24 11:11:08 -070074 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
75
Patrick Venture61d2ed42019-05-23 18:16:31 -070076 getToVerificationPending(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070077
Patrick Venture61d2ed42019-05-23 18:16:31 -070078 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -070079 EXPECT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Venture61d2ed42019-05-23 18:16:31 -070080}
81
Patrick Ventureb386b862019-05-23 18:42:54 -070082/*
83 * delete(blob) TODO: Implement this.
84 */
85
86/*
87 * stat(blob)
88 */
89TEST_F(FirmwareHandlerVerificationPendingTest, StatOnActiveImageReturnsFailure)
90{
91 getToVerificationPending(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070092 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -070093
94 blobs::BlobMeta meta;
95 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
96}
97
98TEST_F(FirmwareHandlerVerificationPendingTest, StatOnActiveHashReturnsFailure)
99{
100 getToVerificationPending(hashBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -0700101 ASSERT_TRUE(handler->canHandleBlob(activeHashBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -0700102
103 blobs::BlobMeta meta;
104 EXPECT_FALSE(handler->stat(activeHashBlobId, &meta));
105}
106
107TEST_F(FirmwareHandlerVerificationPendingTest,
108 StatOnVerificationBlobReturnsFailure)
109{
110 getToVerificationPending(hashBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -0700111 ASSERT_TRUE(handler->canHandleBlob(activeHashBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -0700112
113 blobs::BlobMeta meta;
114 EXPECT_FALSE(handler->stat(verifyBlobId, &meta));
115}
116
117TEST_F(FirmwareHandlerVerificationPendingTest, StatOnNormalBlobsReturnsSuccess)
118{
119 getToVerificationPending(staticLayoutBlobId);
120
121 blobs::BlobMeta expected;
122 expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
123 expected.size = 0;
124
125 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
126 for (const auto& blob : testBlobs)
127 {
Patrick Venture930c7b72019-05-24 11:11:08 -0700128 ASSERT_TRUE(handler->canHandleBlob(blob));
Patrick Ventureb386b862019-05-23 18:42:54 -0700129 blobs::BlobMeta meta = {};
130 EXPECT_TRUE(handler->stat(blob, &meta));
131 EXPECT_EQ(expected, meta);
132 }
133}
134
135/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700136 * open(blob)
137 */
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700138TEST_F(FirmwareHandlerVerificationPendingTest, OpenVerifyBlobSucceeds)
139{
140 getToVerificationPending(staticLayoutBlobId);
141
142 /* the session is safe because it was already closed to get to this state.
143 */
144 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
145}
146
147TEST_F(FirmwareHandlerVerificationPendingTest, OpenActiveImageBlobFails)
148{
149 /* Try opening the active blob Id. This test is equivalent to trying to
150 * open the active hash blob id, in that neither are ever allowed.
151 */
152 getToVerificationPending(staticLayoutBlobId);
153 EXPECT_FALSE(handler->open(session, flags, activeImageBlobId));
154}
155
156TEST_F(FirmwareHandlerVerificationPendingTest,
157 OpenImageBlobTransitionsToUploadInProgress)
158{
159 getToVerificationPending(staticLayoutBlobId);
Patrick Ventureefba42d2019-05-24 10:48:16 -0700160
161 /* Verify the active blob for the image is in the list once to start.
162 * Note: This is truly tested under the notYetStarted::open() test.
163 */
164 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId,
165 verifyBlobId, activeImageBlobId};
166
167 EXPECT_THAT(handler->getBlobIds(),
168 UnorderedElementsAreArray(expectedBlobs));
169
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700170 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
171 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
172
173 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
174 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
175 realHandler->getCurrentState());
Patrick Ventureefba42d2019-05-24 10:48:16 -0700176
Patrick Venture930c7b72019-05-24 11:11:08 -0700177 expectedBlobs.erase(
178 std::remove(expectedBlobs.begin(), expectedBlobs.end(), verifyBlobId));
179
180 /* Verify the active blob ID was not added to the list twice and
181 * verifyBlobId is removed
182 */
Patrick Ventureefba42d2019-05-24 10:48:16 -0700183 EXPECT_THAT(handler->getBlobIds(),
184 UnorderedElementsAreArray(expectedBlobs));
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700185}
186
187/*
Patrick Venture1e389c92019-05-23 19:15:05 -0700188 * close(session)
189 */
190TEST_F(FirmwareHandlerVerificationPendingTest,
191 ClosingVerifyBlobDoesNotChangeState)
192{
193 getToVerificationPending(staticLayoutBlobId);
194 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
195
196 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
197 EXPECT_EQ(FirmwareBlobHandler::UpdateState::verificationPending,
198 realHandler->getCurrentState());
199
200 handler->close(session);
201
202 EXPECT_EQ(FirmwareBlobHandler::UpdateState::verificationPending,
203 realHandler->getCurrentState());
204}
205
206/*
Patrick Venture19044e12019-05-23 19:30:28 -0700207 * commit(session)
208 */
209TEST_F(FirmwareHandlerVerificationPendingTest,
210 CommitOnVerifyBlobTriggersVerificationAndStateTransition)
211{
212 getToVerificationPending(staticLayoutBlobId);
213 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
214 EXPECT_CALL(*verifyMockPtr, triggerVerification()).WillOnce(Return(true));
215
216 EXPECT_TRUE(handler->commit(session, {}));
217
218 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
219 EXPECT_EQ(FirmwareBlobHandler::UpdateState::verificationStarted,
220 realHandler->getCurrentState());
221}
222
223/*
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700224 * stat(session) - in this state, you can only open(verifyBlobId) without
225 * changing state.
226 */
Patrick Venture01a33272019-05-23 19:48:22 -0700227TEST_F(FirmwareHandlerVerificationPendingTest, StatOnVerifyBlobIdReturnsState)
228{
229 /* If this is called before commit(), it's still verificationPending, so it
230 * just returns the state is other
231 */
232 getToVerificationPending(staticLayoutBlobId);
233 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
234 EXPECT_CALL(*verifyMockPtr, triggerVerification()).Times(0);
235 EXPECT_CALL(*verifyMockPtr, checkVerificationState()).Times(0);
236
237 blobs::BlobMeta meta, expectedMeta = {};
238 expectedMeta.size = 0;
239 expectedMeta.blobState = flags;
240 expectedMeta.metadata.push_back(
241 static_cast<std::uint8_t>(VerifyCheckResponses::other));
242
243 EXPECT_TRUE(handler->stat(session, &meta));
244 EXPECT_EQ(expectedMeta, meta);
245}
246
Patrick Ventureb386b862019-05-23 18:42:54 -0700247/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700248 * writemeta(session)
249 */
Patrick Ventureb611a082019-05-23 20:27:28 -0700250TEST_F(FirmwareHandlerVerificationPendingTest, WriteMetaAgainstVerifyFails)
251{
252 /* The verifyBlobId has no data handler, which means write meta fails. */
253 getToVerificationPending(staticLayoutBlobId);
254
255 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
256
257 std::vector<std::uint8_t> bytes = {0x01, 0x02};
258 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
259}
260
Patrick Ventureb386b862019-05-23 18:42:54 -0700261/*
262 * write(session)
263 */
Patrick Ventureab731e92019-05-24 09:58:00 -0700264TEST_F(FirmwareHandlerVerificationPendingTest, WriteAgainstVerifyBlobIdFails)
265{
266 getToVerificationPending(staticLayoutBlobId);
267
268 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
269
270 std::vector<std::uint8_t> bytes = {0x01, 0x02};
271 EXPECT_FALSE(handler->write(session, 0, bytes));
272}
273
Patrick Ventureb386b862019-05-23 18:42:54 -0700274/*
275 * read(session)
276 */
Patrick Venture2567ebc2019-05-24 10:02:53 -0700277TEST_F(FirmwareHandlerVerificationPendingTest,
278 ReadAgainstVerifyBlobIdReturnsEmpty)
279{
280 getToVerificationPending(staticLayoutBlobId);
281
282 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
283 EXPECT_THAT(handler->read(session, 0, 32), IsEmpty());
284}
Patrick Ventureb386b862019-05-23 18:42:54 -0700285
Patrick Venture61d2ed42019-05-23 18:16:31 -0700286} // namespace
287} // namespace ipmi_flash