// 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 <inttypes.h>
#include <sys/time.h>

#include <map>
#include <sstream>
#include <string>

#include "base/logging.h"
#include "base/macros.h"

#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_serializer.h"
#include "chromiumos-wide-profiling/perf_test_files.h"
#include "chromiumos-wide-profiling/scoped_temp_path.h"
#include "chromiumos-wide-profiling/test_perf_data.h"
#include "chromiumos-wide-profiling/test_utils.h"
#include "chromiumos-wide-profiling/utils.h"

namespace {

// Returns a string representation of an unsigned integer |value|.
string UintToString(uint64_t value) {
  stringstream ss;
  ss << value;
  return ss.str();
}

}  // namespace

namespace quipper {

namespace {

// Gets the timestamp from an event field in PerfDataProto.
const uint64_t GetSampleTimestampFromEventProto(
    const PerfDataProto_PerfEvent& event) {
  // Get SampleInfo from the correct type-specific event field for the event.
  if (event.has_mmap_event()) {
    return event.mmap_event().sample_info().sample_time_ns();
  } else if (event.has_sample_event()) {
    return event.sample_event().sample_time_ns();
  } else if (event.has_comm_event()) {
    return event.comm_event().sample_info().sample_time_ns();
  } else if (event.has_fork_event()) {
    return event.fork_event().sample_info().sample_time_ns();
  } else if (event.has_exit_event()) {
    return event.exit_event().sample_info().sample_time_ns();
  } else if (event.has_lost_event()) {
    return event.lost_event().sample_info().sample_time_ns();
  } else if (event.has_throttle_event()) {
    return event.throttle_event().sample_info().sample_time_ns();
  } else if (event.has_read_event()) {
    return event.read_event().sample_info().sample_time_ns();
  }
  return 0;
}

// Verifies that |proto|'s events are in chronological order. No event should
// have an earlier timestamp than a preceding event.
void CheckChronologicalOrderOfSerializedEvents(const PerfDataProto& proto) {
  uint64_t prev_time_ns = 0;
  for (int i = 0; i < proto.events_size(); ++i) {
    // Compare each timestamp against the previous event's timestamp.
    uint64_t time_ns = GetSampleTimestampFromEventProto(proto.events(i));
    if (i > 0) {
      EXPECT_GE(time_ns, prev_time_ns);
    }
    prev_time_ns = time_ns;
  }
}

void SerializeAndDeserialize(const string& input,
                             const string& output,
                             bool do_remap,
                             bool discard_unused_events) {
  PerfDataProto perf_data_proto;
  PerfParser::Options options;
  options.do_remap = do_remap;
  options.discard_unused_events = discard_unused_events;
  options.sample_mapping_percentage_threshold = 100.0f;
  PerfSerializer serializer;
  serializer.set_options(options);
  EXPECT_TRUE(serializer.SerializeFromFile(input, &perf_data_proto));

  PerfSerializer deserializer;
  deserializer.set_options(options);
  EXPECT_TRUE(deserializer.DeserializeToFile(perf_data_proto, output));

  // Check perf event stats.
  const PerfEventStats& in_stats = serializer.stats();
  const PerfEventStats& out_stats = deserializer.stats();
  EXPECT_EQ(in_stats.num_sample_events, out_stats.num_sample_events);
  EXPECT_EQ(in_stats.num_mmap_events, out_stats.num_mmap_events);
  EXPECT_EQ(in_stats.num_fork_events, out_stats.num_fork_events);
  EXPECT_EQ(in_stats.num_exit_events, out_stats.num_exit_events);
  EXPECT_EQ(in_stats.num_sample_events_mapped,
            out_stats.num_sample_events_mapped);
  EXPECT_EQ(do_remap, in_stats.did_remap);
  EXPECT_EQ(do_remap, out_stats.did_remap);
}

void SerializeToFileAndBack(const string& input, const string& output) {
  struct timeval pre_serialize_time;
  gettimeofday(&pre_serialize_time, NULL);

  // Serialize with and without sorting by chronological order.
  PerfDataProto input_perf_data_proto;

  // Serialize with and without sorting by chronological order.
  PerfSerializer sorted_serializer;
  sorted_serializer.set_serialize_sorted_events(true);
  EXPECT_TRUE(
      sorted_serializer.SerializeFromFile(input, &input_perf_data_proto));
  CheckChronologicalOrderOfSerializedEvents(input_perf_data_proto);

  input_perf_data_proto.Clear();
  PerfSerializer unsorted_serializer;
  unsorted_serializer.set_serialize_sorted_events(false);
  EXPECT_TRUE(
      unsorted_serializer.SerializeFromFile(input, &input_perf_data_proto));

  // Make sure the timestamp_sec was properly recorded.
  EXPECT_TRUE(input_perf_data_proto.has_timestamp_sec());
  // Check it against the current time.
  struct timeval post_serialize_time;
  gettimeofday(&post_serialize_time, NULL);
  EXPECT_GE(input_perf_data_proto.timestamp_sec(), pre_serialize_time.tv_sec);
  EXPECT_LE(input_perf_data_proto.timestamp_sec(), post_serialize_time.tv_sec);

  // Now store the protobuf into a file.
  ScopedTempFile input_file;
  EXPECT_FALSE(input_file.path().empty());
  string input_filename = input_file.path();
  ScopedTempFile output_file;
  EXPECT_FALSE(output_file.path().empty());
  string output_filename = output_file.path();

  EXPECT_TRUE(WriteProtobufToFile(input_perf_data_proto, input_filename));

  PerfDataProto output_perf_data_proto;
  EXPECT_TRUE(ReadProtobufFromFile(&output_perf_data_proto, input_filename));

  PerfSerializer deserializer;
  EXPECT_TRUE(deserializer.DeserializeToFile(output_perf_data_proto, output));

  EXPECT_TRUE(WriteProtobufToFile(output_perf_data_proto, output_filename));

  EXPECT_NE(GetFileSize(input_filename), 0);
  ASSERT_TRUE(CompareFileContents(input_filename, output_filename));

  remove(input_filename.c_str());
  remove(output_filename.c_str());
}

// Converts build ID data (stored as a string) to an actual string containing
// hex digits.
string BuildIDToString(const string& raw_build_id_data) {
  return HexToString(reinterpret_cast<const u8*>(raw_build_id_data.c_str()),
                     raw_build_id_data.size());
}

}  // namespace

TEST(PerfSerializerTest, Test1Cycle) {
  ScopedTempDir output_dir;
  ASSERT_FALSE(output_dir.path().empty());
  string output_path = output_dir.path();

  // Read perf data using the PerfReader class.
  // Dump it to a protobuf.
  // Read the protobuf, and reconstruct the perf data.
  // TODO(sque): test exact number of events after discarding unused events.
  for (const char* test_file : perf_test_files::kPerfDataFiles) {
    PerfReader input_perf_reader, output_perf_reader, output_perf_reader1,
               output_perf_reader2;
    PerfDataProto perf_data_proto, perf_data_proto1;

    string input_perf_data = GetTestInputFilePath(test_file);
    string output_perf_data = output_path + test_file + ".serialized.out";
    string output_perf_data1 = output_path + test_file + ".serialized.1.out";

    LOG(INFO) << "Testing " << input_perf_data;
    input_perf_reader.ReadFile(input_perf_data);

    // Discard unused events for a pseudorandom selection of half the test data
    // files. The selection is based on the Md5sum prefix of the file contents,
    // so that the files can be moved around in the |kPerfDataFiles| list or
    // renamed.
    std::vector<char> test_file_data;
    ASSERT_TRUE(ReadFileToData(input_perf_data, &test_file_data));
    bool discard = (Md5Prefix(test_file_data) % 2 == 0);

    SerializeAndDeserialize(input_perf_data, output_perf_data, false, discard);
    output_perf_reader.ReadFile(output_perf_data);
    SerializeAndDeserialize(output_perf_data, output_perf_data1, false,
                            discard);
    output_perf_reader1.ReadFile(output_perf_data1);

    ASSERT_TRUE(CompareFileContents(output_perf_data, output_perf_data1));

    string output_perf_data2 = output_path + test_file + ".io.out";
    SerializeToFileAndBack(input_perf_data, output_perf_data2);
    output_perf_reader2.ReadFile(output_perf_data2);

    // Make sure the # of events do not increase.  They can decrease because
    // some unused non-sample events may be discarded.
    if (discard) {
      ASSERT_LE(output_perf_reader.events().size(),
                input_perf_reader.events().size());
    } else {
      ASSERT_EQ(output_perf_reader.events().size(),
                input_perf_reader.events().size());
    }
    ASSERT_EQ(output_perf_reader1.events().size(),
              output_perf_reader.events().size());
    ASSERT_EQ(output_perf_reader2.events().size(),
              input_perf_reader.events().size());

    EXPECT_TRUE(CheckPerfDataAgainstBaseline(output_perf_data));
    EXPECT_TRUE(ComparePerfBuildIDLists(input_perf_data, output_perf_data));
    EXPECT_TRUE(CheckPerfDataAgainstBaseline(output_perf_data2));
    EXPECT_TRUE(ComparePerfBuildIDLists(output_perf_data, output_perf_data2));
  }
}

TEST(PerfSerializerTest, TestRemap) {
  ScopedTempDir output_dir;
  ASSERT_FALSE(output_dir.path().empty());
  string output_path = output_dir.path();

  // Read perf data using the PerfReader class with address remapping.
  // Dump it to a protobuf.
  // Read the protobuf, and reconstruct the perf data.
  for (const char* test_file : perf_test_files::kPerfDataFiles) {
    const string input_perf_data = GetTestInputFilePath(test_file);
    LOG(INFO) << "Testing " << input_perf_data;
    const string output_perf_data = output_path + test_file + ".ser.remap.out";
    SerializeAndDeserialize(input_perf_data, output_perf_data, true, true);
  }

  for (const char* test_file : perf_test_files::kPerfPipedDataFiles) {
    const string input_perf_data = GetTestInputFilePath(test_file);
    LOG(INFO) << "Testing " << input_perf_data;
    const string output_perf_data = output_path + test_file + ".ser.remap.out";
    SerializeAndDeserialize(input_perf_data, output_perf_data, true, true);
  }
}

TEST(PerfSerializeTest, TestCommMd5s) {
  ScopedTempDir output_dir;
  ASSERT_FALSE(output_dir.path().empty());
  string output_path = output_dir.path();

  // Replace command strings with their Md5sums.  Test size adjustment for
  // command strings.
  for (const char* test_file : perf_test_files::kPerfDataFiles) {
    const string input_perf_data = GetTestInputFilePath(test_file);
    LOG(INFO) << "Testing COMM Md5sum for " << input_perf_data;

    PerfDataProto perf_data_proto;
    PerfSerializer serializer;
    EXPECT_TRUE(serializer.SerializeFromFile(input_perf_data,
                                             &perf_data_proto));

    for (int j = 0; j < perf_data_proto.events_size(); ++j) {
      PerfDataProto_PerfEvent& event =
          *perf_data_proto.mutable_events(j);
      if (event.header().type() != PERF_RECORD_COMM)
        continue;
      CHECK(event.has_comm_event());

      string comm_md5_string =
          UintToString(event.comm_event().comm_md5_prefix());
      // Make sure it fits in the comm string array, accounting for the null
      // terminator.
      struct comm_event dummy;
      if (comm_md5_string.size() > arraysize(dummy.comm) - 1)
        comm_md5_string.resize(arraysize(dummy.comm) - 1);
      event.mutable_comm_event()->set_comm(comm_md5_string);
    }

    PerfSerializer deserializer;
    const string output_perf_data = output_path + test_file + ".ser.comm.out";
    EXPECT_TRUE(deserializer.DeserializeToFile(perf_data_proto,
                                               output_perf_data));
    EXPECT_TRUE(CheckPerfDataAgainstBaseline(output_perf_data));
  }
}

TEST(PerfSerializeTest, TestMmapMd5s) {
  ScopedTempDir output_dir;
  ASSERT_FALSE(output_dir.path().empty());
  string output_path = output_dir.path();

  // Replace MMAP filename strings with their Md5sums.  Test size adjustment for
  // MMAP filename strings.
  for (const char* test_file : perf_test_files::kPerfDataFiles) {
    const string input_perf_data = GetTestInputFilePath(test_file);
    LOG(INFO) << "Testing MMAP Md5sum for " << input_perf_data;

    PerfDataProto perf_data_proto;
    PerfSerializer serializer;
    EXPECT_TRUE(serializer.SerializeFromFile(input_perf_data,
                                             &perf_data_proto));

    for (int j = 0; j < perf_data_proto.events_size(); ++j) {
      PerfDataProto_PerfEvent& event =
          *perf_data_proto.mutable_events(j);
      if (event.header().type() != PERF_RECORD_MMAP)
        continue;
      CHECK(event.has_mmap_event());

      string filename_md5_string =
          UintToString(event.mmap_event().filename_md5_prefix());
      struct mmap_event dummy;
      // Make sure the Md5 prefix string can fit in the filename buffer,
      // including the null terminator
      if (filename_md5_string.size() > arraysize(dummy.filename) - 1)
        filename_md5_string.resize(arraysize(dummy.filename) - 1);
      event.mutable_mmap_event()->set_filename(filename_md5_string);
    }

    PerfSerializer deserializer;
    const string output_perf_data = output_path + test_file + ".ser.mmap.out";
    // Make sure the data can be deserialized after replacing the filenames with
    // Md5sum prefixes.  No need to check the output.
    EXPECT_TRUE(deserializer.DeserializeToFile(perf_data_proto,
                                               output_perf_data));
  }
}

TEST(PerfSerializerTest, TestProtoFiles) {
  for (const char* test_file : perf_test_files::kPerfDataProtoFiles) {
    string perf_data_proto_file = GetTestInputFilePath(test_file);
    LOG(INFO) << "Testing " << perf_data_proto_file;
    std::vector<char> data;
    ASSERT_TRUE(FileToBuffer(perf_data_proto_file, &data));
    string text(data.begin(), data.end());

    PerfDataProto perf_data_proto;
    ASSERT_TRUE(TextFormat::ParseFromString(text, &perf_data_proto));
    LOG(INFO) << perf_data_proto.file_attrs_size();

    // Test deserializing.
    PerfSerializer perf_serializer;
    EXPECT_TRUE(perf_serializer.Deserialize(perf_data_proto));
  }
}

TEST(PerfSerializerTest, TestBuildIDs) {
  for (const char* test_file : perf_test_files::kPerfDataFiles) {
    string perf_data_file = GetTestInputFilePath(test_file);
    LOG(INFO) << "Testing " << perf_data_file;

    // Serialize into a protobuf.
    PerfSerializer perf_serializer;
    PerfDataProto perf_data_proto;
    EXPECT_TRUE(perf_serializer.SerializeFromFile(perf_data_file,
                                                  &perf_data_proto));

    // Test a file with build ID filenames removed.
    for (int i = 0; i < perf_data_proto.build_ids_size(); ++i) {
      perf_data_proto.mutable_build_ids(i)->clear_filename();
    }
    PerfSerializer perf_serializer_build_ids;
    EXPECT_TRUE(perf_serializer_build_ids.Deserialize(perf_data_proto));
  }
}

TEST(PerfSerializerTest, SerializesAndDeserializesTraceMetadata) {
  std::stringstream input;

  const size_t attr_count = 1;
  const size_t data_size =
      testing::ExamplePerfSampleEvent_Tracepoint::kEventSize;

  // header
  testing::ExamplePerfDataFileHeader file_header(attr_count, data_size,
                                                 1 << HEADER_TRACING_DATA);
  file_header.WriteTo(&input);
  const perf_file_header &header = file_header.header();
  // attrs
  testing::ExamplePerfFileAttr_Tracepoint(73).WriteTo(&input);
  // data
  ASSERT_EQ(static_cast<u64>(input.tellp()), header.data.offset);
  testing::ExamplePerfSampleEvent_Tracepoint().WriteTo(&input);
  ASSERT_EQ(input.tellp(), file_header.data_end());
  // metadata
  const unsigned int metadata_count = 1;
  // HEADER_TRACING_DATA
  testing::ExampleTracingMetadata tracing_metadata(
      file_header.data_end() + metadata_count*sizeof(perf_file_section));
  tracing_metadata.index_entry().WriteTo(&input);
  tracing_metadata.data().WriteTo(&input);

  // Parse and Serialize

  PerfSerializer perf_serializer;
  // Disable mapping threshold--we have no mappable events.
  PerfParser::Options options;
  options.sample_mapping_percentage_threshold = 0.0;
  perf_serializer.set_options(options);
  PerfDataProto perf_data_proto;
  EXPECT_TRUE(perf_serializer.ReadFromString(input.str()));
  EXPECT_TRUE(perf_serializer.Serialize(&perf_data_proto));

  const std::vector<char> &tracing_metadata_value =
      tracing_metadata.data().value();
  const string tracing_metadata_str(tracing_metadata_value.data(),
                                    tracing_metadata_value.size());
  uint64_t tracing_metadata_md5_prefix =
      Md5Prefix(tracing_metadata_value);
  EXPECT_EQ(tracing_metadata_str,
            perf_data_proto.tracing_data().tracing_data());
  EXPECT_EQ(tracing_metadata_md5_prefix,
            perf_data_proto.tracing_data().tracing_data_md5_prefix());

  // Deserialize

  PerfSerializer deserializer;
  deserializer.set_options(options);
  EXPECT_TRUE(deserializer.Deserialize(perf_data_proto));
  EXPECT_EQ(tracing_metadata_value, deserializer.tracing_data());
}

TEST(PerfSerializerTest, SerializesAndDeserializesMmapEvents) {
  std::stringstream input;

  // header
  testing::ExamplePipedPerfDataFileHeader().WriteTo(&input);

  // data

  // PERF_RECORD_HEADER_ATTR
  testing::ExamplePerfEventAttrEvent_Hardware(PERF_SAMPLE_IP |
                                              PERF_SAMPLE_TID,
                                              true /*sample_id_all*/)
      .WriteTo(&input);

  // PERF_RECORD_MMAP
  testing::ExampleMmapEvent(
      1001, 0x1c1000, 0x1000, 0, "/usr/lib/foo.so",
      testing::SampleInfo().Tid(1001)).WriteTo(&input);

  // PERF_RECORD_MMAP2
  testing::ExampleMmap2Event(
      1002, 0x2c1000, 0x2000, 0x3000, "/usr/lib/bar.so",
      testing::SampleInfo().Tid(1002)).WriteTo(&input);

  // Parse and Serialize

  PerfSerializer perf_serializer;
  // Disable mapping threshold--we have no mappable events.
  PerfParser::Options options;
  options.sample_mapping_percentage_threshold = 0.0;
  perf_serializer.set_options(options);
  PerfDataProto perf_data_proto;
  EXPECT_TRUE(perf_serializer.ReadFromString(input.str()));
  EXPECT_TRUE(perf_serializer.Serialize(&perf_data_proto));

  EXPECT_EQ(2, perf_data_proto.events().size());

  {
    const PerfDataProto::PerfEvent& event = perf_data_proto.events(0);
    EXPECT_EQ(PERF_RECORD_MMAP, event.header().type());
    EXPECT_TRUE(event.has_mmap_event());
    const PerfDataProto::MMapEvent& mmap = event.mmap_event();
    EXPECT_EQ(1001, mmap.pid());
    EXPECT_EQ(1001, mmap.tid());
    EXPECT_EQ(0x1c1000, mmap.start());
    EXPECT_EQ(0x1000, mmap.len());
    EXPECT_EQ(0, mmap.pgoff());
    EXPECT_EQ("/usr/lib/foo.so", mmap.filename());
  }

  {
    const PerfDataProto::PerfEvent& event = perf_data_proto.events(1);
    EXPECT_EQ(PERF_RECORD_MMAP2, event.header().type());
    EXPECT_TRUE(event.has_mmap_event());
    const PerfDataProto::MMapEvent& mmap = event.mmap_event();
    EXPECT_EQ(1002, mmap.pid());
    EXPECT_EQ(1002, mmap.tid());
    EXPECT_EQ(0x2c1000, mmap.start());
    EXPECT_EQ(0x2000, mmap.len());
    EXPECT_EQ(0x3000, mmap.pgoff());
    EXPECT_EQ("/usr/lib/bar.so", mmap.filename());
    // These values are hard-coded in ExampleMmap2Event:
    EXPECT_EQ(6, mmap.maj());
    EXPECT_EQ(7, mmap.min());
    EXPECT_EQ(8, mmap.ino());
    EXPECT_EQ(9, mmap.ino_generation());
    EXPECT_EQ(1|2, mmap.prot());
    EXPECT_EQ(2, mmap.flags());
  }
}

// Regression test for http://crbug.com/501004.
TEST(PerfSerializerTest, SerializesAndDeserializesBuildIDs) {
  std::stringstream input;

  // header
  testing::ExamplePipedPerfDataFileHeader().WriteTo(&input);

  // no data

  // PERF_RECORD_HEADER_ATTR
  testing::ExamplePerfEventAttrEvent_Hardware(PERF_SAMPLE_TID |
                                              PERF_SAMPLE_TIME,
                                              true /*sample_id_all*/)
      .WriteTo(&input);

  PerfSerializer serializer;
  EXPECT_TRUE(serializer.ReadFromString(input.str()));

  std::map<string, string> build_id_map;
  build_id_map["file1"] = "0123456789abcdef0123456789abcdef01234567";
  build_id_map["file2"] = "0123456789abcdef0123456789abcdef01230000";
  build_id_map["file3"] = "0123456789abcdef0123456789abcdef00000000";
  build_id_map["file4"] = "0123456789abcdef0123456789abcdef0000";
  build_id_map["file5"] = "0123456789abcdef0123456789abcdef";
  build_id_map["file6"] = "0123456789abcdef0123456789ab0000";
  build_id_map["file7"] = "0123456789abcdef012345670000";
  build_id_map["file8"] = "0123456789abcdef01234567";
  build_id_map["file9"] = "00000000";
  EXPECT_TRUE(serializer.InjectBuildIDs(build_id_map));

  PerfDataProto perf_data_proto;
  EXPECT_TRUE(serializer.Serialize(&perf_data_proto));

  // Verify that the build ID info was properly injected.
  EXPECT_EQ(9, perf_data_proto.build_ids_size());
  for (int i = 0; i < perf_data_proto.build_ids_size(); ++i) {
    EXPECT_TRUE(perf_data_proto.build_ids(i).has_filename());
    EXPECT_TRUE(perf_data_proto.build_ids(i).has_build_id_hash());
  }

  // Verify that the serialized build IDs have had their trailing zeroes
  // trimmed.
  EXPECT_EQ("file1", perf_data_proto.build_ids(0).filename());
  EXPECT_EQ("0123456789abcdef0123456789abcdef01234567",
            BuildIDToString(perf_data_proto.build_ids(0).build_id_hash()));

  EXPECT_EQ("file2", perf_data_proto.build_ids(1).filename());
  EXPECT_EQ("0123456789abcdef0123456789abcdef01230000",
            BuildIDToString(perf_data_proto.build_ids(1).build_id_hash()));

  EXPECT_EQ("file3", perf_data_proto.build_ids(2).filename());
  EXPECT_EQ("0123456789abcdef0123456789abcdef",
            BuildIDToString(perf_data_proto.build_ids(2).build_id_hash()));

  EXPECT_EQ("file4", perf_data_proto.build_ids(3).filename());
  EXPECT_EQ("0123456789abcdef0123456789abcdef",
            BuildIDToString(perf_data_proto.build_ids(3).build_id_hash()));

  EXPECT_EQ("file5", perf_data_proto.build_ids(4).filename());
  EXPECT_EQ("0123456789abcdef0123456789abcdef",
            BuildIDToString(perf_data_proto.build_ids(4).build_id_hash()));

  EXPECT_EQ("file6", perf_data_proto.build_ids(5).filename());
  EXPECT_EQ("0123456789abcdef0123456789ab0000",
            BuildIDToString(perf_data_proto.build_ids(5).build_id_hash()));

  EXPECT_EQ("file7", perf_data_proto.build_ids(6).filename());
  EXPECT_EQ("0123456789abcdef01234567",
            BuildIDToString(perf_data_proto.build_ids(6).build_id_hash()));

  EXPECT_EQ("file8", perf_data_proto.build_ids(7).filename());
  EXPECT_EQ("0123456789abcdef01234567",
            BuildIDToString(perf_data_proto.build_ids(7).build_id_hash()));

  EXPECT_EQ("file9", perf_data_proto.build_ids(8).filename());
  EXPECT_EQ("", BuildIDToString(perf_data_proto.build_ids(8).build_id_hash()));

  // Check deserialization.
  PerfSerializer deserializer;
  EXPECT_TRUE(deserializer.Deserialize(perf_data_proto));
  const std::vector<malloced_unique_ptr<build_id_event>>& build_id_events =
      deserializer.build_id_events();
  EXPECT_EQ(9, build_id_events.size());

  // All trimmed build IDs should be padded to the full 20 byte length.
  EXPECT_EQ(string("file1"), build_id_events[0]->filename);
  EXPECT_EQ("0123456789abcdef0123456789abcdef01234567",
            HexToString(build_id_events[0]->build_id, kBuildIDArraySize));

  EXPECT_EQ(string("file2"), build_id_events[1]->filename);
  EXPECT_EQ("0123456789abcdef0123456789abcdef01230000",
            HexToString(build_id_events[1]->build_id, kBuildIDArraySize));

  EXPECT_EQ(string("file3"), build_id_events[2]->filename);
  EXPECT_EQ("0123456789abcdef0123456789abcdef00000000",
            HexToString(build_id_events[2]->build_id, kBuildIDArraySize));

  EXPECT_EQ(string("file4"), build_id_events[3]->filename);
  EXPECT_EQ("0123456789abcdef0123456789abcdef00000000",
            HexToString(build_id_events[3]->build_id, kBuildIDArraySize));

  EXPECT_EQ(string("file5"), build_id_events[4]->filename);
  EXPECT_EQ("0123456789abcdef0123456789abcdef00000000",
            HexToString(build_id_events[4]->build_id, kBuildIDArraySize));

  EXPECT_EQ(string("file6"), build_id_events[5]->filename);
  EXPECT_EQ("0123456789abcdef0123456789ab000000000000",
            HexToString(build_id_events[5]->build_id, kBuildIDArraySize));

  EXPECT_EQ(string("file7"), build_id_events[6]->filename);
  EXPECT_EQ("0123456789abcdef012345670000000000000000",
            HexToString(build_id_events[6]->build_id, kBuildIDArraySize));

  EXPECT_EQ(string("file8"), build_id_events[7]->filename);
  EXPECT_EQ("0123456789abcdef012345670000000000000000",
            HexToString(build_id_events[7]->build_id, kBuildIDArraySize));

  EXPECT_EQ(string("file9"), build_id_events[8]->filename);
  EXPECT_EQ("0000000000000000000000000000000000000000",
            HexToString(build_id_events[8]->build_id, kBuildIDArraySize));
}

// Regression test for http://crbug.com/500746.
TEST(PerfSerializerTest, SerializesAndDeserializesForkAndExitEvents) {
  std::stringstream input;

  // header
  testing::ExamplePipedPerfDataFileHeader().WriteTo(&input);

  // data

  // PERF_RECORD_HEADER_ATTR
  testing::ExamplePerfEventAttrEvent_Hardware(PERF_SAMPLE_TID |
                                              PERF_SAMPLE_TIME,
                                              true /*sample_id_all*/)
      .WriteTo(&input);

  // PERF_RECORD_FORK
  testing::ExampleForkEvent(
      1010, 1020, 1030, 1040, 355ULL * 1000000000,
      testing::SampleInfo().Tid(2010, 2020).Time(356ULL * 1000000000))
          .WriteTo(&input);

  // PERF_RECORD_EXIT
  testing::ExampleExitEvent(
      3010, 3020, 3030, 3040, 432ULL * 1000000000,
      testing::SampleInfo().Tid(4010, 4020).Time(433ULL * 1000000000))
          .WriteTo(&input);

  // Parse and serialize.
  PerfSerializer serializer;
  EXPECT_TRUE(serializer.ReadFromString(input.str()));
  PerfDataProto perf_data_proto;
  EXPECT_TRUE(serializer.Serialize(&perf_data_proto));

  EXPECT_EQ(1, perf_data_proto.stats().num_fork_events());
  EXPECT_EQ(1, perf_data_proto.stats().num_exit_events());
  EXPECT_EQ(2, perf_data_proto.events_size());

  {
    const PerfDataProto_PerfEvent& event = perf_data_proto.events(0);
    EXPECT_EQ(PERF_RECORD_FORK, event.header().type());
    EXPECT_TRUE(event.has_fork_event());
    EXPECT_FALSE(event.has_exit_event());

    EXPECT_EQ(1010, event.fork_event().pid());
    EXPECT_EQ(1020, event.fork_event().ppid());
    EXPECT_EQ(1030, event.fork_event().tid());
    EXPECT_EQ(1040, event.fork_event().ptid());
    EXPECT_EQ(355ULL * 1000000000, event.fork_event().fork_time_ns());

    EXPECT_EQ(2010, event.fork_event().sample_info().pid());
    EXPECT_EQ(2020, event.fork_event().sample_info().tid());
    EXPECT_EQ(356ULL * 1000000000,
              event.fork_event().sample_info().sample_time_ns());
  }

  {
    const PerfDataProto_PerfEvent& event = perf_data_proto.events(1);
    EXPECT_EQ(PERF_RECORD_EXIT, event.header().type());
    EXPECT_FALSE(event.has_fork_event());
    EXPECT_TRUE(event.has_exit_event());

    EXPECT_EQ(3010, event.exit_event().pid());
    EXPECT_EQ(3020, event.exit_event().ppid());
    EXPECT_EQ(3030, event.exit_event().tid());
    EXPECT_EQ(3040, event.exit_event().ptid());
    EXPECT_EQ(432ULL * 1000000000, event.exit_event().fork_time_ns());

    EXPECT_EQ(4010, event.exit_event().sample_info().pid());
    EXPECT_EQ(4020, event.exit_event().sample_info().tid());
    EXPECT_EQ(433ULL * 1000000000,
              event.exit_event().sample_info().sample_time_ns());
  }

  // Deserialize and verify raw events.
  PerfSerializer deserializer;
  EXPECT_TRUE(deserializer.Deserialize(perf_data_proto));

  EXPECT_EQ(2, deserializer.events().size());

  {
    const event_t& event = *deserializer.events()[0].get();
    EXPECT_EQ(PERF_RECORD_FORK, event.header.type);

    EXPECT_EQ(1010, event.fork.pid);
    EXPECT_EQ(1020, event.fork.ppid);
    EXPECT_EQ(1030, event.fork.tid);
    EXPECT_EQ(1040, event.fork.ptid);
    EXPECT_EQ(355ULL * 1000000000, event.fork.time);

    struct perf_sample sample_info;
    EXPECT_TRUE(deserializer.ReadPerfSampleInfo(event, &sample_info));
    EXPECT_EQ(2010, sample_info.pid);
    EXPECT_EQ(2020, sample_info.tid);
    EXPECT_EQ(356ULL * 1000000000, sample_info.time);
  }

  {
    const event_t& event = *deserializer.events()[1].get();
    EXPECT_EQ(PERF_RECORD_EXIT, event.header.type);

    EXPECT_EQ(3010, event.fork.pid);
    EXPECT_EQ(3020, event.fork.ppid);
    EXPECT_EQ(3030, event.fork.tid);
    EXPECT_EQ(3040, event.fork.ptid);
    EXPECT_EQ(432ULL * 1000000000, event.fork.time);

    struct perf_sample sample_info;
    EXPECT_TRUE(deserializer.ReadPerfSampleInfo(event, &sample_info));
    EXPECT_EQ(4010, sample_info.pid);
    EXPECT_EQ(4020, sample_info.tid);
    EXPECT_EQ(433ULL * 1000000000, sample_info.time);
  }
}

// Regression test for http://crbug.com/500746.
TEST(PerfSerializerTest, DeserializeLegacyExitEvents) {
  std::stringstream input;

  // header
  testing::ExamplePipedPerfDataFileHeader().WriteTo(&input);

  // data

  // PERF_RECORD_HEADER_ATTR
  testing::ExamplePerfEventAttrEvent_Hardware(PERF_SAMPLE_TID |
                                              PERF_SAMPLE_TIME,
                                              true /*sample_id_all*/)
      .WriteTo(&input);

  // PERF_RECORD_EXIT
  testing::ExampleExitEvent(
      3010, 3020, 3030, 3040, 432ULL * 1000000000,
      testing::SampleInfo().Tid(4010, 4020).Time(433ULL * 1000000000))
          .WriteTo(&input);

  // Parse and serialize.
  PerfSerializer serializer;
  ASSERT_TRUE(serializer.ReadFromString(input.str()));
  PerfDataProto proto;
  ASSERT_TRUE(serializer.Serialize(&proto));

  EXPECT_EQ(1, proto.stats().num_exit_events());
  EXPECT_EQ(1, proto.events_size());

  ASSERT_TRUE(proto.events(0).has_exit_event());
  ASSERT_FALSE(proto.events(0).has_fork_event());

  // Modify the protobuf to store the exit event in the |fork_event| field
  // instead.
  proto.mutable_events(0)->mutable_fork_event()->Swap(
      proto.mutable_events(0)->mutable_exit_event());
  proto.mutable_events(0)->clear_exit_event();

  PerfSerializer deserializer;
  ASSERT_TRUE(deserializer.Deserialize(proto));

  EXPECT_EQ(1U, deserializer.events().size());

  const event_t& event = *deserializer.events()[0].get();
  EXPECT_EQ(PERF_RECORD_EXIT, event.header.type);

  EXPECT_EQ(3010, event.fork.pid);
  EXPECT_EQ(3020, event.fork.ppid);
  EXPECT_EQ(3030, event.fork.tid);
  EXPECT_EQ(3040, event.fork.ptid);
  EXPECT_EQ(432ULL * 1000000000, event.fork.time);

  struct perf_sample sample_info;
  EXPECT_TRUE(deserializer.ReadPerfSampleInfo(event, &sample_info));
  EXPECT_EQ(4010, sample_info.pid);
  EXPECT_EQ(4020, sample_info.tid);
  EXPECT_EQ(433ULL * 1000000000, sample_info.time);
}

}  // namespace quipper

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