// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.


#include "chrome/browser/metrics/perf/perf_output.h"

#include <stdio.h>
#include <unistd.h>

#include <utility>

#include "base/containers/span.h"
#include "base/files/file.h"
#include "base/posix/eintr_wrapper.h"
#include "base/task/sequenced_task_runner.h"
#include "base/threading/thread_restrictions.h"
#include "chromeos/ash/components/dbus/debug_daemon/fake_debug_daemon_client.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/metrics_proto/sampled_profile.pb.h"

namespace metrics {

namespace {
// Returns an example PerfDataProto. The contents don't have to make sense. They
// just need to constitute a semantically valid protobuf.
// |proto| is an output parameter that will contain the created protobuf.
PerfDataProto GetExamplePerfDataProto() {
  PerfDataProto proto;
  proto.set_timestamp_sec(1435604013);  // Time since epoch in seconds.

  PerfDataProto_PerfFileAttr* file_attr = proto.add_file_attrs();
  file_attr->add_ids(61);
  file_attr->add_ids(62);
  file_attr->add_ids(63);

  PerfDataProto_PerfEventAttr* attr = file_attr->mutable_attr();
  attr->set_type(1);
  attr->set_size(2);
  attr->set_config(3);
  attr->set_sample_period(4);
  attr->set_sample_freq(5);

  PerfDataProto_PerfEventStats* stats = proto.mutable_stats();
  stats->set_num_events_read(100);
  stats->set_num_sample_events(200);
  stats->set_num_mmap_events(300);
  stats->set_num_fork_events(400);
  stats->set_num_exit_events(500);

  return proto;
}

// Perf session ID returned by the GetPerfOutputV2 DBus method call.
const uint64_t kFakePerfSssionId = 101;
// Quipper command line arguments for running perf.
const std::vector<std::string> kQuipperArgs{
    "--duration", "4",      "--", "perf", "record", "-a",
    "-e",         "cycles", "-g", "-c",   "4000037"};

// This fakes DebugDaemonClient by serving example perf data when the profiling
// duration elapses.
class FakeDebugDaemonClient : public ash::FakeDebugDaemonClient {
 public:
  FakeDebugDaemonClient()
      : task_runner_(base::SequencedTaskRunner::GetCurrentDefault()) {}

  FakeDebugDaemonClient(const FakeDebugDaemonClient&) = delete;
  FakeDebugDaemonClient& operator=(const FakeDebugDaemonClient&) = delete;

  ~FakeDebugDaemonClient() override {
    EXPECT_FALSE(perf_output_file_.IsValid());
  }

  void GetPerfOutput(const std::vector<std::string>& quipper_args,
                     bool disable_cpu_idle,
                     int file_descriptor,
                     chromeos::DBusMethodCallback<uint64_t> callback) override {
    // We will write perf output to this pipe FD. dup() |file_descriptor|
    // because it is closed after this method returns.
    base::ScopedPlatformFile perf_output_fd(HANDLE_EINTR(dup(file_descriptor)));
    ASSERT_NE(perf_output_fd, -1);

    perf_output_file_ = base::File(std::move(perf_output_fd));
    ASSERT_TRUE(perf_output_file_.IsValid());

    // Returns a fake perf session ID after calling GetPerfOutputFd.
    task_runner_->PostTask(
        FROM_HERE, base::BindOnce(
                       [](chromeos::DBusMethodCallback<uint64_t> callback) {
                         std::move(callback).Run(kFakePerfSssionId);
                       },
                       std::move(callback)));
  }

  bool stop_called() const { return stop_called_; }

  void StopPerf(uint64_t session_id,
                chromeos::VoidDBusMethodCallback callback) override {
    // Simulates stopping the perf session by writing perf data right away.
    DCHECK(task_runner_->RunsTasksInCurrentSequence());
    EXPECT_EQ(session_id, kFakePerfSssionId);
    stop_called_ = true;
    OnFakePerfOutputComplete();
  }

  // This simulates that profile collection is done and quipper writes perf data
  // over the pipe.
  void OnFakePerfOutputComplete() {
    base::ScopedAllowBlockingForTesting allow_block;

    auto perf_data = GetExamplePerfDataProto().SerializeAsString();
    EXPECT_TRUE(perf_output_file_.WriteAtCurrentPosAndCheck(
        base::as_byte_span(perf_data)));

    // Need to close the pipe to unblock the pipe reader.
    perf_output_file_.Close();
  }

 private:
  scoped_refptr<base::SequencedTaskRunner> task_runner_;
  base::File perf_output_file_;
  chromeos::DBusMethodCallback<uint64_t> get_perf_outjput_callback_;
  bool stop_called_ = false;
};

}  // namespace

class PerfOutputCallTest : public testing::Test {
 public:
  PerfOutputCallTest() = default;

  PerfOutputCallTest(const PerfOutputCallTest&) = delete;
  PerfOutputCallTest& operator=(const PerfOutputCallTest&) = delete;

  void SetUp() override {
    debug_daemon_client_ = std::make_unique<FakeDebugDaemonClient>();
  }

  void TearDown() override { perf_output_call_.reset(); }

  void OnPerfOutputComplete(std::string perf_output) {
    perf_output_ = std::move(perf_output);
  }

 protected:
  // |task_environment_| must be the first member (or at least before
  // any member that cares about tasks) to be initialized first and
  // destroyed last.
  content::BrowserTaskEnvironment task_environment_;

  std::unique_ptr<FakeDebugDaemonClient> debug_daemon_client_;
  std::unique_ptr<PerfOutputCall> perf_output_call_;

  std::string perf_output_;
};

// Test getting perf output after profile duration elapses.
TEST_F(PerfOutputCallTest, GetPerfOutput) {
  perf_output_call_ = std::make_unique<PerfOutputCall>(
      debug_daemon_client_.get(), kQuipperArgs, false,
      base::BindOnce(&PerfOutputCallTest::OnPerfOutputComplete,
                     base::Unretained(this)));
  // Not yet collected.
  EXPECT_EQ(perf_output_, "");

  // Perf data is available.
  debug_daemon_client_->OnFakePerfOutputComplete();

  // Note that we can call RunUntilIdle() only after fake perf data is written
  // over the pipe, or RunUntilIdle() will block forever on the reading end.
  task_environment_.RunUntilIdle();

  EXPECT_FALSE(debug_daemon_client_->stop_called());
  EXPECT_EQ(perf_output_, GetExamplePerfDataProto().SerializeAsString());
}

// Test stopping the perf session and get perf output right away.
TEST_F(PerfOutputCallTest, Stop) {
  perf_output_call_ = std::make_unique<PerfOutputCall>(
      debug_daemon_client_.get(), kQuipperArgs, false,
      base::BindOnce(&PerfOutputCallTest::OnPerfOutputComplete,
                     base::Unretained(this)));
  // Not yet collected.
  EXPECT_EQ(perf_output_, "");

  // Perf data is available after calling Stop().
  perf_output_call_->Stop();

  // Note that we can call RunUntilIdle() only after fake perf data is written
  // over the pipe, or RunUntilIdle() will block forever on the reading end.
  task_environment_.RunUntilIdle();

  EXPECT_TRUE(debug_daemon_client_->stop_called());
  EXPECT_EQ(perf_output_, GetExamplePerfDataProto().SerializeAsString());
}

}  // namespace metrics
