buffer: Implement "readBufferHeader" and enforce endianness

Add buffer header reader and a getter API for the cachedBufferHeader for
testing.

Also update CircularBufferHeader with boost endian library.

Tested: Unit Tested

Signed-off-by: Brandon Kim <brandonkim@google.com>
Change-Id: I3afaa96f1fab2dd160058e8127dcba494efe3ce7
diff --git a/test/buffer_test.cpp b/test/buffer_test.cpp
index ee03163..e3d5621 100644
--- a/test/buffer_test.cpp
+++ b/test/buffer_test.cpp
@@ -1,6 +1,10 @@
 #include "buffer.hpp"
 #include "data_interface_mock.hpp"
 
+#include <boost/endian/arithmetic.hpp>
+#include <boost/endian/conversion.hpp>
+
+#include <algorithm>
 #include <array>
 #include <cstdint>
 #include <memory>
@@ -29,7 +33,11 @@
         testInitializationHeader.bmcInterfaceVersion = testBmcInterfaceVersion;
         testInitializationHeader.queueSize = testQueueSize;
         testInitializationHeader.ueRegionSize = testUeRegionSize;
-        testInitializationHeader.magicNumber = testMagicNumber;
+        std::transform(testMagicNumber.begin(), testMagicNumber.end(),
+                       testInitializationHeader.magicNumber.begin(),
+                       [](uint32_t number) -> little_uint32_t {
+                           return boost::endian::native_to_little(number);
+                       });
     }
     ~BufferTest() override = default;
 
@@ -40,12 +48,14 @@
     static constexpr uint16_t testUeRegionSize = 0x50;
     static constexpr std::array<uint32_t, 4> testMagicNumber = {
         0x12345678, 0x22345678, 0x32345678, 0x42345678};
+    static constexpr size_t bufferHeaderSize =
+        sizeof(struct CircularBufferHeader);
+
     struct CircularBufferHeader testInitializationHeader
     {};
 
     std::unique_ptr<DataInterfaceMock> dataInterfaceMock;
     DataInterfaceMock* dataInterfaceMockPtr;
-
     std::unique_ptr<BufferImpl> bufferImpl;
 };
 
@@ -100,15 +110,44 @@
 
     uint8_t* testInitializationHeaderPtr =
         reinterpret_cast<uint8_t*>(&testInitializationHeader);
-    size_t initializationHeaderSize = sizeof(testInitializationHeader);
     EXPECT_CALL(*dataInterfaceMockPtr,
                 write(0, ElementsAreArray(testInitializationHeaderPtr,
-                                          initializationHeaderSize)))
-        .WillOnce(Return(initializationHeaderSize));
+                                          bufferHeaderSize)))
+        .WillOnce(Return(bufferHeaderSize));
     EXPECT_NO_THROW(bufferImpl->initialize(testBmcInterfaceVersion,
                                            testQueueSize, testUeRegionSize,
                                            testMagicNumber));
 }
 
+TEST_F(BufferTest, BufferHeaderReadFail)
+{
+    std::vector<std::uint8_t> testBytesRead{};
+    EXPECT_CALL(*dataInterfaceMockPtr, read(0, bufferHeaderSize))
+        .WillOnce(Return(testBytesRead));
+    EXPECT_THROW(
+        try {
+            bufferImpl->readBufferHeader();
+        } catch (const std::runtime_error& e) {
+            EXPECT_STREQ(e.what(),
+                         "Buffer header read only read '0', expected '48'");
+            throw;
+        },
+        std::runtime_error);
+}
+
+TEST_F(BufferTest, BufferHeaderReadPass)
+{
+    uint8_t* testInitializationHeaderPtr =
+        reinterpret_cast<uint8_t*>(&testInitializationHeader);
+    std::vector<uint8_t> testInitializationHeaderVector(
+        testInitializationHeaderPtr,
+        testInitializationHeaderPtr + bufferHeaderSize);
+
+    EXPECT_CALL(*dataInterfaceMockPtr, read(0, bufferHeaderSize))
+        .WillOnce(Return(testInitializationHeaderVector));
+    EXPECT_NO_THROW(bufferImpl->readBufferHeader());
+    EXPECT_EQ(bufferImpl->getCachedBufferHeader(), testInitializationHeader);
+}
+
 } // namespace
 } // namespace bios_bmc_smm_error_logger