// 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_data_structures.h"
#include "chromiumos-wide-profiling/perf_data_utils.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 {

using PerfEvent = PerfDataProto_PerfEvent;
using SampleInfo = PerfDataProto_SampleInfo;

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;
  PerfParserOptions options;
  options.do_remap = do_remap;
  options.discard_unused_events = discard_unused_events;
  options.sample_mapping_percentage_threshold = 100.0f;

  ASSERT_TRUE(SerializeFromFileWithOptions(input, options, &perf_data_proto));

  PerfReader reader;
  ASSERT_TRUE(reader.Deserialize(perf_data_proto));

  PerfParser parser(&reader, options);
  ASSERT_TRUE(parser.ParseRawEvents());

  // Check perf event stats.
  const PerfDataProto_PerfEventStats& in_stats = perf_data_proto.stats();
  PerfEventStats out_stats;
  PerfSerializer::DeserializeParserStats(perf_data_proto, &out_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);

  ASSERT_TRUE(reader.WriteFile(output));
}

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 is stateless w/r to Serialize or Deserialize calls so we can
  // use just one.
  PerfParserOptions options;
  options.sort_events_by_time = true;
  EXPECT_TRUE(SerializeFromFileWithOptions(input, options,
                                           &input_perf_data_proto));
  CheckChronologicalOrderOfSerializedEvents(input_perf_data_proto);

  input_perf_data_proto.Clear();
  options.sort_events_by_time = false;
  EXPECT_TRUE(SerializeFromFileWithOptions(input, options,
                                           &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));

  EXPECT_TRUE(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());
}

}  // 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::GetPerfDataFiles()) {
    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;
    ASSERT_TRUE(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::GetPerfDataFiles()) {
    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::GetPerfPipedDataFiles()) {
    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(PerfSerializerTest, 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::GetPerfDataFiles()) {
    const string input_perf_data = GetTestInputFilePath(test_file);
    LOG(INFO) << "Testing COMM Md5sum for " << input_perf_data;

    PerfDataProto perf_data_proto;
    EXPECT_TRUE(SerializeFromFile(input_perf_data, &perf_data_proto));

    // Need to get file attrs to construct a SampleInfoReader within
    // |serializer|.
    ASSERT_GT(perf_data_proto.file_attrs().size(), 0U);
    ASSERT_TRUE(perf_data_proto.file_attrs(0).has_attr());
    PerfSerializer serializer;
    PerfFileAttr attr;
    const auto& proto_attr = perf_data_proto.file_attrs(0);
    ASSERT_TRUE(serializer.DeserializePerfFileAttr(proto_attr, &attr));
    serializer.CreateSampleInfoReader(attr, false /* read_cross_endian */);

    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);
      int64_t string_len_diff =
          GetUint64AlignedStringLength(comm_md5_string) -
          GetUint64AlignedStringLength(event.comm_event().comm());
      event.mutable_comm_event()->set_comm(comm_md5_string);

      // Update with the new size.
      event.mutable_header()->set_size(event.header().size() + string_len_diff);
    }

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

TEST(PerfSerializerTest, 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::GetPerfDataFiles()) {
    const string input_perf_data = GetTestInputFilePath(test_file);
    LOG(INFO) << "Testing MMAP Md5sum for " << input_perf_data;

    PerfDataProto perf_data_proto;
    EXPECT_TRUE(SerializeFromFile(input_perf_data, &perf_data_proto));

    // Need to get file attrs to construct a SampleInfoReader within
    // |serializer|.
    ASSERT_GT(perf_data_proto.file_attrs().size(), 0U);
    ASSERT_TRUE(perf_data_proto.file_attrs(0).has_attr());
    PerfSerializer serializer;
    PerfFileAttr attr;
    const auto& proto_attr = perf_data_proto.file_attrs(0);
    ASSERT_TRUE(serializer.DeserializePerfFileAttr(proto_attr, &attr));
    serializer.CreateSampleInfoReader(attr, false /* read_cross_endian */);

    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;
      ASSERT_TRUE(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);

      int64_t string_len_diff =
          GetUint64AlignedStringLength(filename_md5_string) -
          GetUint64AlignedStringLength(event.mmap_event().filename());
      event.mutable_mmap_event()->set_filename(filename_md5_string);

      // Update with the new size.
      event.mutable_header()->set_size(event.header().size() + string_len_diff);
    }

    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(DeserializeToFile(perf_data_proto, output_perf_data));
  }
}

