blob: b7c1bfc0416cf146d4139bdde57c9a1eb60a8e10 [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{
Patrick Venture61d2ed42019-05-23 18:16:31 -070047};
48
49/*
50 * getBlobIds
Patrick Venture61d2ed42019-05-23 18:16:31 -070051 */
Patrick Venture61d2ed42019-05-23 18:16:31 -070052TEST_F(FirmwareHandlerVerificationPendingTest, VerifyBlobIdAvailableInState)
53{
54 /* Only in the verificationPending state (and later), should the
Patrick Venture0f82ce42019-05-28 14:06:04 -070055 * verifyBlobId be present.
56 */
Patrick Venture930c7b72019-05-24 11:11:08 -070057 EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
58
Patrick Venture61d2ed42019-05-23 18:16:31 -070059 getToVerificationPending(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070060
Patrick Venture61d2ed42019-05-23 18:16:31 -070061 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -070062 EXPECT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Venture0f82ce42019-05-28 14:06:04 -070063 EXPECT_FALSE(handler->canHandleBlob(updateBlobId));
Patrick Venture61d2ed42019-05-23 18:16:31 -070064}
65
Patrick Ventureb386b862019-05-23 18:42:54 -070066/*
67 * delete(blob) TODO: Implement this.
68 */
69
70/*
71 * stat(blob)
72 */
73TEST_F(FirmwareHandlerVerificationPendingTest, StatOnActiveImageReturnsFailure)
74{
75 getToVerificationPending(staticLayoutBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070076 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -070077
78 blobs::BlobMeta meta;
79 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
80}
81
82TEST_F(FirmwareHandlerVerificationPendingTest, StatOnActiveHashReturnsFailure)
83{
84 getToVerificationPending(hashBlobId);
Patrick Venture930c7b72019-05-24 11:11:08 -070085 ASSERT_TRUE(handler->canHandleBlob(activeHashBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -070086
87 blobs::BlobMeta meta;
88 EXPECT_FALSE(handler->stat(activeHashBlobId, &meta));
89}
90
91TEST_F(FirmwareHandlerVerificationPendingTest,
92 StatOnVerificationBlobReturnsFailure)
93{
94 getToVerificationPending(hashBlobId);
Patrick Venture0f82ce42019-05-28 14:06:04 -070095 ASSERT_TRUE(handler->canHandleBlob(verifyBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -070096
97 blobs::BlobMeta meta;
98 EXPECT_FALSE(handler->stat(verifyBlobId, &meta));
99}
100
101TEST_F(FirmwareHandlerVerificationPendingTest, StatOnNormalBlobsReturnsSuccess)
102{
103 getToVerificationPending(staticLayoutBlobId);
104
105 blobs::BlobMeta expected;
106 expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
107 expected.size = 0;
108
109 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
110 for (const auto& blob : testBlobs)
111 {
Patrick Venture930c7b72019-05-24 11:11:08 -0700112 ASSERT_TRUE(handler->canHandleBlob(blob));
Patrick Ventureb386b862019-05-23 18:42:54 -0700113 blobs::BlobMeta meta = {};
114 EXPECT_TRUE(handler->stat(blob, &meta));
115 EXPECT_EQ(expected, meta);
116 }
117}
118
119/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700120 * open(blob)
121 */
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700122TEST_F(FirmwareHandlerVerificationPendingTest, OpenVerifyBlobSucceeds)
123{
124 getToVerificationPending(staticLayoutBlobId);
125
126 /* the session is safe because it was already closed to get to this state.
127 */
128 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
129}
130
Patrick Venture0f82ce42019-05-28 14:06:04 -0700131TEST_F(FirmwareHandlerVerificationPendingTest, OpenActiveBlobsFail)
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700132{
133 /* Try opening the active blob Id. This test is equivalent to trying to
134 * open the active hash blob id, in that neither are ever allowed.
135 */
136 getToVerificationPending(staticLayoutBlobId);
137 EXPECT_FALSE(handler->open(session, flags, activeImageBlobId));
Patrick Venture0f82ce42019-05-28 14:06:04 -0700138 EXPECT_FALSE(handler->open(session, flags, activeHashBlobId));
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700139}
140
141TEST_F(FirmwareHandlerVerificationPendingTest,
142 OpenImageBlobTransitionsToUploadInProgress)
143{
144 getToVerificationPending(staticLayoutBlobId);
Patrick Ventureefba42d2019-05-24 10:48:16 -0700145
146 /* Verify the active blob for the image is in the list once to start.
147 * Note: This is truly tested under the notYetStarted::open() test.
148 */
149 std::vector<std::string> expectedBlobs = {staticLayoutBlobId, hashBlobId,
150 verifyBlobId, activeImageBlobId};
151
152 EXPECT_THAT(handler->getBlobIds(),
153 UnorderedElementsAreArray(expectedBlobs));
154
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700155 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
156 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700157 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
Patrick Ventureefba42d2019-05-24 10:48:16 -0700158
Patrick Venture930c7b72019-05-24 11:11:08 -0700159 expectedBlobs.erase(
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700160 std::remove(expectedBlobs.begin(), expectedBlobs.end(), verifyBlobId),
161 expectedBlobs.end());
Patrick Venture930c7b72019-05-24 11:11:08 -0700162
163 /* Verify the active blob ID was not added to the list twice and
164 * verifyBlobId is removed
165 */
Patrick Ventureefba42d2019-05-24 10:48:16 -0700166 EXPECT_THAT(handler->getBlobIds(),
167 UnorderedElementsAreArray(expectedBlobs));
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700168}
169
170/*
Patrick Venture1e389c92019-05-23 19:15:05 -0700171 * close(session)
172 */
173TEST_F(FirmwareHandlerVerificationPendingTest,
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700174 ClosingVerifyBlobWithoutCommitDoesNotChangeState)
Patrick Venture1e389c92019-05-23 19:15:05 -0700175{
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700176 /* commit() will change the state, closing post-commit is part of
177 * verificationStarted testing.
178 */
Patrick Venture1e389c92019-05-23 19:15:05 -0700179 getToVerificationPending(staticLayoutBlobId);
180 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700181 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture1e389c92019-05-23 19:15:05 -0700182
183 handler->close(session);
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700184 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
Patrick Venture1e389c92019-05-23 19:15:05 -0700185}
186
187/*
Patrick Venture19044e12019-05-23 19:30:28 -0700188 * commit(session)
189 */
190TEST_F(FirmwareHandlerVerificationPendingTest,
191 CommitOnVerifyBlobTriggersVerificationAndStateTransition)
192{
193 getToVerificationPending(staticLayoutBlobId);
194 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture1d66fe62019-06-03 14:57:27 -0700195 EXPECT_CALL(*verifyMockPtr, trigger()).WillOnce(Return(true));
Patrick Venture19044e12019-05-23 19:30:28 -0700196
197 EXPECT_TRUE(handler->commit(session, {}));
Patrick Venture6fdd02e2019-05-28 13:02:04 -0700198 expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);
Patrick Venture19044e12019-05-23 19:30:28 -0700199}
200
201/*
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700202 * stat(session) - in this state, you can only open(verifyBlobId) without
203 * changing state.
204 */
Patrick Venture01a33272019-05-23 19:48:22 -0700205TEST_F(FirmwareHandlerVerificationPendingTest, StatOnVerifyBlobIdReturnsState)
206{
207 /* If this is called before commit(), it's still verificationPending, so it
208 * just returns the state is other
209 */
210 getToVerificationPending(staticLayoutBlobId);
211 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture1d66fe62019-06-03 14:57:27 -0700212 EXPECT_CALL(*verifyMockPtr, trigger()).Times(0);
Patrick Venturef1f0f652019-06-03 09:10:19 -0700213 EXPECT_CALL(*verifyMockPtr, status()).Times(0);
Patrick Venture01a33272019-05-23 19:48:22 -0700214
215 blobs::BlobMeta meta, expectedMeta = {};
216 expectedMeta.size = 0;
217 expectedMeta.blobState = flags;
218 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -0700219 static_cast<std::uint8_t>(ActionStatus::unknown));
Patrick Venture01a33272019-05-23 19:48:22 -0700220
221 EXPECT_TRUE(handler->stat(session, &meta));
222 EXPECT_EQ(expectedMeta, meta);
223}
224
Patrick Ventureb386b862019-05-23 18:42:54 -0700225/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700226 * writemeta(session)
227 */
Patrick Ventureb611a082019-05-23 20:27:28 -0700228TEST_F(FirmwareHandlerVerificationPendingTest, WriteMetaAgainstVerifyFails)
229{
230 /* The verifyBlobId has no data handler, which means write meta fails. */
231 getToVerificationPending(staticLayoutBlobId);
232
233 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
234
235 std::vector<std::uint8_t> bytes = {0x01, 0x02};
236 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
237}
238
Patrick Ventureb386b862019-05-23 18:42:54 -0700239/*
240 * write(session)
241 */
Patrick Ventureab731e92019-05-24 09:58:00 -0700242TEST_F(FirmwareHandlerVerificationPendingTest, WriteAgainstVerifyBlobIdFails)
243{
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->write(session, 0, bytes));
250}
251
Patrick Ventureb386b862019-05-23 18:42:54 -0700252/*
253 * read(session)
254 */
Patrick Venture2567ebc2019-05-24 10:02:53 -0700255TEST_F(FirmwareHandlerVerificationPendingTest,
256 ReadAgainstVerifyBlobIdReturnsEmpty)
257{
258 getToVerificationPending(staticLayoutBlobId);
259
260 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
Patrick Venture0f82ce42019-05-28 14:06:04 -0700261 EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
Patrick Venture2567ebc2019-05-24 10:02:53 -0700262}
Patrick Ventureb386b862019-05-23 18:42:54 -0700263
Patrick Venture61d2ed42019-05-23 18:16:31 -0700264} // namespace
265} // namespace ipmi_flash