blob_handler: move from raw to managed pointer

The blob handler object wants to explictly own its ipmi interface so
that it can't be shared.  This was a good-behavior, but now this
codefies it.

Change-Id: Ie368721a58dc30573f37dc3824da230aca5328d3
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/test/tools_blob_unittest.cpp b/test/tools_blob_unittest.cpp
index 74614a7..75e43cb 100644
--- a/test/tools_blob_unittest.cpp
+++ b/test/tools_blob_unittest.cpp
@@ -1,6 +1,9 @@
+#include <cstdint>
 #include <ipmiblob/blob_handler.hpp>
 #include <ipmiblob/test/crc_mock.hpp>
 #include <ipmiblob/test/ipmi_interface_mock.hpp>
+#include <memory>
+#include <vector>
 
 #include <gtest/gtest.h>
 
@@ -25,13 +28,21 @@
     }
 
     CrcMock crcMock;
+
+    std::unique_ptr<IpmiInterface> CreateIpmiMock()
+    {
+        return std::make_unique<IpmiInterfaceMock>();
+    }
 };
 
 TEST_F(BlobHandlerTest, getCountIpmiHappy)
 {
     /* Verify returns the value specified by the IPMI response. */
-    IpmiInterfaceMock ipmiMock;
-    BlobHandler blob(&ipmiMock);
+    auto ipmi = CreateIpmiMock();
+    IpmiInterfaceMock* ipmiMock =
+        reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
+    BlobHandler blob(std::move(ipmi));
+
     std::vector<std::uint8_t> request = {
         0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobGetCount};
 
@@ -42,15 +53,18 @@
     std::vector<std::uint8_t> bytes = {0x01, 0x00, 0x00, 0x00};
     EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
 
-    EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+    EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
     EXPECT_EQ(1, blob.getBlobCount());
 }
 
 TEST_F(BlobHandlerTest, enumerateBlobIpmiHappy)
 {
     /* Verify returns the name specified by the IPMI response. */
-    IpmiInterfaceMock ipmiMock;
-    BlobHandler blob(&ipmiMock);
+    auto ipmi = CreateIpmiMock();
+    IpmiInterfaceMock* ipmiMock =
+        reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
+    BlobHandler blob(std::move(ipmi));
+
     std::vector<std::uint8_t> request = {
         0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
         0x00, 0x00, 0x01, 0x00,
@@ -65,15 +79,18 @@
     EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
     EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
 
-    EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+    EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
     EXPECT_STREQ("abcd", blob.enumerateBlob(1).c_str());
 }
 
 TEST_F(BlobHandlerTest, enumerateBlobIpmiNoBytes)
 {
     /* Simulate a case where the IPMI command returns no data. */
-    IpmiInterfaceMock ipmiMock;
-    BlobHandler blob(&ipmiMock);
+    auto ipmi = CreateIpmiMock();
+    IpmiInterfaceMock* ipmiMock =
+        reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
+    BlobHandler blob(std::move(ipmi));
+
     std::vector<std::uint8_t> request = {
         0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
         0x00, 0x00, 0x01, 0x00,
@@ -85,15 +102,17 @@
     std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00};
     EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
 
-    EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+    EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
     EXPECT_STREQ("", blob.enumerateBlob(1).c_str());
 }
 
 TEST_F(BlobHandlerTest, getBlobListIpmiHappy)
 {
     /* Verify returns the list built via the above two commands. */
-    IpmiInterfaceMock ipmiMock;
-    BlobHandler blob(&ipmiMock);
+    auto ipmi = CreateIpmiMock();
+    IpmiInterfaceMock* ipmiMock =
+        reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
+    BlobHandler blob(std::move(ipmi));
 
     std::vector<std::uint8_t> request1 = {
         0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobGetCount};
@@ -105,7 +124,7 @@
     std::vector<std::uint8_t> bytes1 = {0x01, 0x00, 0x00, 0x00};
     EXPECT_CALL(crcMock, generateCrc(Eq(bytes1))).WillOnce(Return(0x00));
 
-    EXPECT_CALL(ipmiMock, sendPacket(Eq(request1))).WillOnce(Return(resp1));
+    EXPECT_CALL(*ipmiMock, sendPacket(Eq(request1))).WillOnce(Return(resp1));
 
     std::vector<std::uint8_t> request2 = {
         0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
@@ -121,7 +140,7 @@
     EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
     EXPECT_CALL(crcMock, generateCrc(Eq(bytes2))).WillOnce(Return(0x00));
 
-    EXPECT_CALL(ipmiMock, sendPacket(Eq(request2))).WillOnce(Return(resp2));
+    EXPECT_CALL(*ipmiMock, sendPacket(Eq(request2))).WillOnce(Return(resp2));
 
     /* A std::string is not nul-terminated by default. */
     std::vector<std::string> expectedList = {std::string{"abcd"}};
@@ -132,8 +151,11 @@
 TEST_F(BlobHandlerTest, getStatWithMetadata)
 {
     /* Stat received metadata. */
-    IpmiInterfaceMock ipmiMock;
-    BlobHandler blob(&ipmiMock);
+    auto ipmi = CreateIpmiMock();
+    IpmiInterfaceMock* ipmiMock =
+        reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
+    BlobHandler blob(std::move(ipmi));
+
     std::vector<std::uint8_t> request = {
         0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobStat,
         0x00, 0x00, 'a',  'b',
@@ -149,7 +171,7 @@
     EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
     EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
 
-    EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+    EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
 
     auto meta = blob.getStat("abcd");
     EXPECT_EQ(meta.blob_state, 0xffff);
@@ -161,8 +183,11 @@
 TEST_F(BlobHandlerTest, getStatNoMetadata)
 {
     /* Stat received no metadata. */
-    IpmiInterfaceMock ipmiMock;
-    BlobHandler blob(&ipmiMock);
+    auto ipmi = CreateIpmiMock();
+    IpmiInterfaceMock* ipmiMock =
+        reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
+    BlobHandler blob(std::move(ipmi));
+
     std::vector<std::uint8_t> request = {
         0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobStat,
         0x00, 0x00, 'a',  'b',
@@ -179,7 +204,7 @@
     EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
     EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
 
-    EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+    EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
 
     auto meta = blob.getStat("abcd");
     EXPECT_EQ(meta.blob_state, 0xffff);
@@ -191,8 +216,10 @@
 TEST_F(BlobHandlerTest, getSessionStatNoMetadata)
 {
     /* The get session stat succeeds. */
-    IpmiInterfaceMock ipmiMock;
-    BlobHandler blob(&ipmiMock);
+    auto ipmi = CreateIpmiMock();
+    IpmiInterfaceMock* ipmiMock =
+        reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
+    BlobHandler blob(std::move(ipmi));
 
     std::vector<std::uint8_t> request = {
         0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobSessionStat,
@@ -209,7 +236,7 @@
     EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
     EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
 
-    EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+    EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
 
     auto meta = blob.getStat(0x0001);
     EXPECT_EQ(meta.blob_state, 0xffff);
@@ -221,8 +248,10 @@
 TEST_F(BlobHandlerTest, openBlobSucceeds)
 {
     /* The open blob succeeds. */
-    IpmiInterfaceMock ipmiMock;
-    BlobHandler blob(&ipmiMock);
+    auto ipmi = CreateIpmiMock();
+    IpmiInterfaceMock* ipmiMock =
+        reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
+    BlobHandler blob(std::move(ipmi));
 
     std::vector<std::uint8_t> request = {
         0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobOpen,
@@ -237,7 +266,7 @@
     EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
     EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
 
-    EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+    EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
 
     const int writeBit = (1 << 1);
     const int lpcBit = (1 << 10);
@@ -249,8 +278,10 @@
 TEST_F(BlobHandlerTest, closeBlobSucceeds)
 {
     /* The close succeeds. */
-    IpmiInterfaceMock ipmiMock;
-    BlobHandler blob(&ipmiMock);
+    auto ipmi = CreateIpmiMock();
+    IpmiInterfaceMock* ipmiMock =
+        reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
+    BlobHandler blob(std::move(ipmi));
 
     std::vector<std::uint8_t> request = {
         0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobClose,
@@ -259,7 +290,7 @@
     std::vector<std::uint8_t> reqCrc = {0x01, 0x00};
     EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
 
-    EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+    EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
 
     blob.closeBlob(0x0001);
 }
@@ -267,8 +298,10 @@
 TEST_F(BlobHandlerTest, writeBytesSucceeds)
 {
     /* The write bytes succeeds. */
-    IpmiInterfaceMock ipmiMock;
-    BlobHandler blob(&ipmiMock);
+    auto ipmi = CreateIpmiMock();
+    IpmiInterfaceMock* ipmiMock =
+        reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
+    BlobHandler blob(std::move(ipmi));
 
     std::vector<std::uint8_t> request = {
         0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobWrite,
@@ -282,7 +315,7 @@
                                         0x00, 'a',  'b',  'c',  'd'};
     EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
 
-    EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+    EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
 
     blob.writeBytes(0x0001, 0, bytes);
 }
@@ -290,9 +323,10 @@
 TEST_F(BlobHandlerTest, readBytesSucceeds)
 {
     /* The reading of bytes succeeds. */
-
-    IpmiInterfaceMock ipmiMock;
-    BlobHandler blob(&ipmiMock);
+    auto ipmi = CreateIpmiMock();
+    IpmiInterfaceMock* ipmiMock =
+        reinterpret_cast<IpmiInterfaceMock*>(ipmi.get());
+    BlobHandler blob(std::move(ipmi));
 
     std::vector<std::uint8_t> request = {
         0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobRead,
@@ -310,7 +344,7 @@
     EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
     EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
 
-    EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+    EXPECT_CALL(*ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
 
     EXPECT_EQ(blob.readBytes(0x0001, 0, 4), expectedBytes);
 }