// 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/debug/debug_agent/debug_agent.h"

#include <lib/syslog/cpp/macros.h>
#include <zircon/status.h>

#include <gtest/gtest.h>

#include "src/developer/debug/debug_agent/arch.h"
#include "src/developer/debug/debug_agent/mock_debug_agent_harness.h"
#include "src/developer/debug/debug_agent/mock_exception_handle.h"
#include "src/developer/debug/debug_agent/mock_process.h"
#include "src/developer/debug/debug_agent/mock_process_handle.h"
#include "src/developer/debug/debug_agent/mock_thread_handle.h"
#include "src/developer/debug/debug_agent/test_utils.h"
#include "src/developer/debug/ipc/agent_protocol.h"
#include "src/developer/debug/ipc/message_writer.h"
#include "src/developer/debug/shared/logging/debug.h"
#include "src/developer/debug/shared/test_with_loop.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace debug_agent {
namespace {

bool HasAttachedProcessWithKoid(DebugAgent* debug_agent, zx_koid_t koid) {
  DebuggedProcess* proc = debug_agent->GetDebuggedProcess(koid);
  if (!proc)
    return false;

  // All of our process handles should be mock ones.
  return static_cast<MockProcessHandle&>(proc->process_handle()).is_attached();
}

// Setup -------------------------------------------------------------------------------------------

class DebugAgentMockProcess : public MockProcess {
 public:
  DebugAgentMockProcess(DebugAgent* debug_agent, zx_koid_t koid, std::string name)
      : MockProcess(debug_agent, koid, std::move(name)) {}

  ~DebugAgentMockProcess() = default;

  void SuspendAndSendModulesIfKnown() override {
    // Send the modules over to the ipc.
    debug_ipc::MessageWriter writer;
    debug_ipc::WriteNotifyModules(modules_to_send_, &writer);
    debug_agent()->stream()->Write(writer.MessageComplete());
  };

  void set_modules_to_send(debug_ipc::NotifyModules m) { modules_to_send_ = std::move(m); }

 private:
  debug_ipc::NotifyModules modules_to_send_;
};

}  // namespace

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

class DebugAgentTests : public debug_ipc::TestWithLoop {};

TEST_F(DebugAgentTests, OnGlobalStatus) {
  MockDebugAgentHarness harness;
  RemoteAPI* remote_api = harness.debug_agent();

  debug_ipc::StatusRequest request = {};

  debug_ipc::StatusReply reply = {};
  remote_api->OnStatus(request, &reply);

  ASSERT_EQ(reply.processes.size(), 0u);

  constexpr uint64_t kProcessKoid1 = 0x1234;
  const std::string kProcessName1 = "process-1";
  constexpr uint64_t kProcess1ThreadKoid1 = 0x1;

  auto process1 = std::make_unique<MockProcess>(nullptr, kProcessKoid1, kProcessName1);
  process1->AddThread(kProcess1ThreadKoid1);
  harness.debug_agent()->InjectProcessForTest(std::move(process1));

  reply = {};
  remote_api->OnStatus(request, &reply);

  ASSERT_EQ(reply.processes.size(), 1u);
  EXPECT_EQ(reply.processes[0].process_koid, kProcessKoid1);
  EXPECT_EQ(reply.processes[0].process_name, kProcessName1);
  ASSERT_EQ(reply.processes[0].threads.size(), 1u);
  EXPECT_EQ(reply.processes[0].threads[0].id.process, kProcessKoid1);
  EXPECT_EQ(reply.processes[0].threads[0].id.thread, kProcess1ThreadKoid1);

  constexpr uint64_t kProcessKoid2 = 0x5678;
  const std::string kProcessName2 = "process-2";
  constexpr uint64_t kProcess2ThreadKoid1 = 0x1;
  constexpr uint64_t kProcess2ThreadKoid2 = 0x2;

  auto process2 = std::make_unique<MockProcess>(nullptr, kProcessKoid2, kProcessName2);
  process2->AddThread(kProcess2ThreadKoid1);
  process2->AddThread(kProcess2ThreadKoid2);
  harness.debug_agent()->InjectProcessForTest(std::move(process2));

  reply = {};
  remote_api->OnStatus(request, &reply);

  ASSERT_EQ(reply.processes.size(), 2u);
  EXPECT_EQ(reply.processes[0].process_koid, kProcessKoid1);
  EXPECT_EQ(reply.processes[0].process_name, kProcessName1);
  ASSERT_EQ(reply.processes[0].threads.size(), 1u);
  EXPECT_EQ(reply.processes[0].threads[0].id.process, kProcessKoid1);
  EXPECT_EQ(reply.processes[0].threads[0].id.thread, kProcess1ThreadKoid1);

  EXPECT_EQ(reply.processes[1].process_koid, kProcessKoid2);
  EXPECT_EQ(reply.processes[1].process_name, kProcessName2);
  ASSERT_EQ(reply.processes[1].threads.size(), 2u);
  EXPECT_EQ(reply.processes[1].threads[0].id.process, kProcessKoid2);
  EXPECT_EQ(reply.processes[1].threads[0].id.thread, kProcess2ThreadKoid1);
  EXPECT_EQ(reply.processes[1].threads[1].id.process, kProcessKoid2);
  EXPECT_EQ(reply.processes[1].threads[1].id.thread, kProcess2ThreadKoid2);

  // Set a limbo provider.

  constexpr zx_koid_t kProcKoid1 = 100;
  constexpr zx_koid_t kThreadKoid1 = 101;
  harness.system_interface()->mock_limbo_provider().AppendException(
      MockProcessHandle(kProcKoid1, "proc1"), MockThreadHandle(kThreadKoid1, "thread1"),
      MockExceptionHandle(kThreadKoid1));

  constexpr zx_koid_t kProcKoid2 = 102;
  constexpr zx_koid_t kThreadKoid2 = 103;
  harness.system_interface()->mock_limbo_provider().AppendException(
      MockProcessHandle(kProcKoid2, "proc2"), MockThreadHandle(kThreadKoid1, "thread2"),
      MockExceptionHandle(kThreadKoid2));

  reply = {};
  remote_api->OnStatus(request, &reply);

  // The attached processes should still be there.
  ASSERT_EQ(reply.processes.size(), 2u);

  // The limbo processes should be there.
  ASSERT_EQ(reply.limbo.size(), 2u);
  EXPECT_EQ(reply.limbo[0].process_koid, kProcKoid1);
  EXPECT_EQ(reply.limbo[0].process_name, "proc1");
  ASSERT_EQ(reply.limbo[0].threads.size(), 1u);

  // TODO(donosoc): Add exception type.
}

