blob: 0f02cf37ec00a4c462722c1cee6b1ca4e7008062 [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 Venture6d3a14c2019-05-29 09:24:42 -070094 std::vector<std::string> expected = {verifyBlobId, hashBlobId,
95 activeImageBlobId, staticLayoutBlobId};
96 EXPECT_THAT(handler->getBlobIds(), UnorderedElementsAreArray(expected));
97}
Patrick Venturea82f99e2019-05-24 15:44:35 -070098
99/*
100 * stat(blob)
101 */
Patrick Venture0c642fd2019-05-24 16:09:29 -0700102TEST_F(FirmwareHandlerVerificationCompletedTest,
103 StatOnActiveImageReturnsFailure)
104{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700105 getToVerificationCompleted(ActionStatus::success);
Patrick Venture0c642fd2019-05-24 16:09:29 -0700106 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
107
108 blobs::BlobMeta meta;
109 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
110}
111
Patrick Venturefbf07ff2019-05-29 08:58:45 -0700112TEST_F(FirmwareHandlerVerificationCompletedTest,
113 VerifyActiveHashIdMissingInThisCase)
114{
115 /* The path taken to get to this state never opened the hash blob Id, which
116 * is fine. But let's verify it behaved as intended.
117 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700118 getToVerificationCompleted(ActionStatus::success);
Patrick Venturefbf07ff2019-05-29 08:58:45 -0700119 EXPECT_FALSE(handler->canHandleBlob(activeHashBlobId));
120}
121
122/* TODO: Add sufficient warning that you can get to verificationCompleted
123 * without ever opening the image blob id (or the tarball one).
124 *
125 * Although in this case, it's expected that any verification triggered would
126 * certainly fail. So, although it's possible, it's uninteresting.
127 */
128
Patrick Venture0c642fd2019-05-24 16:09:29 -0700129TEST_F(FirmwareHandlerVerificationCompletedTest, StatOnVerifyBlobReturnsFailure)
130{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700131 getToVerificationCompleted(ActionStatus::success);
Patrick Venture0c642fd2019-05-24 16:09:29 -0700132 ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));
133
134 blobs::BlobMeta meta;
135 EXPECT_FALSE(handler->stat(verifyBlobId, &meta));
136}
137
138TEST_F(FirmwareHandlerVerificationCompletedTest,
139 StatOnNormalBlobsReturnsSuccess)
140{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700141 getToVerificationCompleted(ActionStatus::success);
Patrick Venture0c642fd2019-05-24 16:09:29 -0700142
143 blobs::BlobMeta expected;
144 expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
145 expected.size = 0;
146
147 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
148 for (const auto& blob : testBlobs)
149 {
150 ASSERT_TRUE(handler->canHandleBlob(blob));
151
152 blobs::BlobMeta meta = {};
153 EXPECT_TRUE(handler->stat(blob, &meta));
154 EXPECT_EQ(expected, meta);
155 }
156}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700157
158/*
159 * stat(session) - the verify blobid is open in this state, so stat on that once
160 * completed should have no effect.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700161 */
Patrick Venture615c69e2019-05-29 10:49:54 -0700162TEST_F(FirmwareHandlerVerificationCompletedTest,
163 SessionStatOnVerifyAfterSuccessDoesNothing)
164{
165 /* Every time you stat() once it's triggered, it checks the state again
166 * until it's completed.
167 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700168 getToVerificationCompleted(ActionStatus::success);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700169 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture615c69e2019-05-29 10:49:54 -0700170
171 blobs::BlobMeta meta, expectedMeta = {};
172 expectedMeta.size = 0;
173 expectedMeta.blobState = flags | blobs::StateFlags::committed;
174 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700175 static_cast<std::uint8_t>(ActionStatus::success));
Patrick Venture615c69e2019-05-29 10:49:54 -0700176
177 EXPECT_TRUE(handler->stat(session, &meta));
178 EXPECT_EQ(expectedMeta, meta);
179 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
180}
181
182TEST_F(FirmwareHandlerVerificationCompletedTest,
183 SessionStatOnVerifyAfterFailureDoesNothing)
184{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700185 getToVerificationCompleted(ActionStatus::failed);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700186 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture615c69e2019-05-29 10:49:54 -0700187
188 blobs::BlobMeta meta, expectedMeta = {};
189 expectedMeta.size = 0;
190 expectedMeta.blobState = flags | blobs::StateFlags::commit_error;
191 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700192 static_cast<std::uint8_t>(ActionStatus::failed));
Patrick Venture615c69e2019-05-29 10:49:54 -0700193
194 EXPECT_TRUE(handler->stat(session, &meta));
195 EXPECT_EQ(expectedMeta, meta);
196 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
197}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700198
199/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700200 * open(blob) - all open should fail
Patrick Venturea82f99e2019-05-24 15:44:35 -0700201 */
Patrick Ventureeee71812019-05-29 10:41:04 -0700202TEST_F(FirmwareHandlerVerificationCompletedTest,
203 OpeningAnyBlobAvailableFailsAfterSuccess)
204{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700205 getToVerificationCompleted(ActionStatus::success);
Patrick Ventureeee71812019-05-29 10:41:04 -0700206
207 auto blobs = handler->getBlobIds();
208 for (const auto& blob : blobs)
209 {
210 EXPECT_FALSE(handler->open(session + 1, flags, blob));
211 }
212}
213
214TEST_F(FirmwareHandlerVerificationCompletedTest,
215 OpeningAnyBlobAvailableFailsAfterFailure)
216{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700217 getToVerificationCompleted(ActionStatus::failed);
Patrick Ventureeee71812019-05-29 10:41:04 -0700218
219 auto blobs = handler->getBlobIds();
220 for (const auto& blob : blobs)
221 {
222 EXPECT_FALSE(handler->open(session + 1, flags, blob));
223 }
224}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700225
226/*
227 * writemeta(session) - write meta should fail.
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700228 */
Patrick Venture2b801372019-05-29 10:26:01 -0700229TEST_F(FirmwareHandlerVerificationCompletedTest,
230 WriteMetaToVerifyBlobReturnsFailure)
231{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700232 getToVerificationCompleted(ActionStatus::success);
Patrick Venture2b801372019-05-29 10:26:01 -0700233
234 std::vector<std::uint8_t> bytes = {0x01, 0x02};
235 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
236}
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700237
238/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700239 * write(session) - write should fail.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700240 */
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700241TEST_F(FirmwareHandlerVerificationCompletedTest,
242 WriteToVerifyBlobReturnsFailure)
243{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700244 getToVerificationCompleted(ActionStatus::success);
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700245
246 std::vector<std::uint8_t> bytes = {0x01, 0x02};
247 EXPECT_FALSE(handler->write(session, 0, bytes));
248}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700249
250/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700251 * read(session) - read returns empty.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700252 */
253TEST_F(FirmwareHandlerVerificationCompletedTest, ReadOfVerifyBlobReturnsEmpty)
254{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700255 getToVerificationCompleted(ActionStatus::success);
Patrick Venture65cdcf02019-05-29 10:18:50 -0700256 EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
257}
258
259/*
Patrick Venture433cbc32019-05-30 09:53:10 -0700260 * commit(session) - returns failure
Patrick Venturea82f99e2019-05-24 15:44:35 -0700261 */
Patrick Venture433cbc32019-05-30 09:53:10 -0700262TEST_F(FirmwareHandlerVerificationCompletedTest,
263 CommitOnVerifyBlobAfterSuccessReturnsFailure)
264{
265 /* If you've started this'll return success, but if it's finished, it won't
266 * let you try-again.
267 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700268 getToVerificationCompleted(ActionStatus::success);
Patrick Venture1d66fe62019-06-03 14:57:27 -0700269 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venture433cbc32019-05-30 09:53:10 -0700270
271 EXPECT_FALSE(handler->commit(session, {}));
272}
273
274TEST_F(FirmwareHandlerVerificationCompletedTest,
275 CommitOnVerifyBlobAfterFailureReturnsFailure)
276{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700277 getToVerificationCompleted(ActionStatus::failed);
Patrick Venture1d66fe62019-06-03 14:57:27 -0700278 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venture433cbc32019-05-30 09:53:10 -0700279
280 EXPECT_FALSE(handler->commit(session, {}));
281}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700282
Patrick Venture65cdcf02019-05-29 10:18:50 -0700283/*
284 * close(session) - close on the verify blobid:
285 * 1. if successful adds update blob id, changes state to UpdatePending
Patrick Venture1c6d8f52019-05-30 10:53:49 -0700286 */
287TEST_F(FirmwareHandlerVerificationCompletedTest,
288 CloseAfterSuccessChangesStateAddsUpdateBlob)
289{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700290 getToVerificationCompleted(ActionStatus::success);
Patrick Venture1c6d8f52019-05-30 10:53:49 -0700291 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
292
293 handler->close(session);
294 EXPECT_TRUE(handler->canHandleBlob(updateBlobId));
295 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
296}
297
298/*
299 * close(session) - close on the verify blobid:
Patrick Venture5d9fa022019-06-17 13:13:30 -0700300 * 2. if unsuccessful it aborts.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700301 */
Patrick Venture5d9fa022019-06-17 13:13:30 -0700302TEST_F(FirmwareHandlerVerificationCompletedTest, CloseAfterFailureAborts)
303{
304 getToVerificationCompleted(ActionStatus::failed);
305 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
306
307 handler->close(session);
308 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
309 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
310 std::vector<std::string> expected = {staticLayoutBlobId, hashBlobId};
311 EXPECT_THAT(handler->getBlobIds(), UnorderedElementsAreArray(expected));
312}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700313
Patrick Venturea82f99e2019-05-24 15:44:35 -0700314} // namespace
315} // namespace ipmi_flash