firmware: implement verification service call

Add call to start the verification service unit.

Change-Id: I7bf124b9f317a857a85f06f59e3929982c868d8e
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/firmware_handler.cpp b/firmware_handler.cpp
index c6c7fa5..03cf1c2 100644
--- a/firmware_handler.cpp
+++ b/firmware_handler.cpp
@@ -27,6 +27,11 @@
 
 namespace blobs
 {
+// systemd service to kick start a target.
+static constexpr auto systemdService = "org.freedesktop.systemd1";
+static constexpr auto systemdRoot = "/org/freedesktop/systemd1";
+static constexpr auto systemdInterface = "org.freedesktop.systemd1.Manager";
+static constexpr auto verifyTarget = "verify_image.service";
 
 const std::string FirmwareBlobHandler::verifyBlobID = "/flash/verify";
 const std::string FirmwareBlobHandler::hashBlobID = "/flash/hash";
@@ -587,6 +592,23 @@
 
 bool FirmwareBlobHandler::triggerVerification()
 {
+    auto method = bus.new_method_call(systemdService, systemdRoot,
+                                      systemdInterface, "StartUnit");
+    method.append(verifyTarget);
+    method.append("replace");
+
+    try
+    {
+        bus.call_noreply(method);
+    }
+    catch (const sdbusplus::exception::SdBusError& ex)
+    {
+        /* TODO: Once logging supports unit-tests, add a log message to test
+         * this failure.
+         */
+        return false;
+    }
+
     state = UpdateState::verificationStarted;
 
     /* TODO: implement this. */
diff --git a/test/firmware_commit_unittest.cpp b/test/firmware_commit_unittest.cpp
index 35f48d6..7dca2b4 100644
--- a/test/firmware_commit_unittest.cpp
+++ b/test/firmware_commit_unittest.cpp
@@ -9,7 +9,12 @@
 
 namespace blobs
 {
+using ::testing::_;
+using ::testing::IsNull;
+using ::testing::NotNull;
 using ::testing::Return;
+using ::testing::StrEq;
+using ::testing::StrictMock;
 
 TEST(FirmwareHandlerCommitTest, VerifyCannotCommitOnFlashImage)
 {
@@ -112,7 +117,7 @@
         {FirmwareBlobHandler::UpdateFlags::ipmi, nullptr},
     };
 
-    sdbusplus::SdBusMock sdbus_mock;
+    StrictMock<sdbusplus::SdBusMock> sdbus_mock;
     auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock);
 
     auto handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(
@@ -121,6 +126,22 @@
     EXPECT_TRUE(
         handler->open(0, OpenFlags::write, FirmwareBlobHandler::verifyBlobID));
 
+    /* Note: I used StrictMock<> here to just catch all the calls.  However, the
+     * unit-tests pass if we don't use StrictMock and ignore the calls.
+     */
+    EXPECT_CALL(sdbus_mock,
+                sd_bus_message_new_method_call(
+                    IsNull(), NotNull(), StrEq("org.freedesktop.systemd1"),
+                    StrEq("/org/freedesktop/systemd1"),
+                    StrEq("org.freedesktop.systemd1.Manager"),
+                    StrEq("StartUnit")))
+        .WillOnce(Return(0));
+    EXPECT_CALL(sdbus_mock,
+                sd_bus_message_append_basic(IsNull(), 's', NotNull()))
+        .Times(2)
+        .WillRepeatedly(Return(0));
+    EXPECT_CALL(sdbus_mock, sd_bus_call(_, _, _, _, _)).WillOnce(Return(0));
+
     EXPECT_TRUE(handler->commit(0, {}));
     EXPECT_FALSE(handler->commit(0, {}));
 }