blob: 6e3592014ce722e7117fb88d76d8f00dfb54926a [file] [log] [blame]
Patrick Venture123b5c02019-03-05 14:01:00 -08001#include "crc_mock.hpp"
2
3#include <ipmiblob/blob_handler.hpp>
4#include <ipmiblob/test/ipmi_interface_mock.hpp>
5
6#include <gtest/gtest.h>
7
Patrick Venture1470bec2019-03-06 07:33:12 -08008namespace ipmiblob
Patrick Venture123b5c02019-03-05 14:01:00 -08009{
10CrcInterface* crcIntf = nullptr;
11
12std::uint16_t generateCrc(const std::vector<std::uint8_t>& data)
13{
14 return (crcIntf) ? crcIntf->generateCrc(data) : 0x00;
15}
16
17using ::testing::Eq;
18using ::testing::Return;
19
20class BlobHandlerTest : public ::testing::Test
21{
22 protected:
23 void SetUp() override
24 {
25 crcIntf = &crcMock;
26 }
27
28 CrcMock crcMock;
29};
30
31TEST_F(BlobHandlerTest, getCountIpmiHappy)
32{
33 /* Verify returns the value specified by the IPMI response. */
34 IpmiInterfaceMock ipmiMock;
35 BlobHandler blob(&ipmiMock);
36 std::vector<std::uint8_t> request = {
37 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobGetCount};
38
39 /* return 1 blob count. */
40 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
41 0x01, 0x00, 0x00, 0x00};
42
43 std::vector<std::uint8_t> bytes = {0x01, 0x00, 0x00, 0x00};
44 EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
45
46 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
47 EXPECT_EQ(1, blob.getBlobCount());
48}
49
50TEST_F(BlobHandlerTest, enumerateBlobIpmiHappy)
51{
52 /* Verify returns the name specified by the IPMI response. */
53 IpmiInterfaceMock ipmiMock;
54 BlobHandler blob(&ipmiMock);
55 std::vector<std::uint8_t> request = {
56 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
57 0x00, 0x00, 0x01, 0x00,
58 0x00, 0x00};
59
60 /* return value. */
61 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
62 'a', 'b', 'c', 'd', 0x00};
63
64 std::vector<std::uint8_t> bytes = {'a', 'b', 'c', 'd', 0x00};
65 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00};
66 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
67 EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
68
69 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
70 EXPECT_STREQ("abcd", blob.enumerateBlob(1).c_str());
71}
72
73TEST_F(BlobHandlerTest, enumerateBlobIpmiNoBytes)
74{
75 /* Simulate a case where the IPMI command returns no data. */
76 IpmiInterfaceMock ipmiMock;
77 BlobHandler blob(&ipmiMock);
78 std::vector<std::uint8_t> request = {
79 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
80 0x00, 0x00, 0x01, 0x00,
81 0x00, 0x00};
82
83 /* return value. */
84 std::vector<std::uint8_t> resp = {};
85
86 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00};
87 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
88
89 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
90 EXPECT_STREQ("", blob.enumerateBlob(1).c_str());
91}
92
93TEST_F(BlobHandlerTest, getBlobListIpmiHappy)
94{
95 /* Verify returns the list built via the above two commands. */
96 IpmiInterfaceMock ipmiMock;
97 BlobHandler blob(&ipmiMock);
98
99 std::vector<std::uint8_t> request1 = {
100 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobGetCount};
101
102 /* return 1 blob count. */
103 std::vector<std::uint8_t> resp1 = {0xcf, 0xc2, 0x00, 0x00, 0x00,
104 0x01, 0x00, 0x00, 0x00};
105
106 std::vector<std::uint8_t> bytes1 = {0x01, 0x00, 0x00, 0x00};
107 EXPECT_CALL(crcMock, generateCrc(Eq(bytes1))).WillOnce(Return(0x00));
108
109 EXPECT_CALL(ipmiMock, sendPacket(Eq(request1))).WillOnce(Return(resp1));
110
111 std::vector<std::uint8_t> request2 = {
112 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
113 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00};
115
116 /* return value. */
117 std::vector<std::uint8_t> resp2 = {0xcf, 0xc2, 0x00, 0x00, 0x00,
118 'a', 'b', 'c', 'd', 0x00};
119
120 std::vector<std::uint8_t> reqCrc = {0x00, 0x00, 0x00, 0x00};
121 std::vector<std::uint8_t> bytes2 = {'a', 'b', 'c', 'd', 0x00};
122 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
123 EXPECT_CALL(crcMock, generateCrc(Eq(bytes2))).WillOnce(Return(0x00));
124
125 EXPECT_CALL(ipmiMock, sendPacket(Eq(request2))).WillOnce(Return(resp2));
126
127 /* A std::string is not nul-terminated by default. */
128 std::vector<std::string> expectedList = {std::string{"abcd"}};
129
130 EXPECT_EQ(expectedList, blob.getBlobList());
131}
132
133TEST_F(BlobHandlerTest, getStatWithMetadata)
134{
135 /* Stat received metadata. */
136 IpmiInterfaceMock ipmiMock;
137 BlobHandler blob(&ipmiMock);
138 std::vector<std::uint8_t> request = {
139 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobStat,
140 0x00, 0x00, 'a', 'b',
141 'c', 'd', 0x00};
142
143 /* return blob_state: 0xffff, size: 0x00, metadata 0x3445 */
144 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xff, 0xff,
145 0x00, 0x00, 0x00, 0x00, 0x02, 0x34, 0x45};
146
147 std::vector<std::uint8_t> reqCrc = {'a', 'b', 'c', 'd', 0x00};
148 std::vector<std::uint8_t> respCrc = {0xff, 0xff, 0x00, 0x00, 0x00,
149 0x00, 0x02, 0x34, 0x45};
150 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
151 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
152
153 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
154
155 auto meta = blob.getStat("abcd");
156 EXPECT_EQ(meta.blob_state, 0xffff);
157 EXPECT_EQ(meta.size, 0x00);
158 std::vector<std::uint8_t> metadata = {0x34, 0x45};
159 EXPECT_EQ(metadata, meta.metadata);
160}
161
162TEST_F(BlobHandlerTest, getStatNoMetadata)
163{
164 /* Stat received no metadata. */
165 IpmiInterfaceMock ipmiMock;
166 BlobHandler blob(&ipmiMock);
167 std::vector<std::uint8_t> request = {
168 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobStat,
169 0x00, 0x00, 'a', 'b',
170 'c', 'd', 0x00};
171
172 /* return blob_state: 0xffff, size: 0x00, metadata 0x3445 */
173 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xff,
174 0xff, 0x00, 0x00, 0x00, 0x00, 0x00};
175
176 std::vector<std::uint8_t> reqCrc = {'a', 'b', 'c', 'd', 0x00};
177 std::vector<std::uint8_t> respCrc = {0xff, 0xff, 0x00, 0x00,
178 0x00, 0x00, 0x00};
179
180 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
181 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
182
183 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
184
185 auto meta = blob.getStat("abcd");
186 EXPECT_EQ(meta.blob_state, 0xffff);
187 EXPECT_EQ(meta.size, 0x00);
188 std::vector<std::uint8_t> metadata = {};
189 EXPECT_EQ(metadata, meta.metadata);
190}
191
192TEST_F(BlobHandlerTest, openBlobSucceeds)
193{
194 /* The open blob succeeds. */
195 IpmiInterfaceMock ipmiMock;
196 BlobHandler blob(&ipmiMock);
197
198 std::vector<std::uint8_t> request = {
199 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobOpen,
200 0x00, 0x00, 0x02, 0x04,
201 'a', 'b', 'c', 'd',
202 0x00};
203
204 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xfe, 0xed};
205
206 std::vector<std::uint8_t> reqCrc = {0x02, 0x04, 'a', 'b', 'c', 'd', 0x00};
207 std::vector<std::uint8_t> respCrc = {0xfe, 0xed};
208 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
209 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
210
211 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
212
213 const int writeBit = (1 << 1);
214 const int lpcBit = (1 << 10);
215
216 auto session = blob.openBlob("abcd", writeBit | lpcBit);
217 EXPECT_EQ(0xedfe, session);
218}
219
220TEST_F(BlobHandlerTest, closeBlobSucceeds)
221{
222 /* The close succeeds. */
223 IpmiInterfaceMock ipmiMock;
224 BlobHandler blob(&ipmiMock);
225
226 std::vector<std::uint8_t> request = {
227 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobClose,
228 0x00, 0x00, 0x01, 0x00};
229 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00};
230 std::vector<std::uint8_t> reqCrc = {0x01, 0x00};
231 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
232
233 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
234
235 blob.closeBlob(0x0001);
236}
237
238TEST_F(BlobHandlerTest, writeBytesSucceeds)
239{
240 /* The write bytes succeeds. */
241 IpmiInterfaceMock ipmiMock;
242 BlobHandler blob(&ipmiMock);
243
244 std::vector<std::uint8_t> request = {
245 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobWrite,
246 0x00, 0x00, 0x01, 0x00,
247 0x00, 0x00, 0x00, 0x00,
248 'a', 'b', 'c', 'd'};
249
250 std::vector<std::uint8_t> bytes = {'a', 'b', 'c', 'd'};
251 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00};
252 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00, 0x00,
253 0x00, 'a', 'b', 'c', 'd'};
254 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
255
256 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
257
258 blob.writeBytes(0x0001, 0, bytes);
259}
260
261TEST_F(BlobHandlerTest, readBytesSucceeds)
262{
263 /* The reading of bytes succeeds. */
264
265 IpmiInterfaceMock ipmiMock;
266 BlobHandler blob(&ipmiMock);
267
268 std::vector<std::uint8_t> request = {
269 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobRead,
270 0x00, 0x00, 0x01, 0x00,
271 0x00, 0x00, 0x00, 0x00,
272 0x04, 0x00, 0x00, 0x00};
273
274 std::vector<std::uint8_t> expectedBytes = {'a', 'b', 'c', 'd'};
275 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
276 'a', 'b', 'c', 'd'};
277 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00, 0x00,
278 0x00, 0x04, 0x00, 0x00, 0x00};
279 std::vector<std::uint8_t> respCrc = {'a', 'b', 'c', 'd'};
280
281 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
282 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
283
284 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
285
286 EXPECT_EQ(blob.readBytes(0x0001, 0, 4), expectedBytes);
287}
288
Patrick Venture1470bec2019-03-06 07:33:12 -0800289} // namespace ipmiblob