blob: 005ca3f0859df137927dd6ea1e44d6d56cbbae6c [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
43{
44};
45
46TEST_F(FirmwareHandlerUploadInProgressTest, GetBlobIdsVerifyOutputActiveImage)
47{
48 /* Opening the image file will add the active image blob id */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070049 openToInProgress(staticLayoutBlobId);
Patrick Ventureebcc5222019-05-23 10:36:40 -070050
Patrick Ventureebcc5222019-05-23 10:36:40 -070051 EXPECT_THAT(handler->getBlobIds(),
Patrick Venture9a69f732019-06-17 14:05:13 -070052 UnorderedElementsAreArray(
53 {staticLayoutBlobId, hashBlobId, activeImageBlobId}));
Patrick Ventureebcc5222019-05-23 10:36:40 -070054}
55
56TEST_F(FirmwareHandlerUploadInProgressTest, GetBlobIdsVerifyOutputActiveHash)
57{
58 /* Opening the image file will add the active image blob id */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070059 openToInProgress(hashBlobId);
Patrick Ventureebcc5222019-05-23 10:36:40 -070060
Patrick Ventureebcc5222019-05-23 10:36:40 -070061 EXPECT_THAT(handler->getBlobIds(),
Patrick Venture9a69f732019-06-17 14:05:13 -070062 UnorderedElementsAreArray(
63 {staticLayoutBlobId, hashBlobId, activeHashBlobId}));
Patrick Ventureebcc5222019-05-23 10:36:40 -070064}
65
Patrick Venture41205cc2019-05-23 11:43:43 -070066/*
67 * stat(blob)
68 */
69TEST_F(FirmwareHandlerUploadInProgressTest, StatOnActiveImageReturnsFailure)
70{
71 /* you cannot call stat() on the active image or the active hash or the
72 * verify blob.
73 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070074 openToInProgress(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070075 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Venture41205cc2019-05-23 11:43:43 -070076
Patrick Venture41205cc2019-05-23 11:43:43 -070077 blobs::BlobMeta meta;
78 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
79}
80
81TEST_F(FirmwareHandlerUploadInProgressTest, StatOnActiveHashReturnsFailure)
82{
83 /* this test is separate from the active image one so that the state doesn't
84 * change from close.
85 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070086 openToInProgress(hashBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070087 ASSERT_TRUE(handler->canHandleBlob(activeHashBlobId));
Patrick Venture41205cc2019-05-23 11:43:43 -070088
Patrick Venture41205cc2019-05-23 11:43:43 -070089 blobs::BlobMeta meta;
90 EXPECT_FALSE(handler->stat(activeHashBlobId, &meta));
91}
92
93TEST_F(FirmwareHandlerUploadInProgressTest, StatOnNormalBlobsReturnsSuccess)
94{
95 /* Calling stat() on the normal blobs (not the active) ones will work and
96 * return the same information as in the notYetStarted state.
97 */
98 blobs::BlobMeta expected;
99 expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
100 expected.size = 0;
101
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700102 openToInProgress(staticLayoutBlobId);
Patrick Venture41205cc2019-05-23 11:43:43 -0700103
104 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
105 for (const auto& blob : testBlobs)
106 {
107 blobs::BlobMeta meta = {};
108 EXPECT_TRUE(handler->stat(blob, &meta));
109 EXPECT_EQ(expected, meta);
110 }
111}
112
Patrick Venture41205cc2019-05-23 11:43:43 -0700113/*
114 * stat(session)
Patrick Ventureefc366e2019-05-23 12:00:21 -0700115 */
116TEST_F(FirmwareHandlerUploadInProgressTest,
117 CallingStatOnActiveImageOrHashSessionReturnsDetails)
118{
119 /* This test will verify that the underlying image handler is called with
120 * this stat, in addition to the normal information.
121 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700122 openToInProgress(staticLayoutBlobId);
Patrick Ventureefc366e2019-05-23 12:00:21 -0700123
124 EXPECT_CALL(imageMock, getSize()).WillOnce(Return(32));
125
126 blobs::BlobMeta meta, expectedMeta = {};
127 expectedMeta.size = 32;
128 expectedMeta.blobState =
129 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
130 EXPECT_TRUE(handler->stat(session, &meta));
131 EXPECT_EQ(expectedMeta, meta);
132}
133
134/*
Patrick Venture5788dbb2019-05-23 12:25:42 -0700135 * open(blob) - While any blob is open, all other fail.
Patrick Venture072a7dd2019-05-28 13:51:26 -0700136 *
137 * The fullBlobsList is all the blob_ids present if both /flash/image and
138 * /flash/hash are opened, and one is left open (so there's no verify blob). if
139 * left closed, we'd be in verificationPending, not uploadInProgress.
Patrick Venture5788dbb2019-05-23 12:25:42 -0700140 */
Patrick Venture072a7dd2019-05-28 13:51:26 -0700141const std::vector<std::string> fullBlobsList = {
142 activeHashBlobId, activeImageBlobId, hashBlobId, staticLayoutBlobId};
143
Patrick Venture5788dbb2019-05-23 12:25:42 -0700144TEST_F(FirmwareHandlerUploadInProgressTest, OpeningHashFileWhileImageOpenFails)
145{
146 /* To be in this state, something must be open (and specifically either an
147 * active image (or tarball) or the hash file. Also verifies you can't just
148 * re-open the currently open file.
149 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700150 openToInProgress(staticLayoutBlobId);
Patrick Venture5788dbb2019-05-23 12:25:42 -0700151
Patrick Venture072a7dd2019-05-28 13:51:26 -0700152 for (const auto& blob : fullBlobsList)
Patrick Venture5788dbb2019-05-23 12:25:42 -0700153 {
154 EXPECT_FALSE(handler->open(2, flags, blob));
155 }
156}
157
158TEST_F(FirmwareHandlerUploadInProgressTest, OpeningImageFileWhileHashOpenFails)
159{
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700160 openToInProgress(hashBlobId);
Patrick Venture5788dbb2019-05-23 12:25:42 -0700161
Patrick Venture072a7dd2019-05-28 13:51:26 -0700162 for (const auto& blob : fullBlobsList)
Patrick Venture5788dbb2019-05-23 12:25:42 -0700163 {
164 EXPECT_FALSE(handler->open(2, flags, blob));
165 }
166}
167
168/*
Patrick Venture79b44742019-05-23 12:36:11 -0700169 * close(session) - closing the hash or image will trigger a state transition to
170 * verificationPending.
Patrick Venture79b44742019-05-23 12:36:11 -0700171 *
172 * NOTE: Re-opening /flash/image will transition back to uploadInProgress, but
173 * that is verified in the verificationPending::open tests.
174 */
175TEST_F(FirmwareHandlerUploadInProgressTest,
176 ClosingImageFileTransitionsToVerificationPending)
177{
Patrick Venture930c7b72019-05-24 11:11:08 -0700178 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700179 openToInProgress(staticLayoutBlobId);
Patrick Venture79b44742019-05-23 12:36:11 -0700180
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700181 handler->close(session);
182 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture79b44742019-05-23 12:36:11 -0700183
184 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
185}
186
187TEST_F(FirmwareHandlerUploadInProgressTest,
188 ClosingHashFileTransitionsToVerificationPending)
189{
Patrick Venture930c7b72019-05-24 11:11:08 -0700190 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700191 openToInProgress(hashBlobId);
Patrick Venture79b44742019-05-23 12:36:11 -0700192
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700193 handler->close(session);
194 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture79b44742019-05-23 12:36:11 -0700195
196 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
197}
198
199/*
Patrick Venture41205cc2019-05-23 11:43:43 -0700200 * writemeta(session)
Patrick Venture7cf44402019-05-23 13:01:47 -0700201 */
Patrick Venture31eefd42019-05-23 20:27:41 -0700202TEST_F(FirmwareHandlerUploadInProgressTest,
203 WriteMetaAgainstImageReturnsFailureIfNoDataHandler)
Patrick Venture7cf44402019-05-23 13:01:47 -0700204{
205 /* Calling write/read/writeMeta are uninteresting against the open blob in
206 * this case because the blob will just pass the call along. Whereas
207 * calling against the verify or update blob may be more interesting.
208 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700209 openToInProgress(staticLayoutBlobId);
Patrick Venture7cf44402019-05-23 13:01:47 -0700210
Patrick Venture31eefd42019-05-23 20:27:41 -0700211 /* TODO: Consider adding a test that has a data handler, but that test
212 * already exists under the general writeMeta test suite.
213 */
Patrick Venture7cf44402019-05-23 13:01:47 -0700214 /* Note: with IPMI as the transport there's no data handler, so this should
215 * fail nicely. */
216 std::vector<std::uint8_t> bytes = {0x01, 0x02};
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700217 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
Patrick Venture7cf44402019-05-23 13:01:47 -0700218}
219
220/*
Patrick Venture41205cc2019-05-23 11:43:43 -0700221 * write(session)
Patrick Venture615123a2019-05-23 17:20:07 -0700222 */
223TEST_F(FirmwareHandlerUploadInProgressTest, WriteToImageReturnsSuccess)
224{
225 openToInProgress(staticLayoutBlobId);
226 std::vector<std::uint8_t> bytes = {0x01, 0x02};
227 EXPECT_CALL(imageMock, write(0, ContainerEq(bytes))).WillOnce(Return(true));
228 EXPECT_TRUE(handler->write(session, 0, bytes));
229}
230
231TEST_F(FirmwareHandlerUploadInProgressTest, WriteToHashReturnsSuccess)
232{
233 openToInProgress(hashBlobId);
234 std::vector<std::uint8_t> bytes = {0x01, 0x02};
235 EXPECT_CALL(imageMock, write(0, ContainerEq(bytes))).WillOnce(Return(true));
236 EXPECT_TRUE(handler->write(session, 0, bytes));
237}
238
239/*
Patrick Venture41205cc2019-05-23 11:43:43 -0700240 * read(session)
Patrick Venture615123a2019-05-23 17:20:07 -0700241 */
Patrick Venture8326d072019-05-23 17:45:42 -0700242TEST_F(FirmwareHandlerUploadInProgressTest, ReadImageFileReturnsFailure)
243{
244 /* Read is not supported. */
245 openToInProgress(staticLayoutBlobId);
246 EXPECT_THAT(handler->read(session, 0, 32), IsEmpty());
247}
Patrick Venture615123a2019-05-23 17:20:07 -0700248
249/*
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700250 * commit(session)
Patrick Venture41205cc2019-05-23 11:43:43 -0700251 */
Patrick Venture1fca1902019-05-23 17:54:18 -0700252TEST_F(FirmwareHandlerUploadInProgressTest,
253 CommitAgainstImageFileReturnsFailure)
254{
255 /* Commit is only valid against specific blobs. */
256 openToInProgress(staticLayoutBlobId);
257 EXPECT_FALSE(handler->commit(session, {}));
258}
259
260TEST_F(FirmwareHandlerUploadInProgressTest, CommitAgainstHashFileReturnsFailure)
261{
262 openToInProgress(hashBlobId);
263 EXPECT_FALSE(handler->commit(session, {}));
264}
Patrick Venture41205cc2019-05-23 11:43:43 -0700265
Patrick Venturebcc0c772019-06-17 10:42:06 -0700266/*
267 * deleteBlob(blob)
268 */
269TEST_F(FirmwareHandlerUploadInProgressTest, DeleteBlobReturnsFalse)
270{
271 /* Try deleting all blobs, it doesn't really matter which though because you
272 * cannot close out an open session, therefore you must fail to delete
273 * anything unless everything is closed.
274 */
275 openToInProgress(staticLayoutBlobId);
276 auto blobs = handler->getBlobIds();
277 for (const auto& b : blobs)
278 {
279 EXPECT_FALSE(handler->deleteBlob(b));
280 }
281}
282
Patrick Ventureebcc5222019-05-23 10:36:40 -0700283} // namespace
284} // namespace ipmi_flash