blob: f7b099809d64c8ea6bcc555b5c658a957a478901 [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
Patrick Venture9b37b092020-05-28 20:58:57 -070045class FirmwareHandlerVerificationCompletedTest :
46 public IpmiOnlyFirmwareStaticTest
47{};
Patrick Venturea82f99e2019-05-24 15:44:35 -070048
Patrick Venturebcc0c772019-06-17 10:42:06 -070049/*
50 * deleteBlob(blob)
51 */
52TEST_F(FirmwareHandlerVerificationCompletedTest, DeleteBlobReturnsFalse)
53{
54 /* Try deleting all blobs, it doesn't really matter which though because you
55 * cannot close out an open session, therefore you must fail to delete
56 * anything unless everything is closed.
57 */
58 getToVerificationCompleted(ActionStatus::success);
59 auto blobs = handler->getBlobIds();
60 for (const auto& b : blobs)
61 {
62 EXPECT_FALSE(handler->deleteBlob(b));
63 }
64}
Patrick Venture6d3a14c2019-05-29 09:24:42 -070065
66/*
67 * canHandleBlob
Patrick Venturea82f99e2019-05-24 15:44:35 -070068 */
Patrick Venture6d3a14c2019-05-29 09:24:42 -070069TEST_F(FirmwareHandlerVerificationCompletedTest,
70 OnVerificationCompleteSuccessUpdateBlobIdNotPresent)
71{
72 /* the uploadBlobId is only added on close() of the verifyBlobId. This is a
73 * consistent behavior with verifyBlobId only added when closing the image
74 * or hash.
75 */
Patrick Ventureda66fd82019-06-03 11:11:24 -070076 getToVerificationCompleted(ActionStatus::success);
Patrick Venture6d3a14c2019-05-29 09:24:42 -070077 EXPECT_FALSE(handler->canHandleBlob(updateBlobId));
78}
79
80TEST_F(FirmwareHandlerVerificationCompletedTest,
81 OnVerificationCompleteFailureUpdateBlobIdNotPresent)
82{
Patrick Ventureda66fd82019-06-03 11:11:24 -070083 getToVerificationCompleted(ActionStatus::failed);
Patrick Venture6d3a14c2019-05-29 09:24:42 -070084 EXPECT_FALSE(handler->canHandleBlob(updateBlobId));
85}
86
87/*
88 * getBlobIds
89 */
90TEST_F(FirmwareHandlerVerificationCompletedTest, GetBlobIdsReturnsExpectedList)
91{
Patrick Ventureda66fd82019-06-03 11:11:24 -070092 getToVerificationCompleted(ActionStatus::success);
Patrick Venture9a69f732019-06-17 14:05:13 -070093 EXPECT_THAT(
94 handler->getBlobIds(),
95 UnorderedElementsAreArray(
96 {verifyBlobId, hashBlobId, activeImageBlobId, staticLayoutBlobId}));
Patrick Venture6d3a14c2019-05-29 09:24:42 -070097}
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
Patrick Venture0c642fd2019-05-24 16:09:29 -0700143 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
144 for (const auto& blob : testBlobs)
145 {
146 ASSERT_TRUE(handler->canHandleBlob(blob));
147
148 blobs::BlobMeta meta = {};
149 EXPECT_TRUE(handler->stat(blob, &meta));
Benjamin Fair12901982019-11-12 13:55:46 -0800150 EXPECT_EQ(expectedIdleMeta, meta);
Patrick Venture0c642fd2019-05-24 16:09:29 -0700151 }
152}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700153
154/*
155 * stat(session) - the verify blobid is open in this state, so stat on that once
156 * completed should have no effect.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700157 */
Patrick Venture615c69e2019-05-29 10:49:54 -0700158TEST_F(FirmwareHandlerVerificationCompletedTest,
159 SessionStatOnVerifyAfterSuccessDoesNothing)
160{
161 /* Every time you stat() once it's triggered, it checks the state again
162 * until it's completed.
163 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700164 getToVerificationCompleted(ActionStatus::success);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700165 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture615c69e2019-05-29 10:49:54 -0700166
167 blobs::BlobMeta meta, expectedMeta = {};
168 expectedMeta.size = 0;
169 expectedMeta.blobState = flags | blobs::StateFlags::committed;
170 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700171 static_cast<std::uint8_t>(ActionStatus::success));
Patrick Venture615c69e2019-05-29 10:49:54 -0700172
173 EXPECT_TRUE(handler->stat(session, &meta));
174 EXPECT_EQ(expectedMeta, meta);
175 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
176}
177
178TEST_F(FirmwareHandlerVerificationCompletedTest,
179 SessionStatOnVerifyAfterFailureDoesNothing)
180{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700181 getToVerificationCompleted(ActionStatus::failed);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700182 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture615c69e2019-05-29 10:49:54 -0700183
184 blobs::BlobMeta meta, expectedMeta = {};
185 expectedMeta.size = 0;
186 expectedMeta.blobState = flags | blobs::StateFlags::commit_error;
187 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700188 static_cast<std::uint8_t>(ActionStatus::failed));
Patrick Venture615c69e2019-05-29 10:49:54 -0700189
190 EXPECT_TRUE(handler->stat(session, &meta));
191 EXPECT_EQ(expectedMeta, meta);
192 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
193}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700194
195/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700196 * open(blob) - all open should fail
Patrick Venturea82f99e2019-05-24 15:44:35 -0700197 */
Patrick Ventureeee71812019-05-29 10:41:04 -0700198TEST_F(FirmwareHandlerVerificationCompletedTest,
199 OpeningAnyBlobAvailableFailsAfterSuccess)
200{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700201 getToVerificationCompleted(ActionStatus::success);
Patrick Ventureeee71812019-05-29 10:41:04 -0700202
203 auto blobs = handler->getBlobIds();
204 for (const auto& blob : blobs)
205 {
206 EXPECT_FALSE(handler->open(session + 1, flags, blob));
207 }
208}
209
210TEST_F(FirmwareHandlerVerificationCompletedTest,
211 OpeningAnyBlobAvailableFailsAfterFailure)
212{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700213 getToVerificationCompleted(ActionStatus::failed);
Patrick Ventureeee71812019-05-29 10:41:04 -0700214
215 auto blobs = handler->getBlobIds();
216 for (const auto& blob : blobs)
217 {
218 EXPECT_FALSE(handler->open(session + 1, flags, blob));
219 }
220}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700221
222/*
223 * writemeta(session) - write meta should fail.
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700224 */
Patrick Venture2b801372019-05-29 10:26:01 -0700225TEST_F(FirmwareHandlerVerificationCompletedTest,
226 WriteMetaToVerifyBlobReturnsFailure)
227{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700228 getToVerificationCompleted(ActionStatus::success);
Patrick Venture2b801372019-05-29 10:26:01 -0700229
230 std::vector<std::uint8_t> bytes = {0x01, 0x02};
231 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
232}
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700233
234/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700235 * write(session) - write should fail.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700236 */
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700237TEST_F(FirmwareHandlerVerificationCompletedTest,
238 WriteToVerifyBlobReturnsFailure)
239{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700240 getToVerificationCompleted(ActionStatus::success);
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700241
242 std::vector<std::uint8_t> bytes = {0x01, 0x02};
243 EXPECT_FALSE(handler->write(session, 0, bytes));
244}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700245
246/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700247 * read(session) - read returns empty.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700248 */
249TEST_F(FirmwareHandlerVerificationCompletedTest, ReadOfVerifyBlobReturnsEmpty)
250{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700251 getToVerificationCompleted(ActionStatus::success);
Patrick Venture65cdcf02019-05-29 10:18:50 -0700252 EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
253}
254
255/*
Patrick Venture433cbc32019-05-30 09:53:10 -0700256 * commit(session) - returns failure
Patrick Venturea82f99e2019-05-24 15:44:35 -0700257 */
Patrick Venture433cbc32019-05-30 09:53:10 -0700258TEST_F(FirmwareHandlerVerificationCompletedTest,
259 CommitOnVerifyBlobAfterSuccessReturnsFailure)
260{
261 /* If you've started this'll return success, but if it's finished, it won't
262 * let you try-again.
263 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700264 getToVerificationCompleted(ActionStatus::success);
Patrick Venture1d66fe62019-06-03 14:57:27 -0700265 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venture433cbc32019-05-30 09:53:10 -0700266
267 EXPECT_FALSE(handler->commit(session, {}));
268}
269
270TEST_F(FirmwareHandlerVerificationCompletedTest,
271 CommitOnVerifyBlobAfterFailureReturnsFailure)
272{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700273 getToVerificationCompleted(ActionStatus::failed);
Patrick Venture1d66fe62019-06-03 14:57:27 -0700274 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venture433cbc32019-05-30 09:53:10 -0700275
276 EXPECT_FALSE(handler->commit(session, {}));
277}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700278
Patrick Venture65cdcf02019-05-29 10:18:50 -0700279/*
280 * close(session) - close on the verify blobid:
281 * 1. if successful adds update blob id, changes state to UpdatePending
Patrick Venture1c6d8f52019-05-30 10:53:49 -0700282 */
283TEST_F(FirmwareHandlerVerificationCompletedTest,
284 CloseAfterSuccessChangesStateAddsUpdateBlob)
285{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700286 getToVerificationCompleted(ActionStatus::success);
Patrick Venture1c6d8f52019-05-30 10:53:49 -0700287 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
288
289 handler->close(session);
290 EXPECT_TRUE(handler->canHandleBlob(updateBlobId));
291 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
292}
293
294/*
295 * close(session) - close on the verify blobid:
Patrick Venture5d9fa022019-06-17 13:13:30 -0700296 * 2. if unsuccessful it aborts.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700297 */
Patrick Venture5d9fa022019-06-17 13:13:30 -0700298TEST_F(FirmwareHandlerVerificationCompletedTest, CloseAfterFailureAborts)
299{
300 getToVerificationCompleted(ActionStatus::failed);
301 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
302
303 handler->close(session);
304 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
305 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
Patrick Venture9a69f732019-06-17 14:05:13 -0700306 EXPECT_THAT(handler->getBlobIds(),
307 UnorderedElementsAreArray(startingBlobs));
Patrick Venture5d9fa022019-06-17 13:13:30 -0700308}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700309
Patrick Venturea82f99e2019-05-24 15:44:35 -0700310} // namespace
311} // namespace ipmi_flash