blob: e9f2c9624676a75e186b14e1dcc7c2be64a1e936 [file] [log] [blame]
Patrick Venture786a5412019-05-13 07:40:22 -07001#include <cstdint>
Patrick Venture123b5c02019-03-05 14:01:00 -08002#include <ipmiblob/blob_handler.hpp>
Patrick Venture1681f7f2019-03-07 12:59:29 -08003#include <ipmiblob/test/crc_mock.hpp>
Patrick Venture123b5c02019-03-05 14:01:00 -08004#include <ipmiblob/test/ipmi_interface_mock.hpp>
Patrick Venture786a5412019-05-13 07:40:22 -07005#include <memory>
6#include <vector>
Patrick Venture123b5c02019-03-05 14:01:00 -08007
8#include <gtest/gtest.h>
9
Patrick Venture1470bec2019-03-06 07:33:12 -080010namespace ipmiblob
Patrick Venture123b5c02019-03-05 14:01:00 -080011{
12CrcInterface* crcIntf = nullptr;
13
14std::uint16_t generateCrc(const std::vector<std::uint8_t>& data)
15{
16 return (crcIntf) ? crcIntf->generateCrc(data) : 0x00;
17}
18
19using ::testing::Eq;
20using ::testing::Return;
21
22class BlobHandlerTest : public ::testing::Test
23{
24 protected:
25 void SetUp() override
26 {
27 crcIntf = &crcMock;
28 }
29
30 CrcMock crcMock;
Patrick Venture786a5412019-05-13 07:40:22 -070031
32 std::unique_ptr<IpmiInterface> CreateIpmiMock()
33 {
34 return std::make_unique<IpmiInterfaceMock>();
35 }
Patrick Venture123b5c02019-03-05 14:01:00 -080036};
37
38TEST_F(BlobHandlerTest, getCountIpmiHappy)
39{
40 /* Verify returns the value specified by the IPMI response. */
Patrick Venture786a5412019-05-13 07:40:22 -070041 auto ipmi = CreateIpmiMock();
42 IpmiInterfaceMock* ipmiMock =
43 reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
44 BlobHandler blob(std::move(ipmi));
45
Patrick Venture123b5c02019-03-05 14:01:00 -080046 std::vector<std::uint8_t> request = {
47 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobGetCount};
48
49 /* return 1 blob count. */
50 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
51 0x01, 0x00, 0x00, 0x00};
52
53 std::vector<std::uint8_t> bytes = {0x01, 0x00, 0x00, 0x00};
54 EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
55
Patrick Venture786a5412019-05-13 07:40:22 -070056 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
Patrick Venture123b5c02019-03-05 14:01:00 -080057 EXPECT_EQ(1, blob.getBlobCount());
58}
59
60TEST_F(BlobHandlerTest, enumerateBlobIpmiHappy)
61{
62 /* Verify returns the name specified by the IPMI response. */
Patrick Venture786a5412019-05-13 07:40:22 -070063 auto ipmi = CreateIpmiMock();
64 IpmiInterfaceMock* ipmiMock =
65 reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
66 BlobHandler blob(std::move(ipmi));
67
Patrick Venture123b5c02019-03-05 14:01:00 -080068 std::vector<std::uint8_t> request = {
69 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
70 0x00, 0x00, 0x01, 0x00,
71 0x00, 0x00};
72
73 /* return value. */
74 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
75 'a', 'b', 'c', 'd', 0x00};
76
77 std::vector<std::uint8_t> bytes = {'a', 'b', 'c', 'd', 0x00};
78 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00};
79 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
80 EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
81
Patrick Venture786a5412019-05-13 07:40:22 -070082 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
Patrick Venture123b5c02019-03-05 14:01:00 -080083 EXPECT_STREQ("abcd", blob.enumerateBlob(1).c_str());
84}
85
86TEST_F(BlobHandlerTest, enumerateBlobIpmiNoBytes)
87{
88 /* Simulate a case where the IPMI command returns no data. */
Patrick Venture786a5412019-05-13 07:40:22 -070089 auto ipmi = CreateIpmiMock();
90 IpmiInterfaceMock* ipmiMock =
91 reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
92 BlobHandler blob(std::move(ipmi));
93
Patrick Venture123b5c02019-03-05 14:01:00 -080094 std::vector<std::uint8_t> request = {
95 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
96 0x00, 0x00, 0x01, 0x00,
97 0x00, 0x00};
98
99 /* return value. */
100 std::vector<std::uint8_t> resp = {};
101
102 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00};
103 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
104
Patrick Venture786a5412019-05-13 07:40:22 -0700105 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
Patrick Venture123b5c02019-03-05 14:01:00 -0800106 EXPECT_STREQ("", blob.enumerateBlob(1).c_str());
107}
108
109TEST_F(BlobHandlerTest, getBlobListIpmiHappy)
110{
111 /* Verify returns the list built via the above two commands. */
Patrick Venture786a5412019-05-13 07:40:22 -0700112 auto ipmi = CreateIpmiMock();
113 IpmiInterfaceMock* ipmiMock =
114 reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
115 BlobHandler blob(std::move(ipmi));
Patrick Venture123b5c02019-03-05 14:01:00 -0800116
117 std::vector<std::uint8_t> request1 = {
118 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobGetCount};
119
120 /* return 1 blob count. */
121 std::vector<std::uint8_t> resp1 = {0xcf, 0xc2, 0x00, 0x00, 0x00,
122 0x01, 0x00, 0x00, 0x00};
123
124 std::vector<std::uint8_t> bytes1 = {0x01, 0x00, 0x00, 0x00};
125 EXPECT_CALL(crcMock, generateCrc(Eq(bytes1))).WillOnce(Return(0x00));
126
Patrick Venture786a5412019-05-13 07:40:22 -0700127 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request1))).WillOnce(Return(resp1));
Patrick Venture123b5c02019-03-05 14:01:00 -0800128
129 std::vector<std::uint8_t> request2 = {
130 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
131 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00};
133
134 /* return value. */
135 std::vector<std::uint8_t> resp2 = {0xcf, 0xc2, 0x00, 0x00, 0x00,
136 'a', 'b', 'c', 'd', 0x00};
137
138 std::vector<std::uint8_t> reqCrc = {0x00, 0x00, 0x00, 0x00};
139 std::vector<std::uint8_t> bytes2 = {'a', 'b', 'c', 'd', 0x00};
140 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
141 EXPECT_CALL(crcMock, generateCrc(Eq(bytes2))).WillOnce(Return(0x00));
142
Patrick Venture786a5412019-05-13 07:40:22 -0700143 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request2))).WillOnce(Return(resp2));
Patrick Venture123b5c02019-03-05 14:01:00 -0800144
145 /* A std::string is not nul-terminated by default. */
146 std::vector<std::string> expectedList = {std::string{"abcd"}};
147
148 EXPECT_EQ(expectedList, blob.getBlobList());
149}
150
151TEST_F(BlobHandlerTest, getStatWithMetadata)
152{
153 /* Stat received metadata. */
Patrick Venture786a5412019-05-13 07:40:22 -0700154 auto ipmi = CreateIpmiMock();
155 IpmiInterfaceMock* ipmiMock =
156 reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
157 BlobHandler blob(std::move(ipmi));
158
Patrick Venture123b5c02019-03-05 14:01:00 -0800159 std::vector<std::uint8_t> request = {
160 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobStat,
161 0x00, 0x00, 'a', 'b',
162 'c', 'd', 0x00};
163
164 /* return blob_state: 0xffff, size: 0x00, metadata 0x3445 */
165 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xff, 0xff,
166 0x00, 0x00, 0x00, 0x00, 0x02, 0x34, 0x45};
167
168 std::vector<std::uint8_t> reqCrc = {'a', 'b', 'c', 'd', 0x00};
169 std::vector<std::uint8_t> respCrc = {0xff, 0xff, 0x00, 0x00, 0x00,
170 0x00, 0x02, 0x34, 0x45};
171 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
172 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
173
Patrick Venture786a5412019-05-13 07:40:22 -0700174 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
Patrick Venture123b5c02019-03-05 14:01:00 -0800175
176 auto meta = blob.getStat("abcd");
177 EXPECT_EQ(meta.blob_state, 0xffff);
178 EXPECT_EQ(meta.size, 0x00);
179 std::vector<std::uint8_t> metadata = {0x34, 0x45};
180 EXPECT_EQ(metadata, meta.metadata);
181}
182
183TEST_F(BlobHandlerTest, getStatNoMetadata)
184{
185 /* Stat received no metadata. */
Patrick Venture786a5412019-05-13 07:40:22 -0700186 auto ipmi = CreateIpmiMock();
187 IpmiInterfaceMock* ipmiMock =
188 reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
189 BlobHandler blob(std::move(ipmi));
190
Patrick Venture123b5c02019-03-05 14:01:00 -0800191 std::vector<std::uint8_t> request = {
192 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobStat,
193 0x00, 0x00, 'a', 'b',
194 'c', 'd', 0x00};
195
196 /* return blob_state: 0xffff, size: 0x00, metadata 0x3445 */
197 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xff,
198 0xff, 0x00, 0x00, 0x00, 0x00, 0x00};
199
200 std::vector<std::uint8_t> reqCrc = {'a', 'b', 'c', 'd', 0x00};
201 std::vector<std::uint8_t> respCrc = {0xff, 0xff, 0x00, 0x00,
202 0x00, 0x00, 0x00};
203
204 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
205 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
206
Patrick Venture786a5412019-05-13 07:40:22 -0700207 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
Patrick Venture123b5c02019-03-05 14:01:00 -0800208
209 auto meta = blob.getStat("abcd");
210 EXPECT_EQ(meta.blob_state, 0xffff);
211 EXPECT_EQ(meta.size, 0x00);
212 std::vector<std::uint8_t> metadata = {};
213 EXPECT_EQ(metadata, meta.metadata);
214}
215
Patrick Venture16a99a62019-05-03 17:21:30 -0700216TEST_F(BlobHandlerTest, getSessionStatNoMetadata)
217{
218 /* The get session stat succeeds. */
Patrick Venture786a5412019-05-13 07:40:22 -0700219 auto ipmi = CreateIpmiMock();
220 IpmiInterfaceMock* ipmiMock =
221 reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
222 BlobHandler blob(std::move(ipmi));
Patrick Venture16a99a62019-05-03 17:21:30 -0700223
224 std::vector<std::uint8_t> request = {
225 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobSessionStat,
226 0x00, 0x00, 0x01, 0x00};
227
228 /* return blob_state: 0xffff, size: 0x00, metadata 0x3445 */
229 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xff,
230 0xff, 0x00, 0x00, 0x00, 0x00, 0x00};
231
232 std::vector<std::uint8_t> reqCrc = {0x01, 0x00};
233 std::vector<std::uint8_t> respCrc = {0xff, 0xff, 0x00, 0x00,
234 0x00, 0x00, 0x00};
235
236 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
237 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
238
Patrick Venture786a5412019-05-13 07:40:22 -0700239 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
Patrick Venture16a99a62019-05-03 17:21:30 -0700240
241 auto meta = blob.getStat(0x0001);
242 EXPECT_EQ(meta.blob_state, 0xffff);
243 EXPECT_EQ(meta.size, 0x00);
244 std::vector<std::uint8_t> metadata = {};
245 EXPECT_EQ(metadata, meta.metadata);
246}
247
Patrick Venture123b5c02019-03-05 14:01:00 -0800248TEST_F(BlobHandlerTest, openBlobSucceeds)
249{
250 /* The open blob succeeds. */
Patrick Venture786a5412019-05-13 07:40:22 -0700251 auto ipmi = CreateIpmiMock();
252 IpmiInterfaceMock* ipmiMock =
253 reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
254 BlobHandler blob(std::move(ipmi));
Patrick Venture123b5c02019-03-05 14:01:00 -0800255
256 std::vector<std::uint8_t> request = {
257 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobOpen,
258 0x00, 0x00, 0x02, 0x04,
259 'a', 'b', 'c', 'd',
260 0x00};
261
262 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xfe, 0xed};
263
264 std::vector<std::uint8_t> reqCrc = {0x02, 0x04, 'a', 'b', 'c', 'd', 0x00};
265 std::vector<std::uint8_t> respCrc = {0xfe, 0xed};
266 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
267 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
268
Patrick Venture786a5412019-05-13 07:40:22 -0700269 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
Patrick Venture123b5c02019-03-05 14:01:00 -0800270
271 const int writeBit = (1 << 1);
272 const int lpcBit = (1 << 10);
273
274 auto session = blob.openBlob("abcd", writeBit | lpcBit);
275 EXPECT_EQ(0xedfe, session);
276}
277
278TEST_F(BlobHandlerTest, closeBlobSucceeds)
279{
280 /* The close succeeds. */
Patrick Venture786a5412019-05-13 07:40:22 -0700281 auto ipmi = CreateIpmiMock();
282 IpmiInterfaceMock* ipmiMock =
283 reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
284 BlobHandler blob(std::move(ipmi));
Patrick Venture123b5c02019-03-05 14:01:00 -0800285
286 std::vector<std::uint8_t> request = {
287 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobClose,
288 0x00, 0x00, 0x01, 0x00};
289 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00};
290 std::vector<std::uint8_t> reqCrc = {0x01, 0x00};
291 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
292
Patrick Venture786a5412019-05-13 07:40:22 -0700293 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
Patrick Venture123b5c02019-03-05 14:01:00 -0800294
295 blob.closeBlob(0x0001);
296}
297
Patrick Venture8865e402019-05-14 13:29:10 -0700298TEST_F(BlobHandlerTest, commitSucceedsNoData)
299{
300 /* The commit succeeds. */
301 auto ipmi = CreateIpmiMock();
302 IpmiInterfaceMock* ipmiMock =
303 reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
304 BlobHandler blob(std::move(ipmi));
305
306 std::vector<std::uint8_t> request = {
307 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobCommit,
308 0x00, 0x00, 0x01, 0x00,
309 0x00};
310
311 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00};
312 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00};
313 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
314
315 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
316
317 blob.commit(0x0001, {});
318}
319
Patrick Venture123b5c02019-03-05 14:01:00 -0800320TEST_F(BlobHandlerTest, writeBytesSucceeds)
321{
322 /* The write bytes succeeds. */
Patrick Venture786a5412019-05-13 07:40:22 -0700323 auto ipmi = CreateIpmiMock();
324 IpmiInterfaceMock* ipmiMock =
325 reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
326 BlobHandler blob(std::move(ipmi));
Patrick Venture123b5c02019-03-05 14:01:00 -0800327
328 std::vector<std::uint8_t> request = {
329 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobWrite,
330 0x00, 0x00, 0x01, 0x00,
331 0x00, 0x00, 0x00, 0x00,
332 'a', 'b', 'c', 'd'};
333
334 std::vector<std::uint8_t> bytes = {'a', 'b', 'c', 'd'};
335 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00};
336 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00, 0x00,
337 0x00, 'a', 'b', 'c', 'd'};
338 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
339
Patrick Venture786a5412019-05-13 07:40:22 -0700340 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
Patrick Venture123b5c02019-03-05 14:01:00 -0800341
342 blob.writeBytes(0x0001, 0, bytes);
343}
344
345TEST_F(BlobHandlerTest, readBytesSucceeds)
346{
347 /* The reading of bytes succeeds. */
Patrick Venture786a5412019-05-13 07:40:22 -0700348 auto ipmi = CreateIpmiMock();
349 IpmiInterfaceMock* ipmiMock =
350 reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
351 BlobHandler blob(std::move(ipmi));
Patrick Venture123b5c02019-03-05 14:01:00 -0800352
353 std::vector<std::uint8_t> request = {
354 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobRead,
355 0x00, 0x00, 0x01, 0x00,
356 0x00, 0x00, 0x00, 0x00,
357 0x04, 0x00, 0x00, 0x00};
358
359 std::vector<std::uint8_t> expectedBytes = {'a', 'b', 'c', 'd'};
360 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
361 'a', 'b', 'c', 'd'};
362 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00, 0x00,
363 0x00, 0x04, 0x00, 0x00, 0x00};
364 std::vector<std::uint8_t> respCrc = {'a', 'b', 'c', 'd'};
365
366 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
367 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
368
Patrick Venture786a5412019-05-13 07:40:22 -0700369 EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
Patrick Venture123b5c02019-03-05 14:01:00 -0800370
371 EXPECT_EQ(blob.readBytes(0x0001, 0, 4), expectedBytes);
372}
373
Patrick Venture1470bec2019-03-06 07:33:12 -0800374} // namespace ipmiblob