blob: d757b3c0d322cfe127a286d4a0eb4a3aa3b9ec5b [file] [log] [blame]
Patrick Venture0cd945c2019-05-30 13:36:53 -07001/* The goal of these tests is to verify the behavior of all blob commands given
2 * the current state is updatePending. This state is achieved as an exit from
3 * verificationCompleted.
4 */
5#include "firmware_handler.hpp"
6#include "firmware_unittest.hpp"
7#include "status.hpp"
8#include "util.hpp"
9
10#include <cstdint>
11#include <string>
12#include <vector>
13
14#include <gtest/gtest.h>
15
16namespace ipmi_flash
17{
18namespace
19{
20
Patrick Ventureebe456f2019-05-30 16:40:39 -070021using ::testing::IsEmpty;
Patrick Venture0cd945c2019-05-30 13:36:53 -070022using ::testing::Return;
Patrick Venturead933832019-05-30 14:13:29 -070023using ::testing::UnorderedElementsAreArray;
Patrick Venture0cd945c2019-05-30 13:36:53 -070024
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)
37 * commit(session)
38 *
39 * Testing canHandleBlob is uninteresting in this state. Getting the BlobIDs
40 * will inform what canHandleBlob will return.
41 */
42
43class FirmwareHandlerUpdatePendingTest : public IpmiOnlyFirmwareStaticTest
44{
Patrick Venture0cd945c2019-05-30 13:36:53 -070045};
46
47/*
48 * There are the following calls (parameters may vary):
49 * canHandleBlob(blob)
50 * getBlobIds
51 */
Patrick Venturead933832019-05-30 14:13:29 -070052TEST_F(FirmwareHandlerUpdatePendingTest, GetBlobsListHasExpectedValues)
53{
54 getToUpdatePending();
55
Patrick Venture9a69f732019-06-17 14:05:13 -070056 EXPECT_THAT(handler->getBlobIds(),
57 UnorderedElementsAreArray({updateBlobId, activeImageBlobId,
58 hashBlobId, staticLayoutBlobId}));
Patrick Venturead933832019-05-30 14:13:29 -070059}
60
Patrick Venture0cd945c2019-05-30 13:36:53 -070061/*
Patrick Venture19f5d882019-05-30 14:34:55 -070062 * open(blob) - because updatePending is in a fileOpen==false state, one can
63 * then open blobs. However, because we're in a special state, we will restrict
64 * them s.t. they can only open the updateBlobId.
65 */
66TEST_F(FirmwareHandlerUpdatePendingTest,
67 OpenUpdateBlobIdIsSuccessfulAndDoesNotChangeState)
68{
69 getToUpdatePending();
70
71 /* Opening the update blob isn't interesting, except it's required for
72 * commit() which triggers the update process.
73 */
74 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
Patrick Venture6b0aa182019-05-30 14:47:32 -070075 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
Patrick Venture19f5d882019-05-30 14:34:55 -070076}
77
78TEST_F(FirmwareHandlerUpdatePendingTest, OpenAnyBlobOtherThanUpdateFails)
79{
80 getToUpdatePending();
81
82 auto blobs = handler->getBlobIds();
83 for (const auto& blob : blobs)
84 {
85 if (blob == updateBlobId)
86 {
87 continue;
88 }
89 EXPECT_FALSE(handler->open(session, flags, blob));
90 }
91}
92
93/*
Patrick Venture6b0aa182019-05-30 14:47:32 -070094 * close(session) - close from this state is uninteresting.
95 */
96TEST_F(FirmwareHandlerUpdatePendingTest, CloseUpdateBlobDoesNotChangeState)
97{
98 /* Verify nothing changes when one just opens, then closes the updateBlobId.
99 */
100 getToUpdatePending();
101
102 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
103
104 handler->close(session);
105
106 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
107 EXPECT_TRUE(handler->canHandleBlob(updateBlobId));
108}
109
110/*
Patrick Venture94bb9702019-05-30 14:53:22 -0700111 * writemeta(session) - this will return failure.
112 */
113TEST_F(FirmwareHandlerUpdatePendingTest, WriteMetaToUpdateBlobReturnsFailure)
114{
115 getToUpdatePending();
116
117 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
118 EXPECT_FALSE(handler->writeMeta(session, 0, {0x01}));
119}
120
121/*
Patrick Venture4e2fdcd2019-05-30 14:58:57 -0700122 * write(session)
123 */
124TEST_F(FirmwareHandlerUpdatePendingTest, WriteToUpdateBlobReturnsFailure)
125{
126 getToUpdatePending();
127
128 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
129 EXPECT_FALSE(handler->write(session, 0, {0x01}));
130}
131
132/*
Patrick Ventureebe456f2019-05-30 16:40:39 -0700133 * read(session)
134 */
135TEST_F(FirmwareHandlerUpdatePendingTest, ReadFromUpdateBlobIdReturnsEmpty)
136{
137 getToUpdatePending();
138 EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
139}
140
141/*
Patrick Venture5f562692019-05-30 16:49:46 -0700142 * stat(blob)
Patrick Venture0cd945c2019-05-30 13:36:53 -0700143 */
Patrick Venture5f562692019-05-30 16:49:46 -0700144TEST_F(FirmwareHandlerUpdatePendingTest, StatOnActiveImageReturnsFailure)
145{
146 getToUpdatePending();
147 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
148
149 blobs::BlobMeta meta;
150 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
151}
152
153TEST_F(FirmwareHandlerUpdatePendingTest, StatOnUpdateBlobReturnsFailure)
154{
155 getToUpdatePending();
156 ASSERT_TRUE(handler->canHandleBlob(updateBlobId));
157
158 blobs::BlobMeta meta;
159 EXPECT_FALSE(handler->stat(updateBlobId, &meta));
160}
161
162TEST_F(FirmwareHandlerUpdatePendingTest, StatOnNormalBlobsReturnsSuccess)
163{
164 getToUpdatePending();
165
Patrick Venture9a69f732019-06-17 14:05:13 -0700166 for (const auto& blob : startingBlobs)
Patrick Venture5f562692019-05-30 16:49:46 -0700167 {
168 ASSERT_TRUE(handler->canHandleBlob(blob));
169
170 blobs::BlobMeta meta = {};
171 EXPECT_TRUE(handler->stat(blob, &meta));
Benjamin Fair12901982019-11-12 13:55:46 -0800172 EXPECT_EQ(expectedIdleMeta, meta);
Patrick Venture5f562692019-05-30 16:49:46 -0700173 }
174}
Patrick Venture0cd945c2019-05-30 13:36:53 -0700175
176/*
Patrick Venture40d7ffc2019-05-30 17:12:06 -0700177 * stat(session)
178 * In this case, you can open updateBlobId without changing state, therefore,
179 * let's call stat() against a session against this file. This done, ahead of
180 * commit() should report the state as "other."
Patrick Venture0cd945c2019-05-30 13:36:53 -0700181 */
Patrick Venture40d7ffc2019-05-30 17:12:06 -0700182TEST_F(FirmwareHandlerUpdatePendingTest,
183 SessionStatOnUpdateBlobIdReturnsFailure)
184{
185 getToUpdatePending();
186 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
187 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
188
189 blobs::BlobMeta meta, expectedMeta = {};
190 expectedMeta.size = 0;
191 expectedMeta.blobState = flags;
192 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700193 static_cast<std::uint8_t>(ActionStatus::unknown));
Patrick Venture40d7ffc2019-05-30 17:12:06 -0700194
195 EXPECT_TRUE(handler->stat(session, &meta));
196 EXPECT_EQ(expectedMeta, meta);
197 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
198}
Patrick Venture0cd945c2019-05-30 13:36:53 -0700199
200/*
Patrick Venture1a406fe2019-05-31 07:29:56 -0700201 * commit(session)
Patrick Venture0cd945c2019-05-30 13:36:53 -0700202 */
Patrick Venture1a406fe2019-05-31 07:29:56 -0700203TEST_F(FirmwareHandlerUpdatePendingTest,
204 CommitOnUpdateBlobTriggersUpdateAndChangesState)
205{
206 /* Commit triggers the update mechanism (similarly for the verifyBlobId) and
207 * changes state to updateStarted.
208 */
209 getToUpdatePending();
210 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
211 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
212
Patrick Venture1d66fe62019-06-03 14:57:27 -0700213 EXPECT_CALL(*updateMockPtr, trigger()).WillOnce(Return(true));
Patrick Venture1a406fe2019-05-31 07:29:56 -0700214
215 EXPECT_TRUE(handler->commit(session, {}));
216 expectedState(FirmwareBlobHandler::UpdateState::updateStarted);
217}
218
219TEST_F(FirmwareHandlerUpdatePendingTest,
220 CommitOnUpdateBlobTriggersUpdateAndReturnsFailureDoesNotChangeState)
221{
222 getToUpdatePending();
223 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
224 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
225
Patrick Venture1d66fe62019-06-03 14:57:27 -0700226 EXPECT_CALL(*updateMockPtr, trigger()).WillOnce(Return(false));
Patrick Venture1a406fe2019-05-31 07:29:56 -0700227
228 EXPECT_FALSE(handler->commit(session, {}));
229 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
230}
Patrick Venture0cd945c2019-05-30 13:36:53 -0700231
232/*
Patrick Venturec9f62392019-06-17 12:17:26 -0700233 * deleteBlob(blob)
Patrick Venture0cd945c2019-05-30 13:36:53 -0700234 */
Patrick Venturec9f62392019-06-17 12:17:26 -0700235TEST_F(FirmwareHandlerUpdatePendingTest, DeleteUpdateAbortsProcess)
236{
237 /* It doesn't matter what blob id is used to delete in the design, so just
238 * delete the update blob id
239 */
240 getToUpdatePending();
241
242 EXPECT_CALL(*updateMockPtr, abort()).Times(0);
243
244 ASSERT_TRUE(handler->canHandleBlob(updateBlobId));
245 EXPECT_TRUE(handler->deleteBlob(updateBlobId));
246
Patrick Venturec9f62392019-06-17 12:17:26 -0700247 EXPECT_THAT(handler->getBlobIds(),
Patrick Venture9a69f732019-06-17 14:05:13 -0700248 UnorderedElementsAreArray(startingBlobs));
Patrick Venturec9f62392019-06-17 12:17:26 -0700249 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
250}
251
252TEST_F(FirmwareHandlerUpdatePendingTest, DeleteActiveImageAbortsProcess)
253{
254 getToUpdatePending();
255
256 EXPECT_CALL(*updateMockPtr, abort()).Times(0);
257
258 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
259 EXPECT_TRUE(handler->deleteBlob(activeImageBlobId));
260
Patrick Venturec9f62392019-06-17 12:17:26 -0700261 EXPECT_THAT(handler->getBlobIds(),
Patrick Venture9a69f732019-06-17 14:05:13 -0700262 UnorderedElementsAreArray(startingBlobs));
Patrick Venturec9f62392019-06-17 12:17:26 -0700263 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
264}
265
266TEST_F(FirmwareHandlerUpdatePendingTest, DeleteStaticLayoutAbortsProcess)
267{
268 getToUpdatePending();
269
270 EXPECT_CALL(*updateMockPtr, abort()).Times(0);
271
272 ASSERT_TRUE(handler->canHandleBlob(staticLayoutBlobId));
273 EXPECT_TRUE(handler->deleteBlob(staticLayoutBlobId));
274
Patrick Venturec9f62392019-06-17 12:17:26 -0700275 EXPECT_THAT(handler->getBlobIds(),
Patrick Venture9a69f732019-06-17 14:05:13 -0700276 UnorderedElementsAreArray(startingBlobs));
Patrick Venturec9f62392019-06-17 12:17:26 -0700277 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
278}
279
280TEST_F(FirmwareHandlerUpdatePendingTest, DeleteHashAbortsProcess)
281{
282 getToUpdatePending();
283
284 EXPECT_CALL(*updateMockPtr, abort()).Times(0);
285
286 ASSERT_TRUE(handler->canHandleBlob(hashBlobId));
287 EXPECT_TRUE(handler->deleteBlob(hashBlobId));
288
Patrick Venturec9f62392019-06-17 12:17:26 -0700289 EXPECT_THAT(handler->getBlobIds(),
Patrick Venture9a69f732019-06-17 14:05:13 -0700290 UnorderedElementsAreArray(startingBlobs));
Patrick Venturec9f62392019-06-17 12:17:26 -0700291 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
292}
Patrick Venture0cd945c2019-05-30 13:36:53 -0700293
294} // namespace
295} // namespace ipmi_flash