firmware: enable fileOpen state

At any point, only one file can be open.  The firmware update handler
will allow either the firmware image or the hash file to be open at
once, but not both.  And not any other combination of blob_ids.

Change-Id: I8f7cfbe570647549ea04ca66a2d423c40e2e6aeb
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/firmware_handler.cpp b/firmware_handler.cpp
index 10f427a..09f8b10 100644
--- a/firmware_handler.cpp
+++ b/firmware_handler.cpp
@@ -239,7 +239,6 @@
     if (path == hashBlobID)
     {
         /* 2c) are they opening the /flash/hash ? (to start the process) */
-
         curr = &activeHash;
         active = &activeHashBlobID;
     }
@@ -289,6 +288,8 @@
 
     blobIDs.push_back(*active);
 
+    fileOpen = true;
+
     return true;
 }
 
@@ -390,6 +391,10 @@
  */
 bool FirmwareBlobHandler::close(uint16_t session)
 {
+    fileOpen = false;
+
+    /* TODO: implement other aspects of closing out a session. */
+
     return false;
 }
 
diff --git a/test/firmware_open_unittest.cpp b/test/firmware_open_unittest.cpp
index d2c601a..78c5d69 100644
--- a/test/firmware_open_unittest.cpp
+++ b/test/firmware_open_unittest.cpp
@@ -11,6 +11,7 @@
 {
 using ::testing::Eq;
 using ::testing::Return;
+using ::testing::StrEq;
 
 TEST(FirmwareHandlerOpenTest, OpenWithEverythingValid)
 {
@@ -132,6 +133,50 @@
     EXPECT_EQ(2, currentBlobs.size());
 }
 
+TEST(FirmwareHandlerOpenTest, OpenEverythingSucceedsVerifyOpenFileCheck)
+{
+    /* Verify only one file can be open at a time by opening a file, trying
+     * again, then closing, and trying again.
+     */
+    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"));
+
+    /* The active image blob_id was added. */
+    auto currentBlobs = handler->getBlobIds();
+    EXPECT_EQ(3, currentBlobs.size());
+    EXPECT_EQ(1, std::count(currentBlobs.begin(), currentBlobs.end(),
+                            FirmwareBlobHandler::activeImageBlobID));
+
+    /* Open the hash file (since we opened an image file). */
+    EXPECT_FALSE(handler->open(
+        1, OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi,
+        FirmwareBlobHandler::hashBlobID));
+
+    /* Close the file, currently ignoring its return value. */
+    handler->close(0);
+
+    EXPECT_CALL(imageMock1, open(StrEq(FirmwareBlobHandler::hashBlobID)))
+        .WillOnce(Return(true));
+
+    EXPECT_TRUE(handler->open(
+        1, OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi,
+        FirmwareBlobHandler::hashBlobID));
+}
+
 TEST(FirmwareHandlerOpenTest, OpenEverythingSucceedsOpenActiveFails)
 {
     /* Attempting to open the active image blob, when it's present will fail.
@@ -162,6 +207,11 @@
     EXPECT_EQ(1, std::count(currentBlobs.begin(), currentBlobs.end(),
                             FirmwareBlobHandler::activeImageBlobID));
 
+    /* Close only active session, to verify it's failing on attempt to open a
+     * specific blob_id.
+     */
+    handler->close(0);
+
     EXPECT_FALSE(handler->open(
         1, OpenFlags::write | FirmwareBlobHandler::UpdateFlags::ipmi,
         FirmwareBlobHandler::activeImageBlobID));