blob: a51eb25a8bd9fcad6c594e52426a346fb1088a97 [file] [log] [blame]
Patrick Venturec79faa12018-12-12 13:12:21 -08001#include "blob_handler.hpp"
Patrick Venturebcec9c62018-12-14 13:58:41 -08002#include "crc_mock.hpp"
Patrick Venturec79faa12018-12-12 13:12:21 -08003#include "ipmi_interface_mock.hpp"
4
5#include <gtest/gtest.h>
6
Patrick Venture9b534f02018-12-13 16:10:02 -08007namespace host_tool
8{
Patrick Venturebcec9c62018-12-14 13:58:41 -08009CrcInterface* crcIntf = nullptr;
Patrick Venturec79faa12018-12-12 13:12:21 -080010
11std::uint16_t generateCrc(const std::vector<std::uint8_t>& data)
12{
Patrick Venturebcec9c62018-12-14 13:58:41 -080013 return (crcIntf) ? crcIntf->generateCrc(data) : 0x00;
Patrick Venturec79faa12018-12-12 13:12:21 -080014}
15
16using ::testing::Eq;
17using ::testing::Return;
18
Patrick Venturebcec9c62018-12-14 13:58:41 -080019class BlobHandlerTest : public ::testing::Test
20{
21 protected:
22 void SetUp() override
23 {
24 crcIntf = &crcMock;
25 }
26
27 CrcMock crcMock;
28};
29
30TEST_F(BlobHandlerTest, getCountIpmiHappy)
Patrick Venturec79faa12018-12-12 13:12:21 -080031{
32 /* Verify returns the value specified by the IPMI response. */
33 IpmiInterfaceMock ipmiMock;
34 BlobHandler blob(&ipmiMock);
35 std::vector<std::uint8_t> request = {
36 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobGetCount};
37
38 /* return 1 blob count. */
39 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
40 0x01, 0x00, 0x00, 0x00};
41
Patrick Venturebcec9c62018-12-14 13:58:41 -080042 std::vector<std::uint8_t> bytes = {0x01, 0x00, 0x00, 0x00};
43 EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
44
Patrick Venturec79faa12018-12-12 13:12:21 -080045 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
46 EXPECT_EQ(1, blob.getBlobCount());
47}
48
Patrick Venturebcec9c62018-12-14 13:58:41 -080049TEST_F(BlobHandlerTest, enumerateBlobIpmiHappy)
Patrick Venturec79faa12018-12-12 13:12:21 -080050{
51 /* Verify returns the name specified by the IPMI response. */
52 IpmiInterfaceMock ipmiMock;
53 BlobHandler blob(&ipmiMock);
54 std::vector<std::uint8_t> request = {
55 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
56 0x00, 0x00, 0x01, 0x00,
57 0x00, 0x00};
58
59 /* return value. */
60 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
Patrick Venture86ef75d2018-12-19 15:59:03 -080061 'a', 'b', 'c', 'd', 0x00};
Patrick Venturec79faa12018-12-12 13:12:21 -080062
Patrick Venturebcec9c62018-12-14 13:58:41 -080063 std::vector<std::uint8_t> bytes = {'a', 'b', 'c', 'd', 0x00};
64 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00};
65 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
66 EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
67
Patrick Venturec79faa12018-12-12 13:12:21 -080068 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
69 EXPECT_STREQ("abcd", blob.enumerateBlob(1).c_str());
70}
71
Patrick Venturebcec9c62018-12-14 13:58:41 -080072TEST_F(BlobHandlerTest, enumerateBlobIpmiNoBytes)
Patrick Venturec79faa12018-12-12 13:12:21 -080073{
74 /* Simulate a case where the IPMI command returns no data. */
75 IpmiInterfaceMock ipmiMock;
76 BlobHandler blob(&ipmiMock);
77 std::vector<std::uint8_t> request = {
78 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
79 0x00, 0x00, 0x01, 0x00,
80 0x00, 0x00};
81
82 /* return value. */
83 std::vector<std::uint8_t> resp = {};
84
Patrick Venturebcec9c62018-12-14 13:58:41 -080085 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00};
86 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
87
Patrick Venturec79faa12018-12-12 13:12:21 -080088 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
89 EXPECT_STREQ("", blob.enumerateBlob(1).c_str());
90}
91
Patrick Venturebcec9c62018-12-14 13:58:41 -080092TEST_F(BlobHandlerTest, getBlobListIpmiHappy)
Patrick Venturec79faa12018-12-12 13:12:21 -080093{
94 /* Verify returns the list built via the above two commands. */
95 IpmiInterfaceMock ipmiMock;
96 BlobHandler blob(&ipmiMock);
97
98 std::vector<std::uint8_t> request1 = {
99 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobGetCount};
100
101 /* return 1 blob count. */
102 std::vector<std::uint8_t> resp1 = {0xcf, 0xc2, 0x00, 0x00, 0x00,
103 0x01, 0x00, 0x00, 0x00};
104
Patrick Venturebcec9c62018-12-14 13:58:41 -0800105 std::vector<std::uint8_t> bytes1 = {0x01, 0x00, 0x00, 0x00};
106 EXPECT_CALL(crcMock, generateCrc(Eq(bytes1))).WillOnce(Return(0x00));
107
Patrick Venturec79faa12018-12-12 13:12:21 -0800108 EXPECT_CALL(ipmiMock, sendPacket(Eq(request1))).WillOnce(Return(resp1));
109
110 std::vector<std::uint8_t> request2 = {
111 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
112 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00};
114
115 /* return value. */
116 std::vector<std::uint8_t> resp2 = {0xcf, 0xc2, 0x00, 0x00, 0x00,
Patrick Venture86ef75d2018-12-19 15:59:03 -0800117 'a', 'b', 'c', 'd', 0x00};
Patrick Venturec79faa12018-12-12 13:12:21 -0800118
Patrick Venturebcec9c62018-12-14 13:58:41 -0800119 std::vector<std::uint8_t> reqCrc = {0x00, 0x00, 0x00, 0x00};
120 std::vector<std::uint8_t> bytes2 = {'a', 'b', 'c', 'd', 0x00};
121 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
122 EXPECT_CALL(crcMock, generateCrc(Eq(bytes2))).WillOnce(Return(0x00));
123
Patrick Venturec79faa12018-12-12 13:12:21 -0800124 EXPECT_CALL(ipmiMock, sendPacket(Eq(request2))).WillOnce(Return(resp2));
125
Patrick Venture86ef75d2018-12-19 15:59:03 -0800126 /* A std::string is not nul-terminated by default. */
127 std::vector<std::string> expectedList = {std::string{"abcd"}};
Patrick Venturec79faa12018-12-12 13:12:21 -0800128
129 EXPECT_EQ(expectedList, blob.getBlobList());
130}
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800131
Patrick Venturebcec9c62018-12-14 13:58:41 -0800132TEST_F(BlobHandlerTest, getStatWithMetadata)
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800133{
134 /* Stat received metadata. */
135 IpmiInterfaceMock ipmiMock;
136 BlobHandler blob(&ipmiMock);
137 std::vector<std::uint8_t> request = {
138 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobStat,
139 0x00, 0x00, 'a', 'b',
Patrick Venture0d88a122018-12-17 07:52:04 -0800140 'c', 'd', 0x00};
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800141
142 /* return blob_state: 0xffff, size: 0x00, metadata 0x3445 */
143 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xff, 0xff,
144 0x00, 0x00, 0x00, 0x00, 0x02, 0x34, 0x45};
145
Patrick Venturebcec9c62018-12-14 13:58:41 -0800146 std::vector<std::uint8_t> reqCrc = {'a', 'b', 'c', 'd', 0x00};
147 std::vector<std::uint8_t> respCrc = {0xff, 0xff, 0x00, 0x00, 0x00,
148 0x00, 0x02, 0x34, 0x45};
149 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
150 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
151
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800152 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
153
154 auto meta = blob.getStat("abcd");
155 EXPECT_EQ(meta.blob_state, 0xffff);
156 EXPECT_EQ(meta.size, 0x00);
157 std::vector<std::uint8_t> metadata = {0x34, 0x45};
158 EXPECT_EQ(metadata, meta.metadata);
159}
160
Patrick Venturebcec9c62018-12-14 13:58:41 -0800161TEST_F(BlobHandlerTest, getStatNoMetadata)
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800162{
163 /* Stat received no metadata. */
164 IpmiInterfaceMock ipmiMock;
165 BlobHandler blob(&ipmiMock);
166 std::vector<std::uint8_t> request = {
167 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobStat,
168 0x00, 0x00, 'a', 'b',
Patrick Venture0d88a122018-12-17 07:52:04 -0800169 'c', 'd', 0x00};
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800170
171 /* return blob_state: 0xffff, size: 0x00, metadata 0x3445 */
172 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xff,
173 0xff, 0x00, 0x00, 0x00, 0x00, 0x00};
174
Patrick Venturebcec9c62018-12-14 13:58:41 -0800175 std::vector<std::uint8_t> reqCrc = {'a', 'b', 'c', 'd', 0x00};
176 std::vector<std::uint8_t> respCrc = {0xff, 0xff, 0x00, 0x00,
177 0x00, 0x00, 0x00};
178
179 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
180 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
181
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800182 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
183
184 auto meta = blob.getStat("abcd");
185 EXPECT_EQ(meta.blob_state, 0xffff);
186 EXPECT_EQ(meta.size, 0x00);
187 std::vector<std::uint8_t> metadata = {};
188 EXPECT_EQ(metadata, meta.metadata);
189}
Patrick Venture0533d0b2018-12-13 08:48:24 -0800190
Patrick Venturebcec9c62018-12-14 13:58:41 -0800191TEST_F(BlobHandlerTest, openBlobSucceeds)
Patrick Venture0533d0b2018-12-13 08:48:24 -0800192{
193 /* The open blob succeeds. */
194 IpmiInterfaceMock ipmiMock;
195 BlobHandler blob(&ipmiMock);
196
197 std::vector<std::uint8_t> request = {
198 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobOpen,
199 0x00, 0x00, 0x02, 0x04,
Patrick Venture0d88a122018-12-17 07:52:04 -0800200 'a', 'b', 'c', 'd',
201 0x00};
Patrick Venture0533d0b2018-12-13 08:48:24 -0800202
203 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xfe, 0xed};
204
Patrick Venturebcec9c62018-12-14 13:58:41 -0800205 std::vector<std::uint8_t> reqCrc = {0x02, 0x04, 'a', 'b', 'c', 'd', 0x00};
206 std::vector<std::uint8_t> respCrc = {0xfe, 0xed};
207 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
208 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
209
Patrick Venture0533d0b2018-12-13 08:48:24 -0800210 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
211
212 auto session =
213 blob.openBlob("abcd", blobs::FirmwareBlobHandler::UpdateFlags::lpc);
214 EXPECT_EQ(0xedfe, session);
215}
Patrick Venture9b534f02018-12-13 16:10:02 -0800216
Patrick Venture13e49862019-01-24 11:43:13 -0800217TEST_F(BlobHandlerTest, closeBlobSucceeds)
218{
219 /* The close succeeds. */
220 IpmiInterfaceMock ipmiMock;
221 BlobHandler blob(&ipmiMock);
222
223 std::vector<std::uint8_t> request = {
224 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobClose,
225 0x00, 0x00, 0x01, 0x00};
226 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00};
227 std::vector<std::uint8_t> reqCrc = {0x01, 0x00};
228 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
229
230 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
231
232 blob.closeBlob(0x0001);
233}
234
Patrick Venture0309f102019-01-15 13:41:05 -0800235TEST_F(BlobHandlerTest, writeBytesSucceeds)
236{
237 /* The write bytes succeeds. */
238 IpmiInterfaceMock ipmiMock;
239 BlobHandler blob(&ipmiMock);
240
241 std::vector<std::uint8_t> request = {
242 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobWrite,
243 0x00, 0x00, 0x01, 0x00,
244 0x00, 0x00, 0x00, 0x00,
245 'a', 'b', 'c', 'd'};
246
247 std::vector<std::uint8_t> bytes = {'a', 'b', 'c', 'd'};
248 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00};
249 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00, 0x00,
250 0x00, 'a', 'b', 'c', 'd'};
251 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
252
253 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
254
255 blob.writeBytes(0x0001, 0, bytes);
256}
257
Patrick Venture957f0862019-02-01 14:40:06 -0800258TEST_F(BlobHandlerTest, readBytesSucceeds)
259{
260 /* The reading of bytes succeeds. */
261
262 IpmiInterfaceMock ipmiMock;
263 BlobHandler blob(&ipmiMock);
264
265 std::vector<std::uint8_t> request = {
266 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobRead,
267 0x00, 0x00, 0x01, 0x00,
268 0x00, 0x00, 0x00, 0x00,
269 0x04, 0x00, 0x00, 0x00};
270
271 std::vector<std::uint8_t> expectedBytes = {'a', 'b', 'c', 'd'};
272 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
273 'a', 'b', 'c', 'd'};
274 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x04, 0x00, 0x00, 0x00};
276 std::vector<std::uint8_t> respCrc = {'a', 'b', 'c', 'd'};
277
278 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
279 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
280
281 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
282
283 EXPECT_EQ(blob.readBytes(0x0001, 0, 4), expectedBytes);
284}
285
Patrick Venture9b534f02018-12-13 16:10:02 -0800286} // namespace host_tool