1 #include "ipmi.hpp" 2 #include "manager_mock.hpp" 3 4 #include <cstring> 5 #include <string> 6 7 #include <gtest/gtest.h> 8 9 namespace blobs 10 { 11 12 using ::testing::_; 13 using ::testing::Invoke; 14 using ::testing::NotNull; 15 using ::testing::Return; 16 using ::testing::StrEq; 17 18 // ipmid.hpp isn't installed where we can grab it and this value is per BMC 19 // SoC. 20 #define MAX_IPMI_BUFFER 64 21 22 TEST(BlobOpenTest, InvalidRequestLengthReturnsFailure) 23 { 24 // There is a minimum blobId length of one character, this test verifies 25 // we check that. 26 27 ManagerMock mgr; 28 size_t dataLen; 29 uint8_t request[MAX_IPMI_BUFFER] = {0}; 30 uint8_t reply[MAX_IPMI_BUFFER] = {0}; 31 auto req = reinterpret_cast<struct BmcBlobOpenTx*>(request); 32 std::string blobId = "abc"; 33 34 req->cmd = BlobOEMCommands::bmcBlobOpen; 35 req->crc = 0; 36 req->flags = 0; 37 // length() doesn't include the nul-terminator. 38 std::memcpy(req->blobId, blobId.c_str(), blobId.length()); 39 40 dataLen = sizeof(struct BmcBlobOpenTx) + blobId.length(); 41 42 EXPECT_EQ(IPMI_CC_INVALID, openBlob(&mgr, request, reply, &dataLen)); 43 } 44 45 TEST(BlobOpenTest, RequestRejectedReturnsFailure) 46 { 47 // The blobId is rejected for any reason. 48 49 ManagerMock mgr; 50 size_t dataLen; 51 uint8_t request[MAX_IPMI_BUFFER] = {0}; 52 uint8_t reply[MAX_IPMI_BUFFER] = {0}; 53 auto req = reinterpret_cast<struct BmcBlobOpenTx*>(request); 54 std::string blobId = "a"; 55 56 req->cmd = BlobOEMCommands::bmcBlobOpen; 57 req->crc = 0; 58 req->flags = 0; 59 // length() doesn't include the nul-terminator, request buff is initialized 60 // to 0s 61 std::memcpy(req->blobId, blobId.c_str(), blobId.length()); 62 63 dataLen = sizeof(struct BmcBlobOpenTx) + blobId.length() + 1; 64 65 EXPECT_CALL(mgr, open(req->flags, StrEq(blobId), _)) 66 .WillOnce(Return(false)); 67 68 EXPECT_EQ(IPMI_CC_INVALID, openBlob(&mgr, request, reply, &dataLen)); 69 } 70 71 TEST(BlobOpenTest, BlobOpenReturnsOk) 72 { 73 // The boring case where the blobId opens. 74 75 ManagerMock mgr; 76 size_t dataLen; 77 uint8_t request[MAX_IPMI_BUFFER] = {0}; 78 uint8_t reply[MAX_IPMI_BUFFER] = {0}; 79 auto req = reinterpret_cast<struct BmcBlobOpenTx*>(request); 80 struct BmcBlobOpenRx rep; 81 std::string blobId = "a"; 82 83 req->cmd = BlobOEMCommands::bmcBlobOpen; 84 req->crc = 0; 85 req->flags = 0; 86 // length() doesn't include the nul-terminator, request buff is initialized 87 // to 0s 88 std::memcpy(req->blobId, blobId.c_str(), blobId.length()); 89 90 dataLen = sizeof(struct BmcBlobOpenTx) + blobId.length() + 1; 91 uint16_t returnedSession = 0x54; 92 93 EXPECT_CALL(mgr, open(req->flags, StrEq(blobId), NotNull())) 94 .WillOnce(Invoke( 95 [&](uint16_t flags, const std::string& path, uint16_t* session) { 96 (*session) = returnedSession; 97 return true; 98 })); 99 100 EXPECT_EQ(IPMI_CC_OK, openBlob(&mgr, request, reply, &dataLen)); 101 102 rep.crc = 0; 103 rep.sessionId = returnedSession; 104 105 EXPECT_EQ(sizeof(rep), dataLen); 106 EXPECT_EQ(0, std::memcmp(reply, &rep, sizeof(rep))); 107 } 108 } // namespace blobs 109