blob: e958630b73b9d51a7ee4a4109e05f14610bb7152 [file] [log] [blame]
Patrick Venture123b5c02019-03-05 14:01:00 -08001#include <ipmiblob/blob_handler.hpp>
Patrick Venture1681f7f2019-03-07 12:59:29 -08002#include <ipmiblob/test/crc_mock.hpp>
Patrick Venture123b5c02019-03-05 14:01:00 -08003#include <ipmiblob/test/ipmi_interface_mock.hpp>
4
5#include <gtest/gtest.h>
6
Patrick Venture1470bec2019-03-06 07:33:12 -08007namespace ipmiblob
Patrick Venture123b5c02019-03-05 14:01:00 -08008{
9CrcInterface* crcIntf = nullptr;
10
11std::uint16_t generateCrc(const std::vector<std::uint8_t>& data)
12{
13 return (crcIntf) ? crcIntf->generateCrc(data) : 0x00;
14}
15
16using ::testing::Eq;
17using ::testing::Return;
18
19class 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)
31{
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
42 std::vector<std::uint8_t> bytes = {0x01, 0x00, 0x00, 0x00};
43 EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
44
45 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
46 EXPECT_EQ(1, blob.getBlobCount());
47}
48
49TEST_F(BlobHandlerTest, enumerateBlobIpmiHappy)
50{
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,
61 'a', 'b', 'c', 'd', 0x00};
62
63 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
68 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
69 EXPECT_STREQ("abcd", blob.enumerateBlob(1).c_str());
70}
71
72TEST_F(BlobHandlerTest, enumerateBlobIpmiNoBytes)
73{
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
85 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00};
86 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
87
88 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
89 EXPECT_STREQ("", blob.enumerateBlob(1).c_str());
90}
91
92TEST_F(BlobHandlerTest, getBlobListIpmiHappy)
93{
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
105 std::vector<std::uint8_t> bytes1 = {0x01, 0x00, 0x00, 0x00};
106 EXPECT_CALL(crcMock, generateCrc(Eq(bytes1))).WillOnce(Return(0x00));
107
108 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,
117 'a', 'b', 'c', 'd', 0x00};
118
119 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
124 EXPECT_CALL(ipmiMock, sendPacket(Eq(request2))).WillOnce(Return(resp2));
125
126 /* A std::string is not nul-terminated by default. */
127 std::vector<std::string> expectedList = {std::string{"abcd"}};
128
129 EXPECT_EQ(expectedList, blob.getBlobList());
130}
131
132TEST_F(BlobHandlerTest, getStatWithMetadata)
133{
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',
140 'c', 'd', 0x00};
141
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
146 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
152 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
161TEST_F(BlobHandlerTest, getStatNoMetadata)
162{
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',
169 'c', 'd', 0x00};
170
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
175 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
182 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}
190
191TEST_F(BlobHandlerTest, openBlobSucceeds)
192{
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,
200 'a', 'b', 'c', 'd',
201 0x00};
202
203 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xfe, 0xed};
204
205 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
210 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
211
212 const int writeBit = (1 << 1);
213 const int lpcBit = (1 << 10);
214
215 auto session = blob.openBlob("abcd", writeBit | lpcBit);
216 EXPECT_EQ(0xedfe, session);
217}
218
219TEST_F(BlobHandlerTest, closeBlobSucceeds)
220{
221 /* The close succeeds. */
222 IpmiInterfaceMock ipmiMock;
223 BlobHandler blob(&ipmiMock);
224
225 std::vector<std::uint8_t> request = {
226 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobClose,
227 0x00, 0x00, 0x01, 0x00};
228 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00};
229 std::vector<std::uint8_t> reqCrc = {0x01, 0x00};
230 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
231
232 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
233
234 blob.closeBlob(0x0001);
235}
236
237TEST_F(BlobHandlerTest, writeBytesSucceeds)
238{
239 /* The write bytes succeeds. */
240 IpmiInterfaceMock ipmiMock;
241 BlobHandler blob(&ipmiMock);
242
243 std::vector<std::uint8_t> request = {
244 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobWrite,
245 0x00, 0x00, 0x01, 0x00,
246 0x00, 0x00, 0x00, 0x00,
247 'a', 'b', 'c', 'd'};
248
249 std::vector<std::uint8_t> bytes = {'a', 'b', 'c', 'd'};
250 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00};
251 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00, 0x00,
252 0x00, 'a', 'b', 'c', 'd'};
253 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
254
255 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
256
257 blob.writeBytes(0x0001, 0, bytes);
258}
259
260TEST_F(BlobHandlerTest, readBytesSucceeds)
261{
262 /* The reading of bytes succeeds. */
263
264 IpmiInterfaceMock ipmiMock;
265 BlobHandler blob(&ipmiMock);
266
267 std::vector<std::uint8_t> request = {
268 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobRead,
269 0x00, 0x00, 0x01, 0x00,
270 0x00, 0x00, 0x00, 0x00,
271 0x04, 0x00, 0x00, 0x00};
272
273 std::vector<std::uint8_t> expectedBytes = {'a', 'b', 'c', 'd'};
274 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
275 'a', 'b', 'c', 'd'};
276 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00, 0x00,
277 0x00, 0x04, 0x00, 0x00, 0x00};
278 std::vector<std::uint8_t> respCrc = {'a', 'b', 'c', 'd'};
279
280 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
281 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
282
283 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
284
285 EXPECT_EQ(blob.readBytes(0x0001, 0, 4), expectedBytes);
286}
287
Patrick Venture1470bec2019-03-06 07:33:12 -0800288} // namespace ipmiblob