// Copyright (c) 2012 The Chromium OS 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 <string>
#include <vector>

#include "chromiumos-wide-profiling/compat/string.h"
#include "chromiumos-wide-profiling/compat/test.h"
#include "chromiumos-wide-profiling/perf_protobuf_io.h"
#include "chromiumos-wide-profiling/perf_reader.h"
#include "chromiumos-wide-profiling/perf_recorder.h"
#include "chromiumos-wide-profiling/perf_serializer.h"
#include "chromiumos-wide-profiling/run_command.h"
#include "chromiumos-wide-profiling/test_utils.h"

namespace quipper {

// Runs "perf record" to see if the command is available on the current system.
// This should also cover the availability of "perf stat", which is a simpler
// way to get information from the counters.
bool IsPerfRecordAvailable() {
  return RunCommand(
      {"perf", "record", "-a", "-o", "-", "--", "sleep", "0.01"}, NULL) == 0;
}

// Runs "perf mem record" to see if the command is available on the current
// system.
bool IsPerfMemRecordAvailable() {
  return RunCommand(
      {"perf", "mem", "record", "-a", "-e", "cycles", "--", "sleep", "0.01"},
      NULL) == 0;
}

class PerfRecorderTest : public ::testing::Test {
 public:
  PerfRecorderTest() : perf_recorder_({"sudo", GetPerfPath()}) {}
 protected:
  PerfRecorder perf_recorder_;
};

TEST_F(PerfRecorderTest, RecordToProtobuf) {
  // Read perf data using the PerfReader class.
  // Dump it to a string and convert to a protobuf.
  // Read the protobuf, and reconstruct the perf data.
  string output_string;
  EXPECT_TRUE(perf_recorder_.RunCommandAndGetSerializedOutput(
      {"perf", "record"}, 0.2, &output_string));

  quipper::PerfDataProto perf_data_proto;
  EXPECT_TRUE(perf_data_proto.ParseFromString(output_string));

  const auto& string_meta = perf_data_proto.string_metadata();
  const auto& command = string_meta.perf_command_line_token();
  EXPECT_EQ(GetPerfPath(), command.Get(0).value());
  EXPECT_EQ("record", command.Get(1).value());
  EXPECT_EQ("-o", command.Get(2).value());

  // Unpredictable: EXPECT_EQ("/tmp/quipper.XXXXXX", command.Get(3).value());
  // Instead, check the file path length and prefix.
  EXPECT_EQ(strlen("/tmp/quipper.XXXXXX"), command.Get(3).value().size());
  EXPECT_EQ("/tmp/quipper",
            command.Get(3).value().substr(0, strlen("/tmp/quipper")));

  EXPECT_EQ("--", command.Get(4).value());
  EXPECT_EQ("sleep", command.Get(5).value());
  EXPECT_EQ("0.2", command.Get(6).value());
}

TEST_F(PerfRecorderTest, StatToProtobuf) {
  // Run perf stat and verify output.
  string output_string;
  EXPECT_TRUE(perf_recorder_.RunCommandAndGetSerializedOutput(
      {"perf", "stat"}, 0.2, &output_string));

  EXPECT_GT(output_string.size(), 0);
  quipper::PerfStatProto stat;
  ASSERT_TRUE(stat.ParseFromString(output_string));
  EXPECT_GT(stat.line_size(), 0);
}

TEST_F(PerfRecorderTest, MemRecordToProtobuf) {
  if (!IsPerfMemRecordAvailable())
    return;

  // Run perf mem record and verify output.
  string output_string;
  EXPECT_TRUE(perf_recorder_.RunCommandAndGetSerializedOutput(
      {"perf", "mem", "record"}, 0.2, &output_string));

  EXPECT_GT(output_string.size(), 0);
  quipper::PerfDataProto perf_data_proto;
  ASSERT_TRUE(perf_data_proto.ParseFromString(output_string));
}

TEST_F(PerfRecorderTest, StatSingleEvent) {
  string output_string;
  ASSERT_TRUE(perf_recorder_.RunCommandAndGetSerializedOutput(
      {"perf", "stat", "-a", "-e", "cycles"},
      0.2, &output_string));

  EXPECT_GT(output_string.size(), 0);

  quipper::PerfStatProto stat;
  ASSERT_TRUE(stat.ParseFromString(output_string));
  // Replace the placeholder "perf" with the actual perf path.
  string expected_command_line =
      string("sudo ") + GetPerfPath() + " stat -a -e cycles -v -- sleep 0.2";
  EXPECT_EQ(expected_command_line, stat.command_line());

  // Make sure the event counter was read.
  ASSERT_EQ(1, stat.line_size());
  EXPECT_TRUE(stat.line(0).has_time_ms());
  EXPECT_TRUE(stat.line(0).has_count());
  EXPECT_TRUE(stat.line(0).has_event_name());
  // Running for at least one second.
  EXPECT_GE(stat.line(0).time_ms(), 200);
  EXPECT_EQ("cycles", stat.line(0).event_name());
}

TEST_F(PerfRecorderTest, StatMultipleEvents) {
  string output_string;
  ASSERT_TRUE(perf_recorder_.RunCommandAndGetSerializedOutput(
      { "perf", "stat", "-a",
        "-e", "cycles",
        "-e", "instructions",
        "-e", "branches",
        "-e", "branch-misses" },
      0.2, &output_string));

  EXPECT_GT(output_string.size(), 0);

  quipper::PerfStatProto stat;
  ASSERT_TRUE(stat.ParseFromString(output_string));
  // Replace the placeholder "perf" with the actual perf path.
  string command_line =
      string("sudo ") + GetPerfPath() + " stat -a "
          "-e cycles "
          "-e instructions "
          "-e branches "
          "-e branch-misses "
          "-v "
          "-- sleep 0.2";
  EXPECT_TRUE(stat.has_command_line());
  EXPECT_EQ(command_line, stat.command_line());

  // Make sure all event counters were read.
  // Check:
  // - Number of events.
  // - Running for at least two seconds.
  // - Event names recorded properly.
  ASSERT_EQ(4, stat.line_size());

  EXPECT_TRUE(stat.line(0).has_time_ms());
  EXPECT_TRUE(stat.line(0).has_count());
  EXPECT_TRUE(stat.line(0).has_event_name());
  EXPECT_GE(stat.line(0).time_ms(), 200);
  EXPECT_EQ("cycles", stat.line(0).event_name());

  EXPECT_TRUE(stat.line(1).has_time_ms());
  EXPECT_TRUE(stat.line(1).has_count());
  EXPECT_TRUE(stat.line(1).has_event_name());
  EXPECT_GE(stat.line(1).time_ms(), 200);
  EXPECT_EQ("instructions", stat.line(1).event_name());

  EXPECT_TRUE(stat.line(2).has_time_ms());
  EXPECT_TRUE(stat.line(2).has_count());
  EXPECT_TRUE(stat.line(2).has_event_name());
  EXPECT_GE(stat.line(2).time_ms(), 200);
  EXPECT_EQ("branches", stat.line(2).event_name());

  EXPECT_TRUE(stat.line(3).has_time_ms());
  EXPECT_TRUE(stat.line(3).has_count());
  EXPECT_TRUE(stat.line(3).has_event_name());
  EXPECT_GE(stat.line(3).time_ms(), 200);
  EXPECT_EQ("branch-misses", stat.line(3).event_name());
}

TEST_F(PerfRecorderTest, DontAllowCommands) {
  string output_string;
  EXPECT_FALSE(perf_recorder_.RunCommandAndGetSerializedOutput(
      {"perf", "record", "--", "sh", "-c", "echo 'malicious'"},
      0.2, &output_string));
  EXPECT_FALSE(perf_recorder_.RunCommandAndGetSerializedOutput(
      {"perf", "stat", "--", "sh", "-c", "echo 'malicious'"},
      0.2, &output_string));
}

TEST(PerfRecorderNoPerfTest, FailsIfPerfDoesntExist) {
  string output_string;
  PerfRecorder perf_recorder({"sudo", "/doesnt-exist/usr/not-bin/not-perf"});
  EXPECT_FALSE(perf_recorder.RunCommandAndGetSerializedOutput(
      {"perf", "record"}, 0.2, &output_string));
}

}  // namespace quipper

int main(int argc, char* argv[]) {
  ::testing::InitGoogleTest(&argc, argv);
  if (!quipper::IsPerfRecordAvailable())
    return 0;
  return RUN_ALL_TESTS();
}
