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 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 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 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 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