1 #include "ipmi.hpp" 2 3 #include <blobs-ipmid/test/manager_mock.hpp> 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_INVALID, commitBlob(&mgr, request, reply, &dataLen)); 39 } 40 41 TEST(BlobCommitTest, ValidCommitNoDataHandlerRejectsReturnsFailure) 42 { 43 // The commit packet is valid and the manager's commit call returns failure. 44 45 ManagerMock mgr; 46 size_t dataLen; 47 uint8_t request[MAX_IPMI_BUFFER] = {0}; 48 uint8_t reply[MAX_IPMI_BUFFER] = {0}; 49 auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request); 50 51 req->cmd = BlobOEMCommands::bmcBlobCommit; 52 req->crc = 0; 53 req->sessionId = 0x54; 54 req->commitDataLen = 0; 55 56 dataLen = sizeof(struct BmcBlobCommitTx); 57 58 EXPECT_CALL(mgr, commit(req->sessionId, _)).WillOnce(Return(false)); 59 60 EXPECT_EQ(IPMI_CC_INVALID, commitBlob(&mgr, request, reply, &dataLen)); 61 } 62 63 TEST(BlobCommitTest, ValidCommitNoDataHandlerAcceptsReturnsSuccess) 64 { 65 // Commit called with no data and everything returns success. 66 67 ManagerMock mgr; 68 size_t dataLen; 69 uint8_t request[MAX_IPMI_BUFFER] = {0}; 70 uint8_t reply[MAX_IPMI_BUFFER] = {0}; 71 auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request); 72 73 req->cmd = BlobOEMCommands::bmcBlobCommit; 74 req->crc = 0; 75 req->sessionId = 0x54; 76 req->commitDataLen = 0; 77 78 dataLen = sizeof(struct BmcBlobCommitTx); 79 80 EXPECT_CALL(mgr, commit(req->sessionId, _)).WillOnce(Return(true)); 81 82 EXPECT_EQ(IPMI_CC_OK, commitBlob(&mgr, request, reply, &dataLen)); 83 } 84 85 TEST(BlobCommitTest, ValidCommitWithDataHandlerAcceptsReturnsSuccess) 86 { 87 // Commit called with extra data and everything returns success. 88 89 ManagerMock mgr; 90 size_t dataLen; 91 uint8_t request[MAX_IPMI_BUFFER] = {0}; 92 uint8_t reply[MAX_IPMI_BUFFER] = {0}; 93 auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request); 94 95 uint8_t expectedBlob[4] = {0x25, 0x33, 0x45, 0x67}; 96 97 req->cmd = BlobOEMCommands::bmcBlobCommit; 98 req->crc = 0; 99 req->sessionId = 0x54; 100 req->commitDataLen = sizeof(expectedBlob); 101 std::memcpy(req->commitData, &expectedBlob[0], sizeof(expectedBlob)); 102 103 dataLen = sizeof(struct BmcBlobCommitTx) + sizeof(expectedBlob); 104 105 EXPECT_CALL(mgr, 106 commit(req->sessionId, 107 ElementsAreArray(expectedBlob, sizeof(expectedBlob)))) 108 .WillOnce(Return(true)); 109 110 EXPECT_EQ(IPMI_CC_OK, commitBlob(&mgr, request, reply, &dataLen)); 111 } 112 } // namespace blobs 113