1 #include "helper.hpp"
2 #include "ipmi.hpp"
3 #include "manager_mock.hpp"
4
5 #include <cstring>
6 #include <string>
7
8 #include <gtest/gtest.h>
9
10 namespace blobs
11 {
12
13 using ::testing::_;
14 using ::testing::Invoke;
15 using ::testing::Matcher;
16 using ::testing::NotNull;
17 using ::testing::Return;
18 using ::testing::StrEq;
19
20 // ipmid.hpp isn't installed where we can grab it and this value is per BMC
21 // SoC.
22 #define MAX_IPMI_BUFFER 64
23
TEST(BlobStatTest,InvalidRequestLengthReturnsFailure)24 TEST(BlobStatTest, InvalidRequestLengthReturnsFailure)
25 {
26 // There is a minimum blobId length of one character, this test verifies
27 // we check that.
28 ManagerMock mgr;
29 std::vector<uint8_t> request;
30 struct BmcBlobStatTx req;
31 std::string blobId = "abc";
32
33 req.crc = 0;
34 request.resize(sizeof(struct BmcBlobStatTx));
35 std::memcpy(request.data(), &req, sizeof(struct BmcBlobStatTx));
36 // Do not include the nul-terminator
37 request.insert(request.end(), blobId.begin(), blobId.end());
38
39 EXPECT_EQ(ipmi::responseReqDataLenInvalid(), statBlob(&mgr, request));
40 }
41
TEST(BlobStatTest,RequestRejectedReturnsFailure)42 TEST(BlobStatTest, RequestRejectedReturnsFailure)
43 {
44 // The blobId is rejected for any reason.
45
46 ManagerMock mgr;
47 std::vector<uint8_t> request;
48 struct BmcBlobStatTx req;
49 std::string blobId = "a";
50
51 req.crc = 0;
52 request.resize(sizeof(struct BmcBlobStatTx));
53 std::memcpy(request.data(), &req, sizeof(struct BmcBlobStatTx));
54 request.insert(request.end(), blobId.begin(), blobId.end());
55 request.emplace_back('\0');
56
57 EXPECT_CALL(mgr, stat(Matcher<const std::string&>(StrEq(blobId)),
58 Matcher<BlobMeta*>(_)))
59 .WillOnce(Return(false));
60
61 EXPECT_EQ(ipmi::responseUnspecifiedError(), statBlob(&mgr, request));
62 }
63
TEST(BlobStatTest,RequestSucceedsNoMetadata)64 TEST(BlobStatTest, RequestSucceedsNoMetadata)
65 {
66 // Stat request succeeeds but there were no metadata bytes.
67
68 ManagerMock mgr;
69 std::vector<uint8_t> request;
70 struct BmcBlobStatTx req;
71 std::string blobId = "a";
72
73 req.crc = 0;
74 request.resize(sizeof(struct BmcBlobStatTx));
75 std::memcpy(request.data(), &req, sizeof(struct BmcBlobStatTx));
76 request.insert(request.end(), blobId.begin(), blobId.end());
77 request.emplace_back('\0');
78
79 struct BmcBlobStatRx rep;
80 rep.crc = 0x00;
81 rep.blobState = 0x01;
82 rep.size = 0x100;
83 rep.metadataLen = 0x00;
84
85 uint16_t blobState = rep.blobState;
86 uint32_t size = rep.size;
87
88 EXPECT_CALL(mgr, stat(Matcher<const std::string&>(StrEq(blobId)),
89 Matcher<BlobMeta*>(NotNull())))
90 .WillOnce(Invoke([&](const std::string&, BlobMeta* meta) {
91 meta->blobState = blobState;
92 meta->size = size;
93 return true;
94 }));
95
96 auto result = validateReply(statBlob(&mgr, request));
97
98 EXPECT_EQ(sizeof(rep), result.size());
99 EXPECT_EQ(0, std::memcmp(result.data(), &rep, sizeof(rep)));
100 }
101
TEST(BlobStatTest,RequestSucceedsWithMetadata)102 TEST(BlobStatTest, RequestSucceedsWithMetadata)
103 {
104 // Stat request succeeds and there were metadata bytes.
105
106 ManagerMock mgr;
107 std::vector<uint8_t> request;
108 struct BmcBlobStatTx req;
109 std::string blobId = "a";
110
111 req.crc = 0;
112 request.resize(sizeof(struct BmcBlobStatTx));
113 std::memcpy(request.data(), &req, sizeof(struct BmcBlobStatTx));
114 request.insert(request.end(), blobId.begin(), blobId.end());
115 request.emplace_back('\0');
116
117 BlobMeta lmeta;
118 lmeta.blobState = 0x01;
119 lmeta.size = 0x100;
120 lmeta.metadata.push_back(0x01);
121 lmeta.metadata.push_back(0x02);
122 lmeta.metadata.push_back(0x03);
123 lmeta.metadata.push_back(0x04);
124
125 struct BmcBlobStatRx rep;
126 rep.crc = 0x00;
127 rep.blobState = lmeta.blobState;
128 rep.size = lmeta.size;
129 rep.metadataLen = lmeta.metadata.size();
130
131 EXPECT_CALL(mgr, stat(Matcher<const std::string&>(StrEq(blobId)),
132 Matcher<BlobMeta*>(NotNull())))
133 .WillOnce(Invoke([&](const std::string&, BlobMeta* meta) {
134 (*meta) = lmeta;
135 return true;
136 }));
137
138 auto result = validateReply(statBlob(&mgr, request));
139
140 EXPECT_EQ(sizeof(rep) + lmeta.metadata.size(), result.size());
141 EXPECT_EQ(0, std::memcmp(result.data(), &rep, sizeof(rep)));
142 EXPECT_EQ(0, std::memcmp(result.data() + sizeof(rep), lmeta.metadata.data(),
143 lmeta.metadata.size()));
144 }
145 } // namespace blobs
146