blob: 817fc8f33b4df5366ccc62016248f3e020043313 [file] [log] [blame]
#include "pci_handler.hpp"
#include <stdplus/fd/gmock.hpp>
#include <stdplus/fd/managed.hpp>
#include <stdplus/fd/mmap.hpp>
#include <cstdint>
#include <memory>
#include <span>
#include <vector>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
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<stdplus::fd::FdMock>()), fdMockPtr(fdMock.get())
{
// Verify that the constructor is called as expected
EXPECT_CALL(*fdMockPtr, mmap(_, _, _, _))
.WillOnce(Return(std::span<std::byte>(testMapped)));
pciDataHandler = std::make_unique<PciDataHandler>(
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<std::byte> testMapped;
std::unique_ptr<stdplus::fd::FdMock> fdMock;
stdplus::fd::FdMock* fdMockPtr;
std::unique_ptr<PciDataHandler> pciDataHandler;
};
TEST_F(PciHandlerTest, GetMemoryRegionSizeSanity)
{
EXPECT_EQ(pciDataHandler->getMemoryRegionSize(), testRegionSize);
}
TEST_F(PciHandlerTest, BoundaryChecksReadFail)
{
std::vector<uint8_t> 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<uint8_t> emptyVector;
// Zero size
EXPECT_EQ(pciDataHandler->write(0, emptyVector), 0);
const int offsetTooBig = testRegionSize + 1;
std::vector<uint8_t> 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<uint8_t> 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<std::byte> 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<uint8_t> 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