blob: c42d83e9e4ac11f7e37720ee070cd99afa4915b4 [file] [log] [blame]
Patrick Venture61d2ed42019-05-23 18:16:31 -07001/**
2 * The goal of these tests is to verify the behavior of all blob commands given
3 * the current state is verificationPending. This state is achieved as a
4 * transition out of uploadInProgress.
5 */
6#include "firmware_handler.hpp"
7#include "firmware_unittest.hpp"
Patrick Venture01a33272019-05-23 19:48:22 -07008#include "status.hpp"
Patrick Venture61d2ed42019-05-23 18:16:31 -07009#include "util.hpp"
10
Patrick Venture930c7b72019-05-24 11:11:08 -070011#include <algorithm>
Patrick Venture61d2ed42019-05-23 18:16:31 -070012#include <cstdint>
13#include <string>
14#include <vector>
15
16#include <gtest/gtest.h>
17
18namespace ipmi_flash
19{
20namespace
21{
22
Patrick Venture2567ebc2019-05-24 10:02:53 -070023using ::testing::IsEmpty;
Patrick Venture61d2ed42019-05-23 18:16:31 -070024using ::testing::Return;
Patrick Ventureefba42d2019-05-24 10:48:16 -070025using ::testing::UnorderedElementsAreArray;
Patrick Venture61d2ed42019-05-23 18:16:31 -070026
27/*
28 * There are the following calls (parameters may vary):
29 * canHandleBlob(blob)
30 * getBlobIds
31 * deleteBlob(blob)
32 * stat(blob)
33 * stat(session)
34 * open(blob)
35 * close(session)
36 * writemeta(session)
37 * write(session)
38 * read(session)
39 * commit(session)
40 *
41 * Testing canHandleBlob is uninteresting in this state. Getting the BlobIDs
42 * will inform what canHandleBlob will return.
43 */
44
45class FirmwareHandlerVerificationPendingTest : public IpmiOnlyFirmwareStaticTest
46{
47 protected:
48 void getToVerificationPending(const std::string& blobId)
49 {
Patrick Venture61d2ed42019-05-23 18:16:31 -070050 EXPECT_CALL(imageMock, open(blobId)).WillOnce(Return(true));
51 EXPECT_TRUE(handler->open(session, flags, blobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -070052 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
53
Patrick Venture61d2ed42019-05-23 18:16:31 -070054 EXPECT_CALL(imageMock, close()).WillRepeatedly(Return());
55 handler->close(session);
Patrick Venture6fdd02e2019-05-28 13:02:04 -070056 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture61d2ed42019-05-23 18:16:31 -070057 }
58
59 std::uint16_t session = 1;
60 std::uint16_t flags =
61 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
62};
63
64/*
65 * getBlobIds
Patrick Venture61d2ed42019-05-23 18:16:31 -070066 */
Patrick Venture61d2ed42019-05-23 18:16:31 -070067TEST_F(FirmwareHandlerVerificationPendingTest, VerifyBlobIdAvailableInState)
68{
69 /* Only in the verificationPending state (and later), should the
70 * verifyBlobId be present. */
71
Patrick Venture930c7b72019-05-24 11:11:08 -070072 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
73
Patrick Venture61d2ed42019-05-23 18:16:31 -070074 getToVerificationPending(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070075
Patrick Venture61d2ed42019-05-23 18:16:31 -070076 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -070077 EXPECT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Venture61d2ed42019-05-23 18:16:31 -070078}
79
Patrick Ventureb386b862019-05-23 18:42:54 -070080/*
81 * delete(blob) TODO: Implement this.
82 */
83
84/*
85 * stat(blob)
86 */
87TEST_F(FirmwareHandlerVerificationPendingTest, StatOnActiveImageReturnsFailure)
88{
89 getToVerificationPending(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070090 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -070091
92 blobs::BlobMeta meta;
93 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
94}
95
96TEST_F(FirmwareHandlerVerificationPendingTest, StatOnActiveHashReturnsFailure)
97{
98 getToVerificationPending(hashBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070099 ASSERT_TRUE(handler->canHandleBlob(activeHashBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -0700100
101 blobs::BlobMeta meta;
102 EXPECT_FALSE(handler->stat(activeHashBlobId, &meta));
103}
104
105TEST_F(FirmwareHandlerVerificationPendingTest,
106 StatOnVerificationBlobReturnsFailure)
107{
108 getToVerificationPending(hashBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -0700109 ASSERT_TRUE(handler->canHandleBlob(activeHashBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -0700110
111 blobs::BlobMeta meta;
112 EXPECT_FALSE(handler->stat(verifyBlobId, &meta));
113}
114
115TEST_F(FirmwareHandlerVerificationPendingTest, StatOnNormalBlobsReturnsSuccess)
116{
117 getToVerificationPending(staticLayoutBlobId);
118
119 blobs::BlobMeta expected;
120 expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
121 expected.size = 0;
122
123 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
124 for (const auto& blob : testBlobs)
125 {
Patrick Venture930c7b72019-05-24 11:11:08 -0700126 ASSERT_TRUE(handler->canHandleBlob(blob));
Patrick Ventureb386b862019-05-23 18:42:54 -0700127 blobs::BlobMeta meta = {};
128 EXPECT_TRUE(handler->stat(blob, &meta));
129 EXPECT_EQ(expected, meta);
130 }
131}
132
133/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700134 * open(blob)
135 */
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700136TEST_F(FirmwareHandlerVerificationPendingTest, OpenVerifyBlobSucceeds)
137{
138 getToVerificationPending(staticLayoutBlobId);
139
140 /* the session is safe because it was already closed to get to this state.
141 */
142 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
143}
144
145TEST_F(FirmwareHandlerVerificationPendingTest, OpenActiveImageBlobFails)
146{
147 /* Try opening the active blob Id. This test is equivalent to trying to
148 * open the active hash blob id, in that neither are ever allowed.
149 */
150 getToVerificationPending(staticLayoutBlobId);
151 EXPECT_FALSE(handler->open(session, flags, activeImageBlobId));
152}
153
154TEST_F(FirmwareHandlerVerificationPendingTest,
155 OpenImageBlobTransitionsToUploadInProgress)
156{
157 getToVerificationPending(staticLayoutBlobId);
Patrick Ventureefba42d2019-05-24 10:48:16 -0700158
159 /* Verify the active blob for the image is in the list once to start.
160 * Note: This is truly tested under the notYetStarted::open() test.
161 */
162 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId,
163 verifyBlobId, activeImageBlobId};
164
165 EXPECT_THAT(handler->getBlobIds(),
166 UnorderedElementsAreArray(expectedBlobs));
167
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700168 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
169 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700170 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
Patrick Ventureefba42d2019-05-24 10:48:16 -0700171
Patrick Venture930c7b72019-05-24 11:11:08 -0700172 expectedBlobs.erase(
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700173 std::remove(expectedBlobs.begin(), expectedBlobs.end(), verifyBlobId),
174 expectedBlobs.end());
Patrick Venture930c7b72019-05-24 11:11:08 -0700175
176 /* Verify the active blob ID was not added to the list twice and
177 * verifyBlobId is removed
178 */
Patrick Ventureefba42d2019-05-24 10:48:16 -0700179 EXPECT_THAT(handler->getBlobIds(),
180 UnorderedElementsAreArray(expectedBlobs));
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700181}
182
183/*
Patrick Venture1e389c92019-05-23 19:15:05 -0700184 * close(session)
185 */
186TEST_F(FirmwareHandlerVerificationPendingTest,
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700187 ClosingVerifyBlobWithoutCommitDoesNotChangeState)
Patrick Venture1e389c92019-05-23 19:15:05 -0700188{
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700189 /* commit() will change the state, closing post-commit is part of
190 * verificationStarted testing.
191 */
Patrick Venture1e389c92019-05-23 19:15:05 -0700192 getToVerificationPending(staticLayoutBlobId);
193 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700194 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture1e389c92019-05-23 19:15:05 -0700195
196 handler->close(session);
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700197 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture1e389c92019-05-23 19:15:05 -0700198}
199
200/*
Patrick Venture19044e12019-05-23 19:30:28 -0700201 * commit(session)
202 */
203TEST_F(FirmwareHandlerVerificationPendingTest,
204 CommitOnVerifyBlobTriggersVerificationAndStateTransition)
205{
206 getToVerificationPending(staticLayoutBlobId);
207 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
208 EXPECT_CALL(*verifyMockPtr, triggerVerification()).WillOnce(Return(true));
209
210 EXPECT_TRUE(handler->commit(session, {}));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700211 expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);
Patrick Venture19044e12019-05-23 19:30:28 -0700212}
213
214/*
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700215 * stat(session) - in this state, you can only open(verifyBlobId) without
216 * changing state.
217 */
Patrick Venture01a33272019-05-23 19:48:22 -0700218TEST_F(FirmwareHandlerVerificationPendingTest, StatOnVerifyBlobIdReturnsState)
219{
220 /* If this is called before commit(), it's still verificationPending, so it
221 * just returns the state is other
222 */
223 getToVerificationPending(staticLayoutBlobId);
224 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
225 EXPECT_CALL(*verifyMockPtr, triggerVerification()).Times(0);
226 EXPECT_CALL(*verifyMockPtr, checkVerificationState()).Times(0);
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>(VerifyCheckResponses::other));
233
234 EXPECT_TRUE(handler->stat(session, &meta));
235 EXPECT_EQ(expectedMeta, meta);
236}
237
Patrick Ventureb386b862019-05-23 18:42:54 -0700238/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700239 * writemeta(session)
240 */
Patrick Ventureb611a082019-05-23 20:27:28 -0700241TEST_F(FirmwareHandlerVerificationPendingTest, WriteMetaAgainstVerifyFails)
242{
243 /* The verifyBlobId has no data handler, which means write meta fails. */
244 getToVerificationPending(staticLayoutBlobId);
245
246 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
247
248 std::vector<std::uint8_t> bytes = {0x01, 0x02};
249 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
250}
251
Patrick Ventureb386b862019-05-23 18:42:54 -0700252/*
253 * write(session)
254 */
Patrick Ventureab731e92019-05-24 09:58:00 -0700255TEST_F(FirmwareHandlerVerificationPendingTest, WriteAgainstVerifyBlobIdFails)
256{
257 getToVerificationPending(staticLayoutBlobId);
258
259 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
260
261 std::vector<std::uint8_t> bytes = {0x01, 0x02};
262 EXPECT_FALSE(handler->write(session, 0, bytes));
263}
264
Patrick Ventureb386b862019-05-23 18:42:54 -0700265/*
266 * read(session)
267 */
Patrick Venture2567ebc2019-05-24 10:02:53 -0700268TEST_F(FirmwareHandlerVerificationPendingTest,
269 ReadAgainstVerifyBlobIdReturnsEmpty)
270{
271 getToVerificationPending(staticLayoutBlobId);
272
273 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
274 EXPECT_THAT(handler->read(session, 0, 32), IsEmpty());
275}
Patrick Ventureb386b862019-05-23 18:42:54 -0700276
Patrick Venture61d2ed42019-05-23 18:16:31 -0700277} // namespace
278} // namespace ipmi_flash