blob: 49c162254e59aef5259e4b632cf3a952296a6457 [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)
31 *
32 * Testing canHandleBlob is uninteresting in this state. Getting the BlobIDs
33 * will inform what canHandleBlob will return.
34 */
35class FirmwareHandlerUploadInProgressTest : public IpmiOnlyFirmwareStaticTest
36{
37};
38
39TEST_F(FirmwareHandlerUploadInProgressTest, GetBlobIdsVerifyOutputActiveImage)
40{
41 /* Opening the image file will add the active image blob id */
42 std::uint16_t flags =
43 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
44 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
45
46 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
47
48 EXPECT_TRUE(handler->open(1, flags, staticLayoutBlobId));
49 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
50 realHandler->getCurrentState());
51
52 std::vector<std::string> expectedAfterImage = {
53 staticLayoutBlobId, hashBlobId, verifyBlobId, activeImageBlobId};
54 EXPECT_THAT(handler->getBlobIds(),
55 UnorderedElementsAreArray(expectedAfterImage));
56}
57
58TEST_F(FirmwareHandlerUploadInProgressTest, GetBlobIdsVerifyOutputActiveHash)
59{
60 /* Opening the image file will add the active image blob id */
61 std::uint16_t flags =
62 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
63 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
64
65 EXPECT_CALL(imageMock, open(hashBlobId)).WillOnce(Return(true));
66
67 EXPECT_TRUE(handler->open(1, flags, hashBlobId));
68 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
69 realHandler->getCurrentState());
70
71 std::vector<std::string> expectedAfterImage = {
72 staticLayoutBlobId, hashBlobId, verifyBlobId, activeHashBlobId};
73 EXPECT_THAT(handler->getBlobIds(),
74 UnorderedElementsAreArray(expectedAfterImage));
75}
76
Patrick Venture6f729782019-05-23 11:16:13 -070077/* TODO: Try deleting some blobs -- in this state it will depend on what the
78 * blob id is, but it's not yet implemented
79 */
80
Patrick Venture41205cc2019-05-23 11:43:43 -070081/*
82 * stat(blob)
83 */
84TEST_F(FirmwareHandlerUploadInProgressTest, StatOnActiveImageReturnsFailure)
85{
86 /* you cannot call stat() on the active image or the active hash or the
87 * verify blob.
88 */
89 std::uint16_t flags =
90 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
91 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
92
93 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
94
95 EXPECT_TRUE(handler->open(1, flags, staticLayoutBlobId));
96 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
97 realHandler->getCurrentState());
98
Patrick Venture41205cc2019-05-23 11:43:43 -070099 blobs::BlobMeta meta;
100 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
101}
102
103TEST_F(FirmwareHandlerUploadInProgressTest, StatOnActiveHashReturnsFailure)
104{
105 /* this test is separate from the active image one so that the state doesn't
106 * change from close.
107 */
108 std::uint16_t flags =
109 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
110 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
111
112 EXPECT_CALL(imageMock, open(hashBlobId)).WillOnce(Return(true));
113
114 EXPECT_TRUE(handler->open(1, flags, hashBlobId));
115 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
116 realHandler->getCurrentState());
117
Patrick Venture41205cc2019-05-23 11:43:43 -0700118 blobs::BlobMeta meta;
119 EXPECT_FALSE(handler->stat(activeHashBlobId, &meta));
120}
121
122TEST_F(FirmwareHandlerUploadInProgressTest, StatOnNormalBlobsReturnsSuccess)
123{
124 /* Calling stat() on the normal blobs (not the active) ones will work and
125 * return the same information as in the notYetStarted state.
126 */
127 blobs::BlobMeta expected;
128 expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
129 expected.size = 0;
130
131 std::uint16_t flags =
132 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
133 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
134
135 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
136
137 EXPECT_TRUE(handler->open(1, flags, staticLayoutBlobId));
138 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
139 realHandler->getCurrentState());
140
141 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
142 for (const auto& blob : testBlobs)
143 {
144 blobs::BlobMeta meta = {};
145 EXPECT_TRUE(handler->stat(blob, &meta));
146 EXPECT_EQ(expected, meta);
147 }
148}
149
150/* TODO: stat(verifyblobid) only should exist once both /image and /hash have
151 * closed, so add this test when this is the case. NOTE: /image or /tarball
152 * should have the same effect.
153 */
154
155/*
156 * stat(session)
Patrick Ventureefc366e2019-05-23 12:00:21 -0700157 */
158TEST_F(FirmwareHandlerUploadInProgressTest,
159 CallingStatOnActiveImageOrHashSessionReturnsDetails)
160{
161 /* This test will verify that the underlying image handler is called with
162 * this stat, in addition to the normal information.
163 */
164 std::uint16_t session = 1;
165 std::uint16_t flags =
166 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
167 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
168
169 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
170
171 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
172 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
173 realHandler->getCurrentState());
174
175 EXPECT_CALL(imageMock, getSize()).WillOnce(Return(32));
176
177 blobs::BlobMeta meta, expectedMeta = {};
178 expectedMeta.size = 32;
179 expectedMeta.blobState =
180 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
181 EXPECT_TRUE(handler->stat(session, &meta));
182 EXPECT_EQ(expectedMeta, meta);
183}
184
185/*
Patrick Venture5788dbb2019-05-23 12:25:42 -0700186 * open(blob) - While any blob is open, all other fail.
187 */
188TEST_F(FirmwareHandlerUploadInProgressTest, OpeningHashFileWhileImageOpenFails)
189{
190 /* To be in this state, something must be open (and specifically either an
191 * active image (or tarball) or the hash file. Also verifies you can't just
192 * re-open the currently open file.
193 */
194 std::uint16_t flags =
195 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
196 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
197
198 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
199
200 EXPECT_TRUE(handler->open(1, flags, staticLayoutBlobId));
201 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
202 realHandler->getCurrentState());
203
204 std::vector<std::string> blobsToTry = {
205 hashBlobId, activeImageBlobId, activeHashBlobId, staticLayoutBlobId};
206 for (const auto& blob : blobsToTry)
207 {
208 EXPECT_FALSE(handler->open(2, flags, blob));
209 }
210}
211
212TEST_F(FirmwareHandlerUploadInProgressTest, OpeningImageFileWhileHashOpenFails)
213{
214 std::uint16_t flags =
215 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
216 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
217
218 EXPECT_CALL(imageMock, open(hashBlobId)).WillOnce(Return(true));
219
220 EXPECT_TRUE(handler->open(1, flags, hashBlobId));
221 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
222 realHandler->getCurrentState());
223
224 std::vector<std::string> blobsToTry = {
225 hashBlobId, activeImageBlobId, activeHashBlobId, staticLayoutBlobId};
226 for (const auto& blob : blobsToTry)
227 {
228 EXPECT_FALSE(handler->open(2, flags, blob));
229 }
230}
231
232/*
Patrick Venture41205cc2019-05-23 11:43:43 -0700233 * close(session)
234 * writemeta(session)
235 * write(session)
236 * read(session)
237 */
238
Patrick Ventureebcc5222019-05-23 10:36:40 -0700239} // namespace
240} // namespace ipmi_flash