TEST_F(DebugAgentTests, OnProcessStatus) {
  MockDebugAgentHarness harness;
  RemoteAPI* remote_api = harness.debug_agent();

  constexpr uint64_t kProcessKoid1 = 0x1234;
  std::string kProcessName1 = "process-1";
  auto process1 =
      std::make_unique<DebugAgentMockProcess>(harness.debug_agent(), kProcessKoid1, kProcessName1);
  harness.debug_agent()->InjectProcessForTest(std::move(process1));

  constexpr uint64_t kProcessKoid2 = 0x5678;
  std::string kProcessName2 = "process-2";
  auto process2 =
      std::make_unique<DebugAgentMockProcess>(harness.debug_agent(), kProcessKoid2, kProcessName2);
  auto* process2_ptr = process2.get();
  harness.debug_agent()->InjectProcessForTest(std::move(process2));

  // Asking for a un-existent process should fail.
  debug_ipc::ProcessStatusRequest request = {};
  request.process_koid = 0xdeadbeef;

  debug_ipc::ProcessStatusReply reply = {};
  remote_api->OnProcessStatus(request, &reply);
  EXPECT_TRUE(reply.status.has_error());

  debug_ipc::NotifyModules modules_to_send = {};
  modules_to_send.process_koid = kProcessKoid2;
  modules_to_send.modules.push_back({"module-1", 0x1, 0x5, "build-1"});
  modules_to_send.modules.push_back({"module-2", 0x2, 0x7, "build-2"});
  process2_ptr->set_modules_to_send(modules_to_send);

  // Asking for an existent one should send the process and modules notification.
  request.process_koid = kProcessKoid2;
  remote_api->OnProcessStatus(request, &reply);
  EXPECT_TRUE(reply.status.ok());

  loop().RunUntilNoTasks();

  auto& process_starts = harness.stream_backend()->process_starts();
  ASSERT_EQ(process_starts.size(), 1u);
  EXPECT_EQ(process_starts[0].koid, kProcessKoid2);
  EXPECT_EQ(process_starts[0].name, kProcessName2);

  auto& modules = harness.stream_backend()->modules();
  ASSERT_EQ(modules.size(), 1u);
  EXPECT_EQ(modules[0].process_koid, kProcessKoid2);

  ASSERT_EQ(modules[0].modules.size(), modules_to_send.modules.size());
  ASSERT_EQ(modules[0].modules[0].name, modules_to_send.modules[0].name);
  ASSERT_EQ(modules[0].modules[0].base, modules_to_send.modules[0].base);
  ASSERT_EQ(modules[0].modules[0].debug_address, modules_to_send.modules[0].debug_address);
  ASSERT_EQ(modules[0].modules[0].build_id, modules_to_send.modules[0].build_id);
  ASSERT_EQ(modules[0].modules[1].name, modules_to_send.modules[1].name);
  ASSERT_EQ(modules[0].modules[1].base, modules_to_send.modules[1].base);
  ASSERT_EQ(modules[0].modules[1].debug_address, modules_to_send.modules[1].debug_address);
  ASSERT_EQ(modules[0].modules[1].build_id, modules_to_send.modules[1].build_id);
}

