update_engine: Fake chromeos-setgoodkernel command for testing.

This patch fakes the chromeos-setgoodkernel command when running
unittests so the command doesn't attempt to run it. It also makes
Subprocess log the error message when there's a failure running
an async process.

BUG=chromium:401866
TEST=cros_workon_make update_engine --test

Change-Id: Ieca3216c57f6f9bc2f71a53e520575ae1fc19c0e
Reviewed-on: https://chromium-review.googlesource.com/212260
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/subprocess.cc b/subprocess.cc
index fb34267..aab71b5 100644
--- a/subprocess.cc
+++ b/subprocess.cc
@@ -148,6 +148,7 @@
   record->callback = callback;
   record->callback_data = p;
   gint stdout_fd = -1;
+  GError* error = nullptr;
   bool success = g_spawn_async_with_pipes(
       NULL,  // working directory
       argv.get(),
@@ -159,10 +160,10 @@
       NULL,
       &stdout_fd,
       NULL,
-      NULL);
+      &error);
   FreeArgv(argv.get());
   if (!success) {
-    LOG(ERROR) << "g_spawn_async failed";
+    LOG(ERROR) << "g_spawn_async failed: " << utils::GetAndFreeGError(&error);
     return 0;
   }
   record->tag =
diff --git a/update_attempter.cc b/update_attempter.cc
index 437ff42..05cfd49 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -1150,7 +1150,7 @@
   // the script runtime.
   update_boot_flags_running_ = true;
   LOG(INFO) << "Updating boot flags...";
-  vector<string> cmd(1, "/usr/sbin/chromeos-setgoodkernel");
+  vector<string> cmd{set_good_kernel_cmd_};
   if (!Subprocess::Get().Exec(cmd, StaticCompleteUpdateBootFlags, this)) {
     CompleteUpdateBootFlags(1);
   }
diff --git a/update_attempter.h b/update_attempter.h
index f29b4e8..ce827e3 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -457,6 +457,9 @@
   // True if UpdateBootFlags is running.
   bool update_boot_flags_running_ = false;
 
+  // The command to run to set the current kernel as good.
+  std::string set_good_kernel_cmd_ = "/usr/sbin/chromeos-setgoodkernel";
+
   // True if the action processor needs to be started by the boot flag updater.
   bool start_action_processor_ = false;
 
diff --git a/update_attempter_unittest.cc b/update_attempter_unittest.cc
index 632c297..c9ff687 100644
--- a/update_attempter_unittest.cc
+++ b/update_attempter_unittest.cc
@@ -71,6 +71,12 @@
 
     // Finish initializing the attempter.
     attempter_.Init();
+
+    // We set the set_good_kernel command to a non-existent path so it fails to
+    // run it. This avoids the async call to the command and continues the
+    // update process right away. Tests testing that behavior can override the
+    // default set_good_kernel command if needed.
+    attempter_.set_good_kernel_cmd_ = "/path/to/non-existent/command";
   }
 
   virtual void SetUp() {