blob: f3a01c1dd3560565cc2357b9a8fdd914c1e5ddb9 [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 Venturebcec9c62018-12-14 13:58:41 -08007CrcInterface* crcIntf = nullptr;
Patrick Venturec79faa12018-12-12 13:12:21 -08008
9std::uint16_t generateCrc(const std::vector<std::uint8_t>& data)
10{
Patrick Venturebcec9c62018-12-14 13:58:41 -080011 return (crcIntf) ? crcIntf->generateCrc(data) : 0x00;
Patrick Venturec79faa12018-12-12 13:12:21 -080012}
13
14using ::testing::Eq;
15using ::testing::Return;
16
Patrick Venturebcec9c62018-12-14 13:58:41 -080017class BlobHandlerTest : public ::testing::Test
18{
19 protected:
20 void SetUp() override
21 {
22 crcIntf = &crcMock;
23 }
24
25 CrcMock crcMock;
26};
27
28TEST_F(BlobHandlerTest, getCountIpmiHappy)
Patrick Venturec79faa12018-12-12 13:12:21 -080029{
30 /* Verify returns the value specified by the IPMI response. */
31 IpmiInterfaceMock ipmiMock;
32 BlobHandler blob(&ipmiMock);
33 std::vector<std::uint8_t> request = {
34 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobGetCount};
35
36 /* return 1 blob count. */
37 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
38 0x01, 0x00, 0x00, 0x00};
39
Patrick Venturebcec9c62018-12-14 13:58:41 -080040 std::vector<std::uint8_t> bytes = {0x01, 0x00, 0x00, 0x00};
41 EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
42
Patrick Venturec79faa12018-12-12 13:12:21 -080043 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
44 EXPECT_EQ(1, blob.getBlobCount());
45}
46
Patrick Venturebcec9c62018-12-14 13:58:41 -080047TEST_F(BlobHandlerTest, enumerateBlobIpmiHappy)
Patrick Venturec79faa12018-12-12 13:12:21 -080048{
49 /* Verify returns the name specified by the IPMI response. */
50 IpmiInterfaceMock ipmiMock;
51 BlobHandler blob(&ipmiMock);
52 std::vector<std::uint8_t> request = {
53 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
54 0x00, 0x00, 0x01, 0x00,
55 0x00, 0x00};
56
57 /* return value. */
58 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
Patrick Venture86ef75d2018-12-19 15:59:03 -080059 'a', 'b', 'c', 'd', 0x00};
Patrick Venturec79faa12018-12-12 13:12:21 -080060
Patrick Venturebcec9c62018-12-14 13:58:41 -080061 std::vector<std::uint8_t> bytes = {'a', 'b', 'c', 'd', 0x00};
62 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00};
63 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
64 EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
65
Patrick Venturec79faa12018-12-12 13:12:21 -080066 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
67 EXPECT_STREQ("abcd", blob.enumerateBlob(1).c_str());
68}
69
Patrick Venturebcec9c62018-12-14 13:58:41 -080070TEST_F(BlobHandlerTest, enumerateBlobIpmiNoBytes)
Patrick Venturec79faa12018-12-12 13:12:21 -080071{
72 /* Simulate a case where the IPMI command returns no data. */
73 IpmiInterfaceMock ipmiMock;
74 BlobHandler blob(&ipmiMock);
75 std::vector<std::uint8_t> request = {
76 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
77 0x00, 0x00, 0x01, 0x00,
78 0x00, 0x00};
79
80 /* return value. */
81 std::vector<std::uint8_t> resp = {};
82
Patrick Venturebcec9c62018-12-14 13:58:41 -080083 std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00};
84 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
85
Patrick Venturec79faa12018-12-12 13:12:21 -080086 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
87 EXPECT_STREQ("", blob.enumerateBlob(1).c_str());
88}
89
Patrick Venturebcec9c62018-12-14 13:58:41 -080090TEST_F(BlobHandlerTest, getBlobListIpmiHappy)
Patrick Venturec79faa12018-12-12 13:12:21 -080091{
92 /* Verify returns the list built via the above two commands. */
93 IpmiInterfaceMock ipmiMock;
94 BlobHandler blob(&ipmiMock);
95
96 std::vector<std::uint8_t> request1 = {
97 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobGetCount};
98
99 /* return 1 blob count. */
100 std::vector<std::uint8_t> resp1 = {0xcf, 0xc2, 0x00, 0x00, 0x00,
101 0x01, 0x00, 0x00, 0x00};
102
Patrick Venturebcec9c62018-12-14 13:58:41 -0800103 std::vector<std::uint8_t> bytes1 = {0x01, 0x00, 0x00, 0x00};
104 EXPECT_CALL(crcMock, generateCrc(Eq(bytes1))).WillOnce(Return(0x00));
105
Patrick Venturec79faa12018-12-12 13:12:21 -0800106 EXPECT_CALL(ipmiMock, sendPacket(Eq(request1))).WillOnce(Return(resp1));
107
108 std::vector<std::uint8_t> request2 = {
109 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
110 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00};
112
113 /* return value. */
114 std::vector<std::uint8_t> resp2 = {0xcf, 0xc2, 0x00, 0x00, 0x00,
Patrick Venture86ef75d2018-12-19 15:59:03 -0800115 'a', 'b', 'c', 'd', 0x00};
Patrick Venturec79faa12018-12-12 13:12:21 -0800116
Patrick Venturebcec9c62018-12-14 13:58:41 -0800117 std::vector<std::uint8_t> reqCrc = {0x00, 0x00, 0x00, 0x00};
118 std::vector<std::uint8_t> bytes2 = {'a', 'b', 'c', 'd', 0x00};
119 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
120 EXPECT_CALL(crcMock, generateCrc(Eq(bytes2))).WillOnce(Return(0x00));
121
Patrick Venturec79faa12018-12-12 13:12:21 -0800122 EXPECT_CALL(ipmiMock, sendPacket(Eq(request2))).WillOnce(Return(resp2));
123
Patrick Venture86ef75d2018-12-19 15:59:03 -0800124 /* A std::string is not nul-terminated by default. */
125 std::vector<std::string> expectedList = {std::string{"abcd"}};
Patrick Venturec79faa12018-12-12 13:12:21 -0800126
127 EXPECT_EQ(expectedList, blob.getBlobList());
128}
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800129
Patrick Venturebcec9c62018-12-14 13:58:41 -0800130TEST_F(BlobHandlerTest, getStatWithMetadata)
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800131{
132 /* Stat received metadata. */
133 IpmiInterfaceMock ipmiMock;
134 BlobHandler blob(&ipmiMock);
135 std::vector<std::uint8_t> request = {
136 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobStat,
137 0x00, 0x00, 'a', 'b',
Patrick Venture0d88a122018-12-17 07:52:04 -0800138 'c', 'd', 0x00};
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800139
140 /* return blob_state: 0xffff, size: 0x00, metadata 0x3445 */
141 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xff, 0xff,
142 0x00, 0x00, 0x00, 0x00, 0x02, 0x34, 0x45};
143
Patrick Venturebcec9c62018-12-14 13:58:41 -0800144 std::vector<std::uint8_t> reqCrc = {'a', 'b', 'c', 'd', 0x00};
145 std::vector<std::uint8_t> respCrc = {0xff, 0xff, 0x00, 0x00, 0x00,
146 0x00, 0x02, 0x34, 0x45};
147 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
148 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
149
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800150 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
151
152 auto meta = blob.getStat("abcd");
153 EXPECT_EQ(meta.blob_state, 0xffff);
154 EXPECT_EQ(meta.size, 0x00);
155 std::vector<std::uint8_t> metadata = {0x34, 0x45};
156 EXPECT_EQ(metadata, meta.metadata);
157}
158
Patrick Venturebcec9c62018-12-14 13:58:41 -0800159TEST_F(BlobHandlerTest, getStatNoMetadata)
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800160{
161 /* Stat received no metadata. */
162 IpmiInterfaceMock ipmiMock;
163 BlobHandler blob(&ipmiMock);
164 std::vector<std::uint8_t> request = {
165 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobStat,
166 0x00, 0x00, 'a', 'b',
Patrick Venture0d88a122018-12-17 07:52:04 -0800167 'c', 'd', 0x00};
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800168
169 /* return blob_state: 0xffff, size: 0x00, metadata 0x3445 */
170 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xff,
171 0xff, 0x00, 0x00, 0x00, 0x00, 0x00};
172
Patrick Venturebcec9c62018-12-14 13:58:41 -0800173 std::vector<std::uint8_t> reqCrc = {'a', 'b', 'c', 'd', 0x00};
174 std::vector<std::uint8_t> respCrc = {0xff, 0xff, 0x00, 0x00,
175 0x00, 0x00, 0x00};
176
177 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
178 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
179
Patrick Venture0bf8bf02018-12-12 20:43:25 -0800180 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
181
182 auto meta = blob.getStat("abcd");
183 EXPECT_EQ(meta.blob_state, 0xffff);
184 EXPECT_EQ(meta.size, 0x00);
185 std::vector<std::uint8_t> metadata = {};
186 EXPECT_EQ(metadata, meta.metadata);
187}
Patrick Venture0533d0b2018-12-13 08:48:24 -0800188
Patrick Venturebcec9c62018-12-14 13:58:41 -0800189TEST_F(BlobHandlerTest, openBlobSucceeds)
Patrick Venture0533d0b2018-12-13 08:48:24 -0800190{
191 /* The open blob succeeds. */
192 IpmiInterfaceMock ipmiMock;
193 BlobHandler blob(&ipmiMock);
194
195 std::vector<std::uint8_t> request = {
196 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobOpen,
197 0x00, 0x00, 0x02, 0x04,
Patrick Venture0d88a122018-12-17 07:52:04 -0800198 'a', 'b', 'c', 'd',
199 0x00};
Patrick Venture0533d0b2018-12-13 08:48:24 -0800200
201 std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xfe, 0xed};
202
Patrick Venturebcec9c62018-12-14 13:58:41 -0800203 std::vector<std::uint8_t> reqCrc = {0x02, 0x04, 'a', 'b', 'c', 'd', 0x00};
204 std::vector<std::uint8_t> respCrc = {0xfe, 0xed};
205 EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
206 EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
207
Patrick Venture0533d0b2018-12-13 08:48:24 -0800208 EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
209
210 auto session =
211 blob.openBlob("abcd", blobs::FirmwareBlobHandler::UpdateFlags::lpc);
212 EXPECT_EQ(0xedfe, session);
213}