TEST_F(DebugAgentTests, OnAttachNotFound) {
  uint32_t transaction_id = 1u;

  MockDebugAgentHarness harness;
  RemoteAPI* remote_api = harness.debug_agent();

  debug_ipc::AttachRequest attach_request;
  attach_request.type = debug_ipc::TaskType::kProcess;
  attach_request.koid = -1;

  remote_api->OnAttach(transaction_id++, attach_request);

  {
    // Should've gotten an attach reply.
    auto& attach_replies = harness.stream_backend()->attach_replies();
    ASSERT_EQ(attach_replies.size(), 1u);
    EXPECT_TRUE(attach_replies[0].status.has_error());
  }

  constexpr zx_koid_t kProcKoid1 = 100;
  constexpr zx_koid_t kThreadKoid1 = 101;
  harness.system_interface()->mock_limbo_provider().AppendException(
      MockProcessHandle(kProcKoid1, "proc1"), MockThreadHandle(kThreadKoid1, "thread1"),
      MockExceptionHandle(kThreadKoid1));

  // Even with limbo it should fail.
  remote_api->OnAttach(transaction_id++, attach_request);

  {
    // Should've gotten an attach reply.
    auto& attach_replies = harness.stream_backend()->attach_replies();
    ASSERT_EQ(attach_replies.size(), 2u);
    EXPECT_TRUE(attach_replies[1].status.has_error());
  }
}

TEST_F(DebugAgentTests, OnAttach) {
  constexpr zx_koid_t kProcess1Koid = 11u;  // Koid for job1-p2 from the GetMockJobTree() hierarchy.
  uint32_t transaction_id = 1u;

  MockDebugAgentHarness harness;
  RemoteAPI* remote_api = harness.debug_agent();

  debug_ipc::AttachRequest attach_request;
  attach_request.type = debug_ipc::TaskType::kProcess;
  attach_request.koid = kProcess1Koid;

  remote_api->OnAttach(transaction_id++, attach_request);

  // We should've received a watch command (which does the low level exception watching).
  EXPECT_TRUE(HasAttachedProcessWithKoid(harness.debug_agent(), kProcess1Koid));

  // We should've gotten an attach reply.
  auto& attach_replies = harness.stream_backend()->attach_replies();
  auto reply = attach_replies.back();
  ASSERT_EQ(attach_replies.size(), 1u);
  EXPECT_TRUE(reply.status.ok());
  EXPECT_EQ(reply.koid, kProcess1Koid);
  EXPECT_EQ(reply.name, "job1-p2");

  // Asking for some invalid process should fail.
  attach_request.koid = 0x231315;  // Some invalid value.
  remote_api->OnAttach(transaction_id++, attach_request);

  // We should've gotten an error reply.
  ASSERT_EQ(attach_replies.size(), 2u);
  reply = attach_replies.back();
  EXPECT_TRUE(reply.status.has_error());

  // Attaching to a third process should work.
  attach_request.koid = 21u;
  remote_api->OnAttach(transaction_id++, attach_request);

  ASSERT_EQ(attach_replies.size(), 3u);
  reply = attach_replies.back();
  EXPECT_TRUE(reply.status.ok());
  EXPECT_EQ(reply.koid, 21u);
  EXPECT_EQ(reply.name, "job121-p2");

  // Attaching again to a process should fail.
  remote_api->OnAttach(transaction_id++, attach_request);

  ASSERT_EQ(attach_replies.size(), 4u);
  reply = attach_replies.back();
  EXPECT_TRUE(reply.status.has_error());
}

