Support setting mount points in fake image loader client

Adds logic to register and load/unload components to fake image loader
client, so it can be used to test code that depends on image loader
client.

Introduces SetMountPathForComponent that sets up mount points
LoadComponent/LoadComponentAtPath return as component's mount point when
called (if a mount point has not been set, the LoadComponent methods
will fail).

Implements logic to register/remove components - it keeps mapping from a
registered component name to its version in memory.

BUG=863162

Change-Id: Iffa3504fc92d495cc46a35caffd3acdd4b7038c8
Reviewed-on: https://chromium-review.googlesource.com/1145463
Commit-Queue: Toni Barzic <tbarzic@chromium.org>
Reviewed-by: Dan Erat <derat@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576956}
diff --git a/chromeos/dbus/fake_image_loader_client.cc b/chromeos/dbus/fake_image_loader_client.cc
index 144336a1..4f327fa 100644
--- a/chromeos/dbus/fake_image_loader_client.cc
+++ b/chromeos/dbus/fake_image_loader_client.cc
@@ -6,45 +6,103 @@
 
 #include <utility>
 
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/location.h"
 #include "base/optional.h"
+#include "base/threading/thread_task_runner_handle.h"
 
 namespace chromeos {
 
+FakeImageLoaderClient::FakeImageLoaderClient() = default;
+
+FakeImageLoaderClient::~FakeImageLoaderClient() = default;
+
+void FakeImageLoaderClient::SetMountPathForComponent(
+    const std::string& component_name,
+    const base::FilePath& mount_path) {
+  mount_paths_[component_name] = mount_path;
+}
+
 void FakeImageLoaderClient::RegisterComponent(
     const std::string& name,
     const std::string& version,
     const std::string& component_folder_abs_path,
     DBusMethodCallback<bool> callback) {
-  std::move(callback).Run(base::nullopt);
+  registered_components_[name] = version;
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::BindOnce(std::move(callback), base::make_optional(true)));
 }
 
 void FakeImageLoaderClient::LoadComponent(
     const std::string& name,
     DBusMethodCallback<std::string> callback) {
-  std::move(callback).Run(base::nullopt);
+  const auto& version_it = registered_components_.find(name);
+  if (version_it == registered_components_.end()) {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(std::move(callback), base::nullopt));
+    return;
+  }
+
+  const auto& mount_path_it = mount_paths_.find(name);
+  if (mount_path_it == mount_paths_.end()) {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(std::move(callback), base::nullopt));
+    return;
+  }
+
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          std::move(callback),
+          base::make_optional(
+              mount_path_it->second.Append(version_it->second).value())));
 }
+
 void FakeImageLoaderClient::LoadComponentAtPath(
     const std::string& name,
     const base::FilePath& path,
     DBusMethodCallback<base::FilePath> callback) {
-  std::move(callback).Run(base::nullopt);
+  const auto& mount_path_it = mount_paths_.find(name);
+  if (mount_path_it == mount_paths_.end()) {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(std::move(callback), base::nullopt));
+    return;
+  }
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(std::move(callback),
+                                base::make_optional(mount_path_it->second)));
 }
 
 void FakeImageLoaderClient::RemoveComponent(const std::string& name,
                                             DBusMethodCallback<bool> callback) {
-  std::move(callback).Run(base::nullopt);
+  registered_components_.erase(name);
+  UnmountComponent(name, std::move(callback));
 }
 
 void FakeImageLoaderClient::RequestComponentVersion(
     const std::string& name,
     DBusMethodCallback<std::string> callback) {
-  std::move(callback).Run(base::nullopt);
+  const auto& version_it = registered_components_.find(name);
+  if (version_it == registered_components_.end()) {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(std::move(callback), base::nullopt));
+    return;
+  }
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(std::move(callback),
+                                base::make_optional(version_it->second)));
 }
 
 void FakeImageLoaderClient::UnmountComponent(
     const std::string& name,
     DBusMethodCallback<bool> callback) {
-  std::move(callback).Run(base::nullopt);
+  mount_paths_.erase(name);
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::BindOnce(std::move(callback), base::make_optional(true)));
 }
 
 }  // namespace chromeos
diff --git a/chromeos/dbus/fake_image_loader_client.h b/chromeos/dbus/fake_image_loader_client.h
index cb7f397..9b0615c 100644
--- a/chromeos/dbus/fake_image_loader_client.h
+++ b/chromeos/dbus/fake_image_loader_client.h
@@ -5,20 +5,29 @@
 #ifndef CHROMEOS_DBUS_FAKE_IMAGE_LOADER_CLIENT_H_
 #define CHROMEOS_DBUS_FAKE_IMAGE_LOADER_CLIENT_H_
 
+#include <map>
 #include <string>
 
 #include "base/macros.h"
 #include "chromeos/dbus/image_loader_client.h"
 
+namespace base {
+class FilePath;
+}
+
 namespace chromeos {
 
 // A fake implementation of ImageLoaderClient. This class does nothing.
 class CHROMEOS_EXPORT FakeImageLoaderClient : public ImageLoaderClient {
  public:
-  FakeImageLoaderClient() {}
-  ~FakeImageLoaderClient() override {}
+  FakeImageLoaderClient();
+  ~FakeImageLoaderClient() override;
 
-  // DBusClient ovveride.
+  // Sets intended mount path for a component.
+  void SetMountPathForComponent(const std::string& component_name,
+                                const base::FilePath& mount_path);
+
+  // DBusClient override.
   void Init(dbus::Bus* dbus) override {}
 
   // ImageLoaderClient override:
@@ -41,6 +50,14 @@
                         DBusMethodCallback<bool> callback) override;
 
  private:
+  // Maps registered component name to its registered varsion.
+  std::map<std::string, std::string> registered_components_;
+
+  // Maps component names to paths to which they should be mounted.
+  // Registered using SetMountPathForComponent() before LoadComponent*() is
+  // called, and removed by a later call to UnmountComponent().
+  std::map<std::string, base::FilePath> mount_paths_;
+
   DISALLOW_COPY_AND_ASSIGN(FakeImageLoaderClient);
 };