// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "garnet/bin/appmgr/component_controller_impl.h"

#include <fs/pseudo-dir.h>
#include <fs/remote-dir.h>
#include <fs/synchronous-vfs.h>
#include <lib/fdio/spawn.h>

#include "garnet/bin/appmgr/util.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "lib/fsl/handles/object_info.h"
#include "lib/fxl/strings/split_string.h"
#include "lib/gtest/real_loop_fixture.h"
#include "lib/svc/cpp/services.h"

namespace component {
namespace {

using fuchsia::sys::ServiceList;
using fuchsia::sys::ServiceListPtr;
using fuchsia::sys::TerminationReason;

template <typename T>
class ComponentContainerImpl : public ComponentContainer<T> {
 public:
  size_t ComponentCount() { return components_.size(); }
  const std::string koid() { return "5342"; }

  void AddComponent(std::unique_ptr<T> component);

  std::unique_ptr<T> ExtractComponent(T* controller) override;

 private:
  std::unordered_map<T*, std::unique_ptr<T>> components_;
};

template <typename T>
void ComponentContainerImpl<T>::AddComponent(std::unique_ptr<T> component) {
  auto key = component.get();
  components_.emplace(key, std::move(component));
}

template <typename T>
std::unique_ptr<T> ComponentContainerImpl<T>::ExtractComponent(T* controller) {
  auto it = components_.find(controller);
  if (it == components_.end()) {
    return nullptr;
  }
  auto component = std::move(it->second);

  components_.erase(it);
  return component;
}

// Get a list of the default service entries that exist in every namespace.
// See |Namespace::Namespace| constructor.
std::vector<std::string> GetDefaultNamespaceServiceEntries() {
  return std::vector<std::string>{
      ".", fuchsia::sys::Environment::Name_, Namespace::Launcher::Name_,
      fuchsia::process::Launcher::Name_, fuchsia::process::Resolver::Name_};
}

// Create a new Namespace that contains the default services available to all
// namespaces, plus the given |service_names|. The resulting object is useful
// for listing its service names but not much else.
fxl::RefPtr<Namespace> CreateFakeNamespace(
    const std::vector<const char*>& extra_service_names) {
  ServiceListPtr service_list(new ServiceList());
  for (auto& service : extra_service_names) {
    service_list->names.push_back(service);
  }
  return fxl::MakeRefCounted<Namespace>(nullptr, nullptr,
                                        std::move(service_list), nullptr);
}

std::vector<std::string> SplitPath(const std::string& path) {
  return fxl::SplitStringCopy(path, "/",
                              fxl::WhiteSpaceHandling::kKeepWhitespace,
                              fxl::SplitResult::kSplitWantAll);
}

bool PathExists(const fbl::RefPtr<fs::PseudoDir>& hub_dir, std::string path,
                fbl::RefPtr<fs::Vnode>* out = nullptr) {
  auto tokens = SplitPath(path);
  auto ntokens = tokens.size();
  fbl::RefPtr<fs::Vnode> dir = hub_dir;
  fbl::RefPtr<fs::Vnode> pdir;
  for (size_t i = 0; i < ntokens; i++) {
    auto token = tokens[i];
    pdir = dir;
    if (pdir->Lookup(&dir, token) != ZX_OK) {
      return false;
    }
  }
  if (out != nullptr) {
    *out = dir;
  }
  return true;
}

// Get a list of names of the entries in a directory. This will generally
// include at least "." (i.e. the current directory).
std::vector<std::string> GetDirectoryEntries(fbl::RefPtr<fs::Vnode> dir) {
  std::vector<std::string> entry_names{};
  // Arbitrary size.
  uint8_t buffer[4096];

  fs::vdircookie_t cookie{};
  // Actual number of bytes read into the buffer.
  size_t real_len = 0;
  while (dir->Readdir(&cookie, buffer, sizeof(buffer), &real_len) == ZX_OK &&
         real_len > 0) {
    size_t offset = 0;
    while (offset < real_len) {
      auto dir_entry = reinterpret_cast<vdirent_t*>(buffer + offset);
      size_t entry_size = sizeof(vdirent_t) + dir_entry->size;
      std::string name(dir_entry->name, dir_entry->size);
      entry_names.push_back(name);
      offset += entry_size;
    }
  }
  return entry_names;
}

// Assert that the hub for the given component has "in", "in/svc", default
// services, and the given extra service names.
void AssertHubHasIncomingServices(
    const ComponentControllerBase* component,
    const std::vector<std::string>& extra_service_names) {
  ASSERT_TRUE(PathExists(component->hub_dir(), "in"));
  fbl::RefPtr<fs::Vnode> in_svc_dir;
  ASSERT_TRUE(PathExists(component->hub_dir(), "in/svc", &in_svc_dir));
  for (auto& service : extra_service_names) {
    EXPECT_TRUE(PathExists(component->hub_dir(), "in/svc/" + service));
  }

  // Default entries from namespace, plus the two we added.
  auto expected_entries = GetDefaultNamespaceServiceEntries();
  expected_entries.insert(expected_entries.end(), extra_service_names.begin(),
                          extra_service_names.end());
  EXPECT_THAT(GetDirectoryEntries(in_svc_dir),
              ::testing::ElementsAreArray(expected_entries));
}

typedef ComponentContainerImpl<ComponentControllerImpl> FakeRealm;
typedef ComponentContainerImpl<ComponentBridge> FakeRunner;

class ComponentControllerTest : public gtest::RealLoopFixture {
 public:
  void SetUp() override {
    gtest::RealLoopFixture::SetUp();
    vfs_.SetDispatcher(async_get_default_dispatcher());

    // create child job
    zx_status_t status = zx::job::create(*zx::job::default_job(), 0u, &job_);
    ASSERT_EQ(status, ZX_OK);

    // create process
    const char* argv[] = {"sh", NULL};
    char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
    status = fdio_spawn_etc(job_.get(), FDIO_SPAWN_CLONE_ALL, "/boot/bin/sh",
                            argv, NULL, 0, NULL,
                            process_.reset_and_get_address(), err_msg);
    ASSERT_EQ(status, ZX_OK) << err_msg;
    process_koid_ = std::to_string(fsl::GetKoid(process_.get()));
  }