TEST(PerfSerializerTest, TestProtoFiles) {
  for (const char* test_file : perf_test_files::GetPerfDataProtoFiles()) {
    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));

    // Test deserializing.
    PerfReader deserializer;
    EXPECT_TRUE(deserializer.Deserialize(perf_data_proto));
  }
}

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

    // Serialize into a protobuf.
    PerfDataProto perf_data_proto;
    EXPECT_TRUE(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();
    }
    PerfReader deserializer;
    EXPECT_TRUE(deserializer.Deserialize(perf_data_proto));
  }
}

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

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

  // header
  testing::ExamplePerfDataFileHeader file_header(1 << HEADER_TRACING_DATA);
  file_header
      .WithAttrCount(1)
      .WithDataSize(data_size);
  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

  PerfReader reader;
  ASSERT_TRUE(reader.ReadFromString(input.str()));

  PerfDataProto perf_data_proto;
  ASSERT_TRUE(reader.Serialize(&perf_data_proto));

  const string& tracing_metadata_str = tracing_metadata.data().value();
  const auto& tracing_data = perf_data_proto.tracing_data();
  EXPECT_EQ(tracing_metadata_str, tracing_data.tracing_data());
  EXPECT_EQ(Md5Prefix(tracing_metadata_str),
            tracing_data.tracing_data_md5_prefix());

  // Deserialize

  PerfReader deserializer;
  EXPECT_TRUE(deserializer.Deserialize(perf_data_proto));
  EXPECT_EQ(tracing_metadata_str, 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

  PerfReader reader;
  ASSERT_TRUE(reader.ReadFromString(input.str()));

  PerfDataProto perf_data_proto;
  ASSERT_TRUE(reader.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);

  PerfReader reader;
  ASSERT_TRUE(reader.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";
  reader.InjectBuildIDs(build_id_map);

  PerfDataProto perf_data_proto;
  ASSERT_TRUE(reader.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",
            RawDataToHexString(perf_data_proto.build_ids(0).build_id_hash()));

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

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

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

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

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

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

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

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

  // Check deserialization.
  PerfReader out_reader;
  EXPECT_TRUE(out_reader.Deserialize(perf_data_proto));
  const auto& build_ids = out_reader.build_ids();
  ASSERT_EQ(9, build_ids.size());

  std::vector<malloced_unique_ptr<build_id_event>>
      raw_build_ids(build_ids.size());

  // Convert the build IDs back to raw build ID events.
  PerfSerializer serializer;
  for (int i = 0; i < build_ids.size(); ++i) {
    ASSERT_TRUE(serializer.DeserializeBuildIDEvent(build_ids.Get(i),
                                                   &raw_build_ids[i]));
  }

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

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

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

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

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

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

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

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

  EXPECT_EQ(string("file9"), raw_build_ids[8]->filename);
  EXPECT_EQ("0000000000000000000000000000000000000000",
            RawDataToHexString(raw_build_ids[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.
  PerfReader reader;
  ASSERT_TRUE(reader.ReadFromString(input.str()));

  PerfDataProto perf_data_proto;
  ASSERT_TRUE(reader.Serialize(&perf_data_proto));

  ASSERT_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 events.
  PerfReader out_reader;
  ASSERT_TRUE(out_reader.Deserialize(perf_data_proto));

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

  {
    const PerfEvent& event = out_reader.events().Get(0);
    EXPECT_EQ(PERF_RECORD_FORK, event.header().type());

    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());

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

  {
    const PerfEvent& event = out_reader.events().Get(1);
    EXPECT_EQ(PERF_RECORD_EXIT, event.header().type());

    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());

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

// 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.
  PerfReader reader;
  ASSERT_TRUE(reader.ReadFromString(input.str()));

  PerfDataProto proto;
  ASSERT_TRUE(reader.Serialize(&proto));

  ASSERT_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();

  PerfReader out_reader;
  ASSERT_TRUE(out_reader.Deserialize(proto));

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

  const PerfEvent& event = out_reader.events().Get(0);
  EXPECT_EQ(PERF_RECORD_EXIT, event.header().type());
  EXPECT_EQ(3010, event.fork_event().pid());
  EXPECT_EQ(3020, event.fork_event().ppid());
  EXPECT_EQ(3030, event.fork_event().tid());
  EXPECT_EQ(3040, event.fork_event().ptid());
  EXPECT_EQ(432ULL * 1000000000, event.fork_event().fork_time_ns());


  const SampleInfo& sample_info = event.fork_event().sample_info();
  EXPECT_EQ(4010, sample_info.pid());
  EXPECT_EQ(4020, sample_info.tid());
  EXPECT_EQ(433ULL * 1000000000, sample_info.sample_time_ns());
}

}  // namespace quipper
