blob: 85f1895dff8cbb82acaa993cbffbf50a779928e8 [file] [log] [blame]
Patrick Venturea82f99e2019-05-24 15:44:35 -07001/**
2 * The goal of these tests is to verify the behavior of all blob commands given
3 * the current state is verificationCompleted. This state is achieved as a out
4 * of verificationStarted.
5 */
6#include "firmware_handler.hpp"
7#include "firmware_unittest.hpp"
8#include "status.hpp"
9#include "util.hpp"
10
11#include <cstdint>
12#include <string>
13#include <vector>
14
15#include <gtest/gtest.h>
16
17namespace ipmi_flash
18{
19namespace
20{
21
Patrick Venture65cdcf02019-05-29 10:18:50 -070022using ::testing::IsEmpty;
Patrick Venturea82f99e2019-05-24 15:44:35 -070023using ::testing::Return;
Patrick Venture6d3a14c2019-05-29 09:24:42 -070024using ::testing::UnorderedElementsAreArray;
Patrick Venturea82f99e2019-05-24 15:44:35 -070025
26/*
27 * There are the following calls (parameters may vary):
28 * canHandleBlob(blob)
29 * getBlobIds
30 * deleteBlob(blob)
31 * stat(blob)
32 * stat(session)
33 * open(blob)
34 * close(session)
35 * writemeta(session)
36 * write(session)
37 * read(session)
38 * commit(session)
39 *
40 * Like the state verificationStarted, there is a file open in
41 * verificationCompleted. This state is transitioned to after a stat() command
42 * indicates a successful verification.
43 */
44
45class FirmwareHandlerVerificationCompletedTest
46 : public IpmiOnlyFirmwareStaticTest
47{
Patrick Venturea82f99e2019-05-24 15:44:35 -070048};
49
Patrick Venturebcc0c772019-06-17 10:42:06 -070050/*
51 * deleteBlob(blob)
52 */
53TEST_F(FirmwareHandlerVerificationCompletedTest, DeleteBlobReturnsFalse)
54{
55 /* Try deleting all blobs, it doesn't really matter which though because you
56 * cannot close out an open session, therefore you must fail to delete
57 * anything unless everything is closed.
58 */
59 getToVerificationCompleted(ActionStatus::success);
60 auto blobs = handler->getBlobIds();
61 for (const auto& b : blobs)
62 {
63 EXPECT_FALSE(handler->deleteBlob(b));
64 }
65}
Patrick Venture6d3a14c2019-05-29 09:24:42 -070066
67/*
68 * canHandleBlob
Patrick Venturea82f99e2019-05-24 15:44:35 -070069 */
Patrick Venture6d3a14c2019-05-29 09:24:42 -070070TEST_F(FirmwareHandlerVerificationCompletedTest,
71 OnVerificationCompleteSuccessUpdateBlobIdNotPresent)
72{
73 /* the uploadBlobId is only added on close() of the verifyBlobId. This is a
74 * consistent behavior with verifyBlobId only added when closing the image
75 * or hash.
76 */
Patrick Ventureda66fd82019-06-03 11:11:24 -070077 getToVerificationCompleted(ActionStatus::success);
Patrick Venture6d3a14c2019-05-29 09:24:42 -070078 EXPECT_FALSE(handler->canHandleBlob(updateBlobId));
79}
80
81TEST_F(FirmwareHandlerVerificationCompletedTest,
82 OnVerificationCompleteFailureUpdateBlobIdNotPresent)
83{
Patrick Ventureda66fd82019-06-03 11:11:24 -070084 getToVerificationCompleted(ActionStatus::failed);
Patrick Venture6d3a14c2019-05-29 09:24:42 -070085 EXPECT_FALSE(handler->canHandleBlob(updateBlobId));
86}
87
88/*
89 * getBlobIds
90 */
91TEST_F(FirmwareHandlerVerificationCompletedTest, GetBlobIdsReturnsExpectedList)
92{
Patrick Ventureda66fd82019-06-03 11:11:24 -070093 getToVerificationCompleted(ActionStatus::success);
Patrick Venture9a69f732019-06-17 14:05:13 -070094 EXPECT_THAT(
95 handler->getBlobIds(),
96 UnorderedElementsAreArray(
97 {verifyBlobId, hashBlobId, activeImageBlobId, staticLayoutBlobId}));
Patrick Venture6d3a14c2019-05-29 09:24:42 -070098}
Patrick Venturea82f99e2019-05-24 15:44:35 -070099
100/*
101 * stat(blob)
102 */
Patrick Venture0c642fd2019-05-24 16:09:29 -0700103TEST_F(FirmwareHandlerVerificationCompletedTest,
104 StatOnActiveImageReturnsFailure)
105{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700106 getToVerificationCompleted(ActionStatus::success);
Patrick Venture0c642fd2019-05-24 16:09:29 -0700107 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
108
109 blobs::BlobMeta meta;
110 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
111}
112
Patrick Venturefbf07ff2019-05-29 08:58:45 -0700113TEST_F(FirmwareHandlerVerificationCompletedTest,
114 VerifyActiveHashIdMissingInThisCase)
115{
116 /* The path taken to get to this state never opened the hash blob Id, which
117 * is fine. But let's verify it behaved as intended.
118 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700119 getToVerificationCompleted(ActionStatus::success);
Patrick Venturefbf07ff2019-05-29 08:58:45 -0700120 EXPECT_FALSE(handler->canHandleBlob(activeHashBlobId));
121}
122
123/* TODO: Add sufficient warning that you can get to verificationCompleted
124 * without ever opening the image blob id (or the tarball one).
125 *
126 * Although in this case, it's expected that any verification triggered would
127 * certainly fail. So, although it's possible, it's uninteresting.
128 */
129
Patrick Venture0c642fd2019-05-24 16:09:29 -0700130TEST_F(FirmwareHandlerVerificationCompletedTest, StatOnVerifyBlobReturnsFailure)
131{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700132 getToVerificationCompleted(ActionStatus::success);
Patrick Venture0c642fd2019-05-24 16:09:29 -0700133 ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));
134
135 blobs::BlobMeta meta;
136 EXPECT_FALSE(handler->stat(verifyBlobId, &meta));
137}
138
139TEST_F(FirmwareHandlerVerificationCompletedTest,
140 StatOnNormalBlobsReturnsSuccess)
141{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700142 getToVerificationCompleted(ActionStatus::success);
Patrick Venture0c642fd2019-05-24 16:09:29 -0700143
144 blobs::BlobMeta expected;
Patrick Venture84778b82019-06-26 20:11:09 -0700145 expected.blobState = FirmwareFlags::UpdateFlags::ipmi;
Patrick Venture0c642fd2019-05-24 16:09:29 -0700146 expected.size = 0;
147
148 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
149 for (const auto& blob : testBlobs)
150 {
151 ASSERT_TRUE(handler->canHandleBlob(blob));
152
153 blobs::BlobMeta meta = {};
154 EXPECT_TRUE(handler->stat(blob, &meta));
155 EXPECT_EQ(expected, meta);
156 }
157}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700158
159/*
160 * stat(session) - the verify blobid is open in this state, so stat on that once
161 * completed should have no effect.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700162 */
Patrick Venture615c69e2019-05-29 10:49:54 -0700163TEST_F(FirmwareHandlerVerificationCompletedTest,
164 SessionStatOnVerifyAfterSuccessDoesNothing)
165{
166 /* Every time you stat() once it's triggered, it checks the state again
167 * until it's completed.
168 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700169 getToVerificationCompleted(ActionStatus::success);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700170 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture615c69e2019-05-29 10:49:54 -0700171
172 blobs::BlobMeta meta, expectedMeta = {};
173 expectedMeta.size = 0;
174 expectedMeta.blobState = flags | blobs::StateFlags::committed;
175 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700176 static_cast<std::uint8_t>(ActionStatus::success));
Patrick Venture615c69e2019-05-29 10:49:54 -0700177
178 EXPECT_TRUE(handler->stat(session, &meta));
179 EXPECT_EQ(expectedMeta, meta);
180 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
181}
182
183TEST_F(FirmwareHandlerVerificationCompletedTest,
184 SessionStatOnVerifyAfterFailureDoesNothing)
185{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700186 getToVerificationCompleted(ActionStatus::failed);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700187 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture615c69e2019-05-29 10:49:54 -0700188
189 blobs::BlobMeta meta, expectedMeta = {};
190 expectedMeta.size = 0;
191 expectedMeta.blobState = flags | blobs::StateFlags::commit_error;
192 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700193 static_cast<std::uint8_t>(ActionStatus::failed));
Patrick Venture615c69e2019-05-29 10:49:54 -0700194
195 EXPECT_TRUE(handler->stat(session, &meta));
196 EXPECT_EQ(expectedMeta, meta);
197 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
198}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700199
200/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700201 * open(blob) - all open should fail
Patrick Venturea82f99e2019-05-24 15:44:35 -0700202 */
Patrick Ventureeee71812019-05-29 10:41:04 -0700203TEST_F(FirmwareHandlerVerificationCompletedTest,
204 OpeningAnyBlobAvailableFailsAfterSuccess)
205{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700206 getToVerificationCompleted(ActionStatus::success);
Patrick Ventureeee71812019-05-29 10:41:04 -0700207
208 auto blobs = handler->getBlobIds();
209 for (const auto& blob : blobs)
210 {
211 EXPECT_FALSE(handler->open(session + 1, flags, blob));
212 }
213}
214
215TEST_F(FirmwareHandlerVerificationCompletedTest,
216 OpeningAnyBlobAvailableFailsAfterFailure)
217{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700218 getToVerificationCompleted(ActionStatus::failed);
Patrick Ventureeee71812019-05-29 10:41:04 -0700219
220 auto blobs = handler->getBlobIds();
221 for (const auto& blob : blobs)
222 {
223 EXPECT_FALSE(handler->open(session + 1, flags, blob));
224 }
225}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700226
227/*
228 * writemeta(session) - write meta should fail.
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700229 */
Patrick Venture2b801372019-05-29 10:26:01 -0700230TEST_F(FirmwareHandlerVerificationCompletedTest,
231 WriteMetaToVerifyBlobReturnsFailure)
232{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700233 getToVerificationCompleted(ActionStatus::success);
Patrick Venture2b801372019-05-29 10:26:01 -0700234
235 std::vector<std::uint8_t> bytes = {0x01, 0x02};
236 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
237}
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700238
239/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700240 * write(session) - write should fail.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700241 */
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700242TEST_F(FirmwareHandlerVerificationCompletedTest,
243 WriteToVerifyBlobReturnsFailure)
244{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700245 getToVerificationCompleted(ActionStatus::success);
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700246
247 std::vector<std::uint8_t> bytes = {0x01, 0x02};
248 EXPECT_FALSE(handler->write(session, 0, bytes));
249}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700250
251/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700252 * read(session) - read returns empty.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700253 */
254TEST_F(FirmwareHandlerVerificationCompletedTest, ReadOfVerifyBlobReturnsEmpty)
255{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700256 getToVerificationCompleted(ActionStatus::success);
Patrick Venture65cdcf02019-05-29 10:18:50 -0700257 EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
258}
259
260/*
Patrick Venture433cbc32019-05-30 09:53:10 -0700261 * commit(session) - returns failure
Patrick Venturea82f99e2019-05-24 15:44:35 -0700262 */
Patrick Venture433cbc32019-05-30 09:53:10 -0700263TEST_F(FirmwareHandlerVerificationCompletedTest,
264 CommitOnVerifyBlobAfterSuccessReturnsFailure)
265{
266 /* If you've started this'll return success, but if it's finished, it won't
267 * let you try-again.
268 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700269 getToVerificationCompleted(ActionStatus::success);
Patrick Venture1d66fe62019-06-03 14:57:27 -0700270 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venture433cbc32019-05-30 09:53:10 -0700271
272 EXPECT_FALSE(handler->commit(session, {}));
273}
274
275TEST_F(FirmwareHandlerVerificationCompletedTest,
276 CommitOnVerifyBlobAfterFailureReturnsFailure)
277{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700278 getToVerificationCompleted(ActionStatus::failed);
Patrick Venture1d66fe62019-06-03 14:57:27 -0700279 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venture433cbc32019-05-30 09:53:10 -0700280
281 EXPECT_FALSE(handler->commit(session, {}));
282}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700283
Patrick Venture65cdcf02019-05-29 10:18:50 -0700284/*
285 * close(session) - close on the verify blobid:
286 * 1. if successful adds update blob id, changes state to UpdatePending
Patrick Venture1c6d8f52019-05-30 10:53:49 -0700287 */
288TEST_F(FirmwareHandlerVerificationCompletedTest,
289 CloseAfterSuccessChangesStateAddsUpdateBlob)
290{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700291 getToVerificationCompleted(ActionStatus::success);
Patrick Venture1c6d8f52019-05-30 10:53:49 -0700292 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
293
294 handler->close(session);
295 EXPECT_TRUE(handler->canHandleBlob(updateBlobId));
296 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
297}
298
299/*
300 * close(session) - close on the verify blobid:
Patrick Venture5d9fa022019-06-17 13:13:30 -0700301 * 2. if unsuccessful it aborts.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700302 */
Patrick Venture5d9fa022019-06-17 13:13:30 -0700303TEST_F(FirmwareHandlerVerificationCompletedTest, CloseAfterFailureAborts)
304{
305 getToVerificationCompleted(ActionStatus::failed);
306 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
307
308 handler->close(session);
309 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
310 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
Patrick Venture9a69f732019-06-17 14:05:13 -0700311 EXPECT_THAT(handler->getBlobIds(),
312 UnorderedElementsAreArray(startingBlobs));
Patrick Venture5d9fa022019-06-17 13:13:30 -0700313}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700314
Patrick Venturea82f99e2019-05-24 15:44:35 -0700315} // namespace
316} // namespace ipmi_flash