  void TearDown() override {
    if (job_) {
      job_.kill();
    }
    gtest::RealLoopFixture::TearDown();
  }

 protected:
  std::unique_ptr<ComponentControllerImpl> CreateComponent(
      fuchsia::sys::ComponentControllerPtr& controller,
      ExportedDirType export_dir_type = ExportedDirType::kLegacyFlatLayout,
      zx::channel export_dir = zx::channel(),
      fxl::RefPtr<Namespace> ns = CreateFakeNamespace({})) {
    // job_ is used later in a test to check the job-id, so we need to make a
    // clone of it to pass into std::move
    zx::job job_clone;
    zx_status_t status = job_.duplicate(ZX_RIGHT_SAME_RIGHTS, &job_clone);
    if (status != ZX_OK)
      return NULL;
    return std::make_unique<ComponentControllerImpl>(
        controller.NewRequest(), &realm_, std::move(job_clone),
        std::move(process_), "test-url", "test-arg", "test-label", ns,
        export_dir_type, std::move(export_dir), zx::channel(),
        MakeForwardingTerminationCallback());
  }

  FakeRealm realm_;
  zx::job job_;
  std::string process_koid_;
  zx::process process_;
  fs::SynchronousVfs vfs_;
};

class ComponentBridgeTest : public gtest::RealLoopFixture,
                            public fuchsia::sys::ComponentController {
 public:
  ComponentBridgeTest()
      : binding_(this), binding_error_handler_called_(false) {}
  void SetUp() override {
    gtest::RealLoopFixture::SetUp();
    vfs_.SetDispatcher(async_get_default_dispatcher());
    binding_.Bind(remote_controller_.NewRequest());
    binding_.set_error_handler([this](zx_status_t status) {
      binding_error_handler_called_ = true;
      Kill();
    });
  }

  void Kill() override {
    SendReturnCode();
    binding_.Unbind();
  }

  void Detach() override { binding_.set_error_handler(nullptr); }

 protected:
  std::unique_ptr<ComponentBridge> CreateComponentBridge(
      fuchsia::sys::ComponentControllerPtr& controller,
      ExportedDirType export_dir_type = ExportedDirType::kLegacyFlatLayout,
      zx::channel export_dir = zx::channel(),
      fxl::RefPtr<Namespace> ns = CreateFakeNamespace({})) {
    // only allow creation of one component.
    if (!remote_controller_) {
      return nullptr;
    }
    auto component = std::make_unique<ComponentBridge>(
        controller.NewRequest(), std::move(remote_controller_), &runner_,
        "test-url", "test-arg", "test-label", "1", ns, export_dir_type,
        std::move(export_dir), zx::channel(),
        MakeForwardingTerminationCallback());
    component->SetParentJobId(runner_.koid());
    return component;
  }

  void SetReturnCode(int64_t errcode) { errcode_ = errcode; }

  void SendReady() { binding_.events().OnDirectoryReady(); }

  void SendReturnCode() {
    binding_.events().OnTerminated(errcode_, TerminationReason::EXITED);
  }

  FakeRunner runner_;
  ::fidl::Binding<fuchsia::sys::ComponentController> binding_;
  fuchsia::sys::ComponentControllerPtr remote_controller_;
  fs::SynchronousVfs vfs_;
  int64_t errcode_ = 1;

  bool binding_error_handler_called_;
};

fbl::String get_value(const fbl::RefPtr<fs::PseudoDir>& hub_dir,
                      std::string path) {
  auto tokens = SplitPath(path);
  auto ntokens = tokens.size();
  fbl::RefPtr<fs::Vnode> node = hub_dir;
  fbl::RefPtr<fs::Vnode> pdir;
  for (size_t i = 0; i < ntokens; i++) {
    auto token = tokens[i];
    pdir = node;
    if (pdir->Lookup(&node, token) != ZX_OK) {
      EXPECT_FALSE(true) << token << " not found";
      return "";
    }
  }
  fbl::RefPtr<fs::Vnode> file;
  if (node->Open(ZX_FS_RIGHT_READABLE, &file) != ZX_OK) {
    EXPECT_FALSE(true) << "cannot open: " << path;
    return "";
  }
  char buf[1024];
  size_t read_len;
  file->Read(buf, sizeof(buf), 0, &read_len);
  return fbl::String(buf, read_len);
}

TEST_F(ComponentControllerTest, CreateAndKill) {
  fuchsia::sys::ComponentControllerPtr component_ptr;
  auto component = CreateComponent(component_ptr);
  auto hub_info = component->HubInfo();

  EXPECT_EQ(hub_info.label(), "test-label");
  EXPECT_EQ(hub_info.koid(), process_koid_);

  ASSERT_EQ(realm_.ComponentCount(), 0u);
  realm_.AddComponent(std::move(component));

  ASSERT_EQ(realm_.ComponentCount(), 1u);

  bool wait = false;
  int64_t return_code;
  TerminationReason termination_reason;
  component_ptr.events().OnTerminated = [&](int64_t err,
                                            TerminationReason reason) {
    return_code = err;
    termination_reason = reason;
    wait = true;
  };
  component_ptr->Kill();
  EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&wait] { return wait; }, zx::sec(5)));

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(-1, return_code);
  EXPECT_EQ(TerminationReason::EXITED, termination_reason);
  EXPECT_EQ(realm_.ComponentCount(), 0u);
}

