blob: 085f542555c3d7e9a1f815c5278cebfd6bd38ca4 [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{
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070044 protected:
45 void openToInProgress(const std::string& blobId)
46 {
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070047 EXPECT_CALL(imageMock, open(blobId)).WillOnce(Return(true));
48 EXPECT_TRUE(handler->open(session, flags, blobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -070049 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070050 }
51
52 std::uint16_t session = 1;
53 std::uint16_t flags =
54 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
Patrick Ventureebcc5222019-05-23 10:36:40 -070055};
56
57TEST_F(FirmwareHandlerUploadInProgressTest, GetBlobIdsVerifyOutputActiveImage)
58{
59 /* Opening the image file will add the active image blob id */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070060 openToInProgress(staticLayoutBlobId);
Patrick Ventureebcc5222019-05-23 10:36:40 -070061
62 std::vector<std::string> expectedAfterImage = {
Patrick Venture930c7b72019-05-24 11:11:08 -070063 staticLayoutBlobId, hashBlobId, activeImageBlobId};
Patrick Ventureebcc5222019-05-23 10:36:40 -070064 EXPECT_THAT(handler->getBlobIds(),
65 UnorderedElementsAreArray(expectedAfterImage));
66}
67
68TEST_F(FirmwareHandlerUploadInProgressTest, GetBlobIdsVerifyOutputActiveHash)
69{
70 /* Opening the image file will add the active image blob id */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070071 openToInProgress(hashBlobId);
Patrick Ventureebcc5222019-05-23 10:36:40 -070072
73 std::vector<std::string> expectedAfterImage = {
Patrick Venture930c7b72019-05-24 11:11:08 -070074 staticLayoutBlobId, hashBlobId, activeHashBlobId};
Patrick Ventureebcc5222019-05-23 10:36:40 -070075 EXPECT_THAT(handler->getBlobIds(),
76 UnorderedElementsAreArray(expectedAfterImage));
77}
78
Patrick Venture6f729782019-05-23 11:16:13 -070079/* TODO: Try deleting some blobs -- in this state it will depend on what the
80 * blob id is, but it's not yet implemented
81 */
82
Patrick Venture41205cc2019-05-23 11:43:43 -070083/*
84 * stat(blob)
85 */
86TEST_F(FirmwareHandlerUploadInProgressTest, StatOnActiveImageReturnsFailure)
87{
88 /* you cannot call stat() on the active image or the active hash or the
89 * verify blob.
90 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070091 openToInProgress(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070092 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Venture41205cc2019-05-23 11:43:43 -070093
Patrick Venture41205cc2019-05-23 11:43:43 -070094 blobs::BlobMeta meta;
95 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
96}
97
98TEST_F(FirmwareHandlerUploadInProgressTest, StatOnActiveHashReturnsFailure)
99{
100 /* this test is separate from the active image one so that the state doesn't
101 * change from close.
102 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700103 openToInProgress(hashBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -0700104 ASSERT_TRUE(handler->canHandleBlob(activeHashBlobId));
Patrick Venture41205cc2019-05-23 11:43:43 -0700105
Patrick Venture41205cc2019-05-23 11:43:43 -0700106 blobs::BlobMeta meta;
107 EXPECT_FALSE(handler->stat(activeHashBlobId, &meta));
108}
109
110TEST_F(FirmwareHandlerUploadInProgressTest, StatOnNormalBlobsReturnsSuccess)
111{
112 /* Calling stat() on the normal blobs (not the active) ones will work and
113 * return the same information as in the notYetStarted state.
114 */
115 blobs::BlobMeta expected;
116 expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
117 expected.size = 0;
118
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700119 openToInProgress(staticLayoutBlobId);
Patrick Venture41205cc2019-05-23 11:43:43 -0700120
121 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
122 for (const auto& blob : testBlobs)
123 {
124 blobs::BlobMeta meta = {};
125 EXPECT_TRUE(handler->stat(blob, &meta));
126 EXPECT_EQ(expected, meta);
127 }
128}
129
Patrick Venture41205cc2019-05-23 11:43:43 -0700130/*
131 * stat(session)
Patrick Ventureefc366e2019-05-23 12:00:21 -0700132 */
133TEST_F(FirmwareHandlerUploadInProgressTest,
134 CallingStatOnActiveImageOrHashSessionReturnsDetails)
135{
136 /* This test will verify that the underlying image handler is called with
137 * this stat, in addition to the normal information.
138 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700139 openToInProgress(staticLayoutBlobId);
Patrick Ventureefc366e2019-05-23 12:00:21 -0700140
141 EXPECT_CALL(imageMock, getSize()).WillOnce(Return(32));
142
143 blobs::BlobMeta meta, expectedMeta = {};
144 expectedMeta.size = 32;
145 expectedMeta.blobState =
146 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
147 EXPECT_TRUE(handler->stat(session, &meta));
148 EXPECT_EQ(expectedMeta, meta);
149}
150
151/*
Patrick Venture5788dbb2019-05-23 12:25:42 -0700152 * open(blob) - While any blob is open, all other fail.
153 */
154TEST_F(FirmwareHandlerUploadInProgressTest, OpeningHashFileWhileImageOpenFails)
155{
156 /* To be in this state, something must be open (and specifically either an
157 * active image (or tarball) or the hash file. Also verifies you can't just
158 * re-open the currently open file.
159 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700160 openToInProgress(staticLayoutBlobId);
Patrick Venture5788dbb2019-05-23 12:25:42 -0700161
162 std::vector<std::string> blobsToTry = {
163 hashBlobId, activeImageBlobId, activeHashBlobId, staticLayoutBlobId};
164 for (const auto& blob : blobsToTry)
165 {
166 EXPECT_FALSE(handler->open(2, flags, blob));
167 }
168}
169
170TEST_F(FirmwareHandlerUploadInProgressTest, OpeningImageFileWhileHashOpenFails)
171{
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700172 openToInProgress(hashBlobId);
Patrick Venture5788dbb2019-05-23 12:25:42 -0700173
174 std::vector<std::string> blobsToTry = {
175 hashBlobId, activeImageBlobId, activeHashBlobId, staticLayoutBlobId};
176 for (const auto& blob : blobsToTry)
177 {
178 EXPECT_FALSE(handler->open(2, flags, blob));
179 }
180}
181
182/*
Patrick Venture79b44742019-05-23 12:36:11 -0700183 * close(session) - closing the hash or image will trigger a state transition to
184 * verificationPending.
Patrick Venture79b44742019-05-23 12:36:11 -0700185 *
186 * NOTE: Re-opening /flash/image will transition back to uploadInProgress, but
187 * that is verified in the verificationPending::open tests.
188 */
189TEST_F(FirmwareHandlerUploadInProgressTest,
190 ClosingImageFileTransitionsToVerificationPending)
191{
Patrick Venture930c7b72019-05-24 11:11:08 -0700192 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700193 openToInProgress(staticLayoutBlobId);
Patrick Venture79b44742019-05-23 12:36:11 -0700194
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700195 handler->close(session);
196 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture79b44742019-05-23 12:36:11 -0700197
198 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
199}
200
201TEST_F(FirmwareHandlerUploadInProgressTest,
202 ClosingHashFileTransitionsToVerificationPending)
203{
Patrick Venture930c7b72019-05-24 11:11:08 -0700204 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700205 openToInProgress(hashBlobId);
Patrick Venture79b44742019-05-23 12:36:11 -0700206
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700207 handler->close(session);
208 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture79b44742019-05-23 12:36:11 -0700209
210 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
211}
212
213/*
Patrick Venture41205cc2019-05-23 11:43:43 -0700214 * writemeta(session)
Patrick Venture7cf44402019-05-23 13:01:47 -0700215 */
Patrick Venture31eefd42019-05-23 20:27:41 -0700216TEST_F(FirmwareHandlerUploadInProgressTest,
217 WriteMetaAgainstImageReturnsFailureIfNoDataHandler)
Patrick Venture7cf44402019-05-23 13:01:47 -0700218{
219 /* Calling write/read/writeMeta are uninteresting against the open blob in
220 * this case because the blob will just pass the call along. Whereas
221 * calling against the verify or update blob may be more interesting.
222 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700223 openToInProgress(staticLayoutBlobId);
Patrick Venture7cf44402019-05-23 13:01:47 -0700224
Patrick Venture31eefd42019-05-23 20:27:41 -0700225 /* TODO: Consider adding a test that has a data handler, but that test
226 * already exists under the general writeMeta test suite.
227 */
Patrick Venture7cf44402019-05-23 13:01:47 -0700228 /* Note: with IPMI as the transport there's no data handler, so this should
229 * fail nicely. */
230 std::vector<std::uint8_t> bytes = {0x01, 0x02};
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700231 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
Patrick Venture7cf44402019-05-23 13:01:47 -0700232}
233
234/*
Patrick Venture41205cc2019-05-23 11:43:43 -0700235 * write(session)
Patrick Venture615123a2019-05-23 17:20:07 -0700236 */
237TEST_F(FirmwareHandlerUploadInProgressTest, WriteToImageReturnsSuccess)
238{
239 openToInProgress(staticLayoutBlobId);
240 std::vector<std::uint8_t> bytes = {0x01, 0x02};
241 EXPECT_CALL(imageMock, write(0, ContainerEq(bytes))).WillOnce(Return(true));
242 EXPECT_TRUE(handler->write(session, 0, bytes));
243}
244
245TEST_F(FirmwareHandlerUploadInProgressTest, WriteToHashReturnsSuccess)
246{
247 openToInProgress(hashBlobId);
248 std::vector<std::uint8_t> bytes = {0x01, 0x02};
249 EXPECT_CALL(imageMock, write(0, ContainerEq(bytes))).WillOnce(Return(true));
250 EXPECT_TRUE(handler->write(session, 0, bytes));
251}
252
253/*
Patrick Venture41205cc2019-05-23 11:43:43 -0700254 * read(session)
Patrick Venture615123a2019-05-23 17:20:07 -0700255 */
Patrick Venture8326d072019-05-23 17:45:42 -0700256TEST_F(FirmwareHandlerUploadInProgressTest, ReadImageFileReturnsFailure)
257{
258 /* Read is not supported. */
259 openToInProgress(staticLayoutBlobId);
260 EXPECT_THAT(handler->read(session, 0, 32), IsEmpty());
261}
Patrick Venture615123a2019-05-23 17:20:07 -0700262
263/*
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700264 * commit(session)
Patrick Venture41205cc2019-05-23 11:43:43 -0700265 */
Patrick Venture1fca1902019-05-23 17:54:18 -0700266TEST_F(FirmwareHandlerUploadInProgressTest,
267 CommitAgainstImageFileReturnsFailure)
268{
269 /* Commit is only valid against specific blobs. */
270 openToInProgress(staticLayoutBlobId);
271 EXPECT_FALSE(handler->commit(session, {}));
272}
273
274TEST_F(FirmwareHandlerUploadInProgressTest, CommitAgainstHashFileReturnsFailure)
275{
276 openToInProgress(hashBlobId);
277 EXPECT_FALSE(handler->commit(session, {}));
278}
Patrick Venture41205cc2019-05-23 11:43:43 -0700279
Patrick Ventureebcc5222019-05-23 10:36:40 -0700280} // namespace
281} // namespace ipmi_flash