TEST_F(DebugAgentTests, AttachToLimbo) {
  // debug_ipc::SetDebugMode(true);
  // debug_ipc::SetLogCategories({debug_ipc::LogCategory::kAll});
  uint32_t transaction_id = 1u;

  MockDebugAgentHarness harness;
  RemoteAPI* remote_api = harness.debug_agent();

  constexpr zx_koid_t kProcKoid = 100;
  constexpr zx_koid_t kThreadKoid = 101;
  MockProcessHandle mock_process(kProcKoid, "proc");
  MockThreadHandle mock_thread(kThreadKoid, "thread");
  mock_process.set_threads({mock_thread});

  harness.system_interface()->mock_limbo_provider().AppendException(
      mock_process, mock_thread, MockExceptionHandle(kThreadKoid));

  debug_ipc::AttachRequest attach_request = {};
  attach_request.type = debug_ipc::TaskType::kProcess;
  attach_request.koid = kProcKoid;
  remote_api->OnAttach(transaction_id++, attach_request);

  // Process should be watching.
  EXPECT_TRUE(HasAttachedProcessWithKoid(harness.debug_agent(), kProcKoid));

  // We should've gotten an attach reply.
  auto& attach_replies = harness.stream_backend()->attach_replies();
  ASSERT_EQ(attach_replies.size(), 1u);
  auto reply = attach_replies.back();
  EXPECT_TRUE(reply.status.ok());
  EXPECT_EQ(reply.koid, kProcKoid);
  EXPECT_EQ(reply.name, "proc");

  {
    DebuggedProcess* process = harness.debug_agent()->GetDebuggedProcess(kProcKoid);
    ASSERT_TRUE(process);
    auto threads = process->GetThreads();
    ASSERT_EQ(threads.size(), 1u);

    // Search for the exception thread.
    DebuggedThread* exception_thread = nullptr;
    for (DebuggedThread* thread : threads) {
      if (thread->koid() == kThreadKoid) {
        exception_thread = thread;
        break;
      }
    }

    ASSERT_TRUE(exception_thread);
    ASSERT_TRUE(exception_thread->in_exception());
    EXPECT_EQ(exception_thread->exception_handle()->GetThreadHandle()->GetKoid(), kThreadKoid);
  }
}

TEST_F(DebugAgentTests, OnEnterLimbo) {
  MockDebugAgentHarness harness;

  constexpr zx_koid_t kProcKoid1 = 100;
  constexpr zx_koid_t kThreadKoid1 = 101;
  harness.system_interface()->mock_limbo_provider().AppendException(
      MockProcessHandle(kProcKoid1, "proc1"), MockThreadHandle(kThreadKoid1, "thread1"),
      MockExceptionHandle(kThreadKoid1));

  // Call the limbo.
  harness.system_interface()->mock_limbo_provider().CallOnEnterLimbo();

  // Should've sent a notification.
  {
    ASSERT_EQ(harness.stream_backend()->process_starts().size(), 1u);

    auto& process_start = harness.stream_backend()->process_starts()[0];
    EXPECT_EQ(process_start.type, debug_ipc::NotifyProcessStarting::Type::kLimbo);
    EXPECT_EQ(process_start.koid, kProcKoid1);
    EXPECT_EQ(process_start.component_id, 0u);
    EXPECT_EQ(process_start.name, "proc1");
  }
}

TEST_F(DebugAgentTests, DetachFromLimbo) {
  MockDebugAgentHarness harness;
  RemoteAPI* remote_api = harness.debug_agent();

  constexpr zx_koid_t kProcKoid = 14;  // MockJobTree job11-p1

  // Attempting to detach to a process that doesn't exist should fail.
  {
    debug_ipc::DetachRequest request = {};
    request.type = debug_ipc::TaskType::kProcess;
    request.koid = kProcKoid;

    debug_ipc::DetachReply reply = {};
    remote_api->OnDetach(request, &reply);

    ASSERT_TRUE(reply.status.has_error());
    ASSERT_EQ(harness.system_interface()->mock_limbo_provider().release_calls().size(), 0u);
  }

  // Adding it should now find it and remove it.
  constexpr zx_koid_t kProcKoid1 = 100;
  constexpr zx_koid_t kThreadKoid1 = 101;
  harness.system_interface()->mock_limbo_provider().AppendException(
      MockProcessHandle(kProcKoid1, "proc1"), MockThreadHandle(kThreadKoid1, "thread1"),
      MockExceptionHandle(kThreadKoid1));
  {
    debug_ipc::DetachRequest request = {};
    request.type = debug_ipc::TaskType::kProcess;
    request.koid = kProcKoid1;

    debug_ipc::DetachReply reply = {};
    remote_api->OnDetach(request, &reply);

    ASSERT_TRUE(reply.status.ok());
    ASSERT_EQ(harness.system_interface()->mock_limbo_provider().release_calls().size(), 1u);
    EXPECT_EQ(harness.system_interface()->mock_limbo_provider().release_calls()[0], kProcKoid1);
  }

  // This should've remove it from limbo, trying it again should fail.
  {
    debug_ipc::DetachRequest request = {};
    request.type = debug_ipc::TaskType::kProcess;
    request.koid = kProcKoid1;

    debug_ipc::DetachReply reply = {};
    remote_api->OnDetach(request, &reply);

    ASSERT_TRUE(reply.status.has_error());
    ASSERT_EQ(harness.system_interface()->mock_limbo_provider().release_calls().size(), 1u);
    EXPECT_EQ(harness.system_interface()->mock_limbo_provider().release_calls()[0], kProcKoid1);
  }
}

