blob: bb28ecbfff2835bc7dc007efa00a8467dec9ee22 [file] [log] [blame]
Patrick Ventureaa32a362018-12-13 10:52:33 -08001#include "data_interface_mock.hpp"
Patrick Venture84778b82019-06-26 20:11:09 -07002#include "flags.hpp"
Patrick Venture1f09d412019-06-19 16:01:06 -07003#include "status.hpp"
Patrick Venture5f2fcc42019-06-20 07:21:05 -07004#include "tool_errors.hpp"
Patrick Ventureaa32a362018-12-13 10:52:33 -08005#include "updater.hpp"
Patrick Venture55646de2019-05-16 10:06:26 -07006#include "updater_mock.hpp"
Patrick Venture7dad86f2019-05-17 08:52:20 -07007#include "util.hpp"
Patrick Ventureaa32a362018-12-13 10:52:33 -08008
Patrick Venture8cdf9642020-09-30 09:41:51 -07009#include <ipmiblob/blob_errors.hpp>
Patrick Venture664c5bc2019-03-07 08:09:45 -080010#include <ipmiblob/test/blob_interface_mock.hpp>
Patrick Venture9b37b092020-05-28 20:58:57 -070011
Patrick Ventureaa32a362018-12-13 10:52:33 -080012#include <string>
Patrick Venture8cdf9642020-09-30 09:41:51 -070013#include <vector>
Patrick Ventureaa32a362018-12-13 10:52:33 -080014
Patrick Venture8cdf9642020-09-30 09:41:51 -070015#include <gmock/gmock.h>
Patrick Ventureaa32a362018-12-13 10:52:33 -080016#include <gtest/gtest.h>
17
Patrick Venture9b534f02018-12-13 16:10:02 -080018namespace host_tool
19{
20
Patrick Venture7dcca5d2019-05-15 12:32:33 -070021using ::testing::_;
Patrick Ventureaa32a362018-12-13 10:52:33 -080022using ::testing::Eq;
23using ::testing::Return;
Patrick Venture8cdf9642020-09-30 09:41:51 -070024using ::testing::Throw;
Patrick Ventureb58f5612019-05-07 09:22:07 -070025using ::testing::TypedEq;
Patrick Ventureaa32a362018-12-13 10:52:33 -080026
Patrick Venture1f09d412019-06-19 16:01:06 -070027class UpdateHandlerTest : public ::testing::Test
Patrick Venture55646de2019-05-16 10:06:26 -070028{
Patrick Venture1f09d412019-06-19 16:01:06 -070029 protected:
30 const std::uint16_t session = 0xbeef;
31
Patrick Venture55646de2019-05-16 10:06:26 -070032 DataInterfaceMock handlerMock;
33 ipmiblob::BlobInterfaceMock blobMock;
Patrick Venture1f09d412019-06-19 16:01:06 -070034 UpdateHandler updater{&blobMock, &handlerMock};
35};
Patrick Venture55646de2019-05-16 10:06:26 -070036
Patrick Venture1f09d412019-06-19 16:01:06 -070037TEST_F(UpdateHandlerTest, CheckAvailableSuccess)
38{
Patrick Venture55646de2019-05-16 10:06:26 -070039 EXPECT_CALL(blobMock, getBlobList())
Patrick Venture7dad86f2019-05-17 08:52:20 -070040 .WillOnce(
Patrick Venture1d5a31c2019-05-20 11:38:22 -070041 Return(std::vector<std::string>({ipmi_flash::staticLayoutBlobId})));
Patrick Venture55646de2019-05-16 10:06:26 -070042
Patrick Venture1d5a31c2019-05-20 11:38:22 -070043 EXPECT_TRUE(updater.checkAvailable(ipmi_flash::staticLayoutBlobId));
Patrick Venture55646de2019-05-16 10:06:26 -070044}
45
Patrick Venture8cdf9642020-09-30 09:41:51 -070046TEST_F(UpdateHandlerTest, CheckAvailableFailure)
47{
48 EXPECT_CALL(blobMock, getBlobList())
49 .WillOnce(Return(std::vector<std::string>()));
50
51 EXPECT_FALSE(updater.checkAvailable(ipmi_flash::staticLayoutBlobId));
52}
53
Patrick Venture1f09d412019-06-19 16:01:06 -070054TEST_F(UpdateHandlerTest, SendFileSuccess)
Patrick Venture55646de2019-05-16 10:06:26 -070055{
56 /* Call sendFile to verify it does what we expect. */
Patrick Venture55646de2019-05-16 10:06:26 -070057 std::string firmwareImage = "image.bin";
58
59 std::uint16_t supported =
60 static_cast<std::uint16_t>(
Patrick Venture84778b82019-06-26 20:11:09 -070061 ipmi_flash::FirmwareFlags::UpdateFlags::lpc) |
62 static_cast<std::uint16_t>(
63 ipmi_flash::FirmwareFlags::UpdateFlags::openWrite);
Patrick Venture55646de2019-05-16 10:06:26 -070064
65 EXPECT_CALL(handlerMock, supportedType())
Patrick Venture84778b82019-06-26 20:11:09 -070066 .WillOnce(Return(ipmi_flash::FirmwareFlags::UpdateFlags::lpc));
Patrick Venture55646de2019-05-16 10:06:26 -070067
Patrick Venture1f09d412019-06-19 16:01:06 -070068 EXPECT_CALL(blobMock, openBlob(ipmi_flash::staticLayoutBlobId, supported))
Patrick Venture55646de2019-05-16 10:06:26 -070069 .WillOnce(Return(session));
70
Patrick Venture1f09d412019-06-19 16:01:06 -070071 EXPECT_CALL(handlerMock, sendContents(firmwareImage, session))
Patrick Venture55646de2019-05-16 10:06:26 -070072 .WillOnce(Return(true));
73
74 EXPECT_CALL(blobMock, closeBlob(session)).Times(1);
75
Patrick Venture1d5a31c2019-05-20 11:38:22 -070076 updater.sendFile(ipmi_flash::staticLayoutBlobId, firmwareImage);
Patrick Venture55646de2019-05-16 10:06:26 -070077}
78
Patrick Venture8cdf9642020-09-30 09:41:51 -070079TEST_F(UpdateHandlerTest, SendFileExceptsOnBlobOpening)
80{
81 std::string firmwareImage = "image.bin";
82
83 std::uint16_t supported =
84 static_cast<std::uint16_t>(
85 ipmi_flash::FirmwareFlags::UpdateFlags::lpc) |
86 static_cast<std::uint16_t>(
87 ipmi_flash::FirmwareFlags::UpdateFlags::openWrite);
88
89 EXPECT_CALL(handlerMock, supportedType())
90 .WillOnce(Return(ipmi_flash::FirmwareFlags::UpdateFlags::lpc));
91
92 EXPECT_CALL(blobMock, openBlob(ipmi_flash::staticLayoutBlobId, supported))
93 .WillOnce(Throw(ipmiblob::BlobException("asdf")));
94
95 EXPECT_THROW(
96 updater.sendFile(ipmi_flash::staticLayoutBlobId, firmwareImage),
97 ToolException);
98}
99
100TEST_F(UpdateHandlerTest, SendFileHandlerFailureCausesException)
101{
102 std::string firmwareImage = "image.bin";
103
104 std::uint16_t supported =
105 static_cast<std::uint16_t>(
106 ipmi_flash::FirmwareFlags::UpdateFlags::lpc) |
107 static_cast<std::uint16_t>(
108 ipmi_flash::FirmwareFlags::UpdateFlags::openWrite);
109
110 EXPECT_CALL(handlerMock, supportedType())
111 .WillOnce(Return(ipmi_flash::FirmwareFlags::UpdateFlags::lpc));
112
113 EXPECT_CALL(blobMock, openBlob(ipmi_flash::staticLayoutBlobId, supported))
114 .WillOnce(Return(session));
115
116 EXPECT_CALL(handlerMock, sendContents(firmwareImage, session))
117 .WillOnce(Return(false));
118
119 EXPECT_CALL(blobMock, closeBlob(session)).Times(1);
120
121 EXPECT_THROW(
122 updater.sendFile(ipmi_flash::staticLayoutBlobId, firmwareImage),
123 ToolException);
124}
125
Patrick Venture1f09d412019-06-19 16:01:06 -0700126TEST_F(UpdateHandlerTest, VerifyFileHandleReturnsTrueOnSuccess)
Patrick Ventureaa32a362018-12-13 10:52:33 -0800127{
Patrick Venture1f09d412019-06-19 16:01:06 -0700128 EXPECT_CALL(blobMock, openBlob(ipmi_flash::verifyBlobId, _))
Patrick Ventureaa32a362018-12-13 10:52:33 -0800129 .WillOnce(Return(session));
Patrick Venture55646de2019-05-16 10:06:26 -0700130 EXPECT_CALL(blobMock, commit(session, _)).WillOnce(Return());
Patrick Venture1f09d412019-06-19 16:01:06 -0700131 ipmiblob::StatResponse verificationResponse = {};
132 /* the other details of the response are ignored, and should be. */
133 verificationResponse.metadata.push_back(
134 static_cast<std::uint8_t>(ipmi_flash::ActionStatus::success));
Patrick Venture7dcca5d2019-05-15 12:32:33 -0700135
Patrick Venture1f09d412019-06-19 16:01:06 -0700136 EXPECT_CALL(blobMock, getStat(TypedEq<std::uint16_t>(session)))
137 .WillOnce(Return(verificationResponse));
138 EXPECT_CALL(blobMock, closeBlob(session)).WillOnce(Return());
139
Brandon Kim6749ba12019-09-19 13:31:37 -0700140 EXPECT_TRUE(updater.verifyFile(ipmi_flash::verifyBlobId, false));
Patrick Venture1f09d412019-06-19 16:01:06 -0700141}
142
Patrick Venture8cdf9642020-09-30 09:41:51 -0700143TEST_F(UpdateHandlerTest, VerifyFileHandleSkipsPollingIfIgnoreStatus)
144{
145 /* if ignoreStatus, it'll skip polling for a verification result. */
146 EXPECT_CALL(blobMock, openBlob(ipmi_flash::verifyBlobId, _))
147 .WillOnce(Return(session));
148 EXPECT_CALL(blobMock, commit(session, _)).WillOnce(Return());
149
150 EXPECT_CALL(blobMock, closeBlob(session)).WillOnce(Return());
151
152 EXPECT_TRUE(updater.verifyFile(ipmi_flash::verifyBlobId, true));
153}
154
155TEST_F(UpdateHandlerTest, VerifyFileConvertsOpenBlobExceptionToToolException)
156{
157 /* On open, it can except and this is converted to a ToolException. */
158 EXPECT_CALL(blobMock, openBlob(ipmi_flash::verifyBlobId, _))
159 .WillOnce(Throw(ipmiblob::BlobException("asdf")));
160 EXPECT_THROW(updater.verifyFile(ipmi_flash::verifyBlobId, false),
161 ToolException);
162}
163
164TEST_F(UpdateHandlerTest, VerifyFileCommitExceptionForwards)
165{
166 /* On commit, it can except. */
167 EXPECT_CALL(blobMock, openBlob(ipmi_flash::verifyBlobId, _))
168 .WillOnce(Return(session));
169 EXPECT_CALL(blobMock, commit(session, _))
170 .WillOnce(Throw(ipmiblob::BlobException("asdf")));
171 EXPECT_THROW(updater.verifyFile(ipmi_flash::verifyBlobId, false),
172 ToolException);
173}
174
175TEST_F(UpdateHandlerTest, CleanArtifactsSkipsCleanupIfUnableToOpen)
176{
177 /* It only tries to commit if it's able to open the blob. However, if
178 * committing fails, this error is ignored.
179 */
180 EXPECT_CALL(blobMock, openBlob(ipmi_flash::cleanupBlobId, _))
181 .WillOnce(Throw(ipmiblob::BlobException("asdf")));
182 EXPECT_CALL(blobMock, commit(_, _)).Times(0);
183 EXPECT_CALL(blobMock, closeBlob(_)).Times(0);
184
185 updater.cleanArtifacts();
186}
187
188TEST_F(UpdateHandlerTest, CleanArtifactsIfOpenDoesClose)
189{
190 /* The closeBlob call is called even if commit excepts. */
191 std::uint16_t session = 0xa5eb;
192 EXPECT_CALL(blobMock, openBlob(ipmi_flash::cleanupBlobId, _))
193 .WillOnce(Return(session));
194 EXPECT_CALL(blobMock, commit(session, _))
195 .WillOnce(Throw(ipmiblob::BlobException("asdf")));
196 EXPECT_CALL(blobMock, closeBlob(session));
197
198 updater.cleanArtifacts();
199}
200
201TEST_F(UpdateHandlerTest, CleanArtifactsSuccessPath)
202{
203 std::uint16_t session = 0xa5eb;
204 EXPECT_CALL(blobMock, openBlob(ipmi_flash::cleanupBlobId, _))
205 .WillOnce(Return(session));
206 EXPECT_CALL(blobMock, commit(session, _));
207 EXPECT_CALL(blobMock, closeBlob(session));
208
209 updater.cleanArtifacts();
210}
211
Patrick Venture1f09d412019-06-19 16:01:06 -0700212class UpdaterTest : public ::testing::Test
213{
214 protected:
Patrick Venture8cdf9642020-09-30 09:41:51 -0700215 static constexpr char image[] = "image.bin";
216 static constexpr char signature[] = "signature.bin";
217 static constexpr char layout[] = "static";
218 static constexpr char path[] = "/flash/static";
219
Patrick Venture1f09d412019-06-19 16:01:06 -0700220 ipmiblob::BlobInterfaceMock blobMock;
221 std::uint16_t session = 0xbeef;
Brandon Kim6749ba12019-09-19 13:31:37 -0700222 bool defaultIgnore = false;
Patrick Venture1f09d412019-06-19 16:01:06 -0700223};
224
Patrick Venture1f09d412019-06-19 16:01:06 -0700225TEST_F(UpdaterTest, UpdateMainReturnsSuccessIfAllSuccess)
226{
Patrick Venture1f09d412019-06-19 16:01:06 -0700227 UpdateHandlerMock handler;
228
Patrick Venture8cdf9642020-09-30 09:41:51 -0700229 EXPECT_CALL(handler, checkAvailable(path)).WillOnce(Return(true));
230 EXPECT_CALL(handler, sendFile(path, image)).WillOnce(Return());
231 EXPECT_CALL(handler, sendFile(ipmi_flash::hashBlobId, signature))
232 .WillOnce(Return());
Brandon Kim6749ba12019-09-19 13:31:37 -0700233 EXPECT_CALL(handler, verifyFile(ipmi_flash::verifyBlobId, defaultIgnore))
Patrick Venture1f09d412019-06-19 16:01:06 -0700234 .WillOnce(Return(true));
Brandon Kim6749ba12019-09-19 13:31:37 -0700235 EXPECT_CALL(handler, verifyFile(ipmi_flash::updateBlobId, defaultIgnore))
Patrick Venture1f09d412019-06-19 16:01:06 -0700236 .WillOnce(Return(true));
237
Patrick Venture8cdf9642020-09-30 09:41:51 -0700238 updaterMain(&handler, image, signature, layout, defaultIgnore);
Brandon Kim6749ba12019-09-19 13:31:37 -0700239}
240
241TEST_F(UpdaterTest, UpdateMainReturnsSuccessWithIgnoreUpdate)
242{
Brandon Kim6749ba12019-09-19 13:31:37 -0700243 UpdateHandlerMock handler;
244 bool updateIgnore = true;
245
Patrick Venture8cdf9642020-09-30 09:41:51 -0700246 EXPECT_CALL(handler, checkAvailable(path)).WillOnce(Return(true));
247 EXPECT_CALL(handler, sendFile(path, image)).WillOnce(Return());
248 EXPECT_CALL(handler, sendFile(ipmi_flash::hashBlobId, signature))
249 .WillOnce(Return());
Brandon Kim6749ba12019-09-19 13:31:37 -0700250 EXPECT_CALL(handler, verifyFile(ipmi_flash::verifyBlobId, defaultIgnore))
251 .WillOnce(Return(true));
252 EXPECT_CALL(handler, verifyFile(ipmi_flash::updateBlobId, updateIgnore))
253 .WillOnce(Return(true));
254
Patrick Venture8cdf9642020-09-30 09:41:51 -0700255 updaterMain(&handler, image, signature, layout, updateIgnore);
Patrick Venture1f09d412019-06-19 16:01:06 -0700256}
Patrick Venture9b534f02018-12-13 16:10:02 -0800257
Patrick Venture5f2fcc42019-06-20 07:21:05 -0700258TEST_F(UpdaterTest, UpdateMainCleansUpOnFailure)
259{
Patrick Venture5f2fcc42019-06-20 07:21:05 -0700260 UpdateHandlerMock handler;
261
Patrick Venture8cdf9642020-09-30 09:41:51 -0700262 EXPECT_CALL(handler, checkAvailable(path)).WillOnce(Return(true));
263 EXPECT_CALL(handler, sendFile(path, image)).WillOnce(Return());
264 EXPECT_CALL(handler, sendFile(ipmi_flash::hashBlobId, signature))
265 .WillOnce(Return());
Brandon Kim6749ba12019-09-19 13:31:37 -0700266 EXPECT_CALL(handler, verifyFile(ipmi_flash::verifyBlobId, defaultIgnore))
Patrick Venture5f2fcc42019-06-20 07:21:05 -0700267 .WillOnce(Return(false));
268 EXPECT_CALL(handler, cleanArtifacts()).WillOnce(Return());
269
Patrick Venture8cdf9642020-09-30 09:41:51 -0700270 EXPECT_THROW(updaterMain(&handler, image, signature, layout, defaultIgnore),
271 ToolException);
272}
273
274TEST_F(UpdaterTest, UpdateMainExceptsOnUpdateBlobFailure)
275{
276 UpdateHandlerMock handler;
277
278 EXPECT_CALL(handler, checkAvailable(path)).WillOnce(Return(true));
279 EXPECT_CALL(handler, sendFile(path, image)).WillOnce(Return());
280 EXPECT_CALL(handler, sendFile(ipmi_flash::hashBlobId, signature))
281 .WillOnce(Return());
282 EXPECT_CALL(handler, verifyFile(ipmi_flash::verifyBlobId, defaultIgnore))
283 .WillOnce(Return(true));
284 EXPECT_CALL(handler, verifyFile(ipmi_flash::updateBlobId, defaultIgnore))
285 .WillOnce(Return(false));
286 EXPECT_CALL(handler, cleanArtifacts()).WillOnce(Return());
287
288 EXPECT_THROW(updaterMain(&handler, image, signature, layout, defaultIgnore),
289 ToolException);
290}
291
292TEST_F(UpdaterTest, UpdateMainExceptsIfAvailableNotFound)
293{
294 UpdateHandlerMock handler;
295
296 EXPECT_CALL(handler, checkAvailable(path)).WillOnce(Return(false));
297
298 EXPECT_THROW(updaterMain(&handler, image, signature, layout, defaultIgnore),
299 ToolException);
Patrick Venture5f2fcc42019-06-20 07:21:05 -0700300}
301
Patrick Venture9b534f02018-12-13 16:10:02 -0800302} // namespace host_tool