buffer: Implement "initialize" and add unit tests
Add buffer headers and the initialization process
Tested: Unit Tested
Signed-off-by: Brandon Kim <brandonkim@google.com>
Change-Id: Iaf3c26ce01f7109000266cdbc7efa77988eae73b
diff --git a/test/buffer_test.cpp b/test/buffer_test.cpp
new file mode 100644
index 0000000..ee03163
--- /dev/null
+++ b/test/buffer_test.cpp
@@ -0,0 +1,114 @@
+#include "buffer.hpp"
+#include "data_interface_mock.hpp"
+
+#include <array>
+#include <cstdint>
+#include <memory>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace bios_bmc_smm_error_logger
+{
+namespace
+{
+
+using ::testing::_;
+using ::testing::ElementsAreArray;
+using ::testing::InSequence;
+using ::testing::Return;
+
+class BufferTest : public ::testing::Test
+{
+ protected:
+ BufferTest() :
+ dataInterfaceMock(std::make_unique<DataInterfaceMock>()),
+ dataInterfaceMockPtr(dataInterfaceMock.get())
+ {
+ bufferImpl = std::make_unique<BufferImpl>(std::move(dataInterfaceMock));
+ testInitializationHeader.bmcInterfaceVersion = testBmcInterfaceVersion;
+ testInitializationHeader.queueSize = testQueueSize;
+ testInitializationHeader.ueRegionSize = testUeRegionSize;
+ testInitializationHeader.magicNumber = testMagicNumber;
+ }
+ ~BufferTest() override = default;
+
+ // CircularBufferHeader size is 0x30, ensure the test region is bigger
+ static constexpr size_t testRegionSize = 0x200;
+ static constexpr uint32_t testBmcInterfaceVersion = 123;
+ static constexpr uint16_t testQueueSize = 0x100;
+ static constexpr uint16_t testUeRegionSize = 0x50;
+ static constexpr std::array<uint32_t, 4> testMagicNumber = {
+ 0x12345678, 0x22345678, 0x32345678, 0x42345678};
+ struct CircularBufferHeader testInitializationHeader
+ {};
+
+ std::unique_ptr<DataInterfaceMock> dataInterfaceMock;
+ DataInterfaceMock* dataInterfaceMockPtr;
+
+ std::unique_ptr<BufferImpl> bufferImpl;
+};
+
+TEST_F(BufferTest, BufferInitializeEraseFail)
+{
+ InSequence s;
+
+ EXPECT_CALL(*dataInterfaceMockPtr, getMemoryRegionSize())
+ .WillOnce(Return(testRegionSize));
+ const std::vector<uint8_t> emptyArray(testRegionSize, 0);
+ // Return a smaller write than the intended testRegionSize to test the error
+ EXPECT_CALL(*dataInterfaceMockPtr, write(0, ElementsAreArray(emptyArray)))
+ .WillOnce(Return(testRegionSize - 1));
+ EXPECT_THROW(
+ try {
+ bufferImpl->initialize(testBmcInterfaceVersion, testQueueSize,
+ testUeRegionSize, testMagicNumber);
+ } catch (const std::runtime_error& e) {
+ EXPECT_STREQ(e.what(), "Buffer initialization only erased '511'");
+ throw;
+ },
+ std::runtime_error);
+
+ EXPECT_CALL(*dataInterfaceMockPtr, getMemoryRegionSize())
+ .WillOnce(Return(testRegionSize));
+ EXPECT_CALL(*dataInterfaceMockPtr, write(0, ElementsAreArray(emptyArray)))
+ .WillOnce(Return(testRegionSize));
+ // Return a smaller write than the intended initializationHeader to test the
+ // error
+ EXPECT_CALL(*dataInterfaceMockPtr, write(0, _)).WillOnce(Return(0));
+ EXPECT_THROW(
+ try {
+ bufferImpl->initialize(testBmcInterfaceVersion, testQueueSize,
+ testUeRegionSize, testMagicNumber);
+ } catch (const std::runtime_error& e) {
+ EXPECT_STREQ(
+ e.what(),
+ "Buffer initialization buffer header write only wrote '0'");
+ throw;
+ },
+ std::runtime_error);
+}
+
+TEST_F(BufferTest, BufferInitializePass)
+{
+ InSequence s;
+ EXPECT_CALL(*dataInterfaceMockPtr, getMemoryRegionSize())
+ .WillOnce(Return(testRegionSize));
+ const std::vector<uint8_t> emptyArray(testRegionSize, 0);
+ EXPECT_CALL(*dataInterfaceMockPtr, write(0, ElementsAreArray(emptyArray)))
+ .WillOnce(Return(testRegionSize));
+
+ uint8_t* testInitializationHeaderPtr =
+ reinterpret_cast<uint8_t*>(&testInitializationHeader);
+ size_t initializationHeaderSize = sizeof(testInitializationHeader);
+ EXPECT_CALL(*dataInterfaceMockPtr,
+ write(0, ElementsAreArray(testInitializationHeaderPtr,
+ initializationHeaderSize)))
+ .WillOnce(Return(initializationHeaderSize));
+ EXPECT_NO_THROW(bufferImpl->initialize(testBmcInterfaceVersion,
+ testQueueSize, testUeRegionSize,
+ testMagicNumber));
+}
+
+} // namespace
+} // namespace bios_bmc_smm_error_logger
diff --git a/test/include/data_interface_mock.hpp b/test/include/data_interface_mock.hpp
new file mode 100644
index 0000000..942103e
--- /dev/null
+++ b/test/include/data_interface_mock.hpp
@@ -0,0 +1,24 @@
+#pragma once
+#include "data_interface.hpp"
+
+#include <cstdint>
+#include <span>
+#include <vector>
+
+#include <gmock/gmock.h>
+
+namespace bios_bmc_smm_error_logger
+{
+
+class DataInterfaceMock : public DataInterface
+{
+ public:
+ MOCK_METHOD(std::vector<uint8_t>, read,
+ (const uint32_t offset, const uint32_t length), (override));
+ MOCK_METHOD(uint32_t, write,
+ (const uint32_t offset, const std::span<const uint8_t> bytes),
+ (override));
+ MOCK_METHOD(uint32_t, getMemoryRegionSize, (), (override));
+};
+
+} // namespace bios_bmc_smm_error_logger
diff --git a/test/meson.build b/test/meson.build
index 081fcd7..6f72d9f 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -17,13 +17,19 @@
endif
endif
+test_dep = declare_dependency(
+ include_directories: include_directories('include'),
+ dependencies: [bios_bmc_smm_error_logger_dep, gtest, gmock, rde_dep]
+)
+
gtests = [
'pci_handler',
'rde_dictionary_manager',
+ 'buffer',
]
foreach t : gtests
test(t, executable(t.underscorify(), t + '_test.cpp',
build_by_default: false,
implicit_include_directories: false,
- dependencies: [bios_bmc_smm_error_logger_dep, gtest, gmock, rde_dep]))
+ dependencies: test_dep))
endforeach