#include "pci_handler.hpp" #include #include #include #include #include #include #include #include #include namespace bios_bmc_smm_error_logger { namespace { using ::testing::_; using ::testing::ElementsAreArray; using ::testing::Return; class PciHandlerTest : public ::testing::Test { protected: PciHandlerTest() : testMapped({std::byte(0), std::byte(11), std::byte(22), std::byte(33), std::byte(44), std::byte(55), std::byte(66), std::byte(77)}), fdMock(std::make_unique()), fdMockPtr(fdMock.get()) { // Verify that the constructor is called as expected EXPECT_CALL(*fdMockPtr, mmap(_, _, _, _)) .WillOnce(Return(std::span(testMapped))); pciDataHandler = std::make_unique( testRegionAddress, testRegionSize, std::move(fdMock)); } ~PciHandlerTest() override { // Verify that the destructor is called as expected EXPECT_CALL(*fdMockPtr, munmap(_)).Times(1); } static constexpr uint32_t testRegionAddress = 0xF0848000; // Smaller region size for easier boundary testing static constexpr size_t testRegionSize = 8; std::vector testMapped; std::unique_ptr fdMock; stdplus::fd::FdMock* fdMockPtr; std::unique_ptr pciDataHandler; }; TEST_F(PciHandlerTest, GetMemoryRegionSizeSanity) { EXPECT_EQ(pciDataHandler->getMemoryRegionSize(), testRegionSize); } TEST_F(PciHandlerTest, BoundaryChecksReadFail) { std::vector emptyVector; // Zero size EXPECT_THAT(pciDataHandler->read(0, 0), ElementsAreArray(emptyVector)); const int offsetTooBig = testRegionSize + 1; EXPECT_THAT(pciDataHandler->read(offsetTooBig, 1), ElementsAreArray(emptyVector)); } TEST_F(PciHandlerTest, BoundaryChecksWriteFail) { std::vector emptyVector; // Zero size EXPECT_EQ(pciDataHandler->write(0, emptyVector), 0); const int offsetTooBig = testRegionSize + 1; std::vector testVector(testRegionSize - 1); EXPECT_EQ(pciDataHandler->write(offsetTooBig, testVector), 0); } TEST_F(PciHandlerTest, ReadPasses) { // Normal read from 0 uint32_t testOffset = 0; uint32_t testSize = 2; std::vector expectedVector{0, 11}; EXPECT_THAT(pciDataHandler->read(testOffset, testSize), ElementsAreArray(expectedVector)); // Read to buffer boundary from non 0 offset testOffset = 3; testSize = testRegionSize - testOffset; expectedVector.clear(); expectedVector = {33, 44, 55, 66, 77}; EXPECT_THAT(pciDataHandler->read(testOffset, testSize), ElementsAreArray(expectedVector)); // Read over buffer boundary (which will read until the end) testOffset = 4; testSize = testRegionSize - testOffset + 1; expectedVector.clear(); expectedVector = {44, 55, 66, 77}; EXPECT_THAT(pciDataHandler->read(testOffset, testSize), ElementsAreArray(expectedVector)); } TEST_F(PciHandlerTest, WritePasses) { std::vector expectedMapped{ std::byte(0), std::byte(11), std::byte(22), std::byte(33), std::byte(44), std::byte(55), std::byte(66), std::byte(77)}; // Normal write from 0 uint32_t testOffset = 0; std::vector writeVector{99, 88}; expectedMapped[0] = std::byte(99); expectedMapped[1] = std::byte(88); EXPECT_EQ(pciDataHandler->write(testOffset, writeVector), writeVector.size()); EXPECT_THAT(testMapped, ElementsAreArray(expectedMapped)); // Write to buffer boundary from non 0 offset testOffset = 4; writeVector = {55, 44, 33, 22}; expectedMapped[4] = std::byte(55); expectedMapped[5] = std::byte(44); expectedMapped[6] = std::byte(33); expectedMapped[7] = std::byte(22); EXPECT_EQ(pciDataHandler->write(testOffset, writeVector), writeVector.size()); EXPECT_THAT(testMapped, ElementsAreArray(expectedMapped)); // Read over buffer boundary (which will read until the end) testOffset = 7; writeVector = {12, 23, 45}; expectedMapped[7] = std::byte(12); EXPECT_EQ(pciDataHandler->write(testOffset, writeVector), testRegionSize - testOffset); EXPECT_THAT(testMapped, ElementsAreArray(expectedMapped)); } } // namespace } // namespace bios_bmc_smm_error_logger