TEST_F(DebugAgentTests, Kill) {
  uint32_t transaction_id = 1u;

  MockDebugAgentHarness harness;
  RemoteAPI* remote_api = harness.debug_agent();

  constexpr zx_koid_t kProcKoid = 14;  // MockJobTree job11-p1

  // Attempt to kill a process that's not there should fail.
  {
    debug_ipc::KillRequest kill_request = {};
    kill_request.process_koid = kProcKoid;

    debug_ipc::KillReply kill_reply = {};
    remote_api->OnKill(kill_request, &kill_reply);
    ASSERT_TRUE(kill_reply.status.has_error());
  }

  // Attach to a process so that the debugger knows about it.
  {
    debug_ipc::AttachRequest attach_request = {};
    attach_request.type = debug_ipc::TaskType::kProcess;
    attach_request.koid = kProcKoid;
    remote_api->OnAttach(transaction_id++, attach_request);

    // There should be a process.
    ASSERT_EQ(harness.debug_agent()->procs_.size(), 1u);
    // Should not come from limbo.
    EXPECT_FALSE(harness.debug_agent()->procs_.begin()->second->from_limbo());
  }

  // Killing now should work.
  {
    debug_ipc::KillRequest kill_request = {};
    kill_request.process_koid = kProcKoid;

    debug_ipc::KillReply kill_reply = {};
    remote_api->OnKill(kill_request, &kill_reply);

    // There should be no more processes.
    ASSERT_EQ(harness.debug_agent()->procs_.size(), 0u);

    // Killing again should fail.
    remote_api->OnKill(kill_request, &kill_reply);
    ASSERT_TRUE(kill_reply.status.has_error());
  }

  // Add the process to the limbo.
  constexpr zx_koid_t kLimboProcKoid = 100;
  constexpr zx_koid_t kLimboThreadKoid = 101;
  MockProcessHandle mock_process(kLimboProcKoid, "proc");
  // This is a limbo process so we can not kill it.
  mock_process.set_kill_status(debug::Status("Access denied"));
  MockThreadHandle mock_thread(kLimboThreadKoid, "thread");
  MockExceptionHandle mock_exception(kLimboThreadKoid);
  mock_process.set_threads({mock_thread});
  harness.system_interface()->mock_limbo_provider().AppendException(mock_process, mock_thread,
                                                                    mock_exception);

  // There should be no more processes.
  ASSERT_EQ(harness.debug_agent()->procs_.size(), 0u);

  // Killing now should release it.
  {
    debug_ipc::KillRequest kill_request = {};
    kill_request.process_koid = kLimboProcKoid;

    debug_ipc::KillReply kill_reply = {};
    remote_api->OnKill(kill_request, &kill_reply);
    ASSERT_TRUE(kill_reply.status.ok());

    ASSERT_EQ(harness.system_interface()->mock_limbo_provider().release_calls().size(), 1u);
    EXPECT_EQ(harness.system_interface()->mock_limbo_provider().release_calls()[0], kLimboProcKoid);

    // Killing again should not find it.
    remote_api->OnKill(kill_request, &kill_reply);
    ASSERT_TRUE(kill_reply.status.has_error());
  }

  harness.system_interface()->mock_limbo_provider().AppendException(mock_process, mock_thread,
                                                                    mock_exception);

  debug_ipc::AttachRequest attach_request = {};
  attach_request.type = debug_ipc::TaskType::kProcess;
  attach_request.koid = kLimboProcKoid;
  remote_api->OnAttach(transaction_id++, attach_request);

  // There should be a process.
  ASSERT_EQ(harness.debug_agent()->procs_.size(), 1u);

  {
    auto it = harness.debug_agent()->procs_.find(kLimboProcKoid);
    ASSERT_NE(it, harness.debug_agent()->procs_.end());
    EXPECT_TRUE(harness.debug_agent()->procs_.begin()->second->from_limbo());

    // Killing it should free the process.
    debug_ipc::KillRequest kill_request = {};
    kill_request.process_koid = kLimboProcKoid;

    debug_ipc::KillReply kill_reply = {};
    remote_api->OnKill(kill_request, &kill_reply);
    ASSERT_TRUE(kill_reply.status.ok());

    ASSERT_EQ(harness.debug_agent()->procs_.size(), 0u);

    // There should be a limbo process to be killed.
    ASSERT_EQ(harness.debug_agent()->killed_limbo_procs_.size(), 1u);
    EXPECT_EQ(harness.debug_agent()->killed_limbo_procs_.count(kLimboProcKoid), 1u);

    // There should've have been more release calls (yet).
    ASSERT_EQ(harness.system_interface()->mock_limbo_provider().release_calls().size(), 1u);

    // When the process "re-enters" the limbo, it should be removed.
    harness.system_interface()->mock_limbo_provider().AppendException(mock_process, mock_thread,
                                                                      mock_exception);
    harness.system_interface()->mock_limbo_provider().CallOnEnterLimbo();

    // There should not be an additional proc in the agent.
    ASSERT_EQ(harness.debug_agent()->procs_.size(), 0u);

    // There should've been a release call.
    ASSERT_EQ(harness.system_interface()->mock_limbo_provider().release_calls().size(), 2u);
    EXPECT_EQ(harness.system_interface()->mock_limbo_provider().release_calls()[1], kLimboProcKoid);
  }
}