TEST_F(ComponentControllerTest, CreateAndDeleteWithoutKilling) {
  fuchsia::sys::ComponentControllerPtr component_ptr;
  int64_t return_code = 0;
  TerminationReason termination_reason = TerminationReason::INTERNAL_ERROR;

  auto component = CreateComponent(component_ptr);
  auto* component_to_remove = component.get();
  realm_.AddComponent(std::move(component));
  component_ptr.events().OnTerminated = [&](int64_t err,
                                            TerminationReason reason) {
    return_code = err;
    termination_reason = reason;
  };
  realm_.ExtractComponent(component_to_remove);

  EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&return_code] { return return_code; },
                                        zx::sec(5)));

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(-1, return_code);
  EXPECT_EQ(TerminationReason::UNKNOWN, termination_reason);
  EXPECT_EQ(realm_.ComponentCount(), 0u);
}

TEST_F(ComponentControllerTest, ControllerScope) {
  {
    fuchsia::sys::ComponentControllerPtr component_ptr;
    auto component = CreateComponent(component_ptr);
    realm_.AddComponent(std::move(component));

    ASSERT_EQ(realm_.ComponentCount(), 1u);
  }
  EXPECT_TRUE(RunLoopWithTimeoutOrUntil(
      [this]() { return realm_.ComponentCount() == 0; }, zx::sec(5)));
}

