firmare: start implementing session stat

Session-specific stat is a call required by the P2A bridge to allow the
host to configure its side of the equation.

Change-Id: I90570641cf9a6816fb91e8329582b882aef212cf
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index d7ca5a0..6f829b4 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -18,6 +18,7 @@
 	firmware_writemeta_unittest \
 	firmware_close_unittest \
 	firmware_delete_unittest \
+	firmware_sessionstat_unittest \
 	file_handler_unittest
 
 TESTS = $(check_PROGRAMS)
@@ -46,5 +47,8 @@
 firmware_delete_unittest_SOURCES = firmware_delete_unittest.cpp
 firmware_delete_unittest_LDADD = $(top_builddir)/firmware_handler.o
 
+firmware_sessionstat_unittest_SOURCES = firmware_sessionstat_unittest.cpp
+firmware_sessionstat_unittest_LDADD = $(top_builddir)/firmware_handler.o
+
 file_handler_unittest_SOURCES = file_handler_unittest.cpp
 file_handler_unittest_LDADD = $(top_builddir)/file_handler.o
diff --git a/test/firmware_sessionstat_unittest.cpp b/test/firmware_sessionstat_unittest.cpp
new file mode 100644
index 0000000..9dbf909
--- /dev/null
+++ b/test/firmware_sessionstat_unittest.cpp
@@ -0,0 +1,89 @@
+#include "data_mock.hpp"
+#include "firmware_handler.hpp"
+#include "image_mock.hpp"
+
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace blobs
+{
+using ::testing::Eq;
+using ::testing::Return;
+
+TEST(FirmwareSessionStateTest, DataTypeIpmiNoMetadata)
+{
+    /* Verifying running stat if the type of data session is IPMI returns no
+     * metadata.
+     */
+    ImageHandlerMock imageMock1, imageMock2;
+    std::vector<HandlerPack> blobs = {
+        {FirmwareBlobHandler::hashBlobID, &imageMock1},
+        {"asdf", &imageMock2},
+    };
+
+    std::vector<DataHandlerPack> data = {
+        {FirmwareBlobHandler::UpdateFlags::ipmi, nullptr},
+    };
+
+    auto handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(blobs, data);
+
+    EXPECT_CALL(imageMock2, open("asdf")).WillOnce(Return(true));
+
+    EXPECT_TRUE(handler->open(
+        0, OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi, "asdf"));
+
+    int size = 512;
+    EXPECT_CALL(imageMock2, getSize()).WillOnce(Return(size));
+
+    struct BlobMeta meta;
+    EXPECT_TRUE(handler->stat(0, &meta));
+    EXPECT_EQ(meta.blobState,
+              OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi);
+    EXPECT_EQ(meta.size, size);
+    EXPECT_EQ(meta.metadata.size(), 0);
+}
+
+TEST(FirmwareSessionStateTest, DataTypeP2AReturnsMetadata)
+{
+    /* Really any type that isn't IPMI can return metadata, but we only expect
+     * P2A to for now.  Later, LPC may have reason to provide data, and can by
+     * simply implementing read().
+     */
+    ImageHandlerMock imageMock1, imageMock2;
+    std::vector<HandlerPack> blobs = {
+        {FirmwareBlobHandler::hashBlobID, &imageMock1},
+        {"asdf", &imageMock2},
+    };
+
+    DataHandlerMock dataMock;
+
+    std::vector<DataHandlerPack> data = {
+        {FirmwareBlobHandler::UpdateFlags::ipmi, nullptr},
+        {FirmwareBlobHandler::UpdateFlags::lpc, &dataMock},
+    };
+
+    auto handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(blobs, data);
+
+    EXPECT_CALL(dataMock, open()).WillOnce(Return(true));
+    EXPECT_CALL(imageMock2, open("asdf")).WillOnce(Return(true));
+
+    EXPECT_TRUE(handler->open(
+        0, OpenFlags::write | FirmwareBlobHandler::UpdateFlags::lpc, "asdf"));
+
+    int size = 512;
+    EXPECT_CALL(imageMock2, getSize()).WillOnce(Return(size));
+    std::vector<std::uint8_t> mBytes = {0x01, 0x02};
+    EXPECT_CALL(dataMock, read()).WillOnce(Return(mBytes));
+
+    struct BlobMeta meta;
+    EXPECT_TRUE(handler->stat(0, &meta));
+    EXPECT_EQ(meta.blobState,
+              OpenFlags::write | FirmwareBlobHandler::UpdateFlags::lpc);
+    EXPECT_EQ(meta.size, size);
+    EXPECT_EQ(meta.metadata.size(), mBytes.size());
+    EXPECT_EQ(meta.metadata[0], mBytes[0]);
+    EXPECT_EQ(meta.metadata[1], mBytes[1]);
+}
+
+} // namespace blobs
diff --git a/test/image_mock.hpp b/test/image_mock.hpp
index 8259aa9..c831c45 100644
--- a/test/image_mock.hpp
+++ b/test/image_mock.hpp
@@ -15,6 +15,7 @@
     MOCK_METHOD1(open, bool(const std::string&));
     MOCK_METHOD0(close, void());
     MOCK_METHOD2(write, bool(std::uint32_t, const std::vector<std::uint8_t>&));
+    MOCK_METHOD0(getSize, int());
 };
 
 } // namespace blobs