blob: 43f90e3b60a7ab2222b575d105a33cf3cea8829c [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
21using ::testing::Return;
Patrick Venturead933832019-05-30 14:13:29 -070022using ::testing::UnorderedElementsAreArray;
Patrick Venture0cd945c2019-05-30 13:36:53 -070023
24/*
25 * There are the following calls (parameters may vary):
26 * canHandleBlob(blob)
27 * getBlobIds
28 * deleteBlob(blob)
29 * stat(blob)
30 * stat(session)
31 * open(blob)
32 * close(session)
33 * writemeta(session)
34 * write(session)
35 * read(session)
36 * commit(session)
37 *
38 * Testing canHandleBlob is uninteresting in this state. Getting the BlobIDs
39 * will inform what canHandleBlob will return.
40 */
41
42class FirmwareHandlerUpdatePendingTest : public IpmiOnlyFirmwareStaticTest
43{
44 protected:
45 void getToUpdatePending()
46 {
47 /* The hash was not sent up, as it's technically optional. Therefore,
48 * there is no active hash file.
49 */
50 EXPECT_CALL(imageMock, open(staticLayoutBlobId)).WillOnce(Return(true));
51 EXPECT_TRUE(handler->open(session, flags, staticLayoutBlobId));
52 expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress);
53
54 EXPECT_CALL(imageMock, close()).WillRepeatedly(Return());
55 handler->close(session);
56 expectedState(FirmwareBlobHandler::UpdateState::verificationPending);
57
58 EXPECT_TRUE(handler->open(session, flags, verifyBlobId));
59 EXPECT_CALL(*verifyMockPtr, triggerVerification())
60 .WillOnce(Return(true));
61
62 EXPECT_TRUE(handler->commit(session, {}));
63 expectedState(FirmwareBlobHandler::UpdateState::verificationStarted);
64
65 EXPECT_CALL(*verifyMockPtr, checkVerificationState())
66 .WillOnce(Return(VerifyCheckResponses::success));
67 blobs::BlobMeta meta;
68 EXPECT_TRUE(handler->stat(session, &meta));
69 expectedState(FirmwareBlobHandler::UpdateState::verificationCompleted);
70
71 handler->close(session);
72 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
73 }
74
75 std::uint16_t session = 1;
76 std::uint16_t flags =
77 blobs::OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi;
78};
79
80/*
81 * There are the following calls (parameters may vary):
82 * canHandleBlob(blob)
83 * getBlobIds
84 */
Patrick Venturead933832019-05-30 14:13:29 -070085TEST_F(FirmwareHandlerUpdatePendingTest, GetBlobsListHasExpectedValues)
86{
87 getToUpdatePending();
88
89 std::vector<std::string> expected = {updateBlobId, activeImageBlobId,
90 hashBlobId, staticLayoutBlobId};
91 EXPECT_THAT(handler->getBlobIds(), UnorderedElementsAreArray(expected));
92}
93
Patrick Venture0cd945c2019-05-30 13:36:53 -070094/*
Patrick Venture19f5d882019-05-30 14:34:55 -070095 * open(blob) - because updatePending is in a fileOpen==false state, one can
96 * then open blobs. However, because we're in a special state, we will restrict
97 * them s.t. they can only open the updateBlobId.
98 */
99TEST_F(FirmwareHandlerUpdatePendingTest,
100 OpenUpdateBlobIdIsSuccessfulAndDoesNotChangeState)
101{
102 getToUpdatePending();
103
104 /* Opening the update blob isn't interesting, except it's required for
105 * commit() which triggers the update process.
106 */
107 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
Patrick Venture6b0aa182019-05-30 14:47:32 -0700108 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
Patrick Venture19f5d882019-05-30 14:34:55 -0700109}
110
111TEST_F(FirmwareHandlerUpdatePendingTest, OpenAnyBlobOtherThanUpdateFails)
112{
113 getToUpdatePending();
114
115 auto blobs = handler->getBlobIds();
116 for (const auto& blob : blobs)
117 {
118 if (blob == updateBlobId)
119 {
120 continue;
121 }
122 EXPECT_FALSE(handler->open(session, flags, blob));
123 }
124}
125
126/*
Patrick Venture6b0aa182019-05-30 14:47:32 -0700127 * close(session) - close from this state is uninteresting.
128 */
129TEST_F(FirmwareHandlerUpdatePendingTest, CloseUpdateBlobDoesNotChangeState)
130{
131 /* Verify nothing changes when one just opens, then closes the updateBlobId.
132 */
133 getToUpdatePending();
134
135 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
136
137 handler->close(session);
138
139 expectedState(FirmwareBlobHandler::UpdateState::updatePending);
140 EXPECT_TRUE(handler->canHandleBlob(updateBlobId));
141}
142
143/*
Patrick Venture94bb9702019-05-30 14:53:22 -0700144 * writemeta(session) - this will return failure.
145 */
146TEST_F(FirmwareHandlerUpdatePendingTest, WriteMetaToUpdateBlobReturnsFailure)
147{
148 getToUpdatePending();
149
150 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
151 EXPECT_FALSE(handler->writeMeta(session, 0, {0x01}));
152}
153
154/*
Patrick Venture4e2fdcd2019-05-30 14:58:57 -0700155 * write(session)
156 */
157TEST_F(FirmwareHandlerUpdatePendingTest, WriteToUpdateBlobReturnsFailure)
158{
159 getToUpdatePending();
160
161 EXPECT_TRUE(handler->open(session, flags, updateBlobId));
162 EXPECT_FALSE(handler->write(session, 0, {0x01}));
163}
164
165/*
Patrick Venture19f5d882019-05-30 14:34:55 -0700166 * TODO: deleteBlob(blob)
Patrick Venture0cd945c2019-05-30 13:36:53 -0700167 */
168
169/*
170 * stat(blob)
171 */
172
173/*
174 * stat(session)
175 */
176
177/*
Patrick Venture0cd945c2019-05-30 13:36:53 -0700178 * read(session)
179 */
180
181/*
182 * commit(session)
183 */
184
185} // namespace
186} // namespace ipmi_flash