TEST_F(ComponentControllerTest, DetachController) {
  bool wait = false;
  {
    fuchsia::sys::ComponentControllerPtr component_ptr;
    auto component = CreateComponent(component_ptr);
    component_ptr.events().OnTerminated =
        [&](int64_t return_code, TerminationReason termination_reason) {
          wait = true;
        };
    realm_.AddComponent(std::move(component));

    ASSERT_EQ(realm_.ComponentCount(), 1u);

    // detach controller before it goes out of scope and then test that our
    // component did not die.
    component_ptr->Detach();
    RunLoopUntilIdle();
  }

  // make sure all messages are processed if Kill was called.
  RunLoopUntilIdle();
  ASSERT_FALSE(wait);
  EXPECT_EQ(realm_.ComponentCount(), 1u);
}

TEST_F(ComponentControllerTest, Hub) {
  zx::channel export_dir, export_dir_req;
  ASSERT_EQ(zx::channel::create(0, &export_dir, &export_dir_req), ZX_OK);
  vfs_.ServeDirectory(fbl::MakeRefCounted<fs::PseudoDir>(),
                      std::move(export_dir));

  fuchsia::sys::ComponentControllerPtr component_ptr;

  auto component =
      CreateComponent(component_ptr, ExportedDirType::kPublicDebugCtrlLayout,
                      std::move(export_dir_req));

  bool ready = false;
  component_ptr.events().OnDirectoryReady = [&ready] { ready = true; };
  RunLoopWithTimeoutOrUntil([&ready] { return ready; }, zx::sec(10));

  EXPECT_TRUE(PathExists(component->hub_dir(), "out"));
  EXPECT_STREQ(get_value(component->hub_dir(), "name").c_str(), "test-label");
  EXPECT_STREQ(get_value(component->hub_dir(), "args").c_str(), "test-arg");
  EXPECT_STREQ(get_value(component->hub_dir(), "job-id").c_str(),
               std::to_string(fsl::GetKoid(job_.get())).c_str());
  EXPECT_STREQ(get_value(component->hub_dir(), "url").c_str(), "test-url");
  EXPECT_STREQ(get_value(component->hub_dir(), "process-id").c_str(),
               process_koid_.c_str());

  // "in", "in/svc", and default services should exist.
  AssertHubHasIncomingServices(component.get(), {});

  fbl::RefPtr<fs::Vnode> out_dir;
  ASSERT_TRUE(PathExists(component->hub_dir(), "out", &out_dir));
  ASSERT_TRUE(out_dir->IsRemote());
}

TEST_F(ComponentControllerTest, HubWithIncomingServices) {
  zx::channel export_dir, export_dir_req;
  ASSERT_EQ(zx::channel::create(0, &export_dir, &export_dir_req), ZX_OK);
  vfs_.ServeDirectory(fbl::MakeRefCounted<fs::PseudoDir>(),
                      std::move(export_dir));

  fuchsia::sys::ComponentControllerPtr component_ptr;

  fxl::RefPtr<Namespace> ns = CreateFakeNamespace({"service_a", "service_b"});

  auto component =
      CreateComponent(component_ptr, ExportedDirType::kPublicDebugCtrlLayout,
                      std::move(export_dir_req), ns);

  bool ready = false;
  component_ptr.events().OnDirectoryReady = [&ready] { ready = true; };
  RunLoopWithTimeoutOrUntil([&ready] { return ready; }, zx::sec(10));

  AssertHubHasIncomingServices(component.get(), {"service_a", "service_b"});
}

TEST_F(ComponentBridgeTest, CreateAndKill) {
  fuchsia::sys::ComponentControllerPtr component_ptr;
  auto component = CreateComponentBridge(component_ptr);
  auto hub_info = component->HubInfo();

  EXPECT_EQ(hub_info.label(), "test-label");

  ASSERT_EQ(runner_.ComponentCount(), 0u);
  runner_.AddComponent(std::move(component));

  ASSERT_EQ(runner_.ComponentCount(), 1u);

  bool wait = false;
  bool ready = false;
  int64_t retval;
  TerminationReason termination_reason;
  component_ptr.events().OnTerminated = [&wait, &retval, &termination_reason](
                                            int64_t errcode,
                                            TerminationReason tr) {
    wait = true;
    retval = errcode;
    termination_reason = tr;
  };
  component_ptr.events().OnDirectoryReady = [&ready] { ready = true; };
  int64_t expected_retval = (1L << 60);
  SendReady();
  SetReturnCode(expected_retval);
  component_ptr->Kill();
  EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&wait] { return wait; }, zx::sec(5)));
  EXPECT_TRUE(ready);
  EXPECT_EQ(expected_retval, retval);
  EXPECT_EQ(TerminationReason::EXITED, termination_reason);

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(runner_.ComponentCount(), 0u);
}

