// Copyright 2019 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 "src/developer/forensics/exceptions/process_limbo_manager.h"

#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/inspect/cpp/inspect.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/status.h>

#include <gtest/gtest.h>

#include "fuchsia/exception/cpp/fidl.h"
#include "src/developer/forensics/exceptions/exception_broker.h"
#include "src/developer/forensics/exceptions/tests/crasher_wrapper.h"
#include "src/lib/fsl/handles/object_info.h"

namespace forensics {
namespace exceptions {
namespace {

using fuchsia::exception::ExceptionInfo;
using fuchsia::exception::ExceptionType;
using fuchsia::exception::ProcessException;
using fuchsia::exception::ProcessExceptionMetadata;
using fuchsia::exception::ProcessLimbo_AppendFilters_Result;
using fuchsia::exception::ProcessLimbo_ListProcessesWaitingOnException_Result;
using fuchsia::exception::ProcessLimbo_ReleaseProcess_Result;
using fuchsia::exception::ProcessLimbo_RemoveFilters_Result;
using fuchsia::exception::ProcessLimbo_RetrieveException_Result;
using fuchsia::exception::ProcessLimbo_WatchProcessesWaitingOnException_Result;

bool RetrieveExceptionContext(ExceptionContext* pe) {
  // Create a process that crashes and obtain the relevant handles and exception.
  // By the time |SpawnCrasher| has returned, the process has already thrown an exception.
  if (!SpawnCrasher(pe)) {
    FX_LOGS(ERROR) << "Could not spawn crasher process.";
    return false;
  }

  // We mark the exception to be handled. We need this because we pass on the exception to the
  // handler, which will resume it before we get the control back. If we don't mark it as handled,
  // the exception will bubble out of our environment.
  return MarkExceptionAsHandled(pe);
}

ExceptionInfo ExceptionContextToExceptionInfo(const ExceptionContext& pe) {
  // Translate the exception to the fidl format.
  ExceptionInfo exception_info;
  exception_info.process_koid = pe.exception_info.pid;
  exception_info.thread_koid = pe.exception_info.tid;
  exception_info.type = static_cast<ExceptionType>(pe.exception_info.type);

  return exception_info;
}

void AddExceptionToLimbo(ProcessLimboManager* limbo_manager, zx::exception exception,
                         ExceptionInfo info) {
  ProcessException process_exception = {};
  process_exception.set_exception(std::move(exception));
  process_exception.set_info(std::move(info));

  zx_status_t status;
  zx::process process;
  status = process_exception.exception().get_process(&process);
  if (status != ZX_OK) {
    FX_PLOGS(WARNING, status) << "Could not obtain process handle for exception.";
  } else {
    process_exception.set_process(std::move(process));
  }

  zx::thread thread;
  status = process_exception.exception().get_thread(&thread);
  if (status != ZX_OK) {
    FX_PLOGS(WARNING, status) << "Could not obtain thread handle for exception.";
  } else {
    process_exception.set_thread(std::move(thread));
  }

  limbo_manager->AddToLimbo(std::move(process_exception));
}

bool ValidateException(const ProcessExceptionMetadata&) { return true; }
bool ValidateException(const ProcessException& exception) { return exception.has_exception(); }

template <typename T>
void ValidateException(const ExceptionContext& context, const T& process_exception) {
  if (std::is_same<T, ProcessException>::value)
    ASSERT_TRUE(ValidateException(process_exception));
  ASSERT_TRUE(process_exception.has_info());
  ASSERT_TRUE(process_exception.has_process());
  ASSERT_TRUE(process_exception.has_thread());

  const zx::process& process = process_exception.process();
  ASSERT_EQ(context.process_koid, fsl::GetKoid(process.get()));
  ASSERT_EQ(context.process_koid, process_exception.info().process_koid);
  ASSERT_EQ(context.process_name, fsl::GetObjectName(process.get()));

  const zx::thread& thread = process_exception.thread();
  ASSERT_EQ(context.thread_koid, fsl::GetKoid(thread.get()));
  ASSERT_EQ(context.thread_koid, process_exception.info().thread_koid);
  ASSERT_EQ(context.thread_name, fsl::GetObjectName(thread.get()));

  ASSERT_EQ(process_exception.info().type, ExceptionType::FATAL_PAGE_FAULT);
}

std::unique_ptr<ProcessLimboHandler> CreateHandler(ProcessLimboManager* limbo_manager) {
  auto handler = std::make_unique<ProcessLimboHandler>(limbo_manager->GetWeakPtr());
  limbo_manager->AddHandler(handler->GetWeakPtr());

  return handler;
}

ProcessException GetFakeException(zx_koid_t process_koid = 1, zx_koid_t thread_koid = 1,
                                  ExceptionType type = ExceptionType::FATAL_PAGE_FAULT) {
  ExceptionInfo info;
  info.process_koid = process_koid;
  info.thread_koid = thread_koid;
  info.type = type;

  ProcessException exception;
  exception.set_info(info);
  exception.set_process(zx::process(process_koid));  // Invalid handle. Never rely on it.
  exception.set_thread(zx::thread(thread_koid));     // Invalid handle. Never rely on it.

  return exception;
}

// Tests -------------------------------------------------------------------------------------------

TEST(ProcessLimboManagerTest, ProcessLimboHandler) {
  ProcessLimboManager limbo_manager;

  // Use the handler interface.
  auto handler = CreateHandler(&limbo_manager);

  // A disabled limbo should return an error.
  {
    bool called = false;
    ProcessLimbo_WatchProcessesWaitingOnException_Result result;
    handler->WatchProcessesWaitingOnException(
        [&called, &result](ProcessLimbo_WatchProcessesWaitingOnException_Result res) {
          called = true;
          result = std::move(res);
        });
    ASSERT_TRUE(called);
    ASSERT_TRUE(result.is_err());
    EXPECT_EQ(result.err(), ZX_ERR_UNAVAILABLE);
  }

  limbo_manager.SetActive(true);

  // We create multiple exceptions.
  ExceptionContext excps[3];
  ASSERT_TRUE(RetrieveExceptionContext(excps + 0));
  ASSERT_TRUE(RetrieveExceptionContext(excps + 1));
  ASSERT_TRUE(RetrieveExceptionContext(excps + 2));

  // Get the fidl representation of the exception.
  ExceptionInfo infos[3];
  infos[0] = ExceptionContextToExceptionInfo(excps[0]);
  infos[1] = ExceptionContextToExceptionInfo(excps[1]);
  infos[2] = ExceptionContextToExceptionInfo(excps[2]);

  AddExceptionToLimbo(&limbo_manager, std::move(excps[0].exception), infos[0]);
  AddExceptionToLimbo(&limbo_manager, std::move(excps[1].exception), infos[1]);
  AddExceptionToLimbo(&limbo_manager, std::move(excps[2].exception), infos[2]);

  {
    // There should be exceptions listed.
    bool called = false;
    ProcessLimbo_WatchProcessesWaitingOnException_Result result;
    handler->WatchProcessesWaitingOnException(
        [&called, &result](ProcessLimbo_WatchProcessesWaitingOnException_Result res) {
          called = true;
          result = std::move(res);
        });

    ASSERT_TRUE(called);
    ASSERT_TRUE(result.is_response()) << zx_status_get_string(result.err());
    ASSERT_EQ(result.response().exception_list.size(), 3u);
    ValidateException(excps[0], result.response().exception_list[0]);
    ValidateException(excps[1], result.response().exception_list[1]);
    ValidateException(excps[2], result.response().exception_list[2]);
  }

  {
    // ListProcessesWaitingOnException should succeed.
    bool called = false;
    ProcessLimbo_ListProcessesWaitingOnException_Result result;
    handler->ListProcessesWaitingOnException([&called, &result](auto res) {
      called = true;
      result = std::move(res);
    });

    ASSERT_TRUE(called);
    ASSERT_TRUE(result.is_response()) << zx_status_get_string(result.err());
    ASSERT_EQ(result.response().exception_list.size(), 3u);
    ASSERT_EQ(excps[0].process_name, result.response().exception_list[0].process_name());
    ASSERT_EQ(excps[1].process_name, result.response().exception_list[1].process_name());
    ASSERT_EQ(excps[2].process_name, result.response().exception_list[2].process_name());
  }

  {
    // Getting a exception for a process that doesn't exist should fail.
    bool called = false;
    ProcessLimbo_RetrieveException_Result result;
    handler->RetrieveException(-1, [&called, &result](ProcessLimbo_RetrieveException_Result res) {
      called = true;
      result = std::move(res);
    });
    ASSERT_TRUE(called);
    ASSERT_TRUE(result.is_err());

    // There should still be 3 exceptions.
    ASSERT_EQ(limbo_manager.limbo().size(), 3u);
  }

  {
    // Watching for the exception should not call.
    bool watch_called = false;
    ProcessLimbo_WatchProcessesWaitingOnException_Result watch_result;
    handler->WatchProcessesWaitingOnException(
        [&watch_called, &watch_result](ProcessLimbo_WatchProcessesWaitingOnException_Result res) {
          watch_called = true;
          watch_result = std::move(res);
        });
    ASSERT_FALSE(watch_called);

    // Getting an actual exception should work.
    bool called = false;
    ProcessLimbo_RetrieveException_Result result = {};
    handler->RetrieveException(infos[0].process_koid,
                               [&called, &result](ProcessLimbo_RetrieveException_Result res) {
                                 called = true;
                                 result = std::move(res);
                               });
    ASSERT_TRUE(called);
    ASSERT_TRUE(result.is_response()) << zx_status_get_string(result.err());
    ValidateException(excps[0], result.response().process_exception);

    // There should be one less exception.
    ASSERT_EQ(limbo_manager.limbo().size(), 2u);

    // We should've received a notification for the watch.
    ASSERT_TRUE(watch_called);
    ASSERT_TRUE(watch_result.is_response()) << zx_status_get_string(watch_result.err());
    ASSERT_EQ(watch_result.response().exception_list.size(), 2u);
    ValidateException(excps[1], watch_result.response().exception_list[0]);
    ValidateException(excps[2], watch_result.response().exception_list[1]);
  }

  {
    // That process should have been removed.
    bool called = false;
    ProcessLimbo_RetrieveException_Result result = {};
    handler->RetrieveException(infos[0].process_koid,
                               [&called, &result](ProcessLimbo_RetrieveException_Result res) {
                                 called = true;
                                 result = std::move(res);
                               });
    ASSERT_TRUE(called);
    ASSERT_TRUE(result.is_err());
  }

  {
    // Watching for the exception should not call.
    bool watch_called = false;
    ProcessLimbo_WatchProcessesWaitingOnException_Result watch_result;
    handler->WatchProcessesWaitingOnException(
        [&watch_called, &watch_result](ProcessLimbo_WatchProcessesWaitingOnException_Result res) {
          watch_called = true;
          watch_result = std::move(res);
        });
    ASSERT_FALSE(watch_called);

    // Asking for the other process should work.
    bool called = false;
    ProcessLimbo_RetrieveException_Result result = {};
    handler->RetrieveException(infos[2].process_koid,
                               [&called, &result](ProcessLimbo_RetrieveException_Result res) {
                                 called = true;
                                 result = std::move(res);
                               });
    ASSERT_TRUE(called);
    ASSERT_TRUE(result.is_response()) << zx_status_get_string(result.err());
    ValidateException(excps[2], result.response().process_exception);

    // There should be one less exception.
    ASSERT_EQ(limbo_manager.limbo().size(), 1u);

    // We should've received a notification for the watch.
    ASSERT_TRUE(watch_called);
    ASSERT_TRUE(watch_result.is_response()) << zx_status_get_string(watch_result.err());
    ASSERT_EQ(watch_result.response().exception_list.size(), 1u);
    ValidateException(excps[1], watch_result.response().exception_list[0]);
  }

  {
    // Watching for the exception should not call.
    bool watch_called = false;
    ProcessLimbo_WatchProcessesWaitingOnException_Result watch_result;
    handler->WatchProcessesWaitingOnException(
        [&watch_called, &watch_result](ProcessLimbo_WatchProcessesWaitingOnException_Result res) {
          watch_called = true;
          watch_result = std::move(res);
        });
    ASSERT_FALSE(watch_called);

    // Getting the last one should work.
    bool called = false;
    ProcessLimbo_ReleaseProcess_Result release_result = {};
    handler->ReleaseProcess(infos[1].process_koid,
                            [&called, &release_result](ProcessLimbo_ReleaseProcess_Result res) {
                              called = true;
                              release_result = std::move(res);
                            });
    ASSERT_TRUE(called);
    ASSERT_TRUE(release_result.is_response()) << zx_status_get_string(release_result.err());

    // There should be one less exception.
    ASSERT_EQ(limbo_manager.limbo().size(), 0u);

    // We should've received a notification for the watch.
    ASSERT_TRUE(watch_called);
    ASSERT_TRUE(watch_result.is_response()) << zx_status_get_string(watch_result.err());
    ASSERT_EQ(watch_result.response().exception_list.size(), 0u);
  }

  // We kill the jobs. This kills the underlying process. We do this so that the crashed process
  // doesn't get rescheduled. Otherwise the exception on the crash program would bubble out of our
  // environment and create noise on the overall system.
  excps[0].job.kill();
  excps[1].job.kill();
  excps[2].job.kill();
}

TEST(ProcessLimboManagerTest, FromExceptionBroker) {
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);

