blob: 92d5c6b484a01bc9cc5fc27422a09725b03abec5 [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{
Patrick Venture61d2ed42019-05-23 18:16:31 -070047};
48
49/*
50 * getBlobIds
Patrick Venture61d2ed42019-05-23 18:16:31 -070051 */
Patrick Venture61d2ed42019-05-23 18:16:31 -070052TEST_F(FirmwareHandlerVerificationPendingTest, VerifyBlobIdAvailableInState)
53{
54 /* Only in the verificationPending state (and later), should the
Patrick Venture0f82ce42019-05-28 14:06:04 -070055 * verifyBlobId be present.
56 */
Patrick Venture930c7b72019-05-24 11:11:08 -070057 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
58
Patrick Venture61d2ed42019-05-23 18:16:31 -070059 getToVerificationPending(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070060
Patrick Venture61d2ed42019-05-23 18:16:31 -070061 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -070062 EXPECT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Venture0f82ce42019-05-28 14:06:04 -070063 EXPECT_FALSE(handler->canHandleBlob(updateBlobId));
Patrick Venture61d2ed42019-05-23 18:16:31 -070064}
65
Patrick Ventureb386b862019-05-23 18:42:54 -070066/*
Patrick Venture2ca66522019-06-17 11:58:38 -070067 * delete(blob)
Patrick Ventureb386b862019-05-23 18:42:54 -070068 */
Patrick Venture2ca66522019-06-17 11:58:38 -070069TEST_F(FirmwareHandlerVerificationPendingTest, DeleteVerifyPendingAbortsProcess)
70{
71 /* It doesn't matter what blob id is used to delete in the design, so just
72 * delete the verify blob id
73 */
74 getToVerificationPending(staticLayoutBlobId);
75
76 EXPECT_CALL(*verifyMockPtr, abort()).Times(0);
77
78 ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));
79 EXPECT_TRUE(handler->deleteBlob(verifyBlobId));
80
81 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId};
82 EXPECT_THAT(handler->getBlobIds(),
83 UnorderedElementsAreArray(expectedBlobs));
84 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
85}
86
87TEST_F(FirmwareHandlerVerificationPendingTest, DeleteActiveImageAbortsProcess)
88{
89 getToVerificationPending(staticLayoutBlobId);
90
91 EXPECT_CALL(*verifyMockPtr, abort()).Times(0);
92
93 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
94 EXPECT_TRUE(handler->deleteBlob(activeImageBlobId));
95
96 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId};
97 EXPECT_THAT(handler->getBlobIds(),
98 UnorderedElementsAreArray(expectedBlobs));
99 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
100}
101
102TEST_F(FirmwareHandlerVerificationPendingTest, DeleteStaticLayoutAbortsProcess)
103{
104 getToVerificationPending(staticLayoutBlobId);
105
106 EXPECT_CALL(*verifyMockPtr, abort()).Times(0);
107
108 ASSERT_TRUE(handler->canHandleBlob(staticLayoutBlobId));
109 EXPECT_TRUE(handler->deleteBlob(staticLayoutBlobId));
110
111 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId};
112 EXPECT_THAT(handler->getBlobIds(),
113 UnorderedElementsAreArray(expectedBlobs));
114 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
115}
116
117TEST_F(FirmwareHandlerVerificationPendingTest, DeleteHashAbortsProcess)
118{
119 getToVerificationPending(staticLayoutBlobId);
120
121 EXPECT_CALL(*verifyMockPtr, abort()).Times(0);
122
123 ASSERT_TRUE(handler->canHandleBlob(hashBlobId));
124 EXPECT_TRUE(handler->deleteBlob(hashBlobId));
125
126 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId};
127 EXPECT_THAT(handler->getBlobIds(),
128 UnorderedElementsAreArray(expectedBlobs));
129 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
130}
Patrick Ventureb386b862019-05-23 18:42:54 -0700131
132/*
133 * stat(blob)
134 */
135TEST_F(FirmwareHandlerVerificationPendingTest, StatOnActiveImageReturnsFailure)
136{
137 getToVerificationPending(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -0700138 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -0700139
140 blobs::BlobMeta meta;
141 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
142}
143
144TEST_F(FirmwareHandlerVerificationPendingTest, StatOnActiveHashReturnsFailure)
145{
146 getToVerificationPending(hashBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -0700147 ASSERT_TRUE(handler->canHandleBlob(activeHashBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -0700148
149 blobs::BlobMeta meta;
150 EXPECT_FALSE(handler->stat(activeHashBlobId, &meta));
151}
152
153TEST_F(FirmwareHandlerVerificationPendingTest,
154 StatOnVerificationBlobReturnsFailure)
155{
Patrick Venture1999eef2019-07-01 11:44:09 -0700156 getToVerificationPending(staticLayoutBlobId);
Patrick Venture0f82ce42019-05-28 14:06:04 -0700157 ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -0700158
159 blobs::BlobMeta meta;
160 EXPECT_FALSE(handler->stat(verifyBlobId, &meta));
161}
162
Patrick Venture1999eef2019-07-01 11:44:09 -0700163TEST_F(FirmwareHandlerVerificationPendingTest,
164 VerificationBlobNotFoundWithoutStaticDataAsWell)
165{
166 /* If you only ever open the hash blob id, and never the firmware blob id,
167 * the verify blob isn't added.
168 */
169 getToVerificationPending(hashBlobId);
170 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
171}
172
Patrick Ventureb386b862019-05-23 18:42:54 -0700173TEST_F(FirmwareHandlerVerificationPendingTest, StatOnNormalBlobsReturnsSuccess)
174{
175 getToVerificationPending(staticLayoutBlobId);
176
177 blobs::BlobMeta expected;
Patrick Venture84778b82019-06-26 20:11:09 -0700178 expected.blobState = FirmwareFlags::UpdateFlags::ipmi;
Patrick Ventureb386b862019-05-23 18:42:54 -0700179 expected.size = 0;
180
181 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
182 for (const auto& blob : testBlobs)
183 {
Patrick Venture930c7b72019-05-24 11:11:08 -0700184 ASSERT_TRUE(handler->canHandleBlob(blob));
Patrick Ventureb386b862019-05-23 18:42:54 -0700185 blobs::BlobMeta meta = {};
186 EXPECT_TRUE(handler->stat(blob, &meta));
187 EXPECT_EQ(expected, meta);
188 }
189}
190
191/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700192 * open(blob)
193 */
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700194TEST_F(FirmwareHandlerVerificationPendingTest, OpenVerifyBlobSucceeds)
195{
196 getToVerificationPending(staticLayoutBlobId);
197
198 /* the session is safe because it was already closed to get to this state.
199 */
200 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
201}
202
Patrick Venture0f82ce42019-05-28 14:06:04 -0700203TEST_F(FirmwareHandlerVerificationPendingTest, OpenActiveBlobsFail)
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700204{
205 /* Try opening the active blob Id. This test is equivalent to trying to
206 * open the active hash blob id, in that neither are ever allowed.
207 */
208 getToVerificationPending(staticLayoutBlobId);
209 EXPECT_FALSE(handler->open(session, flags, activeImageBlobId));
Patrick Venture0f82ce42019-05-28 14:06:04 -0700210 EXPECT_FALSE(handler->open(session, flags, activeHashBlobId));
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700211}
212
213TEST_F(FirmwareHandlerVerificationPendingTest,
214 OpenImageBlobTransitionsToUploadInProgress)
215{
216 getToVerificationPending(staticLayoutBlobId);
Patrick Ventureefba42d2019-05-24 10:48:16 -0700217
218 /* Verify the active blob for the image is in the list once to start.
219 * Note: This is truly tested under the notYetStarted::open() test.
220 */
221 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId,
222 verifyBlobId, activeImageBlobId};
223
224 EXPECT_THAT(handler->getBlobIds(),
225 UnorderedElementsAreArray(expectedBlobs));
226
Patrick Venture6d7735d2019-06-21 10:03:19 -0700227 /* Verifies it isn't triggered again. */
228 EXPECT_CALL(*prepareMockPtr, trigger()).Times(0);
229
Patrick Ventured4e20de2019-07-18 12:48:05 -0700230 EXPECT_CALL(*imageMock2, open(staticLayoutBlobId)).WillOnce(Return(true));
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700231 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700232 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
Patrick Ventureefba42d2019-05-24 10:48:16 -0700233
Patrick Venture930c7b72019-05-24 11:11:08 -0700234 expectedBlobs.erase(
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700235 std::remove(expectedBlobs.begin(), expectedBlobs.end(), verifyBlobId),
236 expectedBlobs.end());
Patrick Venture930c7b72019-05-24 11:11:08 -0700237
238 /* Verify the active blob ID was not added to the list twice and
239 * verifyBlobId is removed
240 */
Patrick Ventureefba42d2019-05-24 10:48:16 -0700241 EXPECT_THAT(handler->getBlobIds(),
242 UnorderedElementsAreArray(expectedBlobs));
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700243}
244
245/*
Patrick Venture1e389c92019-05-23 19:15:05 -0700246 * close(session)
247 */
248TEST_F(FirmwareHandlerVerificationPendingTest,
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700249 ClosingVerifyBlobWithoutCommitDoesNotChangeState)
Patrick Venture1e389c92019-05-23 19:15:05 -0700250{
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700251 /* commit() will change the state, closing post-commit is part of
252 * verificationStarted testing.
253 */
Patrick Venture1e389c92019-05-23 19:15:05 -0700254 getToVerificationPending(staticLayoutBlobId);
255 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700256 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture1e389c92019-05-23 19:15:05 -0700257
258 handler->close(session);
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700259 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture1e389c92019-05-23 19:15:05 -0700260}
261
262/*
Patrick Venture19044e12019-05-23 19:30:28 -0700263 * commit(session)
264 */
265TEST_F(FirmwareHandlerVerificationPendingTest,
266 CommitOnVerifyBlobTriggersVerificationAndStateTransition)
267{
268 getToVerificationPending(staticLayoutBlobId);
269 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture1d66fe62019-06-03 14:57:27 -0700270 EXPECT_CALL(*verifyMockPtr, trigger()).WillOnce(Return(true));
Patrick Venture19044e12019-05-23 19:30:28 -0700271
272 EXPECT_TRUE(handler->commit(session, {}));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700273 expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);
Patrick Venture19044e12019-05-23 19:30:28 -0700274}
275
276/*
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700277 * stat(session) - in this state, you can only open(verifyBlobId) without
278 * changing state.
279 */
Patrick Venture01a33272019-05-23 19:48:22 -0700280TEST_F(FirmwareHandlerVerificationPendingTest, StatOnVerifyBlobIdReturnsState)
281{
282 /* If this is called before commit(), it's still verificationPending, so it
283 * just returns the state is other
284 */
285 getToVerificationPending(staticLayoutBlobId);
286 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture1d66fe62019-06-03 14:57:27 -0700287 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700288 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture01a33272019-05-23 19:48:22 -0700289
290 blobs::BlobMeta meta, expectedMeta = {};
291 expectedMeta.size = 0;
292 expectedMeta.blobState = flags;
293 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700294 static_cast<std::uint8_t>(ActionStatus::unknown));
Patrick Venture01a33272019-05-23 19:48:22 -0700295
296 EXPECT_TRUE(handler->stat(session, &meta));
297 EXPECT_EQ(expectedMeta, meta);
298}
299
Patrick Ventureb386b862019-05-23 18:42:54 -0700300/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700301 * writemeta(session)
302 */
Patrick Ventureb611a082019-05-23 20:27:28 -0700303TEST_F(FirmwareHandlerVerificationPendingTest, WriteMetaAgainstVerifyFails)
304{
305 /* The verifyBlobId has no data handler, which means write meta fails. */
306 getToVerificationPending(staticLayoutBlobId);
307
308 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
309
310 std::vector<std::uint8_t> bytes = {0x01, 0x02};
311 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
312}
313
Patrick Ventureb386b862019-05-23 18:42:54 -0700314/*
315 * write(session)
316 */
Patrick Ventureab731e92019-05-24 09:58:00 -0700317TEST_F(FirmwareHandlerVerificationPendingTest, WriteAgainstVerifyBlobIdFails)
318{
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->write(session, 0, bytes));
325}
326
Patrick Ventureb386b862019-05-23 18:42:54 -0700327/*
328 * read(session)
329 */
Patrick Venture2567ebc2019-05-24 10:02:53 -0700330TEST_F(FirmwareHandlerVerificationPendingTest,
331 ReadAgainstVerifyBlobIdReturnsEmpty)
332{
333 getToVerificationPending(staticLayoutBlobId);
334
335 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture0f82ce42019-05-28 14:06:04 -0700336 EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
Patrick Venture2567ebc2019-05-24 10:02:53 -0700337}
Patrick Ventureb386b862019-05-23 18:42:54 -0700338
Patrick Venture61d2ed42019-05-23 18:16:31 -0700339} // namespace
340} // namespace ipmi_flash