1 #include "ipmi.hpp" 2 #include "manager_mock.hpp" 3 4 #include <cstring> 5 6 #include <gtest/gtest.h> 7 8 namespace blobs 9 { 10 11 using ::testing::_; 12 using ::testing::ElementsAreArray; 13 using ::testing::Return; 14 15 // ipmid.hpp isn't installed where we can grab it and this value is per BMC 16 // SoC. 17 #define MAX_IPMI_BUFFER 64 18 19 TEST(BlobCommitTest, InvalidCommitDataLengthReturnsFailure) 20 { 21 // The commit command supports an optional commit blob. This test verifies 22 // we sanity check the length of that blob. 23 24 ManagerMock mgr; 25 size_t dataLen; 26 uint8_t request[MAX_IPMI_BUFFER] = {0}; 27 uint8_t reply[MAX_IPMI_BUFFER] = {0}; 28 auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request); 29 30 req->cmd = BlobOEMCommands::bmcBlobCommit; 31 req->crc = 0; 32 req->sessionId = 0x54; 33 req->commitDataLen = 34 1; // It's one byte, but that's more than the packet size. 35 36 dataLen = sizeof(struct BmcBlobCommitTx); 37 38 EXPECT_EQ(IPMI_CC_REQ_DATA_LEN_INVALID, 39 commitBlob(&mgr, request, reply, &dataLen)); 40 } 41 42 TEST(BlobCommitTest, ValidCommitNoDataHandlerRejectsReturnsFailure) 43 { 44 // The commit packet is valid and the manager's commit call returns failure. 45 46 ManagerMock mgr; 47 size_t dataLen; 48 uint8_t request[MAX_IPMI_BUFFER] = {0}; 49 uint8_t reply[MAX_IPMI_BUFFER] = {0}; 50 auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request); 51 52 req->cmd = BlobOEMCommands::bmcBlobCommit; 53 req->crc = 0; 54 req->sessionId = 0x54; 55 req->commitDataLen = 0; 56 57 dataLen = sizeof(struct BmcBlobCommitTx); 58 59 EXPECT_CALL(mgr, commit(req->sessionId, _)).WillOnce(Return(false)); 60 61 EXPECT_EQ(IPMI_CC_UNSPECIFIED_ERROR, 62 commitBlob(&mgr, request, reply, &dataLen)); 63 } 64 65 TEST(BlobCommitTest, ValidCommitNoDataHandlerAcceptsReturnsSuccess) 66 { 67 // Commit called with no data and everything returns success. 68 69 ManagerMock mgr; 70 size_t dataLen; 71 uint8_t request[MAX_IPMI_BUFFER] = {0}; 72 uint8_t reply[MAX_IPMI_BUFFER] = {0}; 73 auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request); 74 75 req->cmd = BlobOEMCommands::bmcBlobCommit; 76 req->crc = 0; 77 req->sessionId = 0x54; 78 req->commitDataLen = 0; 79 80 dataLen = sizeof(struct BmcBlobCommitTx); 81 82 EXPECT_CALL(mgr, commit(req->sessionId, _)).WillOnce(Return(true)); 83 84 EXPECT_EQ(IPMI_CC_OK, commitBlob(&mgr, request, reply, &dataLen)); 85 } 86 87 TEST(BlobCommitTest, ValidCommitWithDataHandlerAcceptsReturnsSuccess) 88 { 89 // Commit called with extra data and everything returns success. 90 91 ManagerMock mgr; 92 size_t dataLen; 93 uint8_t request[MAX_IPMI_BUFFER] = {0}; 94 uint8_t reply[MAX_IPMI_BUFFER] = {0}; 95 auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request); 96 97 uint8_t expectedBlob[4] = {0x25, 0x33, 0x45, 0x67}; 98 99 req->cmd = BlobOEMCommands::bmcBlobCommit; 100 req->crc = 0; 101 req->sessionId = 0x54; 102 req->commitDataLen = sizeof(expectedBlob); 103 std::memcpy(req->commitData, &expectedBlob[0], sizeof(expectedBlob)); 104 105 dataLen = sizeof(struct BmcBlobCommitTx) + sizeof(expectedBlob); 106 107 EXPECT_CALL(mgr, 108 commit(req->sessionId, 109 ElementsAreArray(expectedBlob, sizeof(expectedBlob)))) 110 .WillOnce(Return(true)); 111 112 EXPECT_EQ(IPMI_CC_OK, commitBlob(&mgr, request, reply, &dataLen)); 113 } 114 } // namespace blobs 115