TEST_F(ComponentBridgeTest, CreateAndDeleteWithoutKilling) {
  fuchsia::sys::ComponentControllerPtr component_ptr;
  auto component = CreateComponentBridge(component_ptr);
  auto* component_to_remove = component.get();
  component->SetTerminationReason(TerminationReason::INTERNAL_ERROR);
  runner_.AddComponent(std::move(component));

  bool terminated = false;
  int64_t retval = 0;
  TerminationReason termination_reason;
  component_ptr.events().OnTerminated = [&](int64_t errcode,
                                            TerminationReason tr) {
    terminated = true;
    retval = errcode;
    termination_reason = tr;
  };
  // Component controller called OnTerminated before the component is destroyed,
  // so we expect the value set above (INTERNAL_ERROR).
  runner_.ExtractComponent(component_to_remove);
  EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&terminated] { return terminated; },
                                        zx::sec(5)));
  EXPECT_EQ(-1, retval);
  EXPECT_EQ(TerminationReason::INTERNAL_ERROR, termination_reason);

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(runner_.ComponentCount(), 0u);
}

TEST_F(ComponentBridgeTest, RemoteComponentDied) {
  fuchsia::sys::ComponentControllerPtr component_ptr;
  auto component = CreateComponentBridge(component_ptr);
  component->SetTerminationReason(TerminationReason::EXITED);
  runner_.AddComponent(std::move(component));

  bool terminated = false;
  int64_t retval = 0;
  TerminationReason termination_reason;
  component_ptr.events().OnTerminated = [&](int64_t errcode,
                                            TerminationReason tr) {
    terminated = true;
    retval = errcode;
    termination_reason = tr;
  };
  // Even though the termination reason was set above, unbinding and closing the
  // channel will cause the bridge to return UNKNOWN>.
  binding_.Unbind();
  EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&terminated] { return terminated; },
                                        zx::sec(5)));
  EXPECT_EQ(-1, retval);
  EXPECT_EQ(TerminationReason::UNKNOWN, termination_reason);
  EXPECT_EQ(0u, runner_.ComponentCount());

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(runner_.ComponentCount(), 0u);
}

TEST_F(ComponentBridgeTest, ControllerScope) {
  bool wait = false;
  {
    fuchsia::sys::ComponentControllerPtr component_ptr;
    auto component = CreateComponentBridge(component_ptr);
    component->OnTerminated(
        [&wait](int64_t return_code, TerminationReason termination_reason) {
          wait = true;
        });
    runner_.AddComponent(std::move(component));
    ASSERT_EQ(runner_.ComponentCount(), 1u);
  }
  EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&wait] { return wait; }, zx::sec(5)));

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(runner_.ComponentCount(), 0u);
}

TEST_F(ComponentBridgeTest, DetachController) {
  bool wait = false;
  ComponentBridge* component_bridge_ptr;
  {
    fuchsia::sys::ComponentControllerPtr component_ptr;
    auto component = CreateComponentBridge(component_ptr);
    component_bridge_ptr = component.get();
    runner_.AddComponent(std::move(component));

    ASSERT_EQ(runner_.ComponentCount(), 1u);

    // detach controller before it goes out of scope and then test that our
    // component did not die.
    component_ptr->Detach();
    RunLoopUntilIdle();
  }

  // make sure all messages are processed if Kill was called.
  RunLoopUntilIdle();
  ASSERT_FALSE(wait);
  EXPECT_EQ(runner_.ComponentCount(), 1u);

  // bridge should be still connected, kill that to see if we are able to kill
  // real component.
  component_bridge_ptr->OnTerminated(
      [&wait](int64_t return_code, TerminationReason termination_reason) {
        wait = true;
      });
  component_bridge_ptr->Kill();
  EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&wait] { return wait; }, zx::sec(5)));

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(runner_.ComponentCount(), 0u);
}

