bmc: add test for reserved flags

Test that no one adds transport backends which use the lower 3 bits of
the transport flag bitfield. These bits are reserved for exclusive use
with the IPMI, LPC, and P2A backends to ensure backwards compatibility
with older host tools.

Signed-off-by: Benjamin Fair <benjaminfair@google.com>
Change-Id: I6284f2c864aeb5e20a812c0b13e9ecc61349b127
diff --git a/bmc/test/Makefile.am b/bmc/test/Makefile.am
index ce8ac08..9f1aa37 100644
--- a/bmc/test/Makefile.am
+++ b/bmc/test/Makefile.am
@@ -27,6 +27,7 @@
 	firmware_canhandle_unittest \
 	firmware_write_unittest \
 	firmware_writemeta_unittest \
+	firmware_open_unittest \
 	firmware_close_unittest \
 	firmware_sessionstat_unittest \
 	firmware_commit_unittest \
@@ -60,6 +61,9 @@
 firmware_writemeta_unittest_SOURCES = firmware_writemeta_unittest.cpp
 firmware_writemeta_unittest_LDADD = $(top_builddir)/bmc/libfirmwareblob_common.la
 
+firmware_open_unittest_SOURCES = firmware_open_unittest.cpp
+firmware_open_unittest_LDADD = $(top_builddir)/bmc/libfirmwareblob_common.la
+
 firmware_close_unittest_SOURCES = firmware_close_unittest.cpp
 firmware_close_unittest_LDADD = $(top_builddir)/bmc/libfirmwareblob_common.la
 
diff --git a/bmc/test/firmware_open_unittest.cpp b/bmc/test/firmware_open_unittest.cpp
new file mode 100644
index 0000000..21ab97b
--- /dev/null
+++ b/bmc/test/firmware_open_unittest.cpp
@@ -0,0 +1,63 @@
+#include "firmware_handler.hpp"
+#include "flags.hpp"
+#include "image_mock.hpp"
+#include "triggerable_mock.hpp"
+#include "util.hpp"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace ipmi_flash
+{
+namespace
+{
+
+class FirmwareOpenFailTest : public ::testing::TestWithParam<std::uint16_t>
+{
+};
+
+TEST_P(FirmwareOpenFailTest, WithFlags)
+{
+    std::vector<DataHandlerPack> data = {
+        {FirmwareFlags::UpdateFlags::ipmi, nullptr},
+        {FirmwareFlags::UpdateFlags::p2a, nullptr},
+        {FirmwareFlags::UpdateFlags::lpc, nullptr},
+    };
+
+    std::vector<HandlerPack> blobs;
+    blobs.push_back(std::move(
+        HandlerPack(hashBlobId, std::make_unique<ImageHandlerMock>())));
+    blobs.push_back(
+        std::move(HandlerPack("asdf", std::make_unique<ImageHandlerMock>())));
+
+    auto handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(
+        std::move(blobs), data, std::move(CreateActionMap("asdf")));
+
+    EXPECT_FALSE(handler->open(0, GetParam(), "asdf"));
+}
+
+const std::vector<std::uint16_t> OpenFailParams{
+    /* These first 4 fail because they don't have the "write" flag */
+    0b000 << 8,
+    0b110 << 8,
+    0b101 << 8,
+    0b011 << 8,
+    /* Next 1 doesn't specify any transport */
+    blobs::OpenFlags::write | 0b000 << 8,
+    /* Next 3 specify 2 reserved transport bits at the same time. This isn't
+     * allowed because older code expects these first 3 bits to be mutually
+     * exclusive.
+     */
+    blobs::OpenFlags::write | 0b110 << 8,
+    blobs::OpenFlags::write | 0b101 << 8,
+    blobs::OpenFlags::write | 0b011 << 8,
+};
+
+INSTANTIATE_TEST_CASE_P(WithFlags, FirmwareOpenFailTest,
+                        ::testing::ValuesIn(OpenFailParams));
+
+} // namespace
+} // namespace ipmi_flash