blob: eb9e437c8008939082538390baac5e9d73311da4 [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{
45 protected:
46 void getToUpdatePending()
47 {
48 /* The hash was not sent up, as it's technically optional. Therefore,
49 * there is no active hash file.
50 */
51 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
52 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
53 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
54
55 EXPECT_CALL(imageMock, close()).WillRepeatedly(Return());
56 handler->close(session);
57 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
58
59 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
60 EXPECT_CALL(*verifyMockPtr, triggerVerification())
61 .WillOnce(Return(true));
62
63 EXPECT_TRUE(handler->commit(session, {}));
64 expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);
65
66 EXPECT_CALL(*verifyMockPtr, checkVerificationState())
67 .WillOnce(Return(VerifyCheckResponses::success));
68 blobs::BlobMeta meta;
69 EXPECT_TRUE(handler->stat(session, &meta));
70 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
71
72 handler->close(session);
73 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
74 }
75
76 std::uint16_t session = 1;
77 std::uint16_t flags =
78 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
79};
80
81/*
82 * There are the following calls (parameters may vary):
83 * canHandleBlob(blob)
84 * getBlobIds
85 */
Patrick Venturead933832019-05-30 14:13:29 -070086TEST_F(FirmwareHandlerUpdatePendingTest, GetBlobsListHasExpectedValues)
87{
88 getToUpdatePending();
89
90 std::vector<std::string> expected = {updateBlobId, activeImageBlobId,
91 hashBlobId, staticLayoutBlobId};
92 EXPECT_THAT(handler->getBlobIds(), UnorderedElementsAreArray(expected));
93}
94
Patrick Venture0cd945c2019-05-30 13:36:53 -070095/*
Patrick Venture19f5d882019-05-30 14:34:55 -070096 * open(blob) - because updatePending is in a fileOpen==false state, one can
97 * then open blobs. However, because we're in a special state, we will restrict
98 * them s.t. they can only open the updateBlobId.
99 */
100TEST_F(FirmwareHandlerUpdatePendingTest,
101 OpenUpdateBlobIdIsSuccessfulAndDoesNotChangeState)
102{
103 getToUpdatePending();
104
105 /* Opening the update blob isn't interesting, except it's required for
106 * commit() which triggers the update process.
107 */
108 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
Patrick Venture6b0aa182019-05-30 14:47:32 -0700109 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
Patrick Venture19f5d882019-05-30 14:34:55 -0700110}
111
112TEST_F(FirmwareHandlerUpdatePendingTest, OpenAnyBlobOtherThanUpdateFails)
113{
114 getToUpdatePending();
115
116 auto blobs = handler->getBlobIds();
117 for (const auto& blob : blobs)
118 {
119 if (blob == updateBlobId)
120 {
121 continue;
122 }
123 EXPECT_FALSE(handler->open(session, flags, blob));
124 }
125}
126
127/*
Patrick Venture6b0aa182019-05-30 14:47:32 -0700128 * close(session) - close from this state is uninteresting.
129 */
130TEST_F(FirmwareHandlerUpdatePendingTest, CloseUpdateBlobDoesNotChangeState)
131{
132 /* Verify nothing changes when one just opens, then closes the updateBlobId.
133 */
134 getToUpdatePending();
135
136 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
137
138 handler->close(session);
139
140 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
141 EXPECT_TRUE(handler->canHandleBlob(updateBlobId));
142}
143
144/*
Patrick Venture94bb9702019-05-30 14:53:22 -0700145 * writemeta(session) - this will return failure.
146 */
147TEST_F(FirmwareHandlerUpdatePendingTest, WriteMetaToUpdateBlobReturnsFailure)
148{
149 getToUpdatePending();
150
151 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
152 EXPECT_FALSE(handler->writeMeta(session, 0, {0x01}));
153}
154
155/*
Patrick Venture4e2fdcd2019-05-30 14:58:57 -0700156 * write(session)
157 */
158TEST_F(FirmwareHandlerUpdatePendingTest, WriteToUpdateBlobReturnsFailure)
159{
160 getToUpdatePending();
161
162 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
163 EXPECT_FALSE(handler->write(session, 0, {0x01}));
164}
165
166/*
Patrick Ventureebe456f2019-05-30 16:40:39 -0700167 * read(session)
168 */
169TEST_F(FirmwareHandlerUpdatePendingTest, ReadFromUpdateBlobIdReturnsEmpty)
170{
171 getToUpdatePending();
172 EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
173}
174
175/*
Patrick Venture5f562692019-05-30 16:49:46 -0700176 * stat(blob)
Patrick Venture0cd945c2019-05-30 13:36:53 -0700177 */
Patrick Venture5f562692019-05-30 16:49:46 -0700178TEST_F(FirmwareHandlerUpdatePendingTest, StatOnActiveImageReturnsFailure)
179{
180 getToUpdatePending();
181 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
182
183 blobs::BlobMeta meta;
184 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
185}
186
187TEST_F(FirmwareHandlerUpdatePendingTest, StatOnUpdateBlobReturnsFailure)
188{
189 getToUpdatePending();
190 ASSERT_TRUE(handler->canHandleBlob(updateBlobId));
191
192 blobs::BlobMeta meta;
193 EXPECT_FALSE(handler->stat(updateBlobId, &meta));
194}
195
196TEST_F(FirmwareHandlerUpdatePendingTest, StatOnNormalBlobsReturnsSuccess)
197{
198 getToUpdatePending();
199
200 blobs::BlobMeta expected;
201 expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
202 expected.size = 0;
203
204 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
205 for (const auto& blob : testBlobs)
206 {
207 ASSERT_TRUE(handler->canHandleBlob(blob));
208
209 blobs::BlobMeta meta = {};
210 EXPECT_TRUE(handler->stat(blob, &meta));
211 EXPECT_EQ(expected, meta);
212 }
213}
Patrick Venture0cd945c2019-05-30 13:36:53 -0700214
215/*
Patrick Venture40d7ffc2019-05-30 17:12:06 -0700216 * stat(session)
217 * In this case, you can open updateBlobId without changing state, therefore,
218 * let's call stat() against a session against this file. This done, ahead of
219 * commit() should report the state as "other."
Patrick Venture0cd945c2019-05-30 13:36:53 -0700220 */
Patrick Venture40d7ffc2019-05-30 17:12:06 -0700221TEST_F(FirmwareHandlerUpdatePendingTest,
222 SessionStatOnUpdateBlobIdReturnsFailure)
223{
224 getToUpdatePending();
225 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
226 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
227
228 blobs::BlobMeta meta, expectedMeta = {};
229 expectedMeta.size = 0;
230 expectedMeta.blobState = flags;
231 expectedMeta.metadata.push_back(
232 static_cast<std::uint8_t>(UpdateStatus::unknown));
233
234 EXPECT_TRUE(handler->stat(session, &meta));
235 EXPECT_EQ(expectedMeta, meta);
236 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
237}
Patrick Venture0cd945c2019-05-30 13:36:53 -0700238
239/*
Patrick Venture40d7ffc2019-05-30 17:12:06 -0700240 * TODO: deleteBlob(blob)
Patrick Venture0cd945c2019-05-30 13:36:53 -0700241 */
242
243/*
Patrick Venture0cd945c2019-05-30 13:36:53 -0700244 * commit(session)
245 */
246
247} // namespace
248} // namespace ipmi_flash