TEST_F(DebugAgentTests, OnUpdateGlobalSettings) {
  MockDebugAgentHarness harness;
  RemoteAPI* remote_api = harness.debug_agent();

  // The default strategy should be first chance for a type that has yet to be
  // updated.
  EXPECT_EQ(debug_ipc::ExceptionStrategy::kFirstChance,
            harness.debug_agent()->GetExceptionStrategy(debug_ipc::ExceptionType::kGeneral));
  EXPECT_EQ(debug_ipc::ExceptionStrategy::kFirstChance,
            harness.debug_agent()->GetExceptionStrategy(debug_ipc::ExceptionType::kPageFault));

  {
    const debug_ipc::UpdateGlobalSettingsRequest request = {
        .exception_strategies =
            {
                {
                    .type = debug_ipc::ExceptionType::kGeneral,
                    .value = debug_ipc::ExceptionStrategy::kSecondChance,
                },
                {
                    .type = debug_ipc::ExceptionType::kPageFault,
                    .value = debug_ipc::ExceptionStrategy::kSecondChance,
                },
            },
    };
    debug_ipc::UpdateGlobalSettingsReply reply;
    remote_api->OnUpdateGlobalSettings(request, &reply);
    EXPECT_TRUE(reply.status.ok());
  }

  EXPECT_EQ(debug_ipc::ExceptionStrategy::kSecondChance,
            harness.debug_agent()->GetExceptionStrategy(debug_ipc::ExceptionType::kGeneral));
  EXPECT_EQ(debug_ipc::ExceptionStrategy::kSecondChance,
            harness.debug_agent()->GetExceptionStrategy(debug_ipc::ExceptionType::kPageFault));

  {
    const debug_ipc::UpdateGlobalSettingsRequest request = {
        .exception_strategies =
            {
                {
                    .type = debug_ipc::ExceptionType::kGeneral,
                    .value = debug_ipc::ExceptionStrategy::kFirstChance,
                },
            },
    };
    debug_ipc::UpdateGlobalSettingsReply reply;
    remote_api->OnUpdateGlobalSettings(request, &reply);
    EXPECT_TRUE(reply.status.ok());
  }

  EXPECT_EQ(debug_ipc::ExceptionStrategy::kFirstChance,
            harness.debug_agent()->GetExceptionStrategy(debug_ipc::ExceptionType::kGeneral));
  EXPECT_EQ(debug_ipc::ExceptionStrategy::kSecondChance,
            harness.debug_agent()->GetExceptionStrategy(debug_ipc::ExceptionType::kPageFault));
}

}  // namespace debug_agent
