blob: bdac1234b88c42871f91a5649934f330fbffaaeb [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 Venture6d3a14c2019-05-29 09:24:42 -070023using ::testing::UnorderedElementsAreArray;
Patrick Venturea82f99e2019-05-24 15:44:35 -070024
25/*
26 * There are the following calls (parameters may vary):
27 * canHandleBlob(blob)
28 * getBlobIds
29 * deleteBlob(blob)
30 * stat(blob)
31 * stat(session)
32 * open(blob)
33 * close(session)
34 * writemeta(session)
35 * write(session)
36 * read(session)
37 * commit(session)
38 *
39 * Like the state verificationStarted, there is a file open in
40 * verificationCompleted. This state is transitioned to after a stat() command
41 * indicates a successful verification.
42 */
43
Patrick Venture9b37b092020-05-28 20:58:57 -070044class FirmwareHandlerVerificationCompletedTest :
45 public IpmiOnlyFirmwareStaticTest
46{};
Patrick Venturea82f99e2019-05-24 15:44:35 -070047
Patrick Venturebcc0c772019-06-17 10:42:06 -070048/*
49 * deleteBlob(blob)
50 */
51TEST_F(FirmwareHandlerVerificationCompletedTest, DeleteBlobReturnsFalse)
52{
53 /* Try deleting all blobs, it doesn't really matter which though because you
54 * cannot close out an open session, therefore you must fail to delete
55 * anything unless everything is closed.
56 */
57 getToVerificationCompleted(ActionStatus::success);
58 auto blobs = handler->getBlobIds();
59 for (const auto& b : blobs)
60 {
61 EXPECT_FALSE(handler->deleteBlob(b));
62 }
63}
Patrick Venture6d3a14c2019-05-29 09:24:42 -070064
65/*
66 * canHandleBlob
Patrick Venturea82f99e2019-05-24 15:44:35 -070067 */
Patrick Venture6d3a14c2019-05-29 09:24:42 -070068TEST_F(FirmwareHandlerVerificationCompletedTest,
69 OnVerificationCompleteSuccessUpdateBlobIdNotPresent)
70{
71 /* the uploadBlobId is only added on close() of the verifyBlobId. This is a
72 * consistent behavior with verifyBlobId only added when closing the image
73 * or hash.
74 */
Patrick Ventureda66fd82019-06-03 11:11:24 -070075 getToVerificationCompleted(ActionStatus::success);
Patrick Venture6d3a14c2019-05-29 09:24:42 -070076 EXPECT_FALSE(handler->canHandleBlob(updateBlobId));
77}
78
79TEST_F(FirmwareHandlerVerificationCompletedTest,
80 OnVerificationCompleteFailureUpdateBlobIdNotPresent)
81{
Patrick Ventureda66fd82019-06-03 11:11:24 -070082 getToVerificationCompleted(ActionStatus::failed);
Patrick Venture6d3a14c2019-05-29 09:24:42 -070083 EXPECT_FALSE(handler->canHandleBlob(updateBlobId));
84}
85
86/*
87 * getBlobIds
88 */
89TEST_F(FirmwareHandlerVerificationCompletedTest, GetBlobIdsReturnsExpectedList)
90{
Patrick Ventureda66fd82019-06-03 11:11:24 -070091 getToVerificationCompleted(ActionStatus::success);
Patrick Venture9a69f732019-06-17 14:05:13 -070092 EXPECT_THAT(
93 handler->getBlobIds(),
94 UnorderedElementsAreArray(
95 {verifyBlobId, hashBlobId, activeImageBlobId, staticLayoutBlobId}));
Patrick Venture6d3a14c2019-05-29 09:24:42 -070096}
Patrick Venturea82f99e2019-05-24 15:44:35 -070097
98/*
99 * stat(blob)
100 */
Patrick Venture0c642fd2019-05-24 16:09:29 -0700101TEST_F(FirmwareHandlerVerificationCompletedTest,
102 StatOnActiveImageReturnsFailure)
103{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700104 getToVerificationCompleted(ActionStatus::success);
Patrick Venture0c642fd2019-05-24 16:09:29 -0700105 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
106
107 blobs::BlobMeta meta;
108 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
109}
110
Patrick Venturefbf07ff2019-05-29 08:58:45 -0700111TEST_F(FirmwareHandlerVerificationCompletedTest,
112 VerifyActiveHashIdMissingInThisCase)
113{
114 /* The path taken to get to this state never opened the hash blob Id, which
115 * is fine. But let's verify it behaved as intended.
116 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700117 getToVerificationCompleted(ActionStatus::success);
Patrick Venturefbf07ff2019-05-29 08:58:45 -0700118 EXPECT_FALSE(handler->canHandleBlob(activeHashBlobId));
119}
120
121/* TODO: Add sufficient warning that you can get to verificationCompleted
122 * without ever opening the image blob id (or the tarball one).
123 *
124 * Although in this case, it's expected that any verification triggered would
125 * certainly fail. So, although it's possible, it's uninteresting.
126 */
127
Patrick Venture0c642fd2019-05-24 16:09:29 -0700128TEST_F(FirmwareHandlerVerificationCompletedTest, StatOnVerifyBlobReturnsFailure)
129{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700130 getToVerificationCompleted(ActionStatus::success);
Patrick Venture0c642fd2019-05-24 16:09:29 -0700131 ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));
132
133 blobs::BlobMeta meta;
134 EXPECT_FALSE(handler->stat(verifyBlobId, &meta));
135}
136
137TEST_F(FirmwareHandlerVerificationCompletedTest,
138 StatOnNormalBlobsReturnsSuccess)
139{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700140 getToVerificationCompleted(ActionStatus::success);
Patrick Venture0c642fd2019-05-24 16:09:29 -0700141
Patrick Venture0c642fd2019-05-24 16:09:29 -0700142 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
143 for (const auto& blob : testBlobs)
144 {
145 ASSERT_TRUE(handler->canHandleBlob(blob));
146
147 blobs::BlobMeta meta = {};
148 EXPECT_TRUE(handler->stat(blob, &meta));
Benjamin Fair12901982019-11-12 13:55:46 -0800149 EXPECT_EQ(expectedIdleMeta, meta);
Patrick Venture0c642fd2019-05-24 16:09:29 -0700150 }
151}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700152
153/*
154 * stat(session) - the verify blobid is open in this state, so stat on that once
155 * completed should have no effect.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700156 */
Patrick Venture615c69e2019-05-29 10:49:54 -0700157TEST_F(FirmwareHandlerVerificationCompletedTest,
158 SessionStatOnVerifyAfterSuccessDoesNothing)
159{
160 /* Every time you stat() once it's triggered, it checks the state again
161 * until it's completed.
162 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700163 getToVerificationCompleted(ActionStatus::success);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700164 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture615c69e2019-05-29 10:49:54 -0700165
166 blobs::BlobMeta meta, expectedMeta = {};
167 expectedMeta.size = 0;
168 expectedMeta.blobState = flags | blobs::StateFlags::committed;
169 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700170 static_cast<std::uint8_t>(ActionStatus::success));
Patrick Venture615c69e2019-05-29 10:49:54 -0700171
172 EXPECT_TRUE(handler->stat(session, &meta));
173 EXPECT_EQ(expectedMeta, meta);
174 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
175}
176
177TEST_F(FirmwareHandlerVerificationCompletedTest,
178 SessionStatOnVerifyAfterFailureDoesNothing)
179{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700180 getToVerificationCompleted(ActionStatus::failed);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700181 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture615c69e2019-05-29 10:49:54 -0700182
183 blobs::BlobMeta meta, expectedMeta = {};
184 expectedMeta.size = 0;
185 expectedMeta.blobState = flags | blobs::StateFlags::commit_error;
186 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700187 static_cast<std::uint8_t>(ActionStatus::failed));
Patrick Venture615c69e2019-05-29 10:49:54 -0700188
189 EXPECT_TRUE(handler->stat(session, &meta));
190 EXPECT_EQ(expectedMeta, meta);
191 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
192}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700193
194/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700195 * open(blob) - all open should fail
Patrick Venturea82f99e2019-05-24 15:44:35 -0700196 */
Patrick Ventureeee71812019-05-29 10:41:04 -0700197TEST_F(FirmwareHandlerVerificationCompletedTest,
198 OpeningAnyBlobAvailableFailsAfterSuccess)
199{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700200 getToVerificationCompleted(ActionStatus::success);
Patrick Ventureeee71812019-05-29 10:41:04 -0700201
202 auto blobs = handler->getBlobIds();
203 for (const auto& blob : blobs)
204 {
205 EXPECT_FALSE(handler->open(session + 1, flags, blob));
206 }
207}
208
209TEST_F(FirmwareHandlerVerificationCompletedTest,
210 OpeningAnyBlobAvailableFailsAfterFailure)
211{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700212 getToVerificationCompleted(ActionStatus::failed);
Patrick Ventureeee71812019-05-29 10:41:04 -0700213
214 auto blobs = handler->getBlobIds();
215 for (const auto& blob : blobs)
216 {
217 EXPECT_FALSE(handler->open(session + 1, flags, blob));
218 }
219}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700220
221/*
222 * writemeta(session) - write meta should fail.
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700223 */
Patrick Venture2b801372019-05-29 10:26:01 -0700224TEST_F(FirmwareHandlerVerificationCompletedTest,
225 WriteMetaToVerifyBlobReturnsFailure)
226{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700227 getToVerificationCompleted(ActionStatus::success);
Patrick Venture2b801372019-05-29 10:26:01 -0700228
229 std::vector<std::uint8_t> bytes = {0x01, 0x02};
230 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
231}
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700232
233/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700234 * write(session) - write should fail.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700235 */
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700236TEST_F(FirmwareHandlerVerificationCompletedTest,
237 WriteToVerifyBlobReturnsFailure)
238{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700239 getToVerificationCompleted(ActionStatus::success);
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700240
241 std::vector<std::uint8_t> bytes = {0x01, 0x02};
242 EXPECT_FALSE(handler->write(session, 0, bytes));
243}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700244
245/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700246 * read(session) - read returns empty.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700247 */
248TEST_F(FirmwareHandlerVerificationCompletedTest, ReadOfVerifyBlobReturnsEmpty)
249{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700250 getToVerificationCompleted(ActionStatus::success);
Patrick Venture65cdcf02019-05-29 10:18:50 -0700251 EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
252}
253
254/*
Patrick Venture433cbc32019-05-30 09:53:10 -0700255 * commit(session) - returns failure
Patrick Venturea82f99e2019-05-24 15:44:35 -0700256 */
Patrick Venture433cbc32019-05-30 09:53:10 -0700257TEST_F(FirmwareHandlerVerificationCompletedTest,
258 CommitOnVerifyBlobAfterSuccessReturnsFailure)
259{
260 /* If you've started this'll return success, but if it's finished, it won't
261 * let you try-again.
262 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700263 getToVerificationCompleted(ActionStatus::success);
Patrick Venture1d66fe62019-06-03 14:57:27 -0700264 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venture433cbc32019-05-30 09:53:10 -0700265
266 EXPECT_FALSE(handler->commit(session, {}));
267}
268
269TEST_F(FirmwareHandlerVerificationCompletedTest,
270 CommitOnVerifyBlobAfterFailureReturnsFailure)
271{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700272 getToVerificationCompleted(ActionStatus::failed);
Patrick Venture1d66fe62019-06-03 14:57:27 -0700273 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venture433cbc32019-05-30 09:53:10 -0700274
275 EXPECT_FALSE(handler->commit(session, {}));
276}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700277
Patrick Venture65cdcf02019-05-29 10:18:50 -0700278/*
279 * close(session) - close on the verify blobid:
280 * 1. if successful adds update blob id, changes state to UpdatePending
Patrick Venture1c6d8f52019-05-30 10:53:49 -0700281 */
282TEST_F(FirmwareHandlerVerificationCompletedTest,
283 CloseAfterSuccessChangesStateAddsUpdateBlob)
284{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700285 getToVerificationCompleted(ActionStatus::success);
Patrick Venture1c6d8f52019-05-30 10:53:49 -0700286 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
287
288 handler->close(session);
289 EXPECT_TRUE(handler->canHandleBlob(updateBlobId));
290 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
291}
292
293/*
294 * close(session) - close on the verify blobid:
Patrick Venture5d9fa022019-06-17 13:13:30 -0700295 * 2. if unsuccessful it aborts.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700296 */
Patrick Venture5d9fa022019-06-17 13:13:30 -0700297TEST_F(FirmwareHandlerVerificationCompletedTest, CloseAfterFailureAborts)
298{
299 getToVerificationCompleted(ActionStatus::failed);
300 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
301
302 handler->close(session);
303 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
304 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
Patrick Venture9a69f732019-06-17 14:05:13 -0700305 EXPECT_THAT(handler->getBlobIds(),
306 UnorderedElementsAreArray(startingBlobs));
Patrick Venture5d9fa022019-06-17 13:13:30 -0700307}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700308
Patrick Venture92f26152020-05-26 19:47:36 -0700309/*
310 * expire(session)
311 */
312TEST_F(FirmwareHandlerVerificationCompletedTest,
313 ExpireAfterVerificationCompletedAborts)
314{
315 getToVerificationCompleted(ActionStatus::failed);
316
317 ASSERT_TRUE(handler->expire(session));
318 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
319 EXPECT_THAT(handler->getBlobIds(),
320 UnorderedElementsAreArray(startingBlobs));
321}
322
Patrick Venturea82f99e2019-05-24 15:44:35 -0700323} // namespace
324} // namespace ipmi_flash