blob: dc6f3d3303363e654ff810c086e0947e1f252f61 [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
Patrick Venture9b37b092020-05-28 20:58:57 -070046{};
Patrick Venture61d2ed42019-05-23 18:16:31 -070047
48/*
49 * getBlobIds
Patrick Venture61d2ed42019-05-23 18:16:31 -070050 */
Patrick Venture61d2ed42019-05-23 18:16:31 -070051TEST_F(FirmwareHandlerVerificationPendingTest, VerifyBlobIdAvailableInState)
52{
53 /* Only in the verificationPending state (and later), should the
Patrick Venture0f82ce42019-05-28 14:06:04 -070054 * verifyBlobId be present.
55 */
Patrick Venture930c7b72019-05-24 11:11:08 -070056 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
57
Patrick Venture61d2ed42019-05-23 18:16:31 -070058 getToVerificationPending(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070059
Patrick Venture61d2ed42019-05-23 18:16:31 -070060 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -070061 EXPECT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Venture0f82ce42019-05-28 14:06:04 -070062 EXPECT_FALSE(handler->canHandleBlob(updateBlobId));
Patrick Venture61d2ed42019-05-23 18:16:31 -070063}
64
Patrick Ventureb386b862019-05-23 18:42:54 -070065/*
Patrick Venture2ca66522019-06-17 11:58:38 -070066 * delete(blob)
Patrick Ventureb386b862019-05-23 18:42:54 -070067 */
Patrick Venture2ca66522019-06-17 11:58:38 -070068TEST_F(FirmwareHandlerVerificationPendingTest, DeleteVerifyPendingAbortsProcess)
69{
70 /* It doesn't matter what blob id is used to delete in the design, so just
71 * delete the verify blob id
72 */
73 getToVerificationPending(staticLayoutBlobId);
74
75 EXPECT_CALL(*verifyMockPtr, abort()).Times(0);
76
77 ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));
78 EXPECT_TRUE(handler->deleteBlob(verifyBlobId));
79
80 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId};
81 EXPECT_THAT(handler->getBlobIds(),
82 UnorderedElementsAreArray(expectedBlobs));
83 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
84}
85
86TEST_F(FirmwareHandlerVerificationPendingTest, DeleteActiveImageAbortsProcess)
87{
88 getToVerificationPending(staticLayoutBlobId);
89
90 EXPECT_CALL(*verifyMockPtr, abort()).Times(0);
91
92 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
93 EXPECT_TRUE(handler->deleteBlob(activeImageBlobId));
94
95 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId};
96 EXPECT_THAT(handler->getBlobIds(),
97 UnorderedElementsAreArray(expectedBlobs));
98 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
99}
100
101TEST_F(FirmwareHandlerVerificationPendingTest, DeleteStaticLayoutAbortsProcess)
102{
103 getToVerificationPending(staticLayoutBlobId);
104
105 EXPECT_CALL(*verifyMockPtr, abort()).Times(0);
106
107 ASSERT_TRUE(handler->canHandleBlob(staticLayoutBlobId));
108 EXPECT_TRUE(handler->deleteBlob(staticLayoutBlobId));
109
110 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId};
111 EXPECT_THAT(handler->getBlobIds(),
112 UnorderedElementsAreArray(expectedBlobs));
113 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
114}
115
116TEST_F(FirmwareHandlerVerificationPendingTest, DeleteHashAbortsProcess)
117{
118 getToVerificationPending(staticLayoutBlobId);
119
120 EXPECT_CALL(*verifyMockPtr, abort()).Times(0);
121
122 ASSERT_TRUE(handler->canHandleBlob(hashBlobId));
123 EXPECT_TRUE(handler->deleteBlob(hashBlobId));
124
125 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId};
126 EXPECT_THAT(handler->getBlobIds(),
127 UnorderedElementsAreArray(expectedBlobs));
128 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
129}
Patrick Ventureb386b862019-05-23 18:42:54 -0700130
131/*
Patrick Venture92f26152020-05-26 19:47:36 -0700132 * expire(session)
133 */
134TEST_F(FirmwareHandlerVerificationPendingTest,
135 ExpireVerificationPendingAbortsProcess)
136{
137 getToVerificationPending(staticLayoutBlobId);
138
139 EXPECT_CALL(*verifyMockPtr, abort()).Times(0);
140
141 EXPECT_TRUE(handler->expire(session));
142
143 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId};
144 EXPECT_THAT(handler->getBlobIds(),
145 UnorderedElementsAreArray(expectedBlobs));
146 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
147}
148
149/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700150 * stat(blob)
151 */
152TEST_F(FirmwareHandlerVerificationPendingTest, StatOnActiveImageReturnsFailure)
153{
154 getToVerificationPending(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -0700155 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -0700156
157 blobs::BlobMeta meta;
158 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
159}
160
161TEST_F(FirmwareHandlerVerificationPendingTest, StatOnActiveHashReturnsFailure)
162{
163 getToVerificationPending(hashBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -0700164 ASSERT_TRUE(handler->canHandleBlob(activeHashBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -0700165
166 blobs::BlobMeta meta;
167 EXPECT_FALSE(handler->stat(activeHashBlobId, &meta));
168}
169
170TEST_F(FirmwareHandlerVerificationPendingTest,
171 StatOnVerificationBlobReturnsFailure)
172{
Patrick Venture1999eef2019-07-01 11:44:09 -0700173 getToVerificationPending(staticLayoutBlobId);
Patrick Venture0f82ce42019-05-28 14:06:04 -0700174 ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -0700175
176 blobs::BlobMeta meta;
177 EXPECT_FALSE(handler->stat(verifyBlobId, &meta));
178}
179
Patrick Venture1999eef2019-07-01 11:44:09 -0700180TEST_F(FirmwareHandlerVerificationPendingTest,
181 VerificationBlobNotFoundWithoutStaticDataAsWell)
182{
183 /* If you only ever open the hash blob id, and never the firmware blob id,
184 * the verify blob isn't added.
185 */
186 getToVerificationPending(hashBlobId);
187 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
188}
189
Patrick Ventureb386b862019-05-23 18:42:54 -0700190TEST_F(FirmwareHandlerVerificationPendingTest, StatOnNormalBlobsReturnsSuccess)
191{
192 getToVerificationPending(staticLayoutBlobId);
193
Patrick Ventureb386b862019-05-23 18:42:54 -0700194 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
195 for (const auto& blob : testBlobs)
196 {
Patrick Venture930c7b72019-05-24 11:11:08 -0700197 ASSERT_TRUE(handler->canHandleBlob(blob));
Patrick Ventureb386b862019-05-23 18:42:54 -0700198 blobs::BlobMeta meta = {};
199 EXPECT_TRUE(handler->stat(blob, &meta));
Benjamin Fair12901982019-11-12 13:55:46 -0800200 EXPECT_EQ(expectedIdleMeta, meta);
Patrick Ventureb386b862019-05-23 18:42:54 -0700201 }
202}
203
204/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700205 * open(blob)
206 */
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700207TEST_F(FirmwareHandlerVerificationPendingTest, OpenVerifyBlobSucceeds)
208{
209 getToVerificationPending(staticLayoutBlobId);
210
211 /* the session is safe because it was already closed to get to this state.
212 */
213 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
214}
215
Patrick Venture0f82ce42019-05-28 14:06:04 -0700216TEST_F(FirmwareHandlerVerificationPendingTest, OpenActiveBlobsFail)
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700217{
218 /* Try opening the active blob Id. This test is equivalent to trying to
219 * open the active hash blob id, in that neither are ever allowed.
220 */
221 getToVerificationPending(staticLayoutBlobId);
222 EXPECT_FALSE(handler->open(session, flags, activeImageBlobId));
Patrick Venture0f82ce42019-05-28 14:06:04 -0700223 EXPECT_FALSE(handler->open(session, flags, activeHashBlobId));
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700224}
225
226TEST_F(FirmwareHandlerVerificationPendingTest,
227 OpenImageBlobTransitionsToUploadInProgress)
228{
229 getToVerificationPending(staticLayoutBlobId);
Patrick Ventureefba42d2019-05-24 10:48:16 -0700230
231 /* Verify the active blob for the image is in the list once to start.
232 * Note: This is truly tested under the notYetStarted::open() test.
233 */
234 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId,
235 verifyBlobId, activeImageBlobId};
236
237 EXPECT_THAT(handler->getBlobIds(),
238 UnorderedElementsAreArray(expectedBlobs));
239
Patrick Venture6d7735d2019-06-21 10:03:19 -0700240 /* Verifies it isn't triggered again. */
241 EXPECT_CALL(*prepareMockPtr, trigger()).Times(0);
242
Patrick Ventured4e20de2019-07-18 12:48:05 -0700243 EXPECT_CALL(*imageMock2, open(staticLayoutBlobId)).WillOnce(Return(true));
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700244 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700245 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
Patrick Ventureefba42d2019-05-24 10:48:16 -0700246
Patrick Venture930c7b72019-05-24 11:11:08 -0700247 expectedBlobs.erase(
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700248 std::remove(expectedBlobs.begin(), expectedBlobs.end(), verifyBlobId),
249 expectedBlobs.end());
Patrick Venture930c7b72019-05-24 11:11:08 -0700250
251 /* Verify the active blob ID was not added to the list twice and
252 * verifyBlobId is removed
253 */
Patrick Ventureefba42d2019-05-24 10:48:16 -0700254 EXPECT_THAT(handler->getBlobIds(),
255 UnorderedElementsAreArray(expectedBlobs));
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700256}
257
258/*
Patrick Venture1e389c92019-05-23 19:15:05 -0700259 * close(session)
260 */
261TEST_F(FirmwareHandlerVerificationPendingTest,
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700262 ClosingVerifyBlobWithoutCommitDoesNotChangeState)
Patrick Venture1e389c92019-05-23 19:15:05 -0700263{
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700264 /* commit() will change the state, closing post-commit is part of
265 * verificationStarted testing.
266 */
Patrick Venture1e389c92019-05-23 19:15:05 -0700267 getToVerificationPending(staticLayoutBlobId);
268 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700269 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture1e389c92019-05-23 19:15:05 -0700270
271 handler->close(session);
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700272 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture1e389c92019-05-23 19:15:05 -0700273}
274
275/*
Patrick Venture19044e12019-05-23 19:30:28 -0700276 * commit(session)
277 */
278TEST_F(FirmwareHandlerVerificationPendingTest,
279 CommitOnVerifyBlobTriggersVerificationAndStateTransition)
280{
281 getToVerificationPending(staticLayoutBlobId);
282 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture1d66fe62019-06-03 14:57:27 -0700283 EXPECT_CALL(*verifyMockPtr, trigger()).WillOnce(Return(true));
Patrick Venture19044e12019-05-23 19:30:28 -0700284
285 EXPECT_TRUE(handler->commit(session, {}));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700286 expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);
Patrick Venture19044e12019-05-23 19:30:28 -0700287}
288
289/*
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700290 * stat(session) - in this state, you can only open(verifyBlobId) without
291 * changing state.
292 */
Patrick Venture01a33272019-05-23 19:48:22 -0700293TEST_F(FirmwareHandlerVerificationPendingTest, StatOnVerifyBlobIdReturnsState)
294{
295 /* If this is called before commit(), it's still verificationPending, so it
296 * just returns the state is other
297 */
298 getToVerificationPending(staticLayoutBlobId);
299 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture1d66fe62019-06-03 14:57:27 -0700300 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700301 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture01a33272019-05-23 19:48:22 -0700302
303 blobs::BlobMeta meta, expectedMeta = {};
304 expectedMeta.size = 0;
305 expectedMeta.blobState = flags;
306 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700307 static_cast<std::uint8_t>(ActionStatus::unknown));
Patrick Venture01a33272019-05-23 19:48:22 -0700308
309 EXPECT_TRUE(handler->stat(session, &meta));
310 EXPECT_EQ(expectedMeta, meta);
311}
312
Patrick Ventureb386b862019-05-23 18:42:54 -0700313/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700314 * writemeta(session)
315 */
Patrick Ventureb611a082019-05-23 20:27:28 -0700316TEST_F(FirmwareHandlerVerificationPendingTest, WriteMetaAgainstVerifyFails)
317{
318 /* The verifyBlobId has no data handler, which means write meta fails. */
319 getToVerificationPending(staticLayoutBlobId);
320
321 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
322
323 std::vector<std::uint8_t> bytes = {0x01, 0x02};
324 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
325}
326
Patrick Ventureb386b862019-05-23 18:42:54 -0700327/*
328 * write(session)
329 */
Patrick Ventureab731e92019-05-24 09:58:00 -0700330TEST_F(FirmwareHandlerVerificationPendingTest, WriteAgainstVerifyBlobIdFails)
331{
332 getToVerificationPending(staticLayoutBlobId);
333
334 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
335
336 std::vector<std::uint8_t> bytes = {0x01, 0x02};
337 EXPECT_FALSE(handler->write(session, 0, bytes));
338}
339
Patrick Ventureb386b862019-05-23 18:42:54 -0700340/*
341 * read(session)
342 */
Patrick Venture2567ebc2019-05-24 10:02:53 -0700343TEST_F(FirmwareHandlerVerificationPendingTest,
344 ReadAgainstVerifyBlobIdReturnsEmpty)
345{
346 getToVerificationPending(staticLayoutBlobId);
347
348 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture0f82ce42019-05-28 14:06:04 -0700349 EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
Patrick Venture2567ebc2019-05-24 10:02:53 -0700350}
Patrick Ventureb386b862019-05-23 18:42:54 -0700351
Patrick Venture61d2ed42019-05-23 18:16:31 -0700352} // namespace
353} // namespace ipmi_flash