TEST_F(ComponentBridgeTest, Hub) {
  zx::channel export_dir, export_dir_req;
  ASSERT_EQ(zx::channel::create(0, &export_dir, &export_dir_req), ZX_OK);
  vfs_.ServeDirectory(fbl::MakeRefCounted<fs::PseudoDir>(),
                      std::move(export_dir));

  fuchsia::sys::ComponentControllerPtr component_ptr;

  auto component = CreateComponentBridge(
      component_ptr, ExportedDirType::kPublicDebugCtrlLayout,
      std::move(export_dir_req));

  RunLoopWithTimeoutOrUntil(
      [this, &component] { return PathExists(component->hub_dir(), "out"); },
      zx::sec(10));

  EXPECT_STREQ(get_value(component->hub_dir(), "name").c_str(), "test-label");
  EXPECT_STREQ(get_value(component->hub_dir(), "args").c_str(), "test-arg");
  EXPECT_STREQ(get_value(component->hub_dir(), "job-id").c_str(),
               runner_.koid().c_str());
  EXPECT_STREQ(get_value(component->hub_dir(), "url").c_str(), "test-url");
  fbl::RefPtr<fs::Vnode> out_dir;
  ASSERT_TRUE(PathExists(component->hub_dir(), "out", &out_dir));
  ASSERT_TRUE(out_dir->IsRemote());

  // "in", "in/svc", and default services should exist.
  AssertHubHasIncomingServices(component.get(), {});
}

TEST_F(ComponentBridgeTest, HubWithIncomingServices) {
  zx::channel export_dir, export_dir_req;
  ASSERT_EQ(zx::channel::create(0, &export_dir, &export_dir_req), ZX_OK);
  vfs_.ServeDirectory(fbl::MakeRefCounted<fs::PseudoDir>(),
                      std::move(export_dir));

  fuchsia::sys::ComponentControllerPtr component_ptr;

  fxl::RefPtr<Namespace> ns = CreateFakeNamespace({"service_a", "service_b"});

  auto component = CreateComponentBridge(
      component_ptr, ExportedDirType::kPublicDebugCtrlLayout,
      std::move(export_dir_req), ns);

  RunLoopWithTimeoutOrUntil(
      [this, &component] { return PathExists(component->hub_dir(), "out"); },
      zx::sec(10));

  AssertHubHasIncomingServices(component.get(), {"service_a", "service_b"});
}

TEST_F(ComponentBridgeTest, BindingErrorHandler) {
  zx::channel export_dir, export_dir_req;
  ASSERT_EQ(zx::channel::create(0, &export_dir, &export_dir_req), ZX_OK);

  fuchsia::sys::ComponentControllerPtr component_ptr;
  {
    // let it go out of scope, that should trigger binding error handler.
    auto component = CreateComponentBridge(
        component_ptr, ExportedDirType::kPublicDebugCtrlLayout,
        std::move(export_dir_req));
  }
  EXPECT_TRUE(RunLoopWithTimeoutOrUntil([this] { return !binding_.is_bound(); },
                                        zx::sec(5)));
  EXPECT_TRUE(binding_error_handler_called_);
}

TEST_F(ComponentBridgeTest, BindingErrorHandlerWhenDetached) {
  zx::channel export_dir, export_dir_req;
  ASSERT_EQ(zx::channel::create(0, &export_dir, &export_dir_req), ZX_OK);

  fuchsia::sys::ComponentControllerPtr component_ptr;
  {
    // let it go out of scope, that should trigger binding error handler.
    auto component = CreateComponentBridge(
        component_ptr, ExportedDirType::kPublicDebugCtrlLayout,
        std::move(export_dir_req));
    component_ptr->Detach();
    RunLoopUntilIdle();
  }
  EXPECT_TRUE(RunLoopWithTimeoutOrUntil([this] { return !binding_.is_bound(); },
                                        zx::sec(5)));
  EXPECT_TRUE(binding_error_handler_called_);
}

TEST(ComponentControllerUnitTest, GetDirectoryEntries) {
  auto dir = fbl::AdoptRef<fs::PseudoDir>(new fs::PseudoDir());
  auto subdir = fbl::AdoptRef<fs::Vnode>(new fs::PseudoDir());
  auto file1 = fbl::AdoptRef<fs::Vnode>(new fs::UnbufferedPseudoFile());
  auto file2 = fbl::AdoptRef<fs::Vnode>(new fs::UnbufferedPseudoFile());

  // add entries
  EXPECT_EQ(ZX_OK, dir->AddEntry("subdir", subdir));
  EXPECT_EQ(ZX_OK, dir->AddEntry("file1", file1));
  EXPECT_EQ(ZX_OK, dir->AddEntry("file2", file2));

  const std::vector<std::string> entries = GetDirectoryEntries(dir);
  EXPECT_THAT(entries, ::testing::ElementsAre(".", "subdir", "file1", "file2"));
}

}  // namespace
}  // namespace component
