// 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.

// This target runs all benchmarks for the Garnet layer.

#include "garnet/testing/benchmarking/benchmarking.h"
#include "src/lib/fxl/logging.h"

int main(int argc, const char** argv) {
  auto maybe_benchmarks_runner = benchmarking::BenchmarksRunner::Create(argc, argv);
  if (!maybe_benchmarks_runner) {
    exit(1);
  }

  auto& benchmarks_runner = *maybe_benchmarks_runner;

  std::string benchmarks_bot_name = benchmarks_runner.benchmarks_bot_name();

  // Test storage performance.
  if (benchmarks_bot_name == "garnet-x64-perf-dawson_canyon") {
    constexpr const char* block_device = "/dev/sys/pci/00:17.0/ahci/sata2/block";

    benchmarks_runner.AddTask([=]() {
      int status = benchmarking::Spawn({"/boot/bin/waitfor", "class=block",
                                        std::string("topo=") + block_device, "timeout=30000"});
      FX_CHECK(status == 0);
    });

    // Test block device performance.
    {
      // Passing this parameter reduces the test running time to something
      // reasonable -- 10 seconds for a transfer rate of 500 MiB/second.
      // (Otherwise biotime reads the whole device.)
      auto* kBytesToTransfer = "5G";

      std::string out_file =
          benchmarks_runner.MakePerfResultsOutputFilename("block_device_throughput");
      benchmarks_runner.AddCustomBenchmark(
          "block_device_throughput",
          {"/boot/bin/biotime", "-total-bytes-to-transfer", kBytesToTransfer, "-output-file",
           out_file, block_device},
          out_file);
    }

    // Test filesystem performance.
    benchmarks_runner.AddLibPerfTestBenchmark(
        "fs_bench", "/pkgfs/packages/garnet_benchmarks/0/test/fs/fs-bench-test",
        {"--fs", "minfs", "--block_device", block_device, "--print_statistics"});

    // Test BlobFs performance.
    benchmarks_runner.AddLibPerfTestBenchmark(
        "blobfs_bench", "/pkgfs/packages/blobfs-bench/0/test/blobfs-bench-test",
        {"--fs", "blobfs", "--block_device", block_device, "--print_statistics"});
  } else if (benchmarks_bot_name == "garnet-arm64-perf-vim2") {
    // TODO(ZX-2466): Enable the storage perf tests on the VIM2 bots when we
    // figure out what partition or device we can use for testing.
    FX_LOGS(INFO) << "Storage perf tests skipped on bot '" << benchmarks_bot_name << "'";
  } else {
    FX_LOGS(ERROR) << "Bot '" << benchmarks_bot_name
                   << "' not recognized: please update benchmarks.cc in garnet.";
    exit(1);
  }

  // List block devices.  This is for debugging purposes and to help with
  // enabling the storage tests above on new devices.  We do this at the end
  // of this script because block devices aren't always immediately available
  // soon after boot, and because "waitfor" isn't applicable when we are
  // listing all devices.
  benchmarks_runner.AddTask([]() {
    FX_LOGS(INFO) << "-- block devices list (lsblk): start";
    int status = benchmarking::Spawn({"/boot/bin/lsblk"});
    FX_CHECK(status == 0);
    FX_LOGS(INFO) << "-- block devices list (lsblk): end";
  });

  benchmarks_runner.Finish();
}
