bmc: allow update to use systemd with path

Verification provides a mechanism that has a systemd unit and mode, and
also a path to check the result.  This object can be used for updates,
and will be renamed in a later patchset to be more generically named.

Signed-off-by: Patrick Venture <venture@google.com>
Change-Id: I0a995af0aefff76592247775f22fc84189d14903
diff --git a/bmc/buildjson.cpp b/bmc/buildjson.cpp
index 0be61be..8113d9c 100644
--- a/bmc/buildjson.cpp
+++ b/bmc/buildjson.cpp
@@ -118,6 +118,22 @@
                 pack->update = SystemdUpdateMechanism::CreateSystemdUpdate(
                     sdbusplus::bus::new_default(), rebootTarget, rebootMode);
             }
+            else if (updateType == "fileSystemdUpdate")
+            {
+                const auto& path = update.at("path");
+                const auto& unit = update.at("unit");
+
+                /* the mode parameter is optional. */
+                std::string systemdMode = "replace";
+                const auto& mode = update.find("mode");
+                if (mode != update.end())
+                {
+                    systemdMode = update.at("mode").get<std::string>();
+                }
+
+                pack->update = SystemdVerification::CreateVerification(
+                    sdbusplus::bus::new_default(), path, unit, systemdMode);
+            }
             else if (updateType == "systemd")
             {
                 const auto& unit = update.at("unit");
diff --git a/bmc/test/firmware_json_unittest.cpp b/bmc/test/firmware_json_unittest.cpp
index 70676bf..807856d 100644
--- a/bmc/test/firmware_json_unittest.cpp
+++ b/bmc/test/firmware_json_unittest.cpp
@@ -477,5 +477,50 @@
     EXPECT_THAT(updater->getMode(), "replace-fake");
 }
 
+TEST(FirmwareJsonTest, VerifyValidUpdateWithFilePath)
+{
+    auto j2 = R"(
+        [{
+            "blob" : "/flash/image",
+            "handler" : {
+                "type" : "file",
+                "path" : "/run/initramfs/bmc-image"
+            },
+            "actions" : {
+                "preparation" : {
+                    "type" : "systemd",
+                    "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
+                },
+                "verification" : {
+                    "type" : "fileSystemdVerify",
+                    "unit" : "phosphor-ipmi-flash-bmc-verify.target",
+                    "path" : "/tmp/bmc.verify",
+                    "mode" : "replace-nope"
+                },
+                "update" : {
+                    "type" : "fileSystemdUpdate",
+                    "mode" : "replace-fake",
+                    "unit" : "phosphor-ipmi-flash-bmc-update.target",
+                    "path" : "/tmp/update.verify"
+                }
+            }
+         }]
+    )"_json;
+
+    auto h = buildHandlerFromJson(j2);
+    EXPECT_EQ(h[0].blobId, "/flash/image");
+    EXPECT_FALSE(h[0].handler == nullptr);
+    EXPECT_FALSE(h[0].actions == nullptr);
+    EXPECT_FALSE(h[0].actions->preparation == nullptr);
+    EXPECT_FALSE(h[0].actions->verification == nullptr);
+    auto verifier = reinterpret_cast<SystemdVerification*>(
+        h[0].actions->verification.get());
+    EXPECT_THAT(verifier->getMode(), "replace-nope");
+    EXPECT_FALSE(h[0].actions->update == nullptr);
+    auto updater =
+        reinterpret_cast<SystemdVerification*>(h[0].actions->update.get());
+    EXPECT_THAT(updater->getMode(), "replace-fake");
+}
+
 } // namespace
 } // namespace ipmi_flash