1 #include "buffer.hpp" 2 #include "data_interface_mock.hpp" 3 4 #include <array> 5 #include <cstdint> 6 #include <memory> 7 8 #include <gmock/gmock.h> 9 #include <gtest/gtest.h> 10 11 namespace bios_bmc_smm_error_logger 12 { 13 namespace 14 { 15 16 using ::testing::_; 17 using ::testing::ElementsAreArray; 18 using ::testing::InSequence; 19 using ::testing::Return; 20 21 class BufferTest : public ::testing::Test 22 { 23 protected: 24 BufferTest() : 25 dataInterfaceMock(std::make_unique<DataInterfaceMock>()), 26 dataInterfaceMockPtr(dataInterfaceMock.get()) 27 { 28 bufferImpl = std::make_unique<BufferImpl>(std::move(dataInterfaceMock)); 29 testInitializationHeader.bmcInterfaceVersion = testBmcInterfaceVersion; 30 testInitializationHeader.queueSize = testQueueSize; 31 testInitializationHeader.ueRegionSize = testUeRegionSize; 32 testInitializationHeader.magicNumber = testMagicNumber; 33 } 34 ~BufferTest() override = default; 35 36 // CircularBufferHeader size is 0x30, ensure the test region is bigger 37 static constexpr size_t testRegionSize = 0x200; 38 static constexpr uint32_t testBmcInterfaceVersion = 123; 39 static constexpr uint16_t testQueueSize = 0x100; 40 static constexpr uint16_t testUeRegionSize = 0x50; 41 static constexpr std::array<uint32_t, 4> testMagicNumber = { 42 0x12345678, 0x22345678, 0x32345678, 0x42345678}; 43 struct CircularBufferHeader testInitializationHeader 44 {}; 45 46 std::unique_ptr<DataInterfaceMock> dataInterfaceMock; 47 DataInterfaceMock* dataInterfaceMockPtr; 48 49 std::unique_ptr<BufferImpl> bufferImpl; 50 }; 51 52 TEST_F(BufferTest, BufferInitializeEraseFail) 53 { 54 InSequence s; 55 56 EXPECT_CALL(*dataInterfaceMockPtr, getMemoryRegionSize()) 57 .WillOnce(Return(testRegionSize)); 58 const std::vector<uint8_t> emptyArray(testRegionSize, 0); 59 // Return a smaller write than the intended testRegionSize to test the error 60 EXPECT_CALL(*dataInterfaceMockPtr, write(0, ElementsAreArray(emptyArray))) 61 .WillOnce(Return(testRegionSize - 1)); 62 EXPECT_THROW( 63 try { 64 bufferImpl->initialize(testBmcInterfaceVersion, testQueueSize, 65 testUeRegionSize, testMagicNumber); 66 } catch (const std::runtime_error& e) { 67 EXPECT_STREQ(e.what(), "Buffer initialization only erased '511'"); 68 throw; 69 }, 70 std::runtime_error); 71 72 EXPECT_CALL(*dataInterfaceMockPtr, getMemoryRegionSize()) 73 .WillOnce(Return(testRegionSize)); 74 EXPECT_CALL(*dataInterfaceMockPtr, write(0, ElementsAreArray(emptyArray))) 75 .WillOnce(Return(testRegionSize)); 76 // Return a smaller write than the intended initializationHeader to test the 77 // error 78 EXPECT_CALL(*dataInterfaceMockPtr, write(0, _)).WillOnce(Return(0)); 79 EXPECT_THROW( 80 try { 81 bufferImpl->initialize(testBmcInterfaceVersion, testQueueSize, 82 testUeRegionSize, testMagicNumber); 83 } catch (const std::runtime_error& e) { 84 EXPECT_STREQ( 85 e.what(), 86 "Buffer initialization buffer header write only wrote '0'"); 87 throw; 88 }, 89 std::runtime_error); 90 } 91 92 TEST_F(BufferTest, BufferInitializePass) 93 { 94 InSequence s; 95 EXPECT_CALL(*dataInterfaceMockPtr, getMemoryRegionSize()) 96 .WillOnce(Return(testRegionSize)); 97 const std::vector<uint8_t> emptyArray(testRegionSize, 0); 98 EXPECT_CALL(*dataInterfaceMockPtr, write(0, ElementsAreArray(emptyArray))) 99 .WillOnce(Return(testRegionSize)); 100 101 uint8_t* testInitializationHeaderPtr = 102 reinterpret_cast<uint8_t*>(&testInitializationHeader); 103 size_t initializationHeaderSize = sizeof(testInitializationHeader); 104 EXPECT_CALL(*dataInterfaceMockPtr, 105 write(0, ElementsAreArray(testInitializationHeaderPtr, 106 initializationHeaderSize))) 107 .WillOnce(Return(initializationHeaderSize)); 108 EXPECT_NO_THROW(bufferImpl->initialize(testBmcInterfaceVersion, 109 testQueueSize, testUeRegionSize, 110 testMagicNumber)); 111 } 112 113 } // namespace 114 } // namespace bios_bmc_smm_error_logger 115