  inspect::Inspector inspector;
  auto broker =
      ExceptionBroker::Create(loop.dispatcher(), &inspector.GetRoot(), /*max_num_handlers=*/1u,
                              /*exception_ttl=*/zx::hour(1));
  ASSERT_TRUE(broker);
  ASSERT_TRUE(broker->limbo_manager().SetActive(true));

  // We create multiple exceptions.
  ExceptionContext excps[3];
  ASSERT_TRUE(RetrieveExceptionContext(excps + 0));
  ASSERT_TRUE(RetrieveExceptionContext(excps + 1));
  ASSERT_TRUE(RetrieveExceptionContext(excps + 2));

  // Get the fidl representation of the exception.
  ExceptionInfo infos[3];
  infos[0] = ExceptionContextToExceptionInfo(excps[0]);
  infos[1] = ExceptionContextToExceptionInfo(excps[1]);
  infos[2] = ExceptionContextToExceptionInfo(excps[2]);

  // It's not easy to pass array references to lambdas.
  bool cb_call0 = false;
  bool cb_call1 = false;
  bool cb_call2 = false;
  broker->OnException(std::move(excps[0].exception), infos[0], [&cb_call0]() { cb_call0 = true; });
  broker->OnException(std::move(excps[1].exception), infos[1], [&cb_call1]() { cb_call1 = true; });
  broker->OnException(std::move(excps[2].exception), infos[2], [&cb_call2]() { cb_call2 = true; });

  // There should be 3 exceptions on the limbo.
  auto& limbo = broker->limbo_manager().limbo();
  ValidateException(excps[0], limbo.find(excps[0].process_koid)->second);
  ValidateException(excps[1], limbo.find(excps[1].process_koid)->second);
  ValidateException(excps[2], limbo.find(excps[2].process_koid)->second);

  // We kill the jobs. This kills the underlying process. We do this so that the crashed process
  // doesn't get rescheduled. Otherwise the exception on the crash program would bubble out of our
  // environment and create noise on the overall system.
  excps[0].job.kill();
  excps[1].job.kill();
  excps[2].job.kill();
}

// WatchActive -------------------------------------------------------------------------------------

TEST(ProcessLimboManagerTest, WatchActiveCalls) {
  ProcessLimboManager limbo_manager;
  auto handler = CreateHandler(&limbo_manager);

  // As no hanging get has been made there should be no change.
  ASSERT_TRUE(limbo_manager.SetActive(true));

  // Making a get should return immediatelly.
  bool called = false;
  std::optional<bool> is_active_result = std::nullopt;
  handler->WatchActive([&called, &is_active_result](bool is_active) {
    called = true;
    is_active_result = is_active;
  });

  ASSERT_TRUE(called);
  ASSERT_TRUE(is_active_result.has_value());
  EXPECT_TRUE(is_active_result.value());

  // A second change should not trigger an event (hanging get).
  called = false;
  is_active_result = std::nullopt;
  handler->WatchActive([&called, &is_active_result](bool is_active) {
    called = true;
    is_active_result = is_active;
  });

  ASSERT_FALSE(called);

  // GetActive should always return.
  is_active_result = std::nullopt;
  handler->GetActive([&is_active_result](bool active) { is_active_result = active; });
  ASSERT_TRUE(is_active_result.has_value());
  ASSERT_TRUE(is_active_result.value());

  // Not making the state should no issue the call.
  ASSERT_FALSE(limbo_manager.SetActive(true));
  ASSERT_FALSE(called);

  // Changing the state should trigger the callback.
  ASSERT_TRUE(limbo_manager.SetActive(false));
  ASSERT_TRUE(called);
  ASSERT_TRUE(is_active_result.has_value());
  EXPECT_FALSE(is_active_result.value());

  // Making two get calls should only call the second.
  bool called1 = false;
  handler->WatchActive([&called1](bool) { called1 = true; });

  bool called2 = false;
  is_active_result = std::nullopt;
  handler->WatchActive([&called2, &is_active_result](bool is_active) {
    called2 = true;
    is_active_result = is_active;
  });

  ASSERT_FALSE(called1);
  ASSERT_FALSE(called2);

  // Making the call should only call the second handler.
  ASSERT_TRUE(limbo_manager.SetActive(true));

  ASSERT_FALSE(called1);
  ASSERT_TRUE(called2);
  ASSERT_TRUE(is_active_result.has_value());
  EXPECT_TRUE(is_active_result.value());

  // Having an outstanding watch limbo call should fail when the limbo is disabled.

  {
    // The first call should return successfully an empty list.
    bool called = false;
    ProcessLimbo_WatchProcessesWaitingOnException_Result result;
    handler->WatchProcessesWaitingOnException(
        [&called, &result](ProcessLimbo_WatchProcessesWaitingOnException_Result res) {
          called = true;
          result = std::move(res);
        });

    ASSERT_TRUE(called);
    ASSERT_TRUE(result.is_response()) << zx_status_get_string(result.err());
    ASSERT_EQ(result.response().exception_list.size(), 0u);
  }

  {
    // The second call should be pending.
    bool called = false;
    ProcessLimbo_WatchProcessesWaitingOnException_Result result;
    handler->WatchProcessesWaitingOnException(
        [&called, &result](ProcessLimbo_WatchProcessesWaitingOnException_Result res) {
          called = true;
          result = std::move(res);
        });

    ASSERT_FALSE(called);
    ASSERT_TRUE(result.has_invalid_tag());

    // Disabling the limbo should call the callback.
    ASSERT_TRUE(limbo_manager.SetActive(false));

    ASSERT_TRUE(called);
    ASSERT_TRUE(result.is_err());
    EXPECT_EQ(result.err(), ZX_ERR_CANCELED);
  }
}

TEST(ProcessLimboManagerTest, ManyHandlers) {
  ProcessLimboManager limbo_manager;

  std::vector<std::unique_ptr<ProcessLimboHandler>> handlers;

  handlers.push_back(CreateHandler(&limbo_manager));
  handlers.push_back(CreateHandler(&limbo_manager));
  handlers.push_back(CreateHandler(&limbo_manager));

  // Calling each handler should be call the callback immediatelly.
  for (auto& handler : handlers) {
    bool called = false;
    std::optional<bool> result;
    handler->WatchActive([&called, &result](bool active) {
      called = true;
      result = active;
    });

    ASSERT_TRUE(called);
    ASSERT_TRUE(result.has_value());
    ASSERT_FALSE(result.value());
  }

  // Calling again should not return.
  std::vector<bool> active_callbacks;
  for (auto& handler : handlers) {
    handler->WatchActive([&active_callbacks](bool active) { active_callbacks.push_back(active); });
  }
  ASSERT_EQ(active_callbacks.size(), 0u);

  // Not changing the state should not issue any callbacks.
  ASSERT_FALSE(limbo_manager.SetActive(false));
  ASSERT_EQ(active_callbacks.size(), 0u);

  // Having a handler issue a SetActive command should trigger the callbacks.
  {
    bool called = false;
    handlers[0]->SetActive(true, [&called]() { called = true; });
    ASSERT_TRUE(called);
  }

  ASSERT_EQ(active_callbacks.size(), 3u);
  EXPECT_TRUE(active_callbacks[0]);
  EXPECT_TRUE(active_callbacks[1]);
  EXPECT_TRUE(active_callbacks[2]);
}

TEST(ProcessLimboManagerTest, Filters) {
  ProcessLimboManager limbo_manager;

  // Override how the manager gets the process name.
  std::string name_to_return;
  limbo_manager.set_obtain_process_name_fn(
      [&name_to_return](zx_handle_t) -> std::string { return name_to_return; });

  // No filters should add the exception.
  name_to_return = "some-process";

  constexpr zx_koid_t kProcessKoid1 = 1;
  limbo_manager.AddToLimbo(GetFakeException(kProcessKoid1));

  // It should've added the exception.
  auto& limbo = limbo_manager.limbo();
  ASSERT_EQ(limbo.size(), 1u);
  ASSERT_TRUE(limbo.find(kProcessKoid1) != limbo.end());

  // Adding a filter should filter out.
  limbo_manager.AppendFiltersForTesting({"filter"});

  constexpr zx_koid_t kProcessKoid2 = 2;
  limbo_manager.AddToLimbo(GetFakeException(kProcessKoid2));

  // No match, so the process should've been added.
  ASSERT_EQ(limbo.size(), 2u);
  EXPECT_TRUE(limbo.find(kProcessKoid1) != limbo.end());
  EXPECT_TRUE(limbo.find(kProcessKoid2) != limbo.end());

  // Adding a match should not append the process.
  name_to_return = "some-filtered-process";
  constexpr zx_koid_t kProcessKoid3 = 3;
  limbo_manager.AddToLimbo(GetFakeException(kProcessKoid3));

  ASSERT_EQ(limbo.size(), 2u);
  EXPECT_TRUE(limbo.find(kProcessKoid1) != limbo.end());
  EXPECT_TRUE(limbo.find(kProcessKoid2) != limbo.end());
}

TEST(ProcessLimboManagerTest, FiltersGetSet) {
  ProcessLimboManager limbo_manager;
  auto handler = CreateHandler(&limbo_manager);

  // We add some initial filters.
  limbo_manager.AppendFiltersForTesting({"filter-1", "filter-2"});

  // Get the initial watch.
  {
    bool called = false;
    std::vector<std::string> filters;
    handler->GetFilters([&called, &filters](std::vector<std::string> r) {
      called = true;
      filters = std::move(r);
    });

    ASSERT_TRUE(called);
    ASSERT_EQ(filters.size(), 2u);
    EXPECT_EQ(filters[0], "filter-1");
    EXPECT_EQ(filters[1], "filter-2");
  }

  // Make the hanging get.
  {
    bool append_called = false;
    ProcessLimbo_AppendFilters_Result append_result;
    handler->AppendFilters({"filter-3", "filter-4"},
                           [&append_called, &append_result](ProcessLimbo_AppendFilters_Result r) {
                             append_called = true;
                             append_result = std::move(r);
                           });
    ASSERT_TRUE(append_called);
    ASSERT_FALSE(append_result.is_err()) << zx_status_get_string(append_result.err());

    bool called = true;
    std::vector<std::string> filters;
    handler->GetFilters([&called, &filters](std::vector<std::string> r) {
      called = true;
      filters = std::move(r);
    });

    // The get should've been called.
    ASSERT_TRUE(called);
    ASSERT_EQ(filters.size(), 4u);
    EXPECT_EQ(filters[0], "filter-1");
    EXPECT_EQ(filters[1], "filter-2");
    EXPECT_EQ(filters[2], "filter-3");
    EXPECT_EQ(filters[3], "filter-4");
  }

  // Removing some filters should call the hanging get too.
  {
    bool remove_called = false;
    ProcessLimbo_RemoveFilters_Result remove_result;
    handler->RemoveFilters({"filter-1", "filter-3"},
                           [&remove_called, &remove_result](ProcessLimbo_RemoveFilters_Result r) {
                             remove_called = true;
                             remove_result = std::move(r);
                           });
    ASSERT_TRUE(remove_called);
    ASSERT_FALSE(remove_result.is_err()) << zx_status_get_string(remove_result.err());

    bool called = true;
    std::vector<std::string> filters;
    handler->GetFilters([&called, &filters](std::vector<std::string> r) {
      called = true;
      filters = std::move(r);
    });

    // The get should've been called.
    ASSERT_TRUE(called);
    ASSERT_EQ(filters.size(), 2u);
    EXPECT_EQ(filters[0], "filter-2");
    EXPECT_EQ(filters[1], "filter-4");
  }
}

TEST(ProcessLimboManagerTest, DisablingFrees) {
  ProcessLimboManager limbo_manager;
  auto handler = CreateHandler(&limbo_manager);

  limbo_manager.SetActive(true);

  // We create multiple exceptions.
  ExceptionContext excps[3];
  ASSERT_TRUE(RetrieveExceptionContext(excps + 0));
  ASSERT_TRUE(RetrieveExceptionContext(excps + 1));
  ASSERT_TRUE(RetrieveExceptionContext(excps + 2));

  // Get the fidl representation of the exception.
  ExceptionInfo infos[3];
  infos[0] = ExceptionContextToExceptionInfo(excps[0]);
  infos[1] = ExceptionContextToExceptionInfo(excps[1]);
  infos[2] = ExceptionContextToExceptionInfo(excps[2]);

  AddExceptionToLimbo(&limbo_manager, std::move(excps[0].exception), infos[0]);
  AddExceptionToLimbo(&limbo_manager, std::move(excps[1].exception), infos[1]);
  AddExceptionToLimbo(&limbo_manager, std::move(excps[2].exception), infos[2]);

  // The exceptions should be there.
  ASSERT_EQ(limbo_manager.limbo().size(), 3u);

  {
    bool called = false;
    handler->SetActive(false, [&called]() { called = true; });

    ASSERT_TRUE(called);
    ASSERT_EQ(limbo_manager.limbo().size(), 0u);
  }

  // We kill the jobs. This kills the underlying process. We do this so that the crashed process
  // doesn't get rescheduled. Otherwise the exception on the crash program would bubble out of our
  // environment and create noise on the overall system.
  excps[0].job.kill();
  excps[1].job.kill();
  excps[2].job.kill();
}

}  // namespace
}  // namespace exceptions
}  // namespace forensics
