// 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 <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/sys/internal/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/default.h>
#include <lib/async/dispatcher.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/spawn.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/sys/cpp/file_descriptor.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/sys/cpp/testing/enclosing_environment.h>
#include <lib/sys/cpp/testing/test_with_environment.h>
#include <lib/syslog/cpp/macros.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <zircon/errors.h>
#include <zircon/process.h>
#include <zircon/rights.h>
#include <zircon/status.h>

#include <fstream>
#include <memory>
#include <string>
#include <vector>

#include <fidl/examples/echo/cpp/fidl.h>
#include <fs/pseudo_dir.h>
#include <fs/synchronous_vfs.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <test/appmgr/integration/cpp/fidl.h>

#include "fuchsia/testing/appmgr/cpp/fidl.h"
#include "lib/vfs/cpp/service.h"
#include "src/lib/files/file.h"
#include "src/lib/files/glob.h"
#include "src/lib/files/scoped_temp_dir.h"
#include "src/lib/fsl/handles/object_info.h"
#include "src/lib/fxl/strings/substitute.h"
#include "src/sys/appmgr/component_controller_impl.h"
#include "src/sys/appmgr/integration_tests/util/data_file_reader_writer_util.h"
#include "src/sys/appmgr/realm.h"
#include "src/sys/appmgr/util.h"

namespace component {
namespace {

using fuchsia::sys::TerminationReason;

using ::testing::AnyOf;
using ::testing::Eq;

using sys::testing::EnclosingEnvironment;
using sys::testing::TestWithEnvironment;
using test::appmgr::integration::DataFileReaderWriterPtr;

class RealmTest : virtual public TestWithEnvironment {
 protected:
  void SetUp() override {
    TestWithEnvironment::SetUp();
    OpenNewOutFile();
  }

  void OpenNewOutFile() {
    ASSERT_TRUE(tmp_dir_.NewTempFile(&out_file_));
    outf_ = fileno(std::fopen(out_file_.c_str(), "w"));
  }

  std::string ReadOutFile() {
    std::string out;
    if (!files::ReadFileToString(out_file_, &out)) {
      FX_LOGS(ERROR) << "Could not read output file " << out_file_;
      return "";
    }
    return out;
  }

  fuchsia::sys::LaunchInfo CreateLaunchInfo(const std::string& url,
                                            zx::channel directory_request = zx::channel(),
                                            const std::vector<std::string>& args = {}) {
    fuchsia::sys::LaunchInfo launch_info;
    launch_info.url = url;
    launch_info.arguments = args;
    if (directory_request.is_valid()) {
      launch_info.directory_request = std::move(directory_request);
    }
    launch_info.out = sys::CloneFileDescriptor(outf_);
    launch_info.err = sys::CloneFileDescriptor(STDERR_FILENO);
    return launch_info;
  }

  fuchsia::sys::ComponentControllerPtr RunComponent(EnclosingEnvironment* enclosing_environment,
                                                    const std::string& url,
                                                    zx::channel directory_request = zx::channel(),
                                                    const std::vector<std::string>& args = {}) {
    return enclosing_environment->CreateComponent(
        CreateLaunchInfo(url, std::move(directory_request), std::move(args)));
  }

 private:
  files::ScopedTempDir tmp_dir_;
  std::string out_file_;
  int outf_;
};

constexpr char kRealm[] = "realmintegrationtest";

TEST_F(RealmTest, Resolve) {
  auto enclosing_environment = CreateNewEnclosingEnvironment(kRealm, CreateServices());

  auto resolver = enclosing_environment->ConnectToService<fuchsia::process::Resolver>();

  bool wait = false;
  resolver->Resolve(
      "fuchsia-pkg://fuchsia.com/appmgr_integration_tests#test/"
      "appmgr_realm_integration_tests",
      [&wait](zx_status_t status, zx::vmo binary,
              fidl::InterfaceHandle<fuchsia::ldsvc::Loader> loader) {
        wait = true;

        ASSERT_EQ(ZX_OK, status);

        std::string expect;
        files::ReadFileToString("/pkg/test/appmgr_realm_integration_tests", &expect);
        ASSERT_FALSE(expect.empty());

        std::vector<char> buf(expect.length());
        ASSERT_EQ(ZX_OK, binary.read(buf.data(), 0, buf.size()));
        std::string actual(buf.begin(), buf.end());

        ASSERT_EQ(expect, actual);
      });
  RunLoopUntil([&wait] { return wait; });
}

TEST_F(RealmTest, LaunchNonExistentComponent) {
  auto env_services = CreateServices();
  auto enclosing_environment = CreateNewEnclosingEnvironment(kRealm, std::move(env_services));
  WaitForEnclosingEnvToStart(enclosing_environment.get());

  // try to launch file url.
  auto controller1 = RunComponent(enclosing_environment.get(), "does_not_exist");
  bool wait = false;
  controller1.events().OnTerminated = [&wait](int64_t return_code,
                                              fuchsia::sys::TerminationReason reason) {
    wait = true;
    EXPECT_EQ(reason, fuchsia::sys::TerminationReason::PACKAGE_NOT_FOUND);
  };
  RunLoopUntil([&wait] { return wait; });

  // try to launch pkg url.
  auto controller2 = RunComponent(enclosing_environment.get(),
                                  "fuchsia-pkg://fuchsia.com/does_not_exist#meta/some.cmx");
  wait = false;
  controller2.events().OnTerminated = [&wait](int64_t return_code,
                                              fuchsia::sys::TerminationReason reason) {
    wait = true;
    EXPECT_EQ(reason, fuchsia::sys::TerminationReason::PACKAGE_NOT_FOUND);
  };
  RunLoopUntil([&wait] { return wait; });
}

// This test exercises the fact that two components should be in separate jobs,
// and thus when one component controller kills its job due to a .Kill() call
// the other component should run uninterrupted.
TEST_F(RealmTest, CreateTwoKillOne) {
  // launch component as a service.
  auto env_services = CreateServices();
  ASSERT_EQ(ZX_OK, env_services->AddServiceWithLaunchInfo(
                       CreateLaunchInfo("fuchsia-pkg://fuchsia.com/"
                                        "echo_server_cpp#meta/echo_server_cpp.cmx"),
                       fidl::examples::echo::Echo::Name_));
  auto enclosing_environment = CreateNewEnclosingEnvironment(kRealm, std::move(env_services));
  WaitForEnclosingEnvToStart(enclosing_environment.get());
  // launch component normally
  auto controller1 =
      RunComponent(enclosing_environment.get(),
                   "fuchsia-pkg://fuchsia.com/echo_server_cpp#meta/echo_server_cpp.cmx");

  // make sure echo service is running.
  fidl::examples::echo::EchoPtr echo;
  enclosing_environment->ConnectToService(echo.NewRequest());
  const std::string message = "CreateTwoKillOne";
  fidl::StringPtr ret_msg;
  echo->EchoString(message, [&](::fidl::StringPtr retval) { ret_msg = retval; });
  RunLoopUntil([&] { return ret_msg.has_value(); });

  // Kill one of the two components, make sure it's exited via Wait
  bool wait = false;
  controller1.events().OnTerminated =
      [&wait](int64_t return_code, fuchsia::sys::TerminationReason reason) { wait = true; };
  controller1->Kill();
  RunLoopUntil([&wait] { return wait; });

  // Make sure the second component is still running.
  ret_msg.reset();
  echo->EchoString(message, [&](::fidl::StringPtr retval) { ret_msg = retval; });
  RunLoopUntil([&] { return ret_msg.has_value(); });
}

TEST_F(RealmTest, KillRealmKillsComponent) {
  auto env_services = CreateServices();
  ASSERT_EQ(ZX_OK, env_services->AddServiceWithLaunchInfo(
                       CreateLaunchInfo("fuchsia-pkg://fuchsia.com/"
                                        "echo_server_cpp#meta/echo_server_cpp.cmx"),
                       fidl::examples::echo::Echo::Name_));
  auto enclosing_environment = CreateNewEnclosingEnvironment(kRealm, std::move(env_services));
  WaitForEnclosingEnvToStart(enclosing_environment.get());

  // make sure echo service is running.
  fidl::examples::echo::EchoPtr echo;
  enclosing_environment->ConnectToService(echo.NewRequest());
  const std::string message = "CreateTwoKillOne";
  fidl::StringPtr ret_msg;
  echo->EchoString(message, [&](::fidl::StringPtr retval) { ret_msg = retval; });
  RunLoopUntil([&] { return ret_msg.has_value(); });

  bool killed = false;
  echo.set_error_handler([&](zx_status_t status) { killed = true; });
  enclosing_environment->Kill();
  RunLoopUntil([&] { return enclosing_environment->is_running(); });
  // send a msg, without that error handler won't be called.
  echo->EchoString(message, [&](::fidl::StringPtr retval) { ret_msg = retval; });
  RunLoopUntil([&] { return killed; });
}

// test that service is connected even when realm dies right after connect request.
TEST_F(RealmTest, ConnectToServiceWhenRealmDies) {
  auto env_services = CreateServices();
  bool connected = false;
  auto fake_service = std::make_shared<vfs::Service>(
      [&](zx::channel client_handle, async_dispatcher_t* /*unused*/) mutable { connected = true; });
  env_services->AddSharedService(fake_service, fidl::examples::echo::Echo::Name_);

  auto enclosing_environment = CreateNewEnclosingEnvironment(kRealm, std::move(env_services));
  WaitForEnclosingEnvToStart(enclosing_environment.get());

  // first make sure that environment is running and can process requests.
  fidl::examples::echo::EchoPtr echo;
  enclosing_environment->ConnectToService(echo.NewRequest());
  RunLoopUntil([&] { return connected; });

  // reset connection and now connect and kill the environment.
  connected = false;
  enclosing_environment->ConnectToService(echo.NewRequest());
  bool killed = false;
  // kill enclosing env
  enclosing_environment->Kill([&]() { killed = true; });
  RunLoopUntil([&] { return killed; });
  // make sure we can receive connect request.
  RunLoopUntil([&] { return connected; });
}

TEST_F(RealmTest, EnvironmentControllerRequired) {
  fuchsia::sys::EnvironmentPtr env;
  real_env()->CreateNestedEnvironment(env.NewRequest(), /* controller = */ nullptr, kRealm,
                                      /* additional_services = */ nullptr,
                                      fuchsia::sys::EnvironmentOptions{});

  zx_status_t env_status = ZX_OK;
  env.set_error_handler([&](zx_status_t status) { env_status = status; });

  RunLoopUntil([&] { return env_status != ZX_OK; });
}

TEST_F(RealmTest, EnvironmentLabelMustBeUnique) {
  // Create first environment with label kRealm using EnclosingEnvironment since
  // that's easy.
  auto enclosing_environment = CreateNewEnclosingEnvironment(kRealm, CreateServices());

  // Can't use EnclosingEnvironment here since there's no way to discern between
  // 'not yet created' and 'failed to create'. This also lets us check the
  // specific status returned.
  fuchsia::sys::EnvironmentPtr env;
  fuchsia::sys::EnvironmentControllerPtr env_controller;

  zx_status_t env_status, env_controller_status;
  env.set_error_handler([&](zx_status_t status) { env_status = status; });
  env_controller.set_error_handler([&](zx_status_t status) { env_controller_status = status; });

  // Same environment label as EnclosingEnvironment created above.
  real_env()->CreateNestedEnvironment(env.NewRequest(), env_controller.NewRequest(), kRealm,
                                      nullptr, fuchsia::sys::EnvironmentOptions{});

  RunLoopUntil([&] { return env_status == ZX_ERR_BAD_STATE; });
  RunLoopUntil([&] { return env_controller_status == ZX_ERR_BAD_STATE; });
}

TEST_F(RealmTest, RealmJobProvider) {
  fuchsia::sys::JobProviderSyncPtr ptr;
  fdio_service_connect("/hub/job", ptr.NewRequest().TakeChannel().release());

  zx::job job;
  ASSERT_EQ(ZX_OK, ptr->GetJob(&job));

  // check that we can get properties.
  char name[ZX_MAX_NAME_LEN];
  ASSERT_EQ(ZX_OK, job.get_property(ZX_PROP_NAME, name, sizeof(name)));

  EXPECT_THAT(name, ::testing::StartsWith("test_env"));
  zx_koid_t koid;
  size_t actual;
  size_t avail_count;
  ASSERT_EQ(ZX_OK,
            job.get_info(ZX_INFO_JOB_CHILDREN, &koid, sizeof(zx_koid_t), &actual, &avail_count));
  ASSERT_EQ(1u, actual);

  // check that we can get children
  zx::job child_job;
  ASSERT_EQ(ZX_OK, job.get_child(koid, ZX_RIGHT_SAME_RIGHTS, &child_job));
}

TEST_F(RealmTest, RealmDiesWhenItsJobDies) {
  auto env_services = CreateServices();

  ASSERT_EQ(ZX_OK, env_services->AddServiceWithLaunchInfo(
                       CreateLaunchInfo("fuchsia-pkg://fuchsia.com/"
                                        "echo_server_cpp#meta/echo_server_cpp.cmx"),
                       fidl::examples::echo::Echo::Name_));
  auto enclosing_environment = CreateNewEnclosingEnvironment(kRealm, std::move(env_services));
  WaitForEnclosingEnvToStart(enclosing_environment.get());

  // make sure echo service is running.
  fidl::examples::echo::EchoPtr echo;
  enclosing_environment->ConnectToService(echo.NewRequest());
  const std::string message = "some_msg";
  fidl::StringPtr ret_msg;
  echo->EchoString(message, [&](::fidl::StringPtr retval) { ret_msg = retval; });
  RunLoopUntil([&] { return ret_msg.has_value(); });

  fuchsia::sys::JobProviderSyncPtr ptr;
  files::Glob glob(std::string("/hub/r/") + kRealm + "/*/job");
  ASSERT_EQ(1u, glob.size());
  const std::string path = *glob.begin();
  fdio_service_connect(path.c_str(), ptr.NewRequest().TakeChannel().release());

  zx::job job;
  EXPECT_EQ(ZX_OK, ptr->GetJob(&job));
  ASSERT_EQ(ZX_OK, job.kill());

  RunLoopUntil([&] { return !enclosing_environment->is_running(); });
}

TEST_F(RealmTest, EmptyRealmDiesWhenItsJobDies) {
  auto env_services = CreateServices();

  auto enclosing_environment = CreateNewEnclosingEnvironment(kRealm, std::move(env_services));
  WaitForEnclosingEnvToStart(enclosing_environment.get());

  fuchsia::sys::JobProviderSyncPtr ptr;
  files::Glob glob(std::string("/hub/r/") + kRealm + "/*/job");
  ASSERT_EQ(1u, glob.size());
  const std::string path = *glob.begin();
  fdio_service_connect(path.c_str(), ptr.NewRequest().TakeChannel().release());

  zx::job job;
  EXPECT_EQ(ZX_OK, ptr->GetJob(&job));
  ASSERT_EQ(ZX_OK, job.kill());

  RunLoopUntil([&] { return !enclosing_environment->is_running(); });
}

TEST_F(RealmTest, KillWorks) {
  auto env_services = CreateServices();

  auto enclosing_environment = CreateNewEnclosingEnvironment(kRealm, std::move(env_services));
  WaitForEnclosingEnvToStart(enclosing_environment.get());

  std::string hub_path = std::string("/hub/r/") + kRealm;
  // make sure realm was created
  files::Glob glob1(hub_path);
  ASSERT_EQ(1u, glob1.size());

  bool killed = false;
  enclosing_environment->Kill([&] { killed = true; });
  RunLoopUntil([&] { return killed; });

  // make sure realm was really killed
  files::Glob glob2(hub_path);
  ASSERT_EQ(0u, glob2.size());
}

/// this will remove hash from the url and return un-hashed version.
/// example:
///  `url`:"fuchsia-pkg://fuchsia.com/my-pkg?hash=3204f2f24920e55bfbcb9c3a058ec2869f229b18d00ef1049ec3f47e5b7e4351#meta/my-component.cmx"
///  returns "fuchsia-pkg://fuchsia.com/my-pkg#meta/my-component.cmx"
std::string GetUnhashedUrl(const std::string& url) {
  component::FuchsiaPkgUrl furl;
  furl.Parse(url);
  return fxl::Substitute("fuchsia-pkg://$0/$1#$2", furl.host_name(), furl.package_name(),
                         furl.resource_path());
}

class RealmCrashIntrospectTest : public RealmTest {
 public:
  using CrashIntrospect_FindComponentByThreadKoid_Result =
      fuchsia::sys::internal::CrashIntrospect_FindComponentByThreadKoid_Result;

