// 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 "tools/fidlcat/interception_tests/interception_workflow_test.h"

#include <gtest/gtest.h>

#include "src/developer/debug/zxdb/expr/expr_parser.h"

namespace fidlcat {

// We only test one syscall at a time. We always use the same address for all the syscalls.
constexpr uint64_t kSyscallAddress = 0x100060;
// Address used to generate an exception.
constexpr uint64_t kExceptionAddress = 0x12345678;

constexpr int kFrame1Line = 25;
constexpr int kFrame1Column = 8;
constexpr int kFrame2Line = 50;
constexpr int kFrame2Column = 4;
constexpr int kFrame3Line = 10;
constexpr int kFrame3Column = 2;

constexpr int kFrame2Sp = 0x126790;
constexpr int kFrame3Sp = 0x346712;

constexpr uint64_t kTestTimestampDefault = 0x74657374l;  // hexadecimal for "test" in ascii

static std::vector<debug::RegisterID> aarch64_regs = {
    debug::RegisterID::kARMv8_x0, debug::RegisterID::kARMv8_x1, debug::RegisterID::kARMv8_x2,
    debug::RegisterID::kARMv8_x3, debug::RegisterID::kARMv8_x4, debug::RegisterID::kARMv8_x5,
    debug::RegisterID::kARMv8_x6, debug::RegisterID::kARMv8_x7};

static std::vector<debug::RegisterID> amd64_regs = {
    debug::RegisterID::kX64_rdi, debug::RegisterID::kX64_rsi, debug::RegisterID::kX64_rdx,
    debug::RegisterID::kX64_rcx, debug::RegisterID::kX64_r8,  debug::RegisterID::kX64_r9};

SyscallDecoderDispatcher* global_dispatcher = nullptr;

DataForSyscallTest::DataForSyscallTest(debug::Arch arch) : arch_(arch) {
  param_regs_ = (arch_ == debug::Arch::kArm64) ? &aarch64_regs : &amd64_regs;
  header_.txid = kTxId;
  header_.magic_number = kFidlWireFormatMagicNumberInitial;
  header_.at_rest_flags[0] = 0;
  header_.at_rest_flags[1] = 0;
  header_.dynamic_flags = 0;
  header_.ordinal = kOrdinal;
  header2_.txid = kTxId2;
  header2_.magic_number = kFidlWireFormatMagicNumberInitial;
  header2_.at_rest_flags[0] = 0;
  header2_.at_rest_flags[1] = 0;
  header2_.dynamic_flags = 0;
  header2_.ordinal = kOrdinal2;

  for (int i = 0; i < 100; ++i) {
    large_bytes_.push_back(i * i);
  }
  sp_ = stack_ + kMaxStackSizeInWords;
}

void InterceptionWorkflowTest::PerformDisplayTest(const char* syscall_name,
                                                  std::unique_ptr<SystemCallTest> syscall,
                                                  const char* expected,
                                                  fidl_codec::LibraryLoader* loader) {
  ProcessController controller(this, session(), loop());
  PerformDisplayTest(&controller, syscall_name, std::move(syscall), expected, loader);
  last_decoder_dispatcher_ = controller.GetBackDispatcher();
}

void InterceptionWorkflowTest::PerformDisplayTest(ProcessController* controller,
                                                  const char* syscall_name,
                                                  std::unique_ptr<SystemCallTest> syscall,
                                                  const char* expected,
                                                  fidl_codec::LibraryLoader* loader) {
  PerformTest(syscall_name, std::move(syscall), nullptr, controller,
              std::make_unique<SyscallDisplayDispatcherTest>(
                  loader, decode_options_, display_options_, result_, controller, aborted_),
              /*interleaved_test=*/false, /*multi_thread=*/true);
  std::string both_results = result_.str();
  // The second output starts with "\x1B[32m0.000000\x1B[0m test_2718"
  size_t split = both_results.find("\x1B[32m0.000000\x1B[0m test_2718");
  ASSERT_NE(split, std::string::npos) << both_results;
  if (!display_options_.with_process_info) {
    // When we don't have the process info on each line, the first displayed line is empty (instead
    // of having the process name, process id and thread id). Go back one position to add this line
    // to the second comparison (and remove it from the first comparison);
    --split;
  }
  std::string first = both_results.substr(0, split);
  std::string second = both_results.substr(split);

  // Check that the two syscalls generated the data we expect.
  ASSERT_EQ(expected, first);
  ASSERT_NE(expected, second);

  std::string str_expected(expected);
  // The expected and the second should have the same data from different pids.  Replace
  // the pid from the expected with the pid from the second, and they should look
  // the same.
  size_t i = 0;
  std::string first_pid = std::to_string(kFirstPid);
  std::string second_pid = std::to_string(kSecondPid);
  while ((i = str_expected.find(first_pid, i)) != std::string::npos) {
    str_expected.replace(i, first_pid.length(), second_pid);
    i += second_pid.length();
  }
  // Do it also for thread koids.
  i = 0;
  std::string first_thread_koid = std::to_string(kFirstThreadKoid);
  std::string second_thread_koid = std::to_string(kSecondThreadKoid);
  while ((i = str_expected.find(first_thread_koid, i)) != std::string::npos) {
    str_expected.replace(i, first_thread_koid.length(), second_thread_koid);
    i += second_thread_koid.length();
  }
  ASSERT_EQ(str_expected, second);
}

void InterceptionWorkflowTest::PerformOneThreadDisplayTest(const char* syscall_name,
                                                           std::unique_ptr<SystemCallTest> syscall,
                                                           const char* expected) {
  ProcessController controller(this, session(), loop());

  PerformTest(syscall_name, std::move(syscall), nullptr, &controller,
              std::make_unique<SyscallDisplayDispatcherTest>(
                  nullptr, decode_options_, display_options_, result_, &controller, aborted_),
              /*interleaved_test=*/false, /*multi_thread=*/false);
  ASSERT_EQ(expected, result_.str());
}

void InterceptionWorkflowTest::PerformInterleavedDisplayTest(
    const char* syscall_name, std::unique_ptr<SystemCallTest> syscall, const char* expected) {
  ProcessController controller(this, session(), loop());
  PerformInterleavedDisplayTest(&controller, syscall_name, std::move(syscall), expected);
}

void InterceptionWorkflowTest::PerformInterleavedDisplayTest(
    ProcessController* controller, const char* syscall_name,
    std::unique_ptr<SystemCallTest> syscall, const char* expected) {
  PerformTest(syscall_name, std::move(syscall), nullptr, controller,
              std::make_unique<SyscallDisplayDispatcherTest>(
                  nullptr, decode_options_, display_options_, result_, controller, aborted_),
              /*interleaved_test=*/true, /*multi_thread=*/true);
  ASSERT_EQ(expected, result_.str());
}

void InterceptionWorkflowTest::PerformNoReturnDisplayTest(const char* syscall_name,
                                                          std::unique_ptr<SystemCallTest> syscall,
                                                          const char* expected) {
  ProcessController controller(this, session(), loop());
  controller.Initialize(
      session(),
      std::make_unique<SyscallDisplayDispatcherTest>(nullptr, decode_options_, display_options_,
                                                     result_, &controller, aborted_),
      syscall_name);

  data_.set_syscall(std::move(syscall));
  data_.load_syscall_data();

  TriggerSyscallBreakpoint(kFirstPid, kFirstThreadKoid);

  ASSERT_EQ(expected, result_.str());
}

void InterceptionWorkflowTest::PerformTest(const char* syscall_name,
                                           std::unique_ptr<SystemCallTest> syscall1,
                                           std::unique_ptr<SystemCallTest> syscall2,
                                           ProcessController* controller,
                                           std::unique_ptr<SyscallDecoderDispatcher> dispatcher,
                                           bool interleaved_test, bool multi_thread) {
  controller->Initialize(session(), std::move(dispatcher), syscall_name);

  SimulateSyscall(std::move(syscall1), controller, interleaved_test, multi_thread);

  if (syscall2 != nullptr) {
    data_.set_use_alternate_data();
    SimulateSyscall(std::move(syscall2), controller, interleaved_test, multi_thread);
  }
}

void InterceptionWorkflowTest::PerformAbortedTest(const char* syscall_name,
                                                  std::unique_ptr<SystemCallTest> syscall,
                                                  const char* expected) {
  ProcessController controller(this, session(), loop());
  auto decoder = std::make_unique<SyscallDisplayDispatcherTest>(
      nullptr, decode_options_, display_options_, result_, &controller, aborted_);
  controller.Initialize(session(), std::move(decoder), syscall_name);
  data_.set_syscall(std::move(syscall));
  data_.load_syscall_data();
  TriggerSyscallBreakpoint(kFirstPid, kFirstThreadKoid);
  ASSERT_EQ(expected, result_.str());
}

void InterceptionWorkflowTest::SimulateSyscall(std::unique_ptr<SystemCallTest> syscall,
                                               ProcessController* controller, bool interleaved_test,
                                               bool multi_thread) {
  data_.set_syscall(std::move(syscall));
  if (multi_thread) {
    if (interleaved_test) {
      for (uint64_t process_koid : controller->process_koids()) {
        data_.load_syscall_data();
        TriggerSyscallBreakpoint(process_koid, controller->thread_koid(process_koid));
      }
      for (uint64_t process_koid : controller->process_koids()) {
        TriggerCallerBreakpoint(process_koid, controller->thread_koid(process_koid));
      }
    } else {
      for (uint64_t process_koid : controller->process_koids()) {
        data_.load_syscall_data();
        uint64_t thread_koid = controller->thread_koid(process_koid);
        TriggerSyscallBreakpoint(process_koid, thread_koid);
        TriggerCallerBreakpoint(process_koid, thread_koid);
      }
    }
  } else {
    data_.load_syscall_data();
    TriggerSyscallBreakpoint(kFirstPid, kFirstThreadKoid);
    if (update_data_ != nullptr) {
      update_data_();
    }
    TriggerCallerBreakpoint(kFirstPid, kFirstThreadKoid);
  }
}

// Fill a NotifyException object with all the information we need to simulate a breakpoint.
std::vector<std::unique_ptr<zxdb::Frame>> InterceptionWorkflowTest::FillBreakpoint(
    debug_ipc::NotifyException* notification, uint64_t process_koid, uint64_t thread_koid) {
  notification->timestamp = 0;
  notification->type = debug_ipc::ExceptionType::kSoftwareBreakpoint;
  notification->thread.id = {.process = process_koid, .thread = thread_koid};
  notification->thread.state = debug_ipc::ThreadRecord::State::kBlocked;
  notification->thread.stack_amount = debug_ipc::ThreadRecord::StackAmount::kMinimal;

  std::vector<std::unique_ptr<zxdb::Frame>> frames;

  if (!bad_stack_) {
    debug_ipc::StackFrame frame1(kSyscallAddress, reinterpret_cast<uint64_t>(data_.sp()));
    debug_ipc::StackFrame frame2(kSyscallAddress, kFrame2Sp);
    debug_ipc::StackFrame frame3(kSyscallAddress, kFrame3Sp);

    data_.PopulateRegisters(process_koid, &frame1.regs);
    notification->thread.frames.push_back(frame1);

    zxdb::SymbolContext context(0);
    frames.emplace_back(std::make_unique<zxdb::FrameImpl>(
        threads_[thread_koid], frame1,
        zxdb::Location(kExceptionAddress, zxdb::FileLine("fidlcat/foo.cc", kFrame1Line),
                       kFrame1Column, context)));
    frames.emplace_back(std::make_unique<zxdb::FrameImpl>(
        threads_[thread_koid], frame2,
        zxdb::Location(kExceptionAddress, zxdb::FileLine("fidlcat/foo.cc", kFrame2Line),
                       kFrame2Column, context)));
    frames.emplace_back(std::make_unique<zxdb::FrameImpl>(
        threads_[thread_koid], frame2,
        zxdb::Location(kExceptionAddress, zxdb::FileLine("fidlcat/main.cc", kFrame3Line),
                       kFrame3Column, context)));
  }
  return frames;
}

void InterceptionWorkflowTest::TriggerSyscallBreakpoint(uint64_t process_koid,
                                                        uint64_t thread_koid) {
  // Trigger breakpoint.
  debug_ipc::NotifyException notification;
  std::vector<std::unique_ptr<zxdb::Frame>> frames =
      FillBreakpoint(&notification, process_koid, thread_koid);

  mock_remote_api().PopulateBreakpointIds(kSyscallAddress, notification);

  InjectExceptionWithStack(notification, std::move(frames), /*has_all_frames=*/true);

  if (!aborted_ && !bad_stack_) {
    debug::MessageLoop::Current()->Run();
  }
}

void InterceptionWorkflowTest::TriggerCallerBreakpoint(uint64_t process_koid,
                                                       uint64_t thread_koid) {
  // Trigger next breakpoint, when the syscall has completed.
  debug_ipc::NotifyException notification;
  notification.timestamp = 0;
  notification.type = debug_ipc::ExceptionType::kSoftwareBreakpoint;
  notification.thread.id = {.process = process_koid, .thread = thread_koid};
  notification.thread.state = debug_ipc::ThreadRecord::State::kBlocked;
  notification.thread.stack_amount = debug_ipc::ThreadRecord::StackAmount::kMinimal;

  debug_ipc::StackFrame frame(DataForSyscallTest::kReturnAddress,
                              reinterpret_cast<uint64_t>(data_.sp()));

  data_.PopulateRegisters(process_koid, &frame.regs);
  notification.thread.frames.push_back(frame);

  mock_remote_api().PopulateBreakpointIds(DataForSyscallTest::kReturnAddress, notification);

  InjectException(notification);

  debug::MessageLoop::Current()->Run();
}

void InterceptionWorkflowTest::PerformExceptionDisplayTest(debug_ipc::ExceptionType type,
                                                           const char* expected) {
  ProcessController controller(this, session(), loop());

  PerformExceptionTest(
      &controller,
      std::make_unique<SyscallDisplayDispatcherTest>(nullptr, decode_options_, display_options_,
                                                     result_, &controller, aborted_),
      type);
  ASSERT_EQ(result_.str(), expected);
}

void InterceptionWorkflowTest::PerformExceptionTest(
    ProcessController* controller, std::unique_ptr<SyscallDecoderDispatcher> dispatcher,
    debug_ipc::ExceptionType type) {
  controller->Initialize(session(), std::move(dispatcher), "");

  TriggerException(kFirstPid, kFirstThreadKoid, type);

  debug::MessageLoop::Current()->Run();
}

void InterceptionWorkflowTest::TriggerException(uint64_t process_koid, uint64_t thread_koid,
                                                debug_ipc::ExceptionType type) {
  // Trigger breakpoint.
  debug_ipc::NotifyException notification;
  notification.timestamp = 0;
  notification.type = type;
  notification.thread.id = {.process = process_koid, .thread = thread_koid};
  notification.thread.state = debug_ipc::ThreadRecord::State::kBlocked;
  notification.thread.stack_amount = debug_ipc::ThreadRecord::StackAmount::kMinimal;

  debug_ipc::StackFrame frame1(kExceptionAddress, reinterpret_cast<uint64_t>(data_.sp()));
  debug_ipc::StackFrame frame2(kExceptionAddress, kFrame2Sp);
  debug_ipc::StackFrame frame3(kExceptionAddress, kFrame3Sp);

  data_.PopulateRegisters(process_koid, &frame1.regs);
  notification.thread.frames.push_back(frame1);

  mock_remote_api().PopulateBreakpointIds(kExceptionAddress, notification);

  zxdb::SymbolContext context(0);
  std::vector<std::unique_ptr<zxdb::Frame>> frames;
  frames.emplace_back(std::make_unique<zxdb::FrameImpl>(
      threads_[thread_koid], frame1,
      zxdb::Location(kExceptionAddress, zxdb::FileLine("fidlcat/foo.cc", kFrame1Line),
                     kFrame1Column, context)));
  frames.emplace_back(std::make_unique<zxdb::FrameImpl>(
      threads_[thread_koid], frame2,
      zxdb::Location(kExceptionAddress, zxdb::FileLine("fidlcat/foo.cc", kFrame2Line),
                     kFrame2Column, context)));
  frames.emplace_back(std::make_unique<zxdb::FrameImpl>(
      threads_[thread_koid], frame2,
      zxdb::Location(kExceptionAddress, zxdb::FileLine("fidlcat/main.cc", kFrame3Line),
                     kFrame3Column, context)));

  InjectExceptionWithStack(notification, std::move(frames), /*has_all_frames=*/true);
}

// Functions are different from syscalls because syscalls have a '@' in their name.
// Because of that, zxdb handles the syscalls differently.
// For functions, we can't use TriggerSyscallBreakpoint because the breakpoint is not
// recognized.
void InterceptionWorkflowTest::PerformFunctionTest(ProcessController* controller,
                                                   const char* syscall_name,
                                                   std::unique_ptr<SystemCallTest> syscall,
                                                   uint64_t pid, uint64_t tid) {
  if (!controller->initialized()) {
    controller->Initialize(
        session(),
        std::make_unique<SyscallDisplayDispatcherTest>(nullptr, decode_options_, display_options_,
                                                       result_, controller, aborted_),
        syscall_name);
  }
  data_.set_syscall(std::move(syscall));
  data_.load_syscall_data();

  debug_ipc::NotifyException notification;
  // Fill the breakpoint.
  std::vector<std::unique_ptr<zxdb::Frame>> frames = FillBreakpoint(&notification, pid, tid);
  threads_[tid]->GetStack().SetFramesForTest(std::move(frames),
                                             /*has_all_frames=*/true);

  // Instead of using PopulateBreakpointIds and InjectException, we need to directly
  // call our function interception code.
  SyscallDecoderDispatcher* dispatcher = controller->workflow().syscall_decoder_dispatcher();
  for (const auto& syscall : dispatcher->syscalls()) {
    if (syscall.second->name() == syscall_name) {
      dispatcher->DecodeSyscall(&controller->workflow().thread_observer(), threads_[tid],
                                syscall.second.get(), kTestTimestampDefault);
      break;
    }
  }

  debug::MessageLoop::Current()->Run();
}

ProcessController::ProcessController(InterceptionWorkflowTest* remote_api, zxdb::Session& session,
                                     debug::MessageLoop& loop)
    : remote_api_(remote_api), workflow_(&session, &loop) {
  process_koids_ = {kFirstPid, kSecondPid};
  thread_koids_[kFirstPid] = kFirstThreadKoid;
  thread_koids_[kSecondPid] = kSecondThreadKoid;
}

ProcessController::~ProcessController() {}

void ProcessController::InjectProcesses(zxdb::Session& session) {
  for (auto process_koid : process_koids_) {
    std::string test_name = "test_" + std::to_string(process_koid);
    zxdb::TargetImpl* target = session.system().CreateNewTargetImpl(nullptr);
    target->CreateProcessForTesting(process_koid, test_name);
    processes_.push_back(target->GetProcess());
  }
}

void ProcessController::Initialize(zxdb::Session& session,
                                   std::unique_ptr<SyscallDecoderDispatcher> dispatcher,
                                   const char* syscall_name) {
  initialized_ = true;
  global_dispatcher = dispatcher.get();
  std::vector<std::string> blank;
  workflow_.Initialize(blank, blank, blank, blank, std::nullopt, blank, std::move(dispatcher));

  // Create fake processes and threads.
  InjectProcesses(session);

  for (zxdb::Process* process : processes_) {
    zxdb::Thread* the_thread =
        remote_api_->InjectThread(process->GetKoid(), thread_koids_[process->GetKoid()]);

    // Observe thread.  This is usually done in workflow_::Attach, but
    // RemoteAPITest has its own ideas about attaching, so that method only
    // half-works (the half that registers the target with the workflow). We
    // have to register the observer manually.
    zxdb::Target* target = process->GetTarget();
    targets_.push_back(target);
    remote_api_->AddThread(the_thread);
  }

  // Attach to processes.
  debug::MessageLoop::Current()->PostTask(FROM_HERE, [this]() {
    workflow_.Attach(process_koids_);
    debug::MessageLoop::Current()->QuitNow();
  });
  debug::MessageLoop::Current()->Run();

  // Load modules into program (including the one with the |syscall_name| symbol)
  auto module_symbols = fxl::MakeRefCounted<zxdb::MockModuleSymbols>("zx.so");
  session.system().GetSymbols()->InjectModuleForTesting(DataForSyscallTest::kElfSymbolBuildID,
                                                        module_symbols.get());

  // Inject the syscall symbol if requested. Use the full parser to parse the input identifier to
  // handle all possible cases.
  if (strlen(syscall_name) > 0) {
    zxdb::Identifier syscall_identifier;
    zxdb::Err err = zxdb::ExprParser::ParseIdentifier(syscall_name, &syscall_identifier);
    EXPECT_TRUE(err.ok()) << err.msg();
    module_symbols->AddSymbolLocations(
        syscall_identifier, {zxdb::Location(zxdb::Location::State::kSymbolized, kSyscallAddress)});
  }

  for (zxdb::Target* target : session.system().GetTargets()) {
    zxdb::Err err;
    std::vector<debug_ipc::Module> modules;
    // Force system to load modules.  Callback doesn't need to do anything
    // interesting.
    if (target->GetProcess() != nullptr) {
      target->GetProcess()->GetModules(
          false, [](const zxdb::Err& /*err*/, std::vector<debug_ipc::Module> /*modules*/) {
            debug::MessageLoop::Current()->QuitNow();
          });
      debug::MessageLoop::Current()->Run();
    }
  }
}

void ProcessController::Detach() {
  if (++detached_processes_ == processes_.size()) {
    workflow_.Shutdown();
  }
}

// This tests keeps track of which syscalls have automation.
// It will be destroyed when everything is implemented.
TEST_F(InterceptionWorkflowTestX64, SyscallsAutomated) {
  std::stringstream actual;
  uint32_t actual_fully_automated = 0;
  uint32_t actual_cant_be_automated = 0;
  uint32_t actual_partially_automated = 0;
  uint32_t actual_not_automated = 0;
  ProcessController controller(this, session(), loop());
  controller.Initialize(
      session(),
      std::make_unique<SyscallDisplayDispatcherTest>(nullptr, decode_options_, display_options_,
                                                     result_, &controller, aborted_),
      "");
  SyscallDecoderDispatcher* dispatcher = controller.workflow().syscall_decoder_dispatcher();
  for (const auto& syscall : dispatcher->syscalls()) {
    if (syscall.second->fully_automated()) {
      if (syscall.second->invoked_bp_instructions().size() +
              syscall.second->exit_bp_instructions().size() >
          0) {
        actual << syscall.second->name() << " fully automated\n";
        ++actual_fully_automated;
      } else {
        actual << syscall.second->name() << " doesn't need automation\n";
        ++actual_cant_be_automated;
      }
    } else {
      if (syscall.second->invoked_bp_instructions().size() +
              syscall.second->exit_bp_instructions().size() >
          0) {
        actual << syscall.second->name() << " partially automated\n";
        ++actual_partially_automated;
      } else {
        actual << syscall.second->name() << " not automated\n";
        ++actual_not_automated;
      }
    }
  }
  std::string expected =
      "__libc_extensions_init partially automated\n"
      "processargs_extract_handles fully automated\n"
      "zx_bti_create fully automated\n"
      "zx_bti_pin fully automated\n"
      "zx_bti_release_quarantine doesn't need automation\n"
      "zx_cache_flush doesn't need automation\n"
      "zx_channel_call partially automated\n"
      "zx_channel_call_etc partially automated\n"
      "zx_channel_create fully automated\n"
      "zx_channel_read partially automated\n"
      "zx_channel_read_etc partially automated\n"
      "zx_channel_write fully automated\n"
      "zx_channel_write_etc fully automated\n"
      "zx_clock_adjust doesn't need automation\n"
      "zx_clock_get fully automated\n"
      "zx_clock_get_monotonic doesn't need automation\n"
      "zx_cprng_add_entropy fully automated\n"
      "zx_cprng_draw fully automated\n"
      "zx_deadline_after doesn't need automation\n"
      "zx_debug_read partially automated\n"
      "zx_debug_send_command fully automated\n"
      "zx_debug_write fully automated\n"
      "zx_debuglog_create fully automated\n"
      "zx_debuglog_read fully automated\n"
      "zx_debuglog_write fully automated\n"
      "zx_event_create fully automated\n"
      "zx_eventpair_create fully automated\n"
      "zx_exception_get_process fully automated\n"
      "zx_exception_get_thread fully automated\n"
      "zx_fifo_create fully automated\n"
      "zx_fifo_read not automated\n"
      "zx_fifo_write not automated\n"
      "zx_framebuffer_get_info fully automated\n"
      "zx_framebuffer_set_range doesn't need automation\n"
      "zx_futex_get_owner fully automated\n"
      "zx_futex_requeue doesn't need automation\n"
      "zx_futex_requeue_single_owner doesn't need automation\n"
      "zx_futex_wait doesn't need automation\n"
      "zx_futex_wake doesn't need automation\n"
      "zx_futex_wake_handle_close_thread_exit doesn't need automation\n"
      "zx_futex_wake_single_owner doesn't need automation\n"
      "zx_guest_create fully automated\n"
      "zx_guest_set_trap doesn't need automation\n"
      "zx_handle_close doesn't need automation\n"
      "zx_handle_close_many fully automated\n"
      "zx_handle_duplicate fully automated\n"
      "zx_handle_replace fully automated\n"
      "zx_interrupt_ack doesn't need automation\n"
      "zx_interrupt_bind doesn't need automation\n"
      "zx_interrupt_bind_vcpu doesn't need automation\n"
      "zx_interrupt_create fully automated\n"
      "zx_interrupt_destroy doesn't need automation\n"
      "zx_interrupt_trigger doesn't need automation\n"
      "zx_interrupt_wait fully automated\n"
      "zx_iommu_create partially automated\n"
      "zx_ioports_release doesn't need automation\n"
      "zx_ioports_request doesn't need automation\n"
      "zx_job_create fully automated\n"
      "zx_job_set_policy not automated\n"
      "zx_ktrace_control not automated\n"
      "zx_ktrace_read partially automated\n"
      "zx_ktrace_write doesn't need automation\n"
      "zx_mtrace_control fully automated\n"
      "zx_nanosleep doesn't need automation\n"
      "zx_object_get_child fully automated\n"
      "zx_object_get_info partially automated\n"
      "zx_object_get_property fully automated\n"
      "zx_object_set_profile doesn't need automation\n"
      "zx_object_set_property fully automated\n"
      "zx_object_signal doesn't need automation\n"
      "zx_object_signal_peer doesn't need automation\n"
      "zx_object_wait_async doesn't need automation\n"
      "zx_object_wait_many not automated\n"
      "zx_object_wait_one fully automated\n"
      "zx_pager_create fully automated\n"
      "zx_pager_create_vmo fully automated\n"
      "zx_pager_detach_vmo doesn't need automation\n"
      "zx_pager_supply_pages doesn't need automation\n"
      "zx_pc_firmware_tables fully automated\n"
      "zx_pci_add_subtract_io_range doesn't need automation\n"
      "zx_pci_cfg_pio_rw fully automated\n"
      "zx_pci_config_read fully automated\n"
      "zx_pci_config_write doesn't need automation\n"
      "zx_pci_enable_bus_master doesn't need automation\n"
      "zx_pci_get_bar partially automated\n"
      "zx_pci_get_nth_device partially automated\n"
      "zx_pci_init not automated\n"
      "zx_pci_map_interrupt fully automated\n"
      "zx_pci_query_irq_mode fully automated\n"
      "zx_pci_reset_device doesn't need automation\n"
      "zx_pci_set_irq_mode doesn't need automation\n"
      "zx_pmt_unpin doesn't need automation\n"
      "zx_port_cancel doesn't need automation\n"
      "zx_port_create fully automated\n"
      "zx_port_queue not automated\n"
      "zx_port_wait not automated\n"
      "zx_process_create fully automated\n"
      "zx_process_exit doesn't need automation\n"
      "zx_process_read_memory fully automated\n"
      "zx_process_start doesn't need automation\n"
      "zx_process_write_memory fully automated\n"
      "zx_profile_create partially automated\n"
      "zx_resource_create fully automated\n"
      "zx_smc_call not automated\n"
      "zx_socket_create fully automated\n"
      "zx_socket_read partially automated\n"
      "zx_socket_set_disposition doesn't need automation\n"
      "zx_socket_write partially automated\n"
      "zx_system_get_dcache_line_size doesn't need automation\n"
      "zx_system_get_event fully automated\n"
      "zx_system_get_features fully automated\n"
      "zx_system_get_num_cpus doesn't need automation\n"
      "zx_system_get_physmem doesn't need automation\n"
      "zx_system_get_version_string doesn't need automation\n"
      "zx_system_mexec doesn't need automation\n"
      "zx_system_mexec_payload_get fully automated\n"
      "zx_system_powerctl not automated\n"
      "zx_task_create_exception_channel fully automated\n"
      "zx_task_kill doesn't need automation\n"
      "zx_task_suspend fully automated\n"
      "zx_task_suspend_token fully automated\n"
      "zx_thread_create fully automated\n"
      "zx_thread_exit doesn't need automation\n"
      "zx_thread_read_state partially automated\n"
      "zx_thread_start doesn't need automation\n"
      "zx_thread_write_state partially automated\n"
      "zx_ticks_get doesn't need automation\n"
      "zx_ticks_per_second doesn't need automation\n"
      "zx_timer_cancel doesn't need automation\n"
      "zx_timer_create fully automated\n"
      "zx_timer_set doesn't need automation\n"
      "zx_vcpu_create fully automated\n"
      "zx_vcpu_interrupt doesn't need automation\n"
      "zx_vcpu_read_state partially automated\n"
      "zx_vcpu_resume not automated\n"
      "zx_vcpu_write_state not automated\n"
      "zx_vmar_allocate fully automated\n"
      "zx_vmar_destroy doesn't need automation\n"
      "zx_vmar_map fully automated\n"
      "zx_vmar_protect doesn't need automation\n"
      "zx_vmar_unmap doesn't need automation\n"
      "zx_vmar_unmap_handle_close_thread_exit doesn't need automation\n"
      "zx_vmo_create fully automated\n"
      "zx_vmo_create_child fully automated\n"
      "zx_vmo_create_contiguous fully automated\n"
      "zx_vmo_create_physical fully automated\n"
      "zx_vmo_get_size fully automated\n"
      "zx_vmo_op_range doesn't need automation\n"
      "zx_vmo_read fully automated\n"
      "zx_vmo_replace_as_executable fully automated\n"
      "zx_vmo_set_cache_policy doesn't need automation\n"
      "zx_vmo_set_size doesn't need automation\n"
      "zx_vmo_write fully automated\n";
  uint32_t expected_fully_automated = 65;
  uint32_t expected_cant_be_automated = 59;
  uint32_t expected_partially_automated = 17;
  uint32_t expected_not_automated = 12;
  EXPECT_EQ(actual_fully_automated, expected_fully_automated);
  EXPECT_EQ(actual_cant_be_automated, expected_cant_be_automated);
  EXPECT_EQ(actual_partially_automated, expected_partially_automated);
  EXPECT_EQ(actual_not_automated, expected_not_automated);
  ASSERT_EQ(actual.str(), expected);
}

}  // namespace fidlcat
