blob: 0c6bae795ef0f2182a79f9d6bfb52a37fa43a602 [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
Patrick Venture0c642fd2019-05-24 16:09:29 -0700144 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
145 for (const auto& blob : testBlobs)
146 {
147 ASSERT_TRUE(handler->canHandleBlob(blob));
148
149 blobs::BlobMeta meta = {};
150 EXPECT_TRUE(handler->stat(blob, &meta));
Benjamin Fair12901982019-11-12 13:55:46 -0800151 EXPECT_EQ(expectedIdleMeta, meta);
Patrick Venture0c642fd2019-05-24 16:09:29 -0700152 }
153}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700154
155/*
156 * stat(session) - the verify blobid is open in this state, so stat on that once
157 * completed should have no effect.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700158 */
Patrick Venture615c69e2019-05-29 10:49:54 -0700159TEST_F(FirmwareHandlerVerificationCompletedTest,
160 SessionStatOnVerifyAfterSuccessDoesNothing)
161{
162 /* Every time you stat() once it's triggered, it checks the state again
163 * until it's completed.
164 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700165 getToVerificationCompleted(ActionStatus::success);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700166 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture615c69e2019-05-29 10:49:54 -0700167
168 blobs::BlobMeta meta, expectedMeta = {};
169 expectedMeta.size = 0;
170 expectedMeta.blobState = flags | blobs::StateFlags::committed;
171 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700172 static_cast<std::uint8_t>(ActionStatus::success));
Patrick Venture615c69e2019-05-29 10:49:54 -0700173
174 EXPECT_TRUE(handler->stat(session, &meta));
175 EXPECT_EQ(expectedMeta, meta);
176 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
177}
178
179TEST_F(FirmwareHandlerVerificationCompletedTest,
180 SessionStatOnVerifyAfterFailureDoesNothing)
181{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700182 getToVerificationCompleted(ActionStatus::failed);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700183 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture615c69e2019-05-29 10:49:54 -0700184
185 blobs::BlobMeta meta, expectedMeta = {};
186 expectedMeta.size = 0;
187 expectedMeta.blobState = flags | blobs::StateFlags::commit_error;
188 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700189 static_cast<std::uint8_t>(ActionStatus::failed));
Patrick Venture615c69e2019-05-29 10:49:54 -0700190
191 EXPECT_TRUE(handler->stat(session, &meta));
192 EXPECT_EQ(expectedMeta, meta);
193 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
194}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700195
196/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700197 * open(blob) - all open should fail
Patrick Venturea82f99e2019-05-24 15:44:35 -0700198 */
Patrick Ventureeee71812019-05-29 10:41:04 -0700199TEST_F(FirmwareHandlerVerificationCompletedTest,
200 OpeningAnyBlobAvailableFailsAfterSuccess)
201{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700202 getToVerificationCompleted(ActionStatus::success);
Patrick Ventureeee71812019-05-29 10:41:04 -0700203
204 auto blobs = handler->getBlobIds();
205 for (const auto& blob : blobs)
206 {
207 EXPECT_FALSE(handler->open(session + 1, flags, blob));
208 }
209}
210
211TEST_F(FirmwareHandlerVerificationCompletedTest,
212 OpeningAnyBlobAvailableFailsAfterFailure)
213{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700214 getToVerificationCompleted(ActionStatus::failed);
Patrick Ventureeee71812019-05-29 10:41:04 -0700215
216 auto blobs = handler->getBlobIds();
217 for (const auto& blob : blobs)
218 {
219 EXPECT_FALSE(handler->open(session + 1, flags, blob));
220 }
221}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700222
223/*
224 * writemeta(session) - write meta should fail.
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700225 */
Patrick Venture2b801372019-05-29 10:26:01 -0700226TEST_F(FirmwareHandlerVerificationCompletedTest,
227 WriteMetaToVerifyBlobReturnsFailure)
228{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700229 getToVerificationCompleted(ActionStatus::success);
Patrick Venture2b801372019-05-29 10:26:01 -0700230
231 std::vector<std::uint8_t> bytes = {0x01, 0x02};
232 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
233}
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700234
235/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700236 * write(session) - write should fail.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700237 */
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700238TEST_F(FirmwareHandlerVerificationCompletedTest,
239 WriteToVerifyBlobReturnsFailure)
240{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700241 getToVerificationCompleted(ActionStatus::success);
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700242
243 std::vector<std::uint8_t> bytes = {0x01, 0x02};
244 EXPECT_FALSE(handler->write(session, 0, bytes));
245}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700246
247/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700248 * read(session) - read returns empty.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700249 */
250TEST_F(FirmwareHandlerVerificationCompletedTest, ReadOfVerifyBlobReturnsEmpty)
251{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700252 getToVerificationCompleted(ActionStatus::success);
Patrick Venture65cdcf02019-05-29 10:18:50 -0700253 EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
254}
255
256/*
Patrick Venture433cbc32019-05-30 09:53:10 -0700257 * commit(session) - returns failure
Patrick Venturea82f99e2019-05-24 15:44:35 -0700258 */
Patrick Venture433cbc32019-05-30 09:53:10 -0700259TEST_F(FirmwareHandlerVerificationCompletedTest,
260 CommitOnVerifyBlobAfterSuccessReturnsFailure)
261{
262 /* If you've started this'll return success, but if it's finished, it won't
263 * let you try-again.
264 */
Patrick Ventureda66fd82019-06-03 11:11:24 -0700265 getToVerificationCompleted(ActionStatus::success);
Patrick Venture1d66fe62019-06-03 14:57:27 -0700266 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venture433cbc32019-05-30 09:53:10 -0700267
268 EXPECT_FALSE(handler->commit(session, {}));
269}
270
271TEST_F(FirmwareHandlerVerificationCompletedTest,
272 CommitOnVerifyBlobAfterFailureReturnsFailure)
273{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700274 getToVerificationCompleted(ActionStatus::failed);
Patrick Venture1d66fe62019-06-03 14:57:27 -0700275 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venture433cbc32019-05-30 09:53:10 -0700276
277 EXPECT_FALSE(handler->commit(session, {}));
278}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700279
Patrick Venture65cdcf02019-05-29 10:18:50 -0700280/*
281 * close(session) - close on the verify blobid:
282 * 1. if successful adds update blob id, changes state to UpdatePending
Patrick Venture1c6d8f52019-05-30 10:53:49 -0700283 */
284TEST_F(FirmwareHandlerVerificationCompletedTest,
285 CloseAfterSuccessChangesStateAddsUpdateBlob)
286{
Patrick Ventureda66fd82019-06-03 11:11:24 -0700287 getToVerificationCompleted(ActionStatus::success);
Patrick Venture1c6d8f52019-05-30 10:53:49 -0700288 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
289
290 handler->close(session);
291 EXPECT_TRUE(handler->canHandleBlob(updateBlobId));
292 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
293}
294
295/*
296 * close(session) - close on the verify blobid:
Patrick Venture5d9fa022019-06-17 13:13:30 -0700297 * 2. if unsuccessful it aborts.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700298 */
Patrick Venture5d9fa022019-06-17 13:13:30 -0700299TEST_F(FirmwareHandlerVerificationCompletedTest, CloseAfterFailureAborts)
300{
301 getToVerificationCompleted(ActionStatus::failed);
302 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
303
304 handler->close(session);
305 ASSERT_FALSE(handler->canHandleBlob(updateBlobId));
306 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
Patrick Venture9a69f732019-06-17 14:05:13 -0700307 EXPECT_THAT(handler->getBlobIds(),
308 UnorderedElementsAreArray(startingBlobs));
Patrick Venture5d9fa022019-06-17 13:13:30 -0700309}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700310
Patrick Venturea82f99e2019-05-24 15:44:35 -0700311} // namespace
312} // namespace ipmi_flash