// Copyright 2021 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/sys/fuzzing/common/controller.h"

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

#include <gtest/gtest.h>

#include "src/sys/fuzzing/common/binding.h"
#include "src/sys/fuzzing/common/dispatcher.h"
#include "src/sys/fuzzing/common/status.h"
#include "src/sys/fuzzing/common/testing/corpus-reader.h"
#include "src/sys/fuzzing/common/testing/monitor.h"
#include "src/sys/fuzzing/common/testing/runner.h"
#include "src/sys/fuzzing/common/testing/transceiver.h"

namespace fuzzing {
namespace {

using fuchsia::fuzzer::ControllerSyncPtr;
using fuchsia::fuzzer::ProcessProxySyncPtr;
using fuchsia::fuzzer::UpdateReason;

// Test fixtures.

// Base class for |Controller| unit tests.
class ControllerTest : public ::testing::Test {
 public:
  // Implicitly tests |Controller::SetRunner| and |Controller::Bind|.
  ControllerSyncPtr Bind() {
    // The shared_ptr will be responsible for deleting the FakeRunner memory.
    auto runner = std::make_shared<FakeRunner>();
    runner_ = runner.get();
    controller_.SetRunner(runner);

    ControllerSyncPtr controller;
    controller_.Bind(controller.NewRequest());
    return controller;
  }

  void AddToCorpus(CorpusType corpus_type, Input input) {
    runner_->AddToCorpus(corpus_type, std::move(input));
  }
  Input ReadFromCorpus(CorpusType corpus_type, size_t offset) {
    return runner_->ReadFromCorpus(corpus_type, offset);
  }

  zx_status_t ParseDictionary(const Input& input) { return runner_->ParseDictionary(input); }

  void SetError(zx_status_t error) { runner_->set_error(error); }
  void SetResult(Result result) { runner_->set_result(result); }
  void SetResultInput(const Input& input) { runner_->set_result_input(input); }
  void SetStatus(Status status) { runner_->set_status(std::move(status)); }
  void UpdateMonitors(UpdateReason reason) { runner_->UpdateMonitors(reason); }

  FidlInput Transmit(const Input& input) { return transceiver_.Transmit(input.Duplicate()); }

  // Synchronously receives and returns an |Input| from a provided |FidlInput|.
  Input Receive(FidlInput fidl_input) { return transceiver_.Receive(std::move(fidl_input)); }

 private:
  ControllerImpl controller_;
  FakeRunner* runner_;
  FakeTransceiver transceiver_;
};

// Unit tests.

TEST_F(ControllerTest, ConfigureAndGetOptions) {
  auto controller = Bind();

  // GetOptions without Configure.
  Options options1;
  EXPECT_EQ(controller->GetOptions(&options1), ZX_OK);
  EXPECT_NE(options1.seed(), 0U);

  // Configure.
  uint32_t runs = 1000;
  zx::duration max_total_time = zx::sec(300);
  uint32_t seed = 42;
  uint32_t max_input_size = 1ULL << 10;
  uint16_t mutation_depth = 8;
  bool detect_exits = true;
  bool detect_leaks = false;
  zx::duration run_limit = zx::sec(20);
  options1.set_runs(runs);
  options1.set_max_total_time(max_total_time.get());
  options1.set_seed(seed);
  options1.set_max_input_size(max_input_size);
  options1.set_mutation_depth(mutation_depth);
  options1.set_detect_exits(detect_exits);
  options1.set_detect_leaks(detect_leaks);
  options1.set_run_limit(run_limit.get());
  zx_status_t status;
  auto options2 = CopyOptions(options1);
  EXPECT_EQ(controller->Configure(std::move(options1), &status), ZX_OK);
  EXPECT_EQ(status, ZX_OK);

  // Can Configure again.
  uint64_t malloc_limit = 64ULL << 10;
  uint64_t oom_limit = 1ULL << 20;
  zx::duration purge_interval = zx::sec(10);
  int32_t malloc_exitcode = 1000;
  int32_t death_exitcode = 1001;
  int32_t leak_exitcode = 1002;
  int32_t oom_exitcode = 1003;
  zx::duration pulse_interval = zx::sec(3);
  options2.set_malloc_limit(malloc_limit);
  options2.set_oom_limit(oom_limit);
  options2.set_purge_interval(purge_interval.get());
  options2.set_malloc_exitcode(malloc_exitcode);
  options2.set_death_exitcode(death_exitcode);
  options2.set_leak_exitcode(leak_exitcode);
  options2.set_oom_exitcode(oom_exitcode);
  options2.set_pulse_interval(pulse_interval.get());
  EXPECT_EQ(controller->Configure(std::move(options2), &status), ZX_OK);
  EXPECT_EQ(status, ZX_OK);

  // Changes are reflected.
  Options options3;
  EXPECT_EQ(controller->GetOptions(&options3), ZX_OK);
  EXPECT_EQ(options3.runs(), runs);
  EXPECT_EQ(options3.max_total_time(), max_total_time.get());
  EXPECT_EQ(options3.seed(), seed);
  EXPECT_EQ(options3.max_input_size(), max_input_size);
  EXPECT_EQ(options3.mutation_depth(), mutation_depth);
  EXPECT_EQ(options3.detect_exits(), detect_exits);
  EXPECT_EQ(options3.detect_leaks(), detect_leaks);
  EXPECT_EQ(options3.run_limit(), run_limit.get());
  EXPECT_EQ(options3.malloc_limit(), malloc_limit);
  EXPECT_EQ(options3.oom_limit(), oom_limit);
  EXPECT_EQ(options3.purge_interval(), purge_interval.get());
  EXPECT_EQ(options3.malloc_exitcode(), malloc_exitcode);
  EXPECT_EQ(options3.death_exitcode(), death_exitcode);
  EXPECT_EQ(options3.leak_exitcode(), leak_exitcode);
  EXPECT_EQ(options3.oom_exitcode(), oom_exitcode);
  EXPECT_EQ(options3.pulse_interval(), pulse_interval.get());
}

TEST_F(ControllerTest, AddToCorpus) {
  auto controller = Bind();
  Input input0;
  Input seed_input1({0xde, 0xad});
  Input seed_input2({0xbe, 0xef});
  Input live_input3({0xfe, 0xed});
  Input live_input4({0xfa, 0xce});
  zx_status_t result;

  // Interleave the calls.
  EXPECT_EQ(controller->AddToCorpus(CorpusType::LIVE, Transmit(live_input3), &result), ZX_OK);
  EXPECT_EQ(result, ZX_OK);
  EXPECT_EQ(controller->AddToCorpus(CorpusType::SEED, Transmit(seed_input1), &result), ZX_OK);
  EXPECT_EQ(result, ZX_OK);
  EXPECT_EQ(controller->AddToCorpus(CorpusType::SEED, Transmit(seed_input2), &result), ZX_OK);
  EXPECT_EQ(result, ZX_OK);
  EXPECT_EQ(controller->AddToCorpus(CorpusType::LIVE, Transmit(live_input4), &result), ZX_OK);
  EXPECT_EQ(result, ZX_OK);

  EXPECT_EQ(ReadFromCorpus(CorpusType::SEED, 0).ToHex(), input0.ToHex());
  EXPECT_EQ(ReadFromCorpus(CorpusType::SEED, 1).ToHex(), seed_input1.ToHex());
  EXPECT_EQ(ReadFromCorpus(CorpusType::SEED, 2).ToHex(), seed_input2.ToHex());
  EXPECT_EQ(ReadFromCorpus(CorpusType::SEED, 3).ToHex(), input0.ToHex());

  EXPECT_EQ(ReadFromCorpus(CorpusType::LIVE, 0).ToHex(), input0.ToHex());
  EXPECT_EQ(ReadFromCorpus(CorpusType::LIVE, 1).ToHex(), live_input3.ToHex());
  EXPECT_EQ(ReadFromCorpus(CorpusType::LIVE, 2).ToHex(), live_input4.ToHex());
  EXPECT_EQ(ReadFromCorpus(CorpusType::LIVE, 3).ToHex(), input0.ToHex());
}

TEST_F(ControllerTest, ReadCorpus) {
  auto controller = Bind();
  Input input0;
  Input input1({0xde, 0xad});
  Input input2({0xbe, 0xef});
  Input input3({0xfe, 0xed});
  Input input4({0xfa, 0xce});

  AddToCorpus(CorpusType::SEED, input1.Duplicate());
  AddToCorpus(CorpusType::SEED, input2.Duplicate());

  AddToCorpus(CorpusType::LIVE, input3.Duplicate());
  AddToCorpus(CorpusType::LIVE, input4.Duplicate());

  auto dispatcher = std::make_shared<Dispatcher>();
  FakeCorpusReader seed_reader(dispatcher);
  FakeCorpusReader live_reader(dispatcher);
  EXPECT_EQ(controller->ReadCorpus(CorpusType::SEED, seed_reader.NewBinding()), ZX_OK);
  EXPECT_EQ(controller->ReadCorpus(CorpusType::LIVE, live_reader.NewBinding()), ZX_OK);

  // Interleave the calls.
  ASSERT_TRUE(live_reader.AwaitNext());
  EXPECT_EQ(live_reader.GetNext().ToHex(), input3.ToHex());

  ASSERT_TRUE(seed_reader.AwaitNext());
  EXPECT_EQ(seed_reader.GetNext().ToHex(), input1.ToHex());

  ASSERT_TRUE(live_reader.AwaitNext());
  EXPECT_EQ(live_reader.GetNext().ToHex(), input4.ToHex());

  ASSERT_TRUE(seed_reader.AwaitNext());
  EXPECT_EQ(seed_reader.GetNext().ToHex(), input2.ToHex());

  // All inputs have been sent.
  EXPECT_FALSE(live_reader.AwaitNext());
  EXPECT_FALSE(live_reader.AwaitNext());
}

TEST_F(ControllerTest, WriteDictionary) {
  auto controller = Bind();
  auto invalid = FakeRunner::invalid_dictionary();
  auto valid = FakeRunner::valid_dictionary();
  zx_status_t result;

  EXPECT_EQ(controller->WriteDictionary(Transmit(invalid), &result), ZX_OK);
  EXPECT_EQ(result, ZX_ERR_INVALID_ARGS);

  EXPECT_EQ(controller->WriteDictionary(Transmit(valid), &result), ZX_OK);
  EXPECT_EQ(result, ZX_OK);
}

TEST_F(ControllerTest, ReadDictionary) {
  auto controller = Bind();
  FidlInput result;

  auto dict = FakeRunner::valid_dictionary();
  EXPECT_EQ(ParseDictionary(dict), ZX_OK);
  EXPECT_EQ(controller->ReadDictionary(&result), ZX_OK);
  auto received = Receive(std::move(result));
  EXPECT_EQ(received.ToHex(), dict.ToHex());
}

TEST_F(ControllerTest, GetStatus) {
  auto controller = Bind();
  Status result;

  Status status;
  status.set_running(true);
  status.set_runs(42);
  status.set_elapsed(zx::sec(15).get());
  status.set_covered_pcs(5);
  status.set_covered_features(10);
  status.set_corpus_num_inputs(15);
  status.set_corpus_total_size(25);
  auto expected = CopyStatus(status);
  SetStatus(std::move(status));

  EXPECT_EQ(controller->GetStatus(&result), ZX_OK);
  EXPECT_EQ(result.running(), expected.running());
  EXPECT_EQ(result.runs(), expected.runs());
  EXPECT_EQ(result.elapsed(), expected.elapsed());
  EXPECT_EQ(result.covered_pcs(), expected.covered_pcs());
  EXPECT_EQ(result.covered_features(), expected.covered_features());
  EXPECT_EQ(result.corpus_num_inputs(), expected.corpus_num_inputs());
  EXPECT_EQ(result.corpus_total_size(), expected.corpus_total_size());
}

TEST_F(ControllerTest, AddMonitor) {
  auto controller = Bind();
  FakeMonitor monitor;

  Status status;
  status.set_runs(13);
  auto expected = CopyStatus(status);
  SetStatus(std::move(status));
  EXPECT_EQ(controller->AddMonitor(monitor.NewBinding()), ZX_OK);
  UpdateMonitors(UpdateReason::PULSE);

  UpdateReason reason;
  auto updated = monitor.NextStatus(&reason);
  EXPECT_EQ(updated.runs(), expected.runs());
  EXPECT_EQ(reason, UpdateReason::PULSE);
}

TEST_F(ControllerTest, GetResults) {
  auto controller = Bind();
  Result result;
  FidlInput fidl_input;
  Input result_input({0xde, 0xad, 0xbe, 0xef});

  SetResult(Result::DEATH);
  SetResultInput(result_input);
  EXPECT_EQ(controller->GetResults(&result, &fidl_input), ZX_OK);
  EXPECT_EQ(result, Result::DEATH);
  auto received = Receive(std::move(fidl_input));
  EXPECT_EQ(received.ToHex(), result_input.ToHex());
}

TEST_F(ControllerTest, Execute) {
  auto controller = Bind();
  ::fuchsia::fuzzer::Controller_Execute_Result result;
  Input input({0xde, 0xad, 0xbe, 0xef});

  SetError(ZX_ERR_WRONG_TYPE);
  EXPECT_EQ(controller->Execute(Transmit(input), &result), ZX_OK);
  ASSERT_TRUE(result.is_err());
  EXPECT_EQ(result.err(), ZX_ERR_WRONG_TYPE);

  SetError(ZX_OK);
  SetResult(Result::OOM);
  EXPECT_EQ(controller->Execute(Transmit(input), &result), ZX_OK);
  ASSERT_TRUE(result.is_response());
  auto& response = result.response();
  EXPECT_EQ(response.result, Result::OOM);
}

TEST_F(ControllerTest, Minimize) {
  auto controller = Bind();
  ::fuchsia::fuzzer::Controller_Minimize_Result result;
  Input input({0xde, 0xad, 0xbe, 0xef});
  Input minimized({0xde, 0xbe});

  SetError(ZX_ERR_WRONG_TYPE);
  EXPECT_EQ(controller->Minimize(Transmit(input), &result), ZX_OK);
  ASSERT_TRUE(result.is_err());
  EXPECT_EQ(result.err(), ZX_ERR_WRONG_TYPE);

  SetError(ZX_OK);
  SetResultInput(minimized);
  EXPECT_EQ(controller->Minimize(Transmit(input), &result), ZX_OK);
  ASSERT_TRUE(result.is_response());
  auto& response = result.response();
  auto received = Receive(std::move(response.minimized));
  EXPECT_EQ(received.ToHex(), minimized.ToHex());
}

TEST_F(ControllerTest, Cleanse) {
  auto controller = Bind();
  ::fuchsia::fuzzer::Controller_Cleanse_Result result;
  Input input({0xde, 0xad, 0xbe, 0xef});
  Input cleansed({0x20, 0x20, 0xbe, 0xff});

  SetError(ZX_ERR_WRONG_TYPE);
  EXPECT_EQ(controller->Cleanse(Transmit(input), &result), ZX_OK);
  ASSERT_TRUE(result.is_err());
  EXPECT_EQ(result.err(), ZX_ERR_WRONG_TYPE);

  SetError(ZX_OK);
  SetResultInput(cleansed);
  EXPECT_EQ(controller->Cleanse(Transmit(input), &result), ZX_OK);
  ASSERT_TRUE(result.is_response());
  auto& response = result.response();
  auto received = Receive(std::move(response.cleansed));
  EXPECT_EQ(received.ToHex(), cleansed.ToHex());
}

TEST_F(ControllerTest, Fuzz) {
  auto controller = Bind();
  ::fuchsia::fuzzer::Controller_Fuzz_Result result;
  Input fuzzed({0xde, 0xad, 0xbe, 0xef});

  SetError(ZX_ERR_WRONG_TYPE);
  EXPECT_EQ(controller->Fuzz(&result), ZX_OK);
  ASSERT_TRUE(result.is_err());
  EXPECT_EQ(result.err(), ZX_ERR_WRONG_TYPE);

  SetError(ZX_OK);
  SetResult(Result::CRASH);
  SetResultInput(fuzzed);
  EXPECT_EQ(controller->Fuzz(&result), ZX_OK);
  ASSERT_TRUE(result.is_response());
  auto& response = result.response();
  EXPECT_EQ(response.result, Result::CRASH);
  auto received = Receive(std::move(response.error_input));
  EXPECT_EQ(received.ToHex(), fuzzed.ToHex());
}

TEST_F(ControllerTest, Merge) {
  auto controller = Bind();
  zx_status_t result;

  SetError(ZX_ERR_WRONG_TYPE);
  EXPECT_EQ(controller->Merge(&result), ZX_OK);
  EXPECT_EQ(result, ZX_ERR_WRONG_TYPE);

  SetError(ZX_OK);
  EXPECT_EQ(controller->Merge(&result), ZX_OK);
  EXPECT_EQ(result, ZX_OK);
}

}  // namespace
}  // namespace fuzzing