  void SetUp() override {
    RealmTest::SetUp();
    real_services()->Connect(introspect_.NewRequest());
    ASSERT_TRUE(files::ReadFileToString("hub/name", &current_realm_name_));
  }

  CrashIntrospect_FindComponentByThreadKoid_Result FindComponent(zx_koid_t thread_koid) {
    CrashIntrospect_FindComponentByThreadKoid_Result result;
    auto status = introspect_->FindComponentByThreadKoid(thread_koid, &result);
    FX_CHECK(ZX_OK == status) << "status: " << status;
    return result;
  }
  static zx_koid_t GetKoid(const zx::object_base& obj) { return fsl::GetKoid(obj.get()); }

  static zx_koid_t GetCurrentProcessKoid() {
    auto koid = GetKoid(*zx::process::self());
    ZX_DEBUG_ASSERT(koid != ZX_KOID_INVALID);
    return koid;
  }

  const std::string& current_realm_name() const { return current_realm_name_; }

 private:
  fuchsia::sys::internal::CrashIntrospectSyncPtr introspect_;
  std::string current_realm_name_;
};

// This tests that the service is not available in environment which do not explicitly include it
// from parent environment.
// This test's cmx includes this service that so we are able to indirectly test that inheriting this
// service works.
TEST_F(RealmCrashIntrospectTest, CrashServiceNotAvailableInAllEnvironments) {
  auto env_services = CreateServices();
  auto enclosing_environment = CreateNewEnclosingEnvironment(kRealm, std::move(env_services));
  WaitForEnclosingEnvToStart(enclosing_environment.get());

  fuchsia::sys::internal::CrashIntrospectPtr introspect;
  enclosing_environment->ConnectToService(introspect.NewRequest());
  bool done = false;
  introspect.set_error_handler([&](zx_status_t status) {
    done = true;
    ASSERT_EQ(ZX_ERR_PEER_CLOSED, status);
  });
  RunLoopUntil([&]() { return done; });
}

// pass job's koid so that we can test ZX_ERR_NOT_FOUND.
TEST_F(RealmCrashIntrospectTest, InvalidProcessId) {
  auto job = zx::job::default_job();
  auto koid = GetKoid(*job);
  auto result = FindComponent(koid);
  ASSERT_TRUE(result.is_err());
  EXPECT_EQ(ZX_ERR_NOT_FOUND, result.err());
}

// TODO(fxbug.dev/57032): re-enable once we can intercept the exception after appmgr, but before the
// platform's exception handling.
TEST_F(RealmCrashIntrospectTest, DISABLED_ComponentUrlForNewCrashingProcess) {
  const char* command_argv[] = {"/pkg/bin/crashing_process", nullptr};

  auto job = zx::job::default_job();

  zx::process process;

  ASSERT_EQ(ZX_OK, fdio_spawn(job->get(), FDIO_SPAWN_CLONE_ALL,
                              command_argv[0],  // path
                              command_argv, process.reset_and_get_address()));
  auto koid = GetKoid(process);
  // TODO(fxbug.dev/51382): Remove these logs. Added for debugging incase process never crashes.
  FX_LOGS(INFO) << "Waiting for process to die.";
  process.wait_one(ZX_TASK_TERMINATED, zx::time::infinite(), nullptr);
  FX_LOGS(INFO) << "Process died.";
  auto result = FindComponent(koid);
  ASSERT_FALSE(result.is_err()) << zx_status_get_string(result.err());
  auto& response = result.response().component_info;

  EXPECT_EQ(GetUnhashedUrl(response.component_url()),
            "fuchsia-pkg://fuchsia.com/appmgr_integration_tests#meta/"
            "appmgr_realm_integration_tests.cmx");
  std::vector<std::string> expected = {"app", "sys", current_realm_name()};
  EXPECT_EQ(response.realm_path(), expected);
  EXPECT_EQ(response.instance_id(), std::to_string(GetCurrentProcessKoid()));

  // we should only be able to retrieve it once.
  result = FindComponent(koid);
  ASSERT_TRUE(result.is_err());
  EXPECT_EQ(ZX_ERR_NOT_FOUND, result.err());
}

// TODO(fxbug.dev/57032): re-enable once we can intercept the exception after appmgr, but before the
// platform's exception handling.
TEST_F(RealmCrashIntrospectTest, DISABLED_ComponentUrlForNewComponentInCurrentEnv) {
  zx::channel request;
  auto component_svc = sys::ServiceDirectory::CreateWithRequest(&request);
  auto launch_info = CreateLaunchInfo(
      "fuchsia-pkg://fuchsia.com/appmgr_integration_tests#meta/crashing_component.cmx",
      std::move(request));
  fuchsia::sys::ComponentControllerPtr controller;
  launcher_ptr()->CreateComponent(std::move(launch_info), controller.NewRequest());
  bool component_started = false;
  controller.events().OnDirectoryReady = [&] { component_started = true; };

  RunLoopUntil([&] { return component_started; });

  files::Glob glob("/hub/c/crashing_component.cmx/*/process-id");
  ASSERT_EQ(1u, glob.size());

  std::string process_koid;
  ASSERT_TRUE(files::ReadFileToString(*glob.begin(), &process_koid));

  bool component_died = false;
  controller.events().OnTerminated = [&](int64_t err, TerminationReason r) {
    component_died = true;
  };
  fuchsia::testing::appmgr::CrashInducerPtr crash_srv;
  component_svc->Connect(crash_srv.NewRequest());
  crash_srv->Crash();
  // TODO(fxbug.dev/51382): Remove these logs. Added for debugging incase process never crashes.
  FX_LOGS(INFO) << "Waiting for component to die.";
  RunLoopUntil([&] { return component_died; });
  FX_LOGS(INFO) << "Component died.";

  auto result = FindComponent(std::stoi(process_koid));
  ASSERT_FALSE(result.is_err()) << zx_status_get_string(result.err());
  auto& response = result.response().component_info;

  EXPECT_EQ(response.component_url(),
            "fuchsia-pkg://fuchsia.com/appmgr_integration_tests#meta/crashing_component.cmx");
  std::vector<std::string> expected = {"app", "sys", current_realm_name()};
  EXPECT_EQ(response.realm_path(), expected);
  EXPECT_EQ(response.instance_id(), process_koid);
}

// TODO(fxbug.dev/57032): re-enable once we can intercept the exception after appmgr, but before the
// platform's exception handling.
TEST_F(RealmCrashIntrospectTest, DISABLED_ComponentUrlForNewComponentInEnclosingEnv) {
  auto env_services = CreateServices();
  std::string realm_label = "RealmCrashIntrospectTest";
  auto enclosing_environment = CreateNewEnclosingEnvironment(realm_label, std::move(env_services));
  WaitForEnclosingEnvToStart(enclosing_environment.get());
  zx::channel request;
  auto component_svc = sys::ServiceDirectory::CreateWithRequest(&request);
  auto controller =
      RunComponent(enclosing_environment.get(),
                   "fuchsia-pkg://fuchsia.com/appmgr_integration_tests#meta/crashing_component.cmx",
                   std::move(request));

  bool component_started = false;
  controller.events().OnDirectoryReady = [&] { component_started = true; };
  RunLoopUntil([&] { return component_started; });

  files::Glob glob(std::string("/hub/r/") + realm_label +
                   "/*/c/crashing_component.cmx/*/process-id");
  ASSERT_EQ(1u, glob.size());

  std::string process_koid;
  ASSERT_TRUE(files::ReadFileToString(*glob.begin(), &process_koid));

  bool component_died = false;
  controller.events().OnTerminated = [&](int64_t err, TerminationReason r) {
    component_died = true;
  };
  fuchsia::testing::appmgr::CrashInducerPtr crash_srv;
  component_svc->Connect(crash_srv.NewRequest());
  crash_srv->Crash();
  // TODO(fxbug.dev/51382): Remove these logs. Added for debugging incase process never crashes.
  FX_LOGS(INFO) << "Waiting for component to die.";
  RunLoopUntil([&] { return component_died; });
  FX_LOGS(INFO) << "Component died.";

  auto result = FindComponent(std::stoi(process_koid));
  ASSERT_FALSE(result.is_err()) << zx_status_get_string(result.err());
  auto& response = result.response().component_info;

  EXPECT_EQ(response.component_url(),
            "fuchsia-pkg://fuchsia.com/appmgr_integration_tests#meta/crashing_component.cmx");
  std::vector<std::string> expected = {"app", "sys", current_realm_name(), std::move(realm_label)};
  EXPECT_EQ(response.realm_path(), expected);
  EXPECT_EQ(response.instance_id(), process_koid);
  EXPECT_EQ(response.component_name(), "crashing_component.cmx");
}

// Create a test environment that includes additional functions for
// reading/writing data.
//
// We use virtual inheritance here to work around the LLVM compiler bug
// https://bugs.llvm.org/show_bug.cgi?id=35902 which generates
// a false-positive alignment alert.
class EnvironmentOptionsTest : public virtual RealmTest,
                               public virtual component::testing::DataFileReaderWriterUtil {};

TEST_F(EnvironmentOptionsTest, DeleteStorageOnDeath) {
  constexpr char kTestFileName[] = "some-test-file";
  constexpr char kTestFileContent[] = "the-best-file-content";

  // Create an environment with 'delete_storage_on_death' option enabled.
  zx::channel request;
  auto services = sys::ServiceDirectory::CreateWithRequest(&request);
  DataFileReaderWriterPtr util;
  auto enclosing_environment = CreateNewEnclosingEnvironment(
      kRealm, CreateServices(), fuchsia::sys::EnvironmentOptions{.delete_storage_on_death = true});
  auto ctrl = RunComponent(enclosing_environment.get(),
                           "fuchsia-pkg://fuchsia.com/persistent_storage_test_util#meta/util.cmx",
                           std::move(request));
  services->Connect(util.NewRequest());

  // Write some arbitrary file content into the test util's "/data" dir, and
  // verify that we can read it back.
  ASSERT_EQ(WriteFileSync(util, kTestFileName, kTestFileContent), ZX_OK);
  ASSERT_EQ(ReadFileSync(util, kTestFileName).value_or(""), kTestFileContent);

  // Kill the environment, which should automatically delete any persistent
  // storage it owns.
  bool killed = false;
  enclosing_environment->Kill([&] { killed = true; });
  RunLoopUntil([&] { return killed; });

  // Recreate the environment and component using the same environment label.
  services = sys::ServiceDirectory::CreateWithRequest(&request);
  enclosing_environment = CreateNewEnclosingEnvironment(kRealm, CreateServices());
  ctrl = RunComponent(enclosing_environment.get(),
                      "fuchsia-pkg://fuchsia.com/persistent_storage_test_util#meta/util.cmx",
                      std::move(request));
  services->Connect(util.NewRequest());

  // Verify that the file no longer exists.
  EXPECT_FALSE(ReadFileSync(util, kTestFileName).has_value());
}

using LabelAndValidity = std::tuple<std::string, bool>;
class EnvironmentLabelTest : public RealmTest,
                             public ::testing::WithParamInterface<LabelAndValidity> {};

TEST_P(EnvironmentLabelTest, CheckLabelValidity) {
  // Can't use EnclosingEnvironment here since there's no way to discern between
  // 'not yet created' and 'failed to create'. This also lets use check the
  // specific status returned.
  fuchsia::sys::EnvironmentPtr env;
  fuchsia::sys::EnvironmentControllerPtr env_controller;

  zx_status_t env_status = ZX_OK;
  zx_status_t env_controller_status = ZX_OK;
  bool env_created = false;
  env.set_error_handler([&](zx_status_t status) { env_status = status; });
  env_controller.set_error_handler([&](zx_status_t status) { env_controller_status = status; });
  env_controller.events().OnCreated = [&] { env_created = true; };

  auto [label, label_valid] = GetParam();
  real_env()->CreateNestedEnvironment(env.NewRequest(), env_controller.NewRequest(), label,
                                      /* additional_services = */ nullptr,
                                      fuchsia::sys::EnvironmentOptions{});

  if (label_valid) {
    RunLoopUntil([&] { return env_created; });
  } else {
    RunLoopUntil([&] { return env_status == ZX_ERR_INVALID_ARGS; });
    RunLoopUntil([&] { return env_controller_status == ZX_ERR_INVALID_ARGS; });
    EXPECT_FALSE(env_created);
  }
}

INSTANTIATE_TEST_SUITE_P(
    InvalidLabels, EnvironmentLabelTest,
    ::testing::Combine(::testing::Values("", "a/b", "/", ".", "..", "../..", "\t", "\r", "ab\n",
                                         std::string("123\0", 4), "\10", "\33", "\177", " ",
                                         "my realm", "~", "`", "!", "@", "$", "%", "^", "&", "*",
                                         "(", ")", "=", "+", "{", "}", "[", "]", "|", "?", ";", "'",
                                         "\"", "<", ">", ",",
                                         "fuchsia-pkg://fuchsia.com/abcd#meta/abcd.cmx"),
                       ::testing::Values(false)));

INSTANTIATE_TEST_SUITE_P(
    ValidLabels, EnvironmentLabelTest,
    ::testing::Combine(::testing::Values("abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
                                         "0123456789", "#-_:.", "my.realm", "my..realm",
                                         "fuchsia-pkg:::fuchsia.com:abcd#meta:abcd.cmx"),
                       ::testing::Values(true)));

class RealmFakeLoaderTest : public RealmTest, public fuchsia::sys::Loader {
 protected:
  RealmFakeLoaderTest() {
    sys::testing::EnvironmentServices::ParentOverrides parent_overrides;
    parent_overrides.loader_service_ =
        std::make_shared<vfs::Service>([this](zx::channel channel, async_dispatcher_t* dispatcher) {
          bindings_.AddBinding(this,
                               fidl::InterfaceRequest<fuchsia::sys::Loader>(std::move(channel)));
        });
    enclosing_environment_ = CreateNewEnclosingEnvironment(
        kRealm, CreateServicesWithParentOverrides(std::move(parent_overrides)));
  }

  void LoadUrl(std::string url, LoadUrlCallback callback) override {
    ASSERT_TRUE(component_url_.empty());
    component_url_ = url;
  }

  void WaitForComponentLoad() {
    RunLoopUntil([this] { return !component_url_.empty(); });
  }

  const std::string& component_url() const { return component_url_; }

  std::unique_ptr<EnclosingEnvironment> enclosing_environment_;

 private:
  std::shared_ptr<vfs::Service> loader_service_;
  fidl::BindingSet<fuchsia::sys::Loader> bindings_;
  std::string component_url_;
};

TEST_F(RealmFakeLoaderTest, CreateInvalidComponent) {
  TerminationReason reason = TerminationReason::UNKNOWN;
  int64_t return_code = INT64_MAX;
  auto controller = RunComponent(enclosing_environment_.get(), "garbage://test");
  controller.events().OnTerminated = [&](int64_t err, TerminationReason r) {
    return_code = err;
    reason = r;
  };
  RunLoopUntil([&] { return return_code < INT64_MAX; });
  EXPECT_EQ(TerminationReason::URL_INVALID, reason);
  EXPECT_EQ(-1, return_code);
}

}  // namespace
}  // namespace component
