blob: 320d09e7087b56e3d6484126e6adc18b732e47b3 [file] [log] [blame]
Patrick Venture2098ff92019-06-03 10:18:05 -07001/* The goal of these tests is to verify the behavior of all blob commands given
2 * the current state is UpdateCompleted. This state is achieved as an exit from
3 * updateStarted.
4 *
5 * This can be reached with success or failure from an update, and is reached
6 * via a stat() call from updatedStarted.
7 */
Patrick Ventureab1e9622019-06-03 10:45:06 -07008#include "firmware_handler.hpp"
9#include "firmware_unittest.hpp"
10#include "status.hpp"
11#include "util.hpp"
12
13#include <string>
14#include <vector>
15
16#include <gtest/gtest.h>
17
18namespace ipmi_flash
19{
20namespace
21{
22
Patrick Venture7441ab72019-06-05 07:44:38 -070023using ::testing::IsEmpty;
Patrick Venture0c6daf42019-06-05 09:02:50 -070024using ::testing::UnorderedElementsAreArray;
Patrick Venture7441ab72019-06-05 07:44:38 -070025
Patrick Ventureab1e9622019-06-03 10:45:06 -070026/*
27 * There are the following calls (parameters may vary):
28 * canHandleBlob(blob)
29 * getBlobIds
30 * deleteBlob(blob)
31 * stat(blob)
32 * stat(session)
33 * open(blob)
34 * close(session)
35 * writemeta(session)
36 * write(session)
37 * read(session)
38 * commit(session)
39 */
40
41class FirmwareHandlerUpdateCompletedTest : public IpmiOnlyFirmwareStaticTest
42{
43};
44
45/*
46 * open(blob)
47 */
48TEST_F(FirmwareHandlerUpdateCompletedTest,
49 AttemptToOpenFilesReturnsFailureAfterSuccess)
50{
51 /* In state updateCompleted a file is open, which means no others can be. */
Patrick Ventureda66fd82019-06-03 11:11:24 -070052 getToUpdateCompleted(ActionStatus::success);
Patrick Ventureab1e9622019-06-03 10:45:06 -070053
54 auto blobsToOpen = handler->getBlobIds();
55 for (const auto& blob : blobsToOpen)
56 {
57 EXPECT_FALSE(handler->open(session + 1, flags, blob));
58 }
59}
60
61/*
Patrick Venturea2d82392019-06-03 10:55:17 -070062 * stat(session)
63 */
64TEST_F(FirmwareHandlerUpdateCompletedTest,
65 CallingStatSessionAfterCompletedSuccessReturnsStateWithoutRechecking)
66{
Patrick Ventureda66fd82019-06-03 11:11:24 -070067 getToUpdateCompleted(ActionStatus::success);
Patrick Venturea2d82392019-06-03 10:55:17 -070068 EXPECT_CALL(*updateMockPtr, status()).Times(0);
69
70 blobs::BlobMeta meta, expectedMeta = {};
71 expectedMeta.size = 0;
72 expectedMeta.blobState = flags | blobs::StateFlags::committed;
73 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -070074 static_cast<std::uint8_t>(ActionStatus::success));
Patrick Venturea2d82392019-06-03 10:55:17 -070075
76 EXPECT_TRUE(handler->stat(session, &meta));
77 EXPECT_EQ(expectedMeta, meta);
78 expectedState(FirmwareBlobHandler::UpdateState::updateCompleted);
79}
80
81TEST_F(FirmwareHandlerUpdateCompletedTest,
82 CallingStatSessionAfterCompletedFailureReturnsStateWithoutRechecking)
83{
Patrick Ventureda66fd82019-06-03 11:11:24 -070084 getToUpdateCompleted(ActionStatus::failed);
Patrick Venturea2d82392019-06-03 10:55:17 -070085 EXPECT_CALL(*updateMockPtr, status()).Times(0);
86
87 blobs::BlobMeta meta, expectedMeta = {};
88 expectedMeta.size = 0;
89 expectedMeta.blobState = flags | blobs::StateFlags::commit_error;
90 expectedMeta.metadata.push_back(
Patrick Ventureda66fd82019-06-03 11:11:24 -070091 static_cast<std::uint8_t>(ActionStatus::failed));
Patrick Venturea2d82392019-06-03 10:55:17 -070092
93 EXPECT_TRUE(handler->stat(session, &meta));
94 EXPECT_EQ(expectedMeta, meta);
95 expectedState(FirmwareBlobHandler::UpdateState::updateCompleted);
96}
97
98/*
Patrick Venture25dfaff2019-06-03 13:17:22 -070099 * stat(blob)
100 */
101TEST_F(FirmwareHandlerUpdateCompletedTest, StatOnActiveImageReturnsFailure)
102{
103 getToUpdateCompleted(ActionStatus::success);
104
105 ASSERT_TRUE(handler->canHandleBlob(activeImageBlobId));
106
107 blobs::BlobMeta meta;
108 EXPECT_FALSE(handler->stat(activeImageBlobId, &meta));
109}
110
111TEST_F(FirmwareHandlerUpdateCompletedTest, StatOnUpdateBlobReturnsFailure)
112{
113 getToUpdateCompleted(ActionStatus::success);
114
115 ASSERT_TRUE(handler->canHandleBlob(updateBlobId));
116
117 blobs::BlobMeta meta;
118 EXPECT_FALSE(handler->stat(updateBlobId, &meta));
119}
120
121TEST_F(FirmwareHandlerUpdateCompletedTest, StatOnNormalBlobsReturnsSuccess)
122{
123 getToUpdateCompleted(ActionStatus::success);
124
Patrick Venture25dfaff2019-06-03 13:17:22 -0700125 std::vector<std::string> testBlobs = {staticLayoutBlobId, hashBlobId};
126 for (const auto& blob : testBlobs)
127 {
128 ASSERT_TRUE(handler->canHandleBlob(blob));
129
130 blobs::BlobMeta meta = {};
131 EXPECT_TRUE(handler->stat(blob, &meta));
Benjamin Fair12901982019-11-12 13:55:46 -0800132 EXPECT_EQ(expectedIdleMeta, meta);
Patrick Venture25dfaff2019-06-03 13:17:22 -0700133 }
134}
135
136/*
Patrick Venture58202b22019-06-03 13:38:09 -0700137 * writemeta(session)
138 */
139TEST_F(FirmwareHandlerUpdateCompletedTest, WriteMetaToUpdateBlobReturnsFailure)
140{
141 getToUpdateCompleted(ActionStatus::success);
142
143 EXPECT_FALSE(handler->writeMeta(session, 0, {0x01}));
144}
145
146/*
Patrick Venture254b4cf2019-06-03 13:44:49 -0700147 * write(session)
148 */
149TEST_F(FirmwareHandlerUpdateCompletedTest, WriteToUpdateBlobReturnsFailure)
150{
151 getToUpdateCompleted(ActionStatus::success);
152
153 EXPECT_FALSE(handler->write(session, 0, {0x01}));
154}
155
156/*
Patrick Venturefdeb8642019-06-03 14:30:34 -0700157 * commit(session) - returns failure
158 */
159TEST_F(FirmwareHandlerUpdateCompletedTest,
160 CommitOnUpdateBlobAfterSuccessReturnsFailure)
161{
162 getToUpdateCompleted(ActionStatus::success);
163
Patrick Venture1d66fe62019-06-03 14:57:27 -0700164 EXPECT_CALL(*updateMockPtr, trigger()).Times(0);
Patrick Venturefdeb8642019-06-03 14:30:34 -0700165 EXPECT_FALSE(handler->commit(session, {}));
166}
167
168TEST_F(FirmwareHandlerUpdateCompletedTest,
169 CommitOnUpdateBlobAfterFailureReturnsFailure)
170{
171 getToUpdateCompleted(ActionStatus::failed);
172
Patrick Venture1d66fe62019-06-03 14:57:27 -0700173 EXPECT_CALL(*updateMockPtr, trigger()).Times(0);
Patrick Venturefdeb8642019-06-03 14:30:34 -0700174 EXPECT_FALSE(handler->commit(session, {}));
175}
176
177/*
Patrick Venture7441ab72019-06-05 07:44:38 -0700178 * read(session) - nothing to read here.
179 */
180TEST_F(FirmwareHandlerUpdateCompletedTest, ReadingFromUpdateBlobReturnsNothing)
181{
182 getToUpdateCompleted(ActionStatus::success);
183
184 EXPECT_THAT(handler->read(session, 0, 1), IsEmpty());
185}
186
187/*
Patrick Ventureab1e9622019-06-03 10:45:06 -0700188 * getBlobIds
Patrick Venture0c6daf42019-06-05 09:02:50 -0700189 * canHandleBlob(blob)
190 */
191TEST_F(FirmwareHandlerUpdateCompletedTest, GetBlobListProvidesExpectedBlobs)
192{
193 getToUpdateCompleted(ActionStatus::success);
194
Patrick Venture9a69f732019-06-17 14:05:13 -0700195 EXPECT_THAT(
196 handler->getBlobIds(),
197 UnorderedElementsAreArray(
198 {updateBlobId, hashBlobId, activeImageBlobId, staticLayoutBlobId}));
Patrick Venture0c6daf42019-06-05 09:02:50 -0700199}
200
201/*
Patrick Venture85ae86b2019-06-05 09:18:40 -0700202 * close(session) - closes everything out and returns to state not-yet-started.
203 * It doesn't go and clean out any update artifacts that may be present on the
204 * system. It's up to the update implementation to deal with this before
205 * marking complete.
206 */
207TEST_F(FirmwareHandlerUpdateCompletedTest,
208 ClosingOnUpdateBlobIdAfterSuccessReturnsToNotYetStartedAndCleansBlobList)
209{
210 getToUpdateCompleted(ActionStatus::success);
211
212 handler->close(session);
213 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
214
Patrick Venture9a69f732019-06-17 14:05:13 -0700215 EXPECT_THAT(handler->getBlobIds(),
216 UnorderedElementsAreArray(startingBlobs));
Patrick Venture85ae86b2019-06-05 09:18:40 -0700217}
218
219TEST_F(FirmwareHandlerUpdateCompletedTest,
220 ClosingOnUpdateBlobIdAfterFailureReturnsToNotYetStartedAndCleansBlobList)
221{
222 getToUpdateCompleted(ActionStatus::failed);
223
224 handler->close(session);
225 expectedState(FirmwareBlobHandler::UpdateState::notYetStarted);
226
Patrick Venture9a69f732019-06-17 14:05:13 -0700227 EXPECT_THAT(handler->getBlobIds(),
228 UnorderedElementsAreArray(startingBlobs));
Patrick Venture85ae86b2019-06-05 09:18:40 -0700229}
230
231/*
Patrick Venturebcc0c772019-06-17 10:42:06 -0700232 * deleteBlob(blob)
Patrick Ventureab1e9622019-06-03 10:45:06 -0700233 */
Patrick Venturebcc0c772019-06-17 10:42:06 -0700234TEST_F(FirmwareHandlerUpdateCompletedTest, DeleteBlobReturnsFalse)
235{
236 /* Try deleting all blobs, it doesn't really matter which though because you
237 * cannot close out an open session, therefore you must fail to delete
238 * anything unless everything is closed.
239 */
240 getToUpdateCompleted(ActionStatus::success);
241
242 auto blobs = handler->getBlobIds();
243 for (const auto& b : blobs)
244 {
245 EXPECT_FALSE(handler->deleteBlob(b));
246 }
247}
Patrick Ventureab1e9622019-06-03 10:45:06 -0700248
249} // namespace
250} // namespace ipmi_flash