blob: e8a3bf284a0b2711aa35993abbb221c2bace10e6 [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
11#include <cstdint>
12#include <string>
13#include <vector>
14
15#include <gtest/gtest.h>
16
17namespace ipmi_flash
18{
19namespace
20{
21
Patrick Venture2567ebc2019-05-24 10:02:53 -070022using ::testing::IsEmpty;
Patrick Venture61d2ed42019-05-23 18:16:31 -070023using ::testing::Return;
24
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 FirmwareHandlerVerificationPendingTest : public IpmiOnlyFirmwareStaticTest
44{
45 protected:
46 void getToVerificationPending(const std::string& blobId)
47 {
48 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
49 EXPECT_CALL(imageMock, open(blobId)).WillOnce(Return(true));
50 EXPECT_TRUE(handler->open(session, flags, blobId));
51 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
52 realHandler->getCurrentState());
53 EXPECT_CALL(imageMock, close()).WillRepeatedly(Return());
54 handler->close(session);
55 EXPECT_EQ(FirmwareBlobHandler::UpdateState::verificationPending,
56 realHandler->getCurrentState());
57 }
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
72 /* TODO: Add this test in when the change is made. */
73 // EXPECT_FALSE(handler->canHandleBlob(verifyBlobId));
74 getToVerificationPending(staticLayoutBlobId);
75 EXPECT_TRUE(handler->canHandleBlob(verifyBlobId));
Patrick Ventureb386b862019-05-23 18:42:54 -070076 EXPECT_TRUE(handler->canHandleBlob(activeImageBlobId));
Patrick Venture61d2ed42019-05-23 18:16:31 -070077}
78
Patrick Ventureb386b862019-05-23 18:42:54 -070079/*
80 * delete(blob) TODO: Implement this.
81 */
82
83/*
84 * stat(blob)
85 */
86TEST_F(FirmwareHandlerVerificationPendingTest, StatOnActiveImageReturnsFailure)
87{
88 getToVerificationPending(staticLayoutBlobId);
89
90 blobs::BlobMeta meta;
91 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
92}
93
94TEST_F(FirmwareHandlerVerificationPendingTest, StatOnActiveHashReturnsFailure)
95{
96 getToVerificationPending(hashBlobId);
97
98 blobs::BlobMeta meta;
99 EXPECT_FALSE(handler->stat(activeHashBlobId, &meta));
100}
101
102TEST_F(FirmwareHandlerVerificationPendingTest,
103 StatOnVerificationBlobReturnsFailure)
104{
105 getToVerificationPending(hashBlobId);
106
107 blobs::BlobMeta meta;
108 EXPECT_FALSE(handler->stat(verifyBlobId, &meta));
109}
110
111TEST_F(FirmwareHandlerVerificationPendingTest, StatOnNormalBlobsReturnsSuccess)
112{
113 getToVerificationPending(staticLayoutBlobId);
114
115 blobs::BlobMeta expected;
116 expected.blobState = FirmwareBlobHandler::UpdateFlags::ipmi;
117 expected.size = 0;
118
119 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
120 for (const auto& blob : testBlobs)
121 {
122 blobs::BlobMeta meta = {};
123 EXPECT_TRUE(handler->stat(blob, &meta));
124 EXPECT_EQ(expected, meta);
125 }
126}
127
128/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700129 * open(blob)
130 */
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700131TEST_F(FirmwareHandlerVerificationPendingTest, OpenVerifyBlobSucceeds)
132{
133 getToVerificationPending(staticLayoutBlobId);
134
135 /* the session is safe because it was already closed to get to this state.
136 */
137 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
138}
139
140TEST_F(FirmwareHandlerVerificationPendingTest, OpenActiveImageBlobFails)
141{
142 /* Try opening the active blob Id. This test is equivalent to trying to
143 * open the active hash blob id, in that neither are ever allowed.
144 */
145 getToVerificationPending(staticLayoutBlobId);
146 EXPECT_FALSE(handler->open(session, flags, activeImageBlobId));
147}
148
149TEST_F(FirmwareHandlerVerificationPendingTest,
150 OpenImageBlobTransitionsToUploadInProgress)
151{
152 getToVerificationPending(staticLayoutBlobId);
153 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
154 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
155
156 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
157 EXPECT_EQ(FirmwareBlobHandler::UpdateState::uploadInProgress,
158 realHandler->getCurrentState());
159}
160
161/*
Patrick Venture1e389c92019-05-23 19:15:05 -0700162 * close(session)
163 */
164TEST_F(FirmwareHandlerVerificationPendingTest,
165 ClosingVerifyBlobDoesNotChangeState)
166{
167 getToVerificationPending(staticLayoutBlobId);
168 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
169
170 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
171 EXPECT_EQ(FirmwareBlobHandler::UpdateState::verificationPending,
172 realHandler->getCurrentState());
173
174 handler->close(session);
175
176 EXPECT_EQ(FirmwareBlobHandler::UpdateState::verificationPending,
177 realHandler->getCurrentState());
178}
179
180/*
Patrick Venture19044e12019-05-23 19:30:28 -0700181 * commit(session)
182 */
183TEST_F(FirmwareHandlerVerificationPendingTest,
184 CommitOnVerifyBlobTriggersVerificationAndStateTransition)
185{
186 getToVerificationPending(staticLayoutBlobId);
187 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
188 EXPECT_CALL(*verifyMockPtr, triggerVerification()).WillOnce(Return(true));
189
190 EXPECT_TRUE(handler->commit(session, {}));
191
192 auto realHandler = dynamic_cast<FirmwareBlobHandler*>(handler.get());
193 EXPECT_EQ(FirmwareBlobHandler::UpdateState::verificationStarted,
194 realHandler->getCurrentState());
195}
196
197/*
Patrick Ventureda8fcd12019-05-23 18:53:50 -0700198 * stat(session) - in this state, you can only open(verifyBlobId) without
199 * changing state.
200 */
Patrick Venture01a33272019-05-23 19:48:22 -0700201TEST_F(FirmwareHandlerVerificationPendingTest, StatOnVerifyBlobIdReturnsState)
202{
203 /* If this is called before commit(), it's still verificationPending, so it
204 * just returns the state is other
205 */
206 getToVerificationPending(staticLayoutBlobId);
207 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
208 EXPECT_CALL(*verifyMockPtr, triggerVerification()).Times(0);
209 EXPECT_CALL(*verifyMockPtr, checkVerificationState()).Times(0);
210
211 blobs::BlobMeta meta, expectedMeta = {};
212 expectedMeta.size = 0;
213 expectedMeta.blobState = flags;
214 expectedMeta.metadata.push_back(
215 static_cast<std::uint8_t>(VerifyCheckResponses::other));
216
217 EXPECT_TRUE(handler->stat(session, &meta));
218 EXPECT_EQ(expectedMeta, meta);
219}
220
Patrick Ventureb386b862019-05-23 18:42:54 -0700221/*
Patrick Ventureb386b862019-05-23 18:42:54 -0700222 * writemeta(session)
223 */
Patrick Ventureb611a082019-05-23 20:27:28 -0700224TEST_F(FirmwareHandlerVerificationPendingTest, WriteMetaAgainstVerifyFails)
225{
226 /* The verifyBlobId has no data handler, which means write meta fails. */
227 getToVerificationPending(staticLayoutBlobId);
228
229 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
230
231 std::vector<std::uint8_t> bytes = {0x01, 0x02};
232 EXPECT_FALSE(handler->writeMeta(session, 0, bytes));
233}
234
Patrick Ventureb386b862019-05-23 18:42:54 -0700235/*
236 * write(session)
237 */
Patrick Ventureab731e92019-05-24 09:58:00 -0700238TEST_F(FirmwareHandlerVerificationPendingTest, WriteAgainstVerifyBlobIdFails)
239{
240 getToVerificationPending(staticLayoutBlobId);
241
242 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
243
244 std::vector<std::uint8_t> bytes = {0x01, 0x02};
245 EXPECT_FALSE(handler->write(session, 0, bytes));
246}
247
Patrick Ventureb386b862019-05-23 18:42:54 -0700248/*
249 * read(session)
250 */
Patrick Venture2567ebc2019-05-24 10:02:53 -0700251TEST_F(FirmwareHandlerVerificationPendingTest,
252 ReadAgainstVerifyBlobIdReturnsEmpty)
253{
254 getToVerificationPending(staticLayoutBlobId);
255
256 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
257 EXPECT_THAT(handler->read(session, 0, 32), IsEmpty());
258}
Patrick Ventureb386b862019-05-23 18:42:54 -0700259
Patrick Venture61d2ed42019-05-23 18:16:31 -0700260} // namespace
261} // namespace ipmi_flash