blob: dda95eed54ca20f9ba7bd420186cc067b829a76c [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
9#include <gtest/gtest.h>
10
11namespace ipmi_flash
12{
13namespace
14{
15
16using ::testing::Return;
17using ::testing::UnorderedElementsAreArray;
18
19/*
20 * There are the following calls (parameters may vary):
21 * canHandleBlob(blob)
22 * getBlobIds
23 * deleteBlob(blob)
24 * stat(blob)
25 * stat(session)
26 * open(blob)
27 * close(session)
28 * writemeta(session)
29 * write(session)
30 * read(session)
Patrick Venture547fa3a2019-05-23 16:06:37 -070031 * commit(session)
Patrick Ventureebcc5222019-05-23 10:36:40 -070032 *
33 * Testing canHandleBlob is uninteresting in this state. Getting the BlobIDs
34 * will inform what canHandleBlob will return.
35 */
36class FirmwareHandlerUploadInProgressTest : public IpmiOnlyFirmwareStaticTest
37{
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070038 protected:
39 void openToInProgress(const std::string& blobId)
40 {
41 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
42 EXPECT_CALL(imageMock, open(blobId)).WillOnce(Return(true));
43 EXPECT_TRUE(handler->open(session, flags, blobId));
44 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
45 realHandler->getCurrentState());
46 }
47
48 std::uint16_t session = 1;
49 std::uint16_t flags =
50 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
Patrick Ventureebcc5222019-05-23 10:36:40 -070051};
52
53TEST_F(FirmwareHandlerUploadInProgressTest, GetBlobIdsVerifyOutputActiveImage)
54{
55 /* Opening the image file will add the active image blob id */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070056 openToInProgress(staticLayoutBlobId);
Patrick Ventureebcc5222019-05-23 10:36:40 -070057
58 std::vector<std::string> expectedAfterImage = {
59 staticLayoutBlobId, hashBlobId, verifyBlobId, activeImageBlobId};
60 EXPECT_THAT(handler->getBlobIds(),
61 UnorderedElementsAreArray(expectedAfterImage));
62}
63
64TEST_F(FirmwareHandlerUploadInProgressTest, GetBlobIdsVerifyOutputActiveHash)
65{
66 /* Opening the image file will add the active image blob id */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070067 openToInProgress(hashBlobId);
Patrick Ventureebcc5222019-05-23 10:36:40 -070068
69 std::vector<std::string> expectedAfterImage = {
70 staticLayoutBlobId, hashBlobId, verifyBlobId, activeHashBlobId};
71 EXPECT_THAT(handler->getBlobIds(),
72 UnorderedElementsAreArray(expectedAfterImage));
73}
74
Patrick Venture6f729782019-05-23 11:16:13 -070075/* TODO: Try deleting some blobs -- in this state it will depend on what the
76 * blob id is, but it's not yet implemented
77 */
78
Patrick Venture41205cc2019-05-23 11:43:43 -070079/*
80 * stat(blob)
81 */
82TEST_F(FirmwareHandlerUploadInProgressTest, StatOnActiveImageReturnsFailure)
83{
84 /* you cannot call stat() on the active image or the active hash or the
85 * verify blob.
86 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070087 openToInProgress(staticLayoutBlobId);
Patrick Venture41205cc2019-05-23 11:43:43 -070088
Patrick Venture41205cc2019-05-23 11:43:43 -070089 blobs::BlobMeta meta;
90 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
91}
92
93TEST_F(FirmwareHandlerUploadInProgressTest, StatOnActiveHashReturnsFailure)
94{
95 /* this test is separate from the active image one so that the state doesn't
96 * change from close.
97 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -070098 openToInProgress(hashBlobId);
Patrick Venture41205cc2019-05-23 11:43:43 -070099
Patrick Venture41205cc2019-05-23 11:43:43 -0700100 blobs::BlobMeta meta;
101 EXPECT_FALSE(handler->stat(activeHashBlobId, &meta));
102}
103
104TEST_F(FirmwareHandlerUploadInProgressTest, StatOnNormalBlobsReturnsSuccess)
105{
106 /* Calling stat() on the normal blobs (not the active) ones will work and
107 * return the same information as in the notYetStarted state.
108 */
109 blobs::BlobMeta expected;
110 expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
111 expected.size = 0;
112
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700113 openToInProgress(staticLayoutBlobId);
Patrick Venture41205cc2019-05-23 11:43:43 -0700114
115 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
116 for (const auto& blob : testBlobs)
117 {
118 blobs::BlobMeta meta = {};
119 EXPECT_TRUE(handler->stat(blob, &meta));
120 EXPECT_EQ(expected, meta);
121 }
122}
123
124/* TODO: stat(verifyblobid) only should exist once both /image and /hash have
125 * closed, so add this test when this is the case. NOTE: /image or /tarball
126 * should have the same effect.
127 */
128
129/*
130 * stat(session)
Patrick Ventureefc366e2019-05-23 12:00:21 -0700131 */
132TEST_F(FirmwareHandlerUploadInProgressTest,
133 CallingStatOnActiveImageOrHashSessionReturnsDetails)
134{
135 /* This test will verify that the underlying image handler is called with
136 * this stat, in addition to the normal information.
137 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700138 openToInProgress(staticLayoutBlobId);
Patrick Ventureefc366e2019-05-23 12:00:21 -0700139
140 EXPECT_CALL(imageMock, getSize()).WillOnce(Return(32));
141
142 blobs::BlobMeta meta, expectedMeta = {};
143 expectedMeta.size = 32;
144 expectedMeta.blobState =
145 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
146 EXPECT_TRUE(handler->stat(session, &meta));
147 EXPECT_EQ(expectedMeta, meta);
148}
149
150/*
Patrick Venture5788dbb2019-05-23 12:25:42 -0700151 * open(blob) - While any blob is open, all other fail.
152 */
153TEST_F(FirmwareHandlerUploadInProgressTest, OpeningHashFileWhileImageOpenFails)
154{
155 /* To be in this state, something must be open (and specifically either an
156 * active image (or tarball) or the hash file. Also verifies you can't just
157 * re-open the currently open file.
158 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700159 openToInProgress(staticLayoutBlobId);
Patrick Venture5788dbb2019-05-23 12:25:42 -0700160
161 std::vector<std::string> blobsToTry = {
162 hashBlobId, activeImageBlobId, activeHashBlobId, staticLayoutBlobId};
163 for (const auto& blob : blobsToTry)
164 {
165 EXPECT_FALSE(handler->open(2, flags, blob));
166 }
167}
168
169TEST_F(FirmwareHandlerUploadInProgressTest, OpeningImageFileWhileHashOpenFails)
170{
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700171 openToInProgress(hashBlobId);
Patrick Venture5788dbb2019-05-23 12:25:42 -0700172
173 std::vector<std::string> blobsToTry = {
174 hashBlobId, activeImageBlobId, activeHashBlobId, staticLayoutBlobId};
175 for (const auto& blob : blobsToTry)
176 {
177 EXPECT_FALSE(handler->open(2, flags, blob));
178 }
179}
180
181/*
Patrick Venture79b44742019-05-23 12:36:11 -0700182 * close(session) - closing the hash or image will trigger a state transition to
183 * verificationPending.
184 * TODO: This state transition should add the verifyBlobId. This will test that
185 * it's there, but this test doesn't verify that it only just now appeared.
186 *
187 * NOTE: Re-opening /flash/image will transition back to uploadInProgress, but
188 * that is verified in the verificationPending::open tests.
189 */
190TEST_F(FirmwareHandlerUploadInProgressTest,
191 ClosingImageFileTransitionsToVerificationPending)
192{
Patrick Venture79b44742019-05-23 12:36:11 -0700193 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
194
195 /* TODO: uncomment this when verify is properly added. */
196 // EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
197
198 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
199
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700200 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
Patrick Venture79b44742019-05-23 12:36:11 -0700201 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
202 realHandler->getCurrentState());
203
204 handler->close(1);
205 EXPECT_EQ(FirmwareBlobHandler::UpdateState::verificationPending,
206 realHandler->getCurrentState());
207
208 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
209}
210
211TEST_F(FirmwareHandlerUploadInProgressTest,
212 ClosingHashFileTransitionsToVerificationPending)
213{
Patrick Venture79b44742019-05-23 12:36:11 -0700214 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
215
216 /* TODO: uncomment this when verify is properly added. */
217 // EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
218
219 EXPECT_CALL(imageMock, open(hashBlobId)).WillOnce(Return(true));
220
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700221 EXPECT_TRUE(handler->open(session, flags, hashBlobId));
Patrick Venture79b44742019-05-23 12:36:11 -0700222 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
223 realHandler->getCurrentState());
224
225 handler->close(1);
226 EXPECT_EQ(FirmwareBlobHandler::UpdateState::verificationPending,
227 realHandler->getCurrentState());
228
229 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
230}
231
232/*
Patrick Venture41205cc2019-05-23 11:43:43 -0700233 * writemeta(session)
Patrick Venture7cf44402019-05-23 13:01:47 -0700234 */
235TEST_F(FirmwareHandlerUploadInProgressTest, WriteMetaAgainstImageReturnsSuccess)
236{
237 /* Calling write/read/writeMeta are uninteresting against the open blob in
238 * this case because the blob will just pass the call along. Whereas
239 * calling against the verify or update blob may be more interesting.
240 */
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700241 openToInProgress(staticLayoutBlobId);
Patrick Venture7cf44402019-05-23 13:01:47 -0700242
243 /* Note: with IPMI as the transport there's no data handler, so this should
244 * fail nicely. */
245 std::vector<std::uint8_t> bytes = {0x01, 0x02};
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700246 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
Patrick Venture7cf44402019-05-23 13:01:47 -0700247}
248
249/*
Patrick Venture41205cc2019-05-23 11:43:43 -0700250 * write(session)
251 * read(session)
Patrick Venturebe0fb5e2019-05-23 16:14:20 -0700252 * commit(session)
Patrick Venture41205cc2019-05-23 11:43:43 -0700253 */
254
Patrick Ventureebcc5222019-05-23 10:36:40 -0700255} // namespace
256} // namespace ipmi_flash