1 #include "pci_handler.hpp" 2 3 #include <stdplus/fd/gmock.hpp> 4 #include <stdplus/fd/managed.hpp> 5 #include <stdplus/fd/mmap.hpp> 6 7 #include <cstdint> 8 #include <memory> 9 #include <span> 10 #include <vector> 11 12 #include <gmock/gmock.h> 13 #include <gtest/gtest.h> 14 15 namespace bios_bmc_smm_error_logger 16 { 17 namespace 18 { 19 20 using ::testing::_; 21 using ::testing::ElementsAreArray; 22 using ::testing::Return; 23 24 class PciHandlerTest : public ::testing::Test 25 { 26 protected: 27 PciHandlerTest() : 28 testMapped( 29 {std::byte(0), std::byte(11), std::byte(22), std::byte(33), 30 std::byte(44), std::byte(55), std::byte(66), std::byte(77)}), 31 fdMock(std::make_unique<stdplus::fd::FdMock>()), fdMockPtr(fdMock.get()) 32 { 33 // Verify that the constructor is called as expected 34 EXPECT_CALL(*fdMockPtr, mmap(_, _, _, _)) 35 .WillOnce(Return(std::span<std::byte>(testMapped))); 36 pciDataHandler = std::make_unique<PciDataHandler>( 37 testRegionAddress, testRegionSize, std::move(fdMock)); 38 } 39 ~PciHandlerTest() override 40 { 41 // Verify that the destructor is called as expected 42 EXPECT_CALL(*fdMockPtr, munmap(_)).Times(1); 43 } 44 static constexpr uint32_t testRegionAddress = 0xF0848000; 45 // Smaller region size for easier boundary testing 46 static constexpr size_t testRegionSize = 8; 47 std::vector<std::byte> testMapped; 48 std::unique_ptr<stdplus::fd::FdMock> fdMock; 49 stdplus::fd::FdMock* fdMockPtr; 50 51 std::unique_ptr<PciDataHandler> pciDataHandler; 52 }; 53 54 TEST_F(PciHandlerTest, GetMemoryRegionSizeSanity) 55 { 56 EXPECT_EQ(pciDataHandler->getMemoryRegionSize(), testRegionSize); 57 } 58 59 TEST_F(PciHandlerTest, BoundaryChecksReadFail) 60 { 61 std::vector<uint8_t> emptyVector; 62 // Zero size 63 EXPECT_THAT(pciDataHandler->read(0, 0), ElementsAreArray(emptyVector)); 64 65 const int offsetTooBig = testRegionSize + 1; 66 EXPECT_THAT(pciDataHandler->read(offsetTooBig, 1), 67 ElementsAreArray(emptyVector)); 68 } 69 70 TEST_F(PciHandlerTest, BoundaryChecksWriteFail) 71 { 72 std::vector<uint8_t> emptyVector; 73 // Zero size 74 EXPECT_EQ(pciDataHandler->write(0, emptyVector), 0); 75 76 const int offsetTooBig = testRegionSize + 1; 77 std::vector<uint8_t> testVector(testRegionSize - 1); 78 EXPECT_EQ(pciDataHandler->write(offsetTooBig, testVector), 0); 79 } 80 81 TEST_F(PciHandlerTest, ReadPasses) 82 { 83 // Normal read from 0 84 uint32_t testOffset = 0; 85 uint32_t testSize = 2; 86 std::vector<uint8_t> expectedVector{0, 11}; 87 EXPECT_THAT(pciDataHandler->read(testOffset, testSize), 88 ElementsAreArray(expectedVector)); 89 90 // Read to buffer boundary from non 0 offset 91 testOffset = 3; 92 testSize = testRegionSize - testOffset; 93 expectedVector.clear(); 94 expectedVector = {33, 44, 55, 66, 77}; 95 EXPECT_THAT(pciDataHandler->read(testOffset, testSize), 96 ElementsAreArray(expectedVector)); 97 98 // Read over buffer boundary (which will read until the end) 99 testOffset = 4; 100 testSize = testRegionSize - testOffset + 1; 101 expectedVector.clear(); 102 expectedVector = {44, 55, 66, 77}; 103 EXPECT_THAT(pciDataHandler->read(testOffset, testSize), 104 ElementsAreArray(expectedVector)); 105 } 106 107 TEST_F(PciHandlerTest, WritePasses) 108 { 109 std::vector<std::byte> expectedMapped{ 110 std::byte(0), std::byte(11), std::byte(22), std::byte(33), 111 std::byte(44), std::byte(55), std::byte(66), std::byte(77)}; 112 113 // Normal write from 0 114 uint32_t testOffset = 0; 115 std::vector<uint8_t> writeVector{99, 88}; 116 expectedMapped[0] = std::byte(99); 117 expectedMapped[1] = std::byte(88); 118 119 EXPECT_EQ(pciDataHandler->write(testOffset, writeVector), 120 writeVector.size()); 121 EXPECT_THAT(testMapped, ElementsAreArray(expectedMapped)); 122 123 // Write to buffer boundary from non 0 offset 124 testOffset = 4; 125 writeVector = {55, 44, 33, 22}; 126 expectedMapped[4] = std::byte(55); 127 expectedMapped[5] = std::byte(44); 128 expectedMapped[6] = std::byte(33); 129 expectedMapped[7] = std::byte(22); 130 EXPECT_EQ(pciDataHandler->write(testOffset, writeVector), 131 writeVector.size()); 132 EXPECT_THAT(testMapped, ElementsAreArray(expectedMapped)); 133 134 // Read over buffer boundary (which will read until the end) 135 testOffset = 7; 136 writeVector = {12, 23, 45}; 137 expectedMapped[7] = std::byte(12); 138 EXPECT_EQ(pciDataHandler->write(testOffset, writeVector), 139 testRegionSize - testOffset); 140 EXPECT_THAT(testMapped, ElementsAreArray(expectedMapped)); 141 } 142 143 } // namespace 144 } // namespace bios_bmc_smm_error_logger 145