blob: d5bd3f358ce330a858e85d294182d191f0eb2ab8 [file] [log] [blame]
Patrick Ventureebcc5222019-05-23 10:36:40 -07001/**
2 * The goal of these tests is to verify the behavior of all blob commands given
3 * the current state is uploadInProgress. This state is achieved when an image
4 * or hash blob is opened and the handler is expected to receive bytes.
5 */
6#include "firmware_handler.hpp"
7#include "firmware_unittest.hpp"
8
Patrick Venture615123a2019-05-23 17:20:07 -07009#include <cstdint>
10#include <string>
11#include <vector>
12
Patrick Ventureebcc5222019-05-23 10:36:40 -070013#include <gtest/gtest.h>
14
15namespace ipmi_flash
16{
17namespace
18{
19
Patrick Venture615123a2019-05-23 17:20:07 -070020using ::testing::ContainerEq;
Patrick Venture8326d072019-05-23 17:45:42 -070021using ::testing::IsEmpty;
Patrick Ventureebcc5222019-05-23 10:36:40 -070022using ::testing::Return;
23using ::testing::UnorderedElementsAreArray;
24
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)
Patrick Venture547fa3a2019-05-23 16:06:37 -070037 * commit(session)
Patrick Ventureebcc5222019-05-23 10:36:40 -070038 *
39 * Testing canHandleBlob is uninteresting in this state. Getting the BlobIDs
40 * will inform what canHandleBlob will return.
41 */
42class FirmwareHandlerUploadInProgressTest : public IpmiOnlyFirmwareStaticTest
Patrick Venture9b37b092020-05-28 20:58:57 -070043{};
Patrick Ventureebcc5222019-05-23 10:36:40 -070044
45TEST_F(FirmwareHandlerUploadInProgressTest, GetBlobIdsVerifyOutputActiveImage)
46{
47 /* Opening the image file will add the active image blob id */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070048 openToInProgress(staticLayoutBlobId);
Patrick Ventureebcc5222019-05-23 10:36:40 -070049
Patrick Ventureebcc5222019-05-23 10:36:40 -070050 EXPECT_THAT(handler->getBlobIds(),
Patrick Venture9a69f732019-06-17 14:05:13 -070051 UnorderedElementsAreArray(
52 {staticLayoutBlobId, hashBlobId, activeImageBlobId}));
Patrick Ventureebcc5222019-05-23 10:36:40 -070053}
54
55TEST_F(FirmwareHandlerUploadInProgressTest, GetBlobIdsVerifyOutputActiveHash)
56{
57 /* Opening the image file will add the active image blob id */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070058 openToInProgress(hashBlobId);
Patrick Ventureebcc5222019-05-23 10:36:40 -070059
Patrick Ventureebcc5222019-05-23 10:36:40 -070060 EXPECT_THAT(handler->getBlobIds(),
Patrick Venture9a69f732019-06-17 14:05:13 -070061 UnorderedElementsAreArray(
62 {staticLayoutBlobId, hashBlobId, activeHashBlobId}));
Patrick Ventureebcc5222019-05-23 10:36:40 -070063}
64
Patrick Venture41205cc2019-05-23 11:43:43 -070065/*
66 * stat(blob)
67 */
68TEST_F(FirmwareHandlerUploadInProgressTest, StatOnActiveImageReturnsFailure)
69{
70 /* you cannot call stat() on the active image or the active hash or the
71 * verify blob.
72 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070073 openToInProgress(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070074 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Venture41205cc2019-05-23 11:43:43 -070075
Patrick Venture41205cc2019-05-23 11:43:43 -070076 blobs::BlobMeta meta;
77 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
78}
79
80TEST_F(FirmwareHandlerUploadInProgressTest, StatOnActiveHashReturnsFailure)
81{
82 /* this test is separate from the active image one so that the state doesn't
83 * change from close.
84 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070085 openToInProgress(hashBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070086 ASSERT_TRUE(handler->canHandleBlob(activeHashBlobId));
Patrick Venture41205cc2019-05-23 11:43:43 -070087
Patrick Venture41205cc2019-05-23 11:43:43 -070088 blobs::BlobMeta meta;
89 EXPECT_FALSE(handler->stat(activeHashBlobId, &meta));
90}
91
92TEST_F(FirmwareHandlerUploadInProgressTest, StatOnNormalBlobsReturnsSuccess)
93{
94 /* Calling stat() on the normal blobs (not the active) ones will work and
95 * return the same information as in the notYetStarted state.
96 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070097 openToInProgress(staticLayoutBlobId);
Patrick Venture41205cc2019-05-23 11:43:43 -070098
99 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
100 for (const auto& blob : testBlobs)
101 {
102 blobs::BlobMeta meta = {};
103 EXPECT_TRUE(handler->stat(blob, &meta));
Benjamin Fair12901982019-11-12 13:55:46 -0800104 EXPECT_EQ(expectedIdleMeta, meta);
Patrick Venture41205cc2019-05-23 11:43:43 -0700105 }
106}
107
Patrick Venture41205cc2019-05-23 11:43:43 -0700108/*
109 * stat(session)
Patrick Ventureefc366e2019-05-23 12:00:21 -0700110 */
111TEST_F(FirmwareHandlerUploadInProgressTest,
112 CallingStatOnActiveImageOrHashSessionReturnsDetails)
113{
114 /* This test will verify that the underlying image handler is called with
115 * this stat, in addition to the normal information.
116 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700117 openToInProgress(staticLayoutBlobId);
Patrick Ventureefc366e2019-05-23 12:00:21 -0700118
Patrick Ventured4e20de2019-07-18 12:48:05 -0700119 EXPECT_CALL(*imageMock2, getSize()).WillOnce(Return(32));
Patrick Ventureefc366e2019-05-23 12:00:21 -0700120
121 blobs::BlobMeta meta, expectedMeta = {};
122 expectedMeta.size = 32;
123 expectedMeta.blobState =
Patrick Venture84778b82019-06-26 20:11:09 -0700124 blobs::OpenFlags::write | FirmwareFlags::UpdateFlags::ipmi;
Patrick Ventureefc366e2019-05-23 12:00:21 -0700125 EXPECT_TRUE(handler->stat(session, &meta));
126 EXPECT_EQ(expectedMeta, meta);
127}
128
129/*
Patrick Venture5788dbb2019-05-23 12:25:42 -0700130 * open(blob) - While any blob is open, all other fail.
Patrick Venture072a7dd2019-05-28 13:51:26 -0700131 *
132 * The fullBlobsList is all the blob_ids present if both /flash/image and
133 * /flash/hash are opened, and one is left open (so there's no verify blob). if
134 * left closed, we'd be in verificationPending, not uploadInProgress.
Patrick Venture5788dbb2019-05-23 12:25:42 -0700135 */
Patrick Venture072a7dd2019-05-28 13:51:26 -0700136const std::vector<std::string> fullBlobsList = {
137 activeHashBlobId, activeImageBlobId, hashBlobId, staticLayoutBlobId};
138
Patrick Venture5788dbb2019-05-23 12:25:42 -0700139TEST_F(FirmwareHandlerUploadInProgressTest, OpeningHashFileWhileImageOpenFails)
140{
141 /* To be in this state, something must be open (and specifically either an
142 * active image (or tarball) or the hash file. Also verifies you can't just
143 * re-open the currently open file.
144 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700145 openToInProgress(staticLayoutBlobId);
Patrick Venture5788dbb2019-05-23 12:25:42 -0700146
Patrick Venture072a7dd2019-05-28 13:51:26 -0700147 for (const auto& blob : fullBlobsList)
Patrick Venture5788dbb2019-05-23 12:25:42 -0700148 {
149 EXPECT_FALSE(handler->open(2, flags, blob));
150 }
151}
152
153TEST_F(FirmwareHandlerUploadInProgressTest, OpeningImageFileWhileHashOpenFails)
154{
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700155 openToInProgress(hashBlobId);
Patrick Venture5788dbb2019-05-23 12:25:42 -0700156
Patrick Venture072a7dd2019-05-28 13:51:26 -0700157 for (const auto& blob : fullBlobsList)
Patrick Venture5788dbb2019-05-23 12:25:42 -0700158 {
159 EXPECT_FALSE(handler->open(2, flags, blob));
160 }
161}
162
163/*
Patrick Venture79b44742019-05-23 12:36:11 -0700164 * close(session) - closing the hash or image will trigger a state transition to
165 * verificationPending.
Patrick Venture79b44742019-05-23 12:36:11 -0700166 *
167 * NOTE: Re-opening /flash/image will transition back to uploadInProgress, but
168 * that is verified in the verificationPending::open tests.
169 */
170TEST_F(FirmwareHandlerUploadInProgressTest,
171 ClosingImageFileTransitionsToVerificationPending)
172{
Patrick Venture930c7b72019-05-24 11:11:08 -0700173 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700174 openToInProgress(staticLayoutBlobId);
Patrick Venture79b44742019-05-23 12:36:11 -0700175
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700176 handler->close(session);
177 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture79b44742019-05-23 12:36:11 -0700178
179 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
180}
181
182TEST_F(FirmwareHandlerUploadInProgressTest,
183 ClosingHashFileTransitionsToVerificationPending)
184{
Patrick Venture930c7b72019-05-24 11:11:08 -0700185 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700186 openToInProgress(hashBlobId);
Patrick Venture79b44742019-05-23 12:36:11 -0700187
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700188 handler->close(session);
189 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture79b44742019-05-23 12:36:11 -0700190
Patrick Venture1999eef2019-07-01 11:44:09 -0700191 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
Patrick Venture79b44742019-05-23 12:36:11 -0700192}
193
194/*
Patrick Venture41205cc2019-05-23 11:43:43 -0700195 * writemeta(session)
Patrick Venture7cf44402019-05-23 13:01:47 -0700196 */
Patrick Venture31eefd42019-05-23 20:27:41 -0700197TEST_F(FirmwareHandlerUploadInProgressTest,
198 WriteMetaAgainstImageReturnsFailureIfNoDataHandler)
Patrick Venture7cf44402019-05-23 13:01:47 -0700199{
200 /* Calling write/read/writeMeta are uninteresting against the open blob in
201 * this case because the blob will just pass the call along. Whereas
202 * calling against the verify or update blob may be more interesting.
203 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700204 openToInProgress(staticLayoutBlobId);
Patrick Venture7cf44402019-05-23 13:01:47 -0700205
Patrick Venture31eefd42019-05-23 20:27:41 -0700206 /* TODO: Consider adding a test that has a data handler, but that test
207 * already exists under the general writeMeta test suite.
208 */
Patrick Venture7cf44402019-05-23 13:01:47 -0700209 /* Note: with IPMI as the transport there's no data handler, so this should
210 * fail nicely. */
211 std::vector<std::uint8_t> bytes = {0x01, 0x02};
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700212 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
Patrick Venture7cf44402019-05-23 13:01:47 -0700213}
214
215/*
Patrick Venture41205cc2019-05-23 11:43:43 -0700216 * write(session)
Patrick Venture615123a2019-05-23 17:20:07 -0700217 */
218TEST_F(FirmwareHandlerUploadInProgressTest, WriteToImageReturnsSuccess)
219{
220 openToInProgress(staticLayoutBlobId);
221 std::vector<std::uint8_t> bytes = {0x01, 0x02};
Patrick Ventured4e20de2019-07-18 12:48:05 -0700222 EXPECT_CALL(*imageMock2, write(0, ContainerEq(bytes)))
223 .WillOnce(Return(true));
Patrick Venture615123a2019-05-23 17:20:07 -0700224 EXPECT_TRUE(handler->write(session, 0, bytes));
225}
226
227TEST_F(FirmwareHandlerUploadInProgressTest, WriteToHashReturnsSuccess)
228{
229 openToInProgress(hashBlobId);
230 std::vector<std::uint8_t> bytes = {0x01, 0x02};
Patrick Ventured4e20de2019-07-18 12:48:05 -0700231 EXPECT_CALL(*hashImageMock, write(0, ContainerEq(bytes)))
232 .WillOnce(Return(true));
Patrick Venture615123a2019-05-23 17:20:07 -0700233 EXPECT_TRUE(handler->write(session, 0, bytes));
234}
235
236/*
Patrick Venture41205cc2019-05-23 11:43:43 -0700237 * read(session)
Patrick Venture615123a2019-05-23 17:20:07 -0700238 */
Patrick Venture8326d072019-05-23 17:45:42 -0700239TEST_F(FirmwareHandlerUploadInProgressTest, ReadImageFileReturnsFailure)
240{
241 /* Read is not supported. */
242 openToInProgress(staticLayoutBlobId);
243 EXPECT_THAT(handler->read(session, 0, 32), IsEmpty());
244}
Patrick Venture615123a2019-05-23 17:20:07 -0700245
246/*
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700247 * commit(session)
Patrick Venture41205cc2019-05-23 11:43:43 -0700248 */
Patrick Venture1fca1902019-05-23 17:54:18 -0700249TEST_F(FirmwareHandlerUploadInProgressTest,
250 CommitAgainstImageFileReturnsFailure)
251{
252 /* Commit is only valid against specific blobs. */
253 openToInProgress(staticLayoutBlobId);
254 EXPECT_FALSE(handler->commit(session, {}));
255}
256
257TEST_F(FirmwareHandlerUploadInProgressTest, CommitAgainstHashFileReturnsFailure)
258{
259 openToInProgress(hashBlobId);
260 EXPECT_FALSE(handler->commit(session, {}));
261}
Patrick Venture41205cc2019-05-23 11:43:43 -0700262
Patrick Venturebcc0c772019-06-17 10:42:06 -0700263/*
264 * deleteBlob(blob)
265 */
266TEST_F(FirmwareHandlerUploadInProgressTest, DeleteBlobReturnsFalse)
267{
268 /* Try deleting all blobs, it doesn't really matter which though because you
269 * cannot close out an open session, therefore you must fail to delete
270 * anything unless everything is closed.
271 */
272 openToInProgress(staticLayoutBlobId);
273 auto blobs = handler->getBlobIds();
274 for (const auto& b : blobs)
275 {
276 EXPECT_FALSE(handler->deleteBlob(b));
277 }
278}
279
Patrick Venture92f26152020-05-26 19:47:36 -0700280/*
281 * expire(session)
282 */
283TEST_F(FirmwareHandlerUploadInProgressTest, ExpireAbortsProcess)
284{
285 openToInProgress(staticLayoutBlobId);
286
287 ASSERT_TRUE(handler->expire(session));
288 EXPECT_THAT(handler->getBlobIds(),
289 UnorderedElementsAreArray(startingBlobs));
290 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
291}
292
Patrick Ventureebcc5222019-05-23 10:36:40 -0700293} // namespace
294} // namespace ipmi_flash