blob: c162c5be7f6de0baae826fd165df44642b26d478 [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{
48 protected:
Patrick Venture0c642fd2019-05-24 16:09:29 -070049 void getToVerificationCompleted(VerifyCheckResponses checkResponse)
Patrick Venturea82f99e2019-05-24 15:44:35 -070050 {
Patrick Venture0c642fd2019-05-24 16:09:29 -070051 /* The hash was not sent up, as it's technically optional. Therefore,
52 * there is no active hash file.
53 */
Patrick Venturea82f99e2019-05-24 15:44:35 -070054 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
55 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -070056 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
57
Patrick Venturea82f99e2019-05-24 15:44:35 -070058 EXPECT_CALL(imageMock, close()).WillRepeatedly(Return());
59 handler->close(session);
Patrick Venture6fdd02e2019-05-28 13:02:04 -070060 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venturea82f99e2019-05-24 15:44:35 -070061
62 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
63 EXPECT_CALL(*verifyMockPtr, triggerVerification())
64 .WillOnce(Return(true));
65
66 EXPECT_TRUE(handler->commit(session, {}));
Patrick Venture6fdd02e2019-05-28 13:02:04 -070067 expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);
Patrick Venturea82f99e2019-05-24 15:44:35 -070068
69 EXPECT_CALL(*verifyMockPtr, checkVerificationState())
Patrick Venture0c642fd2019-05-24 16:09:29 -070070 .WillOnce(Return(checkResponse));
Patrick Venturea82f99e2019-05-24 15:44:35 -070071 blobs::BlobMeta meta;
72 EXPECT_TRUE(handler->stat(session, &meta));
Patrick Venture6fdd02e2019-05-28 13:02:04 -070073 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
Patrick Venturea82f99e2019-05-24 15:44:35 -070074 }
75
76 std::uint16_t session = 1;
77 std::uint16_t flags =
78 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
79};
80
Patrick Venture6d3a14c2019-05-29 09:24:42 -070081/* TODO: deleteBlob(blob) */
82
83/*
84 * canHandleBlob
Patrick Venturea82f99e2019-05-24 15:44:35 -070085 */
Patrick Venture6d3a14c2019-05-29 09:24:42 -070086TEST_F(FirmwareHandlerVerificationCompletedTest,
87 OnVerificationCompleteSuccessUpdateBlobIdNotPresent)
88{
89 /* the uploadBlobId is only added on close() of the verifyBlobId. This is a
90 * consistent behavior with verifyBlobId only added when closing the image
91 * or hash.
92 */
93 getToVerificationCompleted(VerifyCheckResponses::success);
94 EXPECT_FALSE(handler->canHandleBlob(updateBlobId));
95}
96
97TEST_F(FirmwareHandlerVerificationCompletedTest,
98 OnVerificationCompleteFailureUpdateBlobIdNotPresent)
99{
100 getToVerificationCompleted(VerifyCheckResponses::failed);
101 EXPECT_FALSE(handler->canHandleBlob(updateBlobId));
102}
103
104/*
105 * getBlobIds
106 */
107TEST_F(FirmwareHandlerVerificationCompletedTest, GetBlobIdsReturnsExpectedList)
108{
109 getToVerificationCompleted(VerifyCheckResponses::success);
110 std::vector<std::string> expected = {verifyBlobId, hashBlobId,
111 activeImageBlobId, staticLayoutBlobId};
112 EXPECT_THAT(handler->getBlobIds(), UnorderedElementsAreArray(expected));
113}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700114
115/*
116 * stat(blob)
117 */
Patrick Venture0c642fd2019-05-24 16:09:29 -0700118TEST_F(FirmwareHandlerVerificationCompletedTest,
119 StatOnActiveImageReturnsFailure)
120{
121 getToVerificationCompleted(VerifyCheckResponses::success);
122 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
123
124 blobs::BlobMeta meta;
125 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
126}
127
Patrick Venturefbf07ff2019-05-29 08:58:45 -0700128TEST_F(FirmwareHandlerVerificationCompletedTest,
129 VerifyActiveHashIdMissingInThisCase)
130{
131 /* The path taken to get to this state never opened the hash blob Id, which
132 * is fine. But let's verify it behaved as intended.
133 */
134 getToVerificationCompleted(VerifyCheckResponses::success);
135 EXPECT_FALSE(handler->canHandleBlob(activeHashBlobId));
136}
137
138/* TODO: Add sufficient warning that you can get to verificationCompleted
139 * without ever opening the image blob id (or the tarball one).
140 *
141 * Although in this case, it's expected that any verification triggered would
142 * certainly fail. So, although it's possible, it's uninteresting.
143 */
144
Patrick Venture0c642fd2019-05-24 16:09:29 -0700145TEST_F(FirmwareHandlerVerificationCompletedTest, StatOnVerifyBlobReturnsFailure)
146{
147 getToVerificationCompleted(VerifyCheckResponses::success);
148 ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));
149
150 blobs::BlobMeta meta;
151 EXPECT_FALSE(handler->stat(verifyBlobId, &meta));
152}
153
154TEST_F(FirmwareHandlerVerificationCompletedTest,
155 StatOnNormalBlobsReturnsSuccess)
156{
157 getToVerificationCompleted(VerifyCheckResponses::success);
158
159 blobs::BlobMeta expected;
160 expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
161 expected.size = 0;
162
163 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
164 for (const auto& blob : testBlobs)
165 {
166 ASSERT_TRUE(handler->canHandleBlob(blob));
167
168 blobs::BlobMeta meta = {};
169 EXPECT_TRUE(handler->stat(blob, &meta));
170 EXPECT_EQ(expected, meta);
171 }
172}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700173
174/*
175 * stat(session) - the verify blobid is open in this state, so stat on that once
176 * completed should have no effect.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700177 */
Patrick Venture615c69e2019-05-29 10:49:54 -0700178TEST_F(FirmwareHandlerVerificationCompletedTest,
179 SessionStatOnVerifyAfterSuccessDoesNothing)
180{
181 /* Every time you stat() once it's triggered, it checks the state again
182 * until it's completed.
183 */
184 getToVerificationCompleted(VerifyCheckResponses::success);
185 EXPECT_CALL(*verifyMockPtr, checkVerificationState()).Times(0);
186
187 blobs::BlobMeta meta, expectedMeta = {};
188 expectedMeta.size = 0;
189 expectedMeta.blobState = flags | blobs::StateFlags::committed;
190 expectedMeta.metadata.push_back(
191 static_cast<std::uint8_t>(VerifyCheckResponses::success));
192
193 EXPECT_TRUE(handler->stat(session, &meta));
194 EXPECT_EQ(expectedMeta, meta);
195 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
196}
197
198TEST_F(FirmwareHandlerVerificationCompletedTest,
199 SessionStatOnVerifyAfterFailureDoesNothing)
200{
201 getToVerificationCompleted(VerifyCheckResponses::failed);
202 EXPECT_CALL(*verifyMockPtr, checkVerificationState()).Times(0);
203
204 blobs::BlobMeta meta, expectedMeta = {};
205 expectedMeta.size = 0;
206 expectedMeta.blobState = flags | blobs::StateFlags::commit_error;
207 expectedMeta.metadata.push_back(
208 static_cast<std::uint8_t>(VerifyCheckResponses::failed));
209
210 EXPECT_TRUE(handler->stat(session, &meta));
211 EXPECT_EQ(expectedMeta, meta);
212 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
213}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700214
215/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700216 * open(blob) - all open should fail
Patrick Venturea82f99e2019-05-24 15:44:35 -0700217 */
Patrick Ventureeee71812019-05-29 10:41:04 -0700218TEST_F(FirmwareHandlerVerificationCompletedTest,
219 OpeningAnyBlobAvailableFailsAfterSuccess)
220{
221 getToVerificationCompleted(VerifyCheckResponses::success);
222
223 auto blobs = handler->getBlobIds();
224 for (const auto& blob : blobs)
225 {
226 EXPECT_FALSE(handler->open(session + 1, flags, blob));
227 }
228}
229
230TEST_F(FirmwareHandlerVerificationCompletedTest,
231 OpeningAnyBlobAvailableFailsAfterFailure)
232{
233 getToVerificationCompleted(VerifyCheckResponses::failed);
234
235 auto blobs = handler->getBlobIds();
236 for (const auto& blob : blobs)
237 {
238 EXPECT_FALSE(handler->open(session + 1, flags, blob));
239 }
240}
Patrick Venturea82f99e2019-05-24 15:44:35 -0700241
242/*
243 * writemeta(session) - write meta should fail.
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700244 */
Patrick Venture2b801372019-05-29 10:26:01 -0700245TEST_F(FirmwareHandlerVerificationCompletedTest,
246 WriteMetaToVerifyBlobReturnsFailure)
247{
248 getToVerificationCompleted(VerifyCheckResponses::success);
249
250 std::vector<std::uint8_t> bytes = {0x01, 0x02};
251 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
252}
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700253
254/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700255 * write(session) - write should fail.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700256 */
Patrick Venture4d9b0e12019-05-29 10:21:40 -0700257TEST_F(FirmwareHandlerVerificationCompletedTest,
258 WriteToVerifyBlobReturnsFailure)
259{
260 getToVerificationCompleted(VerifyCheckResponses::success);
261
262 std::vector<std::uint8_t> bytes = {0x01, 0x02};
263 EXPECT_FALSE(handler->write(session, 0, bytes));
264}
Patrick Venture65cdcf02019-05-29 10:18:50 -0700265
266/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700267 * read(session) - read returns empty.
Patrick Venture65cdcf02019-05-29 10:18:50 -0700268 */
269TEST_F(FirmwareHandlerVerificationCompletedTest, ReadOfVerifyBlobReturnsEmpty)
270{
271 getToVerificationCompleted(VerifyCheckResponses::success);
272 EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
273}
274
275/*
Patrick Venturea82f99e2019-05-24 15:44:35 -0700276 * commit(session) - ?
277 */
278
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
282 * 2. if unsuccessful doesn't add update blob id, changes state to?
283 */
284
Patrick Venturea82f99e2019-05-24 15:44:35 -0700285} // namespace
286} // namespace ipmi_flash