// Copyright (c) 2013 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 <stdint.h>
#include <sys/capability.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>
#include <map>
#include <set>
#include <string>
#include <vector>

#include "base/logging.h"

#include "chromiumos-wide-profiling/compat/string.h"
#include "chromiumos-wide-profiling/compat/test.h"
#include "chromiumos-wide-profiling/compat/thread.h"
#include "chromiumos-wide-profiling/dso_test_utils.h"
#include "chromiumos-wide-profiling/perf_parser.h"
#include "chromiumos-wide-profiling/perf_reader.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 quipper {

using SampleEvent = PerfDataProto_SampleEvent;
using SampleInfo = PerfDataProto_SampleInfo;
using PerfEvent = PerfDataProto_PerfEvent;

namespace {

// Any run of perf should have MMAPs with the following substrings.
const char* kExpectedFilenameSubstrings[] = {
  "perf",
  "kernel",
  "libc",
};

void CheckChronologicalOrderOfEvents(const PerfReader& reader) {
  if (reader.events().empty())
    return;
  const auto& events = reader.events();
  uint64_t prev_time = GetTimeFromPerfEvent(events.Get(0));
  for (int i = 1; i < events.size(); ++i) {
    uint64_t new_time = GetTimeFromPerfEvent(events.Get(i));
    CHECK_LE(prev_time, new_time);
    prev_time = new_time;
  }
}

void CheckNoDuplicates(const std::vector<string>& list) {
  std::set<string> list_as_set(list.begin(), list.end());
  if (list.size() != list_as_set.size())
    ADD_FAILURE() << "Given list has at least one duplicate";
}

void CheckForElementWithSubstring(string substring_to_find,
                                  const std::vector<string>& list) {
  std::vector<string>::const_iterator iter;
  for (iter = list.begin(); iter != list.end(); ++iter)
    if (iter->find(substring_to_find) != string::npos)
      return;
  ADD_FAILURE() << substring_to_find
                << " is not present in any of the elements of the given list";
}

void CreateFilenameToBuildIDMap(
    const std::vector<string>& filenames,
    unsigned int seed,
    std::map<string, string>* filenames_to_build_ids) {
  srand(seed);
  // Only use every other filename, so that half the filenames are unused.
  for (size_t i = 0; i < filenames.size(); i += 2) {
    u8 build_id[kBuildIDArraySize];
    for (size_t j = 0; j < kBuildIDArraySize; ++j)
      build_id[j] = rand_r(&seed);

    (*filenames_to_build_ids)[filenames[i]] =
        RawDataToHexString(build_id, kBuildIDArraySize);
  }
}

// Given a PerfReader that has already consumed an input perf data file, inject
// new build IDs for the MMAP'd files in the perf data and check that they have
// been correctly injected.
void CheckFilenameAndBuildIDMethods(PerfReader* reader,
                                    const string& output_perf_data_prefix,
                                    unsigned int seed) {
  // Check filenames.
  std::vector<string> filenames;
  reader->GetFilenames(&filenames);

  ASSERT_FALSE(filenames.empty());
  CheckNoDuplicates(filenames);
  for (const char* substring : kExpectedFilenameSubstrings)
    CheckForElementWithSubstring(substring, filenames);

  std::set<string> filename_set;
  reader->GetFilenamesAsSet(&filename_set);

  // Make sure all MMAP filenames are in the set.
  for (const auto& event : reader->events()) {
    if (event.header().type() == PERF_RECORD_MMAP) {
      EXPECT_TRUE(filename_set.find(event.mmap_event().filename()) !=
                                    filename_set.end())
          << event.mmap_event().filename()
          << " is not present in the filename set";
    }
  }

  std::map<string, string> expected_map;
  reader->GetFilenamesToBuildIDs(&expected_map);

  // Inject some made up build ids.
  std::map<string, string> filenames_to_build_ids;
  CreateFilenameToBuildIDMap(filenames, seed, &filenames_to_build_ids);
  ASSERT_TRUE(reader->InjectBuildIDs(filenames_to_build_ids));

  // Reader should now correctly populate the filenames to build ids map.
  std::map<string, string>::const_iterator it;
  for (it = filenames_to_build_ids.begin();
       it != filenames_to_build_ids.end();
       ++it) {
    expected_map[it->first] = it->second;
  }
  std::map<string, string> reader_map;
  reader->GetFilenamesToBuildIDs(&reader_map);
  ASSERT_EQ(expected_map, reader_map);

  string output_perf_data1 = output_perf_data_prefix + ".parse.inject.out";
  ASSERT_TRUE(reader->WriteFile(output_perf_data1));

  // Perf should find the same build ids.
  std::map<string, string> perf_build_id_map;
  ASSERT_TRUE(GetPerfBuildIDMap(output_perf_data1, &perf_build_id_map));
  ASSERT_EQ(expected_map, perf_build_id_map);

  std::map<string, string> build_id_localizer;
  // Only localize the first half of the files which have build ids.
  for (size_t j = 0; j < filenames.size() / 2; ++j) {
    string old_filename = filenames[j];
    if (expected_map.find(old_filename) == expected_map.end())
      continue;
    string build_id = expected_map[old_filename];

    string new_filename = old_filename + ".local";
    filenames[j] = new_filename;
    build_id_localizer[build_id] = new_filename;
    expected_map[new_filename] = build_id;
    expected_map.erase(old_filename);
  }
  reader->Localize(build_id_localizer);

  // Filenames should be the same.
  std::vector<string> new_filenames;
  reader->GetFilenames(&new_filenames);
  std::sort(filenames.begin(), filenames.end());
  ASSERT_EQ(filenames, new_filenames);

  // Build ids should be updated.
  reader_map.clear();
  reader->GetFilenamesToBuildIDs(&reader_map);
  ASSERT_EQ(expected_map, reader_map);

  string output_perf_data2 = output_perf_data_prefix + ".parse.localize.out";
  ASSERT_TRUE(reader->WriteFile(output_perf_data2));

  perf_build_id_map.clear();
  ASSERT_TRUE(GetPerfBuildIDMap(output_perf_data2, &perf_build_id_map));
  EXPECT_EQ(expected_map, perf_build_id_map);

  std::map<string, string> filename_localizer;
  // Only localize every third filename.
  for (size_t j = 0; j < filenames.size(); j += 3) {
    string old_filename = filenames[j];
    string new_filename = old_filename + ".local2";
    filenames[j] = new_filename;
    filename_localizer[old_filename] = new_filename;

    if (expected_map.find(old_filename) != expected_map.end()) {
      string build_id = expected_map[old_filename];
      expected_map[new_filename] = build_id;
      expected_map.erase(old_filename);
    }
  }
  reader->LocalizeUsingFilenames(filename_localizer);

  // Filenames should be the same.
  new_filenames.clear();
  reader->GetFilenames(&new_filenames);
  std::sort(filenames.begin(), filenames.end());
  EXPECT_EQ(filenames, new_filenames);

  // Build ids should be updated.
  reader_map.clear();
  reader->GetFilenamesToBuildIDs(&reader_map);
  EXPECT_EQ(expected_map, reader_map);

  string output_perf_data3 = output_perf_data_prefix + ".parse.localize2.out";
  ASSERT_TRUE(reader->WriteFile(output_perf_data3));

  perf_build_id_map.clear();
  ASSERT_TRUE(GetPerfBuildIDMap(output_perf_data3, &perf_build_id_map));
  EXPECT_EQ(expected_map, perf_build_id_map);
}

}  // namespace

TEST(PerfParserTest, TestDSOAndOffsetConstructor) {
  // DSOAndOffset contains a pointer to a dso info struct. Make sure this is
  // initialized in a way such that DSOAndOffset::dso_name() executes without
  // segfault and returns an empty string.
  ParsedEvent::DSOAndOffset dso_and_offset;
  EXPECT_TRUE(dso_and_offset.dso_name().empty());
}

TEST(PerfParserTest, NormalPerfData) {
  ScopedTempDir output_dir;
  ASSERT_FALSE(output_dir.path().empty());
  string output_path = output_dir.path();

  int seed = 0;
  for (const char* test_file : perf_test_files::GetPerfDataFiles()) {
    string input_perf_data = GetTestInputFilePath(test_file);
    LOG(INFO) << "Testing " << input_perf_data;

    PerfReader reader;
    ASSERT_TRUE(reader.ReadFile(input_perf_data));

    // Test the PerfReader stage of the processing before continuing.
    string pr_output_perf_data = output_path + test_file + ".pr.out";
    ASSERT_TRUE(reader.WriteFile(pr_output_perf_data));
    EXPECT_TRUE(CheckPerfDataAgainstBaseline(pr_output_perf_data));

    // Run it through PerfParser.
    PerfParserOptions options = GetTestOptions();
    options.sort_events_by_time = true;
    PerfParser parser(&reader, options);
    ASSERT_TRUE(parser.ParseRawEvents());

    CHECK_GT(parser.parsed_events().size(), 0U);
    CheckChronologicalOrderOfEvents(reader);

    // Check perf event stats.
    const PerfEventStats& stats = parser.stats();
    EXPECT_GT(stats.num_sample_events, 0U);
    EXPECT_GT(stats.num_mmap_events, 0U);
    EXPECT_GT(stats.num_sample_events_mapped, 0U);
    EXPECT_FALSE(stats.did_remap);

    string parsed_perf_data = output_path + test_file + ".parse.out";
    ASSERT_TRUE(reader.WriteFile(parsed_perf_data));

    EXPECT_TRUE(CheckPerfDataAgainstBaseline(parsed_perf_data));
    EXPECT_TRUE(ComparePerfBuildIDLists(input_perf_data, parsed_perf_data));

    // Run the event parsing again, this time with remapping.
    options = PerfParserOptions();
    options.do_remap = true;
    parser.set_options(options);
    ASSERT_TRUE(parser.ParseRawEvents());

    // Check perf event stats.
    EXPECT_GT(stats.num_sample_events, 0U);
    EXPECT_GT(stats.num_mmap_events, 0U);
    EXPECT_GT(stats.num_sample_events_mapped, 0U);
    EXPECT_TRUE(stats.did_remap);

    // Remapped addresses should not match the original addresses.
    string remapped_perf_data = output_path + test_file + ".parse.remap.out";
    ASSERT_TRUE(reader.WriteFile(remapped_perf_data));
    EXPECT_TRUE(CheckPerfDataAgainstBaseline(remapped_perf_data));

    // Remapping again should produce the same addresses.
    LOG(INFO) << "Reading in remapped data: " << remapped_perf_data;
    PerfReader remap_reader;
    ASSERT_TRUE(remap_reader.ReadFile(remapped_perf_data));

    PerfParser remap_parser(&remap_reader, options);
    ASSERT_TRUE(remap_parser.ParseRawEvents());

    const PerfEventStats& remap_stats = remap_parser.stats();
    EXPECT_GT(remap_stats.num_sample_events, 0U);
    EXPECT_GT(remap_stats.num_mmap_events, 0U);
    EXPECT_GT(remap_stats.num_sample_events_mapped, 0U);
    EXPECT_TRUE(remap_stats.did_remap);

    ASSERT_EQ(stats.num_sample_events, remap_stats.num_sample_events);
    ASSERT_EQ(stats.num_mmap_events, remap_stats.num_mmap_events);
    ASSERT_EQ(stats.num_sample_events_mapped,
              remap_stats.num_sample_events_mapped);

    string remapped_perf_data2 = output_path + test_file + ".parse.remap2.out";
    ASSERT_TRUE(remap_reader.WriteFile(remapped_perf_data2));

    // No need to call CheckPerfDataAgainstBaseline again. Just compare
    // ParsedEvents.
    const auto& parser_events = parser.parsed_events();
    const auto& remap_parser_events = remap_parser.parsed_events();
    EXPECT_EQ(parser_events.size(), remap_parser_events.size());
    EXPECT_TRUE(std::equal(parser_events.begin(), parser_events.end(),
                           remap_parser_events.begin()));
    EXPECT_TRUE(
        ComparePerfBuildIDLists(remapped_perf_data, remapped_perf_data2));

    // This must be called when |reader| is no longer going to be used, as it
    // modifies the contents of |reader|.
    CheckFilenameAndBuildIDMethods(&reader, output_path + test_file, seed);
    ++seed;
  }
}

TEST(PerfParserTest, PipedModePerfData) {
  ScopedTempDir output_dir;
  ASSERT_FALSE(output_dir.path().empty());
  string output_path = output_dir.path();

  int seed = 0;
  for (const char* test_file : perf_test_files::GetPerfPipedDataFiles()) {
    string input_perf_data = GetTestInputFilePath(test_file);
    LOG(INFO) << "Testing " << input_perf_data;
    string output_perf_data = output_path + test_file + ".pr.out";

    PerfReader reader;
    ASSERT_TRUE(reader.ReadFile(input_perf_data));

    // Check results from the PerfReader stage.
    ASSERT_TRUE(reader.WriteFile(output_perf_data));
    EXPECT_TRUE(CheckPerfDataAgainstBaseline(output_perf_data));

    PerfParserOptions options = GetTestOptions();
    options.do_remap = true;
    options.sort_events_by_time = true;
    PerfParser parser(&reader, options);
    ASSERT_TRUE(parser.ParseRawEvents());

    EXPECT_GT(parser.stats().num_sample_events, 0U);
    EXPECT_GT(parser.stats().num_mmap_events, 0U);
    EXPECT_GT(parser.stats().num_sample_events_mapped, 0U);
    EXPECT_TRUE(parser.stats().did_remap);

    // This must be called when |reader| is no longer going to be used, as it
    // modifies the contents of |reader|.
    CheckFilenameAndBuildIDMethods(&reader, output_path + test_file, seed);
    ++seed;
  }
}

TEST(PerfParserTest, MapsSampleEventIp) {
  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);        // 0
  // becomes: 0x0000, 0x1000, 0
  testing::ExampleMmapEvent(
      1001, 0x1c3000, 0x2000, 0x2000, "/usr/lib/bar.so",
      testing::SampleInfo().Tid(1001)).WriteTo(&input);        // 1
  // becomes: 0x1000, 0x2000, 0

  // PERF_RECORD_MMAP2
  testing::ExampleMmap2Event(
      1002, 0x2c1000, 0x2000, 0, "/usr/lib/baz.so",
      testing::SampleInfo().Tid(1002)).WriteTo(&input);        // 2
  // becomes: 0x0000, 0x2000, 0
  testing::ExampleMmap2Event(
      1002, 0x2c3000, 0x1000, 0x3000, "/usr/lib/xyz.so",
      testing::SampleInfo().Tid(1002)).WriteTo(&input);        // 3
  // becomes: 0x1000, 0x1000, 0

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(1001))  // 4
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c100a).Tid(1001))  // 5
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c3fff).Tid(1001))  // 6
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c2bad).Tid(1001))  // 7 (not mapped)
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000002c100a).Tid(1002))  // 8
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000002c5bad).Tid(1002))  // 9 (not mapped)
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000002c300b).Tid(1002))  // 10
      .WriteTo(&input);

  // not mapped yet:
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000002c400b).Tid(1002))  // 11
      .WriteTo(&input);
  testing::ExampleMmap2Event(
      1002, 0x2c4000, 0x1000, 0, "/usr/lib/new.so",
      testing::SampleInfo().Tid(1002)).WriteTo(&input);        // 12
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000002c400b).Tid(1002))  // 13
      .WriteTo(&input);

  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.sample_mapping_percentage_threshold = 0;
  options.do_remap = true;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(5, parser.stats().num_mmap_events);
  EXPECT_EQ(9, parser.stats().num_sample_events);
  EXPECT_EQ(6, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(14, events.size());

  // MMAPs

  EXPECT_EQ(PERF_RECORD_MMAP, events[0].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/foo.so", events[0].event_ptr->mmap_event().filename());
  EXPECT_EQ(0x0000, events[0].event_ptr->mmap_event().start());
  EXPECT_EQ(0x1000, events[0].event_ptr->mmap_event().len());
  EXPECT_EQ(0, events[0].event_ptr->mmap_event().pgoff());

  EXPECT_EQ(PERF_RECORD_MMAP, events[1].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/bar.so", events[1].event_ptr->mmap_event().filename());
  EXPECT_EQ(0x1000, events[1].event_ptr->mmap_event().start());
  EXPECT_EQ(0x2000, events[1].event_ptr->mmap_event().len());
  EXPECT_EQ(0x2000, events[1].event_ptr->mmap_event().pgoff());

  EXPECT_EQ(PERF_RECORD_MMAP2, events[2].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/baz.so", events[2].event_ptr->mmap_event().filename());
  EXPECT_EQ(0x0000, events[2].event_ptr->mmap_event().start());
  EXPECT_EQ(0x2000, events[2].event_ptr->mmap_event().len());
  EXPECT_EQ(0, events[2].event_ptr->mmap_event().pgoff());

  EXPECT_EQ(PERF_RECORD_MMAP2, events[3].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/xyz.so", events[3].event_ptr->mmap_event().filename());
  EXPECT_EQ(0x2000, events[3].event_ptr->mmap_event().start());
  EXPECT_EQ(0x1000, events[3].event_ptr->mmap_event().len());
  EXPECT_EQ(0x3000, events[3].event_ptr->mmap_event().pgoff());

  // SAMPLEs

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[4].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/foo.so", events[4].dso_and_offset.dso_name());
  EXPECT_EQ(0x0, events[4].dso_and_offset.offset());
  EXPECT_EQ(0x0, events[4].event_ptr->sample_event().ip());

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[5].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/foo.so", events[5].dso_and_offset.dso_name());
  EXPECT_EQ(0xa, events[5].dso_and_offset.offset());
  EXPECT_EQ(0xa, events[5].event_ptr->sample_event().ip());

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[6].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/bar.so", events[6].dso_and_offset.dso_name());
  EXPECT_EQ(0x2fff, events[6].dso_and_offset.offset());
  EXPECT_EQ(0x1fff, events[6].event_ptr->sample_event().ip());

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[7].event_ptr->header().type());
  EXPECT_EQ(0x00000000001c2bad, events[7].event_ptr->sample_event().ip());

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[8].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/baz.so", events[8].dso_and_offset.dso_name());
  EXPECT_EQ(0xa, events[8].dso_and_offset.offset());
  EXPECT_EQ(0xa, events[8].event_ptr->sample_event().ip());

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[9].event_ptr->header().type());
  EXPECT_EQ(0x00000000002c5bad, events[9].event_ptr->sample_event().ip());

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[10].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/xyz.so", events[10].dso_and_offset.dso_name());
  EXPECT_EQ(0x300b, events[10].dso_and_offset.offset());
  EXPECT_EQ(0x200b, events[10].event_ptr->sample_event().ip());

  // not mapped yet:
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[11].event_ptr->header().type());
  EXPECT_EQ(0x00000000002c400b, events[11].event_ptr->sample_event().ip());

  EXPECT_EQ(PERF_RECORD_MMAP2, events[12].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/new.so", events[12].event_ptr->mmap_event().filename());
  EXPECT_EQ(0x3000, events[12].event_ptr->mmap_event().start());
  EXPECT_EQ(0x1000, events[12].event_ptr->mmap_event().len());
  EXPECT_EQ(0, events[12].event_ptr->mmap_event().pgoff());

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[13].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/new.so", events[13].dso_and_offset.dso_name());
  EXPECT_EQ(0xb, events[13].dso_and_offset.offset());
  EXPECT_EQ(0x300b, events[13].event_ptr->sample_event().ip());
}

TEST(PerfParserTest, DsoInfoHasBuildId) {
  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);        // 0
  // becomes: 0x0000, 0x1000, 0
  testing::ExampleMmapEvent(
      1001, 0x1c3000, 0x2000, 0x2000, "/usr/lib/bar.so",
      testing::SampleInfo().Tid(1001)).WriteTo(&input);        // 1
  // becomes: 0x1000, 0x2000, 0

  // PERF_RECORD_HEADER_BUILDID                                // N/A
  string build_id_filename("/usr/lib/foo.so\0", 2*sizeof(u64));
  ASSERT_EQ(0, build_id_filename.size() % sizeof(u64)) << "Sanity check";
  const size_t event_size =
      sizeof(struct build_id_event) +
      build_id_filename.size();
  const struct build_id_event event = {
    .header = {
      .type = PERF_RECORD_HEADER_BUILD_ID,
      .misc = 0,
      .size = static_cast<u16>(event_size),
    },
    .pid = -1,
    .build_id = {0xde, 0xad, 0xf0, 0x0d },
  };
  input.write(reinterpret_cast<const char*>(&event), sizeof(event));
  input.write(build_id_filename.data(), build_id_filename.size());

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(1001))  // 2
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c300a).Tid(1001))  // 3
      .WriteTo(&input);

  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.sample_mapping_percentage_threshold = 0;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(2, parser.stats().num_mmap_events);
  EXPECT_EQ(2, parser.stats().num_sample_events);
  EXPECT_EQ(2, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(4, events.size());

  EXPECT_EQ("/usr/lib/foo.so", events[2].dso_and_offset.dso_name());
  EXPECT_EQ("deadf00d00000000000000000000000000000000",
            events[2].dso_and_offset.build_id());
  EXPECT_EQ("/usr/lib/bar.so", events[3].dso_and_offset.dso_name());
  EXPECT_EQ("", events[3].dso_and_offset.build_id());
}

// Check the process has a Linux capability. See libcap(3) and capabilities(7).
bool HaveCapability(cap_value_t capability) {
  cap_t capabilities = cap_get_proc();
  cap_flag_value_t value;
  CHECK_EQ(cap_get_flag(capabilities, capability, CAP_EFFECTIVE, &value), 0);
  cap_free(capabilities);
  return value == CAP_SET;
}

class RunInMountNamespaceThread : public quipper::Thread {
 public:
  explicit RunInMountNamespaceThread(string tmpdir, string mntdir)
      : quipper::Thread("MntNamespace"),
        tmpdir_(tmpdir), mntdir_(mntdir) {
  }

  void Start() override {
    quipper::Thread::Start();
    ready.Wait();
  }

  void Join() override {
    exit.Notify();
    quipper::Thread::Join();
  }

 private:
  void Run() override {
    CHECK_EQ(unshare(CLONE_NEWNS), 0);
    CHECK_EQ(mount(tmpdir_.c_str(), mntdir_.c_str(),
                   nullptr, MS_BIND, nullptr), 0);
    ready.Notify();
    exit.Wait();
  }

  Notification ready;
  Notification exit;
  string tmpdir_;
  string mntdir_;
};

// Root task <pid>/<pid> Filesystem:
//   "/tmp/quipper_tmp.../file_in_namespace"  buildid: deadbeef  ino: X
//   "/tmp/quipper_mnt.../file_in_namespace"  (Doesn't exist)
// Container task <pid>/<tid> Filesystem:
//   "/tmp/quipper_tmp.../file_in_namespace"  buildid: deadbeef  ino: X
// * "/tmp/quipper_mnt.../file_in_namespace"  buildid: deadbeef  ino: X
// <path> = marked with *
// MMAP2: <pid+10>/<tid+1>, <path>, ino: X
// MMAP2: <pid>/<tid>, <path>, ino: X
// Reject (doesn't exist): /proc/<tid+10>/root/<path>
// Reject (doesn't exist): /proc/<pid+1>/root/<path>
// Accept:                 /proc/<tid>/root/<path>
// (Not tried):            /proc/<pid>/root/<path>
// (Not tried): /<path>
// Expected buildid for <path>: "deadbeef"
TEST(PerfParserTest, ReadsBuildidsInMountNamespace) {
  if (!HaveCapability(CAP_SYS_ADMIN))
    return;  // Skip test.
  ScopedTempDir tmpdir("/tmp/quipper_tmp.");
  ScopedTempDir mntdir("/tmp/quipper_mnt.");
  RunInMountNamespaceThread thread(tmpdir.path(), mntdir.path());
  thread.Start();
  const pid_t pid = getpid();
  const pid_t tid = thread.tid();

  const string tmpfile = tmpdir.path() + "file_in_namespace";
  const string tmpfile_in_ns = mntdir.path() + "file_in_namespace";
  InitializeLibelf();
  testing::WriteElfWithBuildid(tmpfile, ".note.gnu.build-id",
                               "\xde\xad\xbe\xef");
  struct stat tmp_stat;
  ASSERT_NE(stat(tmpfile_in_ns.c_str(), &tmp_stat), 0);
  ASSERT_EQ(stat(tmpfile.c_str(), &tmp_stat), 0);

  // Create perf.data
  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_MMAP2
  // - mmap from a process and thread that doesn't exist
  testing::ExampleMmap2Event(
      pid, tid, 0x1c1000, 0x1000, 0, tmpfile_in_ns,
      testing::SampleInfo().Tid(pid+10, tid+1))
      .WithDeviceInfo(major(tmp_stat.st_dev), minor(tmp_stat.st_dev),
                      tmp_stat.st_ino)
      .WriteTo(&input);                                            // 0
  // - mmap from a running thread
  testing::ExampleMmap2Event(
      pid, tid, 0x1c2000, 0x1000, 0, tmpfile_in_ns,
      testing::SampleInfo().Tid(pid, tid))
      .WithDeviceInfo(major(tmp_stat.st_dev), minor(tmp_stat.st_dev),
                      tmp_stat.st_ino)
      .WriteTo(&input);                                            // 1

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(pid, tid))  // 2
      .WriteTo(&input);

  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.read_missing_buildids = true;
  options.sample_mapping_percentage_threshold = 0;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(2, parser.stats().num_mmap_events);
  EXPECT_EQ(1, parser.stats().num_sample_events);
  EXPECT_EQ(1, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(3, events.size());

  EXPECT_EQ(tmpfile_in_ns, events[2].dso_and_offset.dso_name());
  EXPECT_EQ("deadbeef", events[2].dso_and_offset.build_id());

  thread.Join();
}

class RunInMountNamespaceProcess {
 public:
  RunInMountNamespaceProcess(string tmpdir, string mntdir)
      : pid_(0), tmpdir_(tmpdir), mntdir_(mntdir) {
  }

  void Start() {
    int pipe_fd[2];
    int nonce = 0;
    CHECK_EQ(pipe(pipe_fd), 0) << "pipe: " << strerror(errno);

    pid_ = fork();
    CHECK_NE(-1, pid_) << "fork: " << strerror(errno);
    if (pid_ == 0) {  // child
      close(pipe_fd[0]);
      CHECK_EQ(unshare(CLONE_NEWNS), 0);
      CHECK_EQ(mount(tmpdir_.c_str(), mntdir_.c_str(),
                     nullptr, MS_BIND, nullptr), 0);
      // Tell parent mounting is done.
      CHECK_EQ(write(pipe_fd[1], &nonce, sizeof(nonce)),
               static_cast<ssize_t>(sizeof(nonce)));
      close(pipe_fd[1]);
      pause();  // Wait to be killed. (So morbid.)
      std::_Exit(-1);
    }
    close(pipe_fd[1]);

    // Wait for child to tell us it has mounted the dir.
    ssize_t sz = read(pipe_fd[0], &nonce, sizeof(nonce));
    CHECK_EQ(sz, static_cast<ssize_t>(sizeof(nonce)))
        << "read: " << strerror(errno);
    close(pipe_fd[0]);
  }

  void Exit() {
    kill(pid_, SIGTERM);
    waitpid(pid_, nullptr, 0);
  }

  pid_t pid() { return pid_; }

 private:
  pid_t pid_;
  string tmpdir_;
  string mntdir_;
};

// Root task <pid>/<pid> Filesystem:
//   "/tmp/quipper_tmp.../file_in_namespace"  buildid: deadbeef  ino: X
// * "/tmp/quipper_mnt.../file_in_namespace"  buildid: baadf00d  ino: Y
// Container task <pid2>/<pid2> Filesystem:
//   "/tmp/quipper_tmp.../file_in_namespace"  buildid: deadbeef  ino: X
// * "/tmp/quipper_mnt.../file_in_namespace"  buildid: deadbeef  ino: X
// <path> = marked with *
// MMAP2: <pid2>/<pid2+1>, <path>, ino: X
// Reject (doesn't exist): /proc/<pid2+1>/root/<path>
// Accept:                 /proc/<pid2>/root/<path>
// (Not tried): /<path>
// Expected buildid for <path>: "deadbeef"
TEST(PerfParserTest, ReadsBuildidsInMountNamespace_TriesOwningProcess) {
  if (!HaveCapability(CAP_SYS_ADMIN))
    return;  // Skip test.
  ScopedTempDir tmpdir("/tmp/quipper_tmp.");
  ScopedTempDir mntdir("/tmp/quipper_mnt.");
  RunInMountNamespaceProcess process(tmpdir.path(), mntdir.path());
  process.Start();

  // Pretend we launched a thread in the other process, it mapped the file,
  // and then exited. Let's make up a tid for it that's not likely to exist.
  const pid_t pid = process.pid();
  const pid_t tid = pid + 1;

  const string tmpfile = tmpdir.path() + "file_in_namespace";
  const string tmpfile_in_ns = mntdir.path() + "file_in_namespace";
  InitializeLibelf();
  testing::WriteElfWithBuildid(tmpfile, ".note.gnu.build-id",
                               "\xde\xad\xbe\xef");
  // It's a trap! If "baadf00d" is seen, we read the wrong file.
  testing::WriteElfWithBuildid(tmpfile_in_ns, ".note.gnu.build-id",
                               "\xba\xad\xf0\x0d");
  struct stat tmp_stat;
  ASSERT_EQ(stat(tmpfile.c_str(), &tmp_stat), 0);

  // Create perf.data
  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_MMAP2
  testing::ExampleMmap2Event(
      pid, tid, 0x1c1000, 0x1000, 0, tmpfile_in_ns,
      testing::SampleInfo().Tid(pid, tid))
      .WithDeviceInfo(major(tmp_stat.st_dev), minor(tmp_stat.st_dev),
                      tmp_stat.st_ino)
      .WriteTo(&input);                                            // 0

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(pid, tid))  // 1
      .WriteTo(&input);

  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.read_missing_buildids = true;
  options.sample_mapping_percentage_threshold = 0;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(1, parser.stats().num_mmap_events);
  EXPECT_EQ(1, parser.stats().num_sample_events);
  EXPECT_EQ(1, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(2, events.size());

  EXPECT_EQ(tmpfile_in_ns, events[1].dso_and_offset.dso_name());
  EXPECT_EQ("deadbeef", events[1].dso_and_offset.build_id());

  process.Exit();
}

// Root task <pid>/<pid> Filesystem:
// * "/tmp/quipper_tmp.../file_in_namespace"  buildid: deadbeef  ino: X
//   "/tmp/quipper_mnt.../file_in_namespace"  buildid: baadf00d  ino: Y
// Container task <pid>/<tid> Filesystem:
// * "/tmp/quipper_tmp.../file_in_namespace"  buildid: deadbeef  ino: X
//   "/tmp/quipper_mnt.../file_in_namespace"  buildid: deadbeef  ino: X
// <path> = marked with *
// MMAP2: <pid+10>/<tid+1>, <path>, ino: X
// Reject (doesn't exist): /proc/<tid+1>/root/<path>
// Reject (doesn't exist): /proc/<pid+10>/root/<path>
// Accept (same inode): /<path>
// Expected buildid for <path>: "deadbeef"
TEST(PerfParserTest, ReadsBuildidsInMountNamespace_TriesRootFs) {
  if (!HaveCapability(CAP_SYS_ADMIN))
    return;  // Skip test.
  ScopedTempDir tmpdir("/tmp/quipper_tmp.");
  ScopedTempDir mntdir("/tmp/quipper_mnt.");
  RunInMountNamespaceThread thread(tmpdir.path(), mntdir.path());
  thread.Start();
  const pid_t pid = getpid();
  const pid_t tid = thread.tid();

  const string tmpfile = tmpdir.path() + "file_in_namespace";
  const string tmpfile_in_ns = mntdir.path() + "file_in_namespace";
  InitializeLibelf();
  testing::WriteElfWithBuildid(tmpfile, ".note.gnu.build-id",
                               "\xde\xad\xbe\xef");
  // It's a trap! If "baadf00d" is seen, we read the wrong file.
  testing::WriteElfWithBuildid(tmpfile_in_ns, ".note.gnu.build-id",
                               "\xba\xad\xf0\x0d");
  struct stat tmp_stat;
  ASSERT_EQ(stat(tmpfile.c_str(), &tmp_stat), 0);

  // Create perf.data
  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_MMAP2
  // - Process doesn't exist, but file exists in our own namespace.
  testing::ExampleMmap2Event(
      pid, pid, 0x1c1000, 0x1000, 0, tmpfile,
      testing::SampleInfo().Tid(pid+10, tid+1))
      .WithDeviceInfo(major(tmp_stat.st_dev), minor(tmp_stat.st_dev),
                      tmp_stat.st_ino)
      .WriteTo(&input);                                            // 0

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(pid))       // 1
      .WriteTo(&input);

  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.read_missing_buildids = true;
  options.sample_mapping_percentage_threshold = 0;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(1, parser.stats().num_mmap_events);
  EXPECT_EQ(1, parser.stats().num_sample_events);
  EXPECT_EQ(1, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(2, events.size());

  EXPECT_EQ(tmpfile, events[1].dso_and_offset.dso_name());
  // Finds file in root FS.
  EXPECT_EQ("deadbeef", events[1].dso_and_offset.build_id());

  thread.Join();
}

// Root task <pid>/<pid> Filesystem:
//   "/tmp/quipper_tmp.../file_in_namespace"  buildid: deadbeef  ino: X
//   "/tmp/quipper_mnt.../file_in_namespace"  buildid: baadf00d  ino: Y
// Container task <pid>/<tid> Filesystem:
//   "/tmp/quipper_tmp.../file_in_namespace"  buildid: deadbeef  ino: X
// * "/tmp/quipper_mnt.../file_in_namespace"  buildid: deadbeef  ino: X
// <path> = marked with *
// MMAP2: <pid>/<tid>, <path>, ino: X+1
// Reject (wrong inode): /proc/<tid>/root/<path>
// Reject (wrong inode): /proc/<pid>/root/<path>
// Reject (wrong inode): /<path>
// Expected buildid for <path>: ""
TEST(PerfParserTest, ReadsBuildidsInMountNamespace_TriesRootFsRejectsInode) {
  if (!HaveCapability(CAP_SYS_ADMIN))
    return;  // Skip test.
  ScopedTempDir tmpdir("/tmp/quipper_tmp.");
  ScopedTempDir mntdir("/tmp/quipper_mnt.");
  RunInMountNamespaceThread thread(tmpdir.path(), mntdir.path());
  thread.Start();
  const pid_t pid = getpid();
  const pid_t tid = thread.tid();

  const string tmpfile = tmpdir.path() + "file_in_namespace";
  const string tmpfile_in_ns = mntdir.path() + "file_in_namespace";
  InitializeLibelf();
  testing::WriteElfWithBuildid(tmpfile, ".note.gnu.build-id",
                               "\xde\xad\xbe\xef");
  // It's a trap! If "baadf00d" is seen, we read the wrong file.
  testing::WriteElfWithBuildid(tmpfile_in_ns, ".note.gnu.build-id",
                               "\xba\xad\xf0\x0d");
  struct stat tmp_stat;
  struct stat tmp_in_ns_stat;
  ASSERT_EQ(stat(tmpfile.c_str(), &tmp_stat), 0);
  ASSERT_EQ(stat(tmpfile_in_ns.c_str(), &tmp_in_ns_stat), 0);
  // inodes are often issued sequentially, so go backwards rather than forwards.
  const ino_t bad_ino = tmp_stat.st_ino - 1;
  ASSERT_NE(bad_ino, tmp_in_ns_stat.st_ino);

  // Create perf.data
  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_MMAP2
  // - Process doesn't exist, but file exists in our own namespace.
  testing::ExampleMmap2Event(
      pid, pid, 0x1c1000, 0x1000, 0, tmpfile_in_ns,
      testing::SampleInfo().Tid(pid, tid))
      .WithDeviceInfo(major(tmp_stat.st_dev), minor(tmp_stat.st_dev), bad_ino)
      .WriteTo(&input);                                            // 0

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(pid))       // 1
      .WriteTo(&input);

  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.read_missing_buildids = true;
  options.sample_mapping_percentage_threshold = 0;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(1, parser.stats().num_mmap_events);
  EXPECT_EQ(1, parser.stats().num_sample_events);
  EXPECT_EQ(1, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(2, events.size());

  EXPECT_EQ(tmpfile_in_ns, events[1].dso_and_offset.dso_name());
  // Wrong inode, so rejects all candidates.
  EXPECT_EQ("", events[1].dso_and_offset.build_id());

  thread.Join();
}

// Root task <pid>/<pid> Filesystem:
//   "/tmp/quipper_tmp.../file_in_namespace"  buildid: deadbeef  ino: X
// * "/tmp/quipper_mnt.../file_in_namespace"  buildid: baadf00d  ino: Y
// Container task <pid>/<tid> Filesystem:
//   "/tmp/quipper_tmp.../file_in_namespace"  buildid: deadbeef  ino: X
// * "/tmp/quipper_mnt.../file_in_namespace"  buildid: deadbeef  ino: X
// <path> = marked with *
// MMAP: <pid+10>/<tid+1>, <path>, ino: Not available
// Reject (not found): /proc/<tid+1>/root/<path>
// Reject (not found): /proc/<pid+10>/root/<path>
// Accept (falsely): /<path>
// Expected buildid for <path>: "baadf00d" (even though incorrect)
TEST(PerfParserTest, ReadsBuildidsInMountNamespace_TriesRootFsNoInodeToReject) {
  if (!HaveCapability(CAP_SYS_ADMIN))
    return;  // Skip test.
  ScopedTempDir tmpdir("/tmp/quipper_tmp.");
  ScopedTempDir mntdir("/tmp/quipper_mnt.");
  RunInMountNamespaceThread thread(tmpdir.path(), mntdir.path());
  thread.Start();
  const pid_t pid = getpid();
  const pid_t tid = thread.tid();

  const string tmpfile = tmpdir.path() + "file_in_namespace";
  const string tmpfile_in_ns = mntdir.path() + "file_in_namespace";
  InitializeLibelf();
  testing::WriteElfWithBuildid(tmpfile, ".note.gnu.build-id",
                               "\xde\xad\xf0\x0d");
  // It's a trap! If "baadf00d" is seen, we read the wrong file.
  testing::WriteElfWithBuildid(tmpfile_in_ns, ".note.gnu.build-id",
                               "\xba\xad\xf0\x0d");
  struct stat tmp_stat;
  ASSERT_EQ(stat(tmpfile.c_str(), &tmp_stat), 0);

  // Create perf.data
  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
  // - Process & thread don't exist, but file exists in our own namespace.
  testing::ExampleMmapEvent(
      pid, 0x1c1000, 0x1000, 0, tmpfile_in_ns,
      testing::SampleInfo().Tid(pid+10, tid+1))
      .WriteTo(&input);                                            // 0

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(pid))       // 1
      .WriteTo(&input);

  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.read_missing_buildids = true;
  options.sample_mapping_percentage_threshold = 0;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(1, parser.stats().num_mmap_events);
  EXPECT_EQ(1, parser.stats().num_sample_events);
  EXPECT_EQ(1, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(2, events.size());

  EXPECT_EQ(tmpfile_in_ns, events[1].dso_and_offset.dso_name());
  // We'll read the wrong file b/c we couldn't reject based on inode:
  EXPECT_EQ("baadf00d", events[1].dso_and_offset.build_id());

  thread.Join();
}

// Root task <pid>/<pid> Filesystem:
//   "/tmp/quipper_tmp.../file_in_namespace"  buildid: deadbeef  ino: X
// * "/tmp/quipper_mnt.../file_in_namespace"  buildid: baadf00d  ino: Y
// Container task <pid>/<tid> Filesystem:
//   "/tmp/quipper_tmp.../file_in_namespace"  buildid: deadbeef  ino: X
// * "/tmp/quipper_mnt.../file_in_namespace"  buildid: deadbeef  ino: X
// <path> = marked with *
// MMAP2(0): <pid>/<tid>, <path>, <maj+1>/<min>,  ino: X
// MMAP2(1): <pid>/<tid>, <path>, <maj>/<min+1>,  ino: X
// MMAP2(2): <pid>/<tid>, <path>, <maj>/<min>,    ino: X+1
// SAMPLE(3): <pid>/<tid>, addr in MMAP2(0)
// SAMPLE(4): <pid>/<tid>, addr in MMAP2(1)
// SAMPLE(5): <pid>/<tid>, addr in MMAP2(2)
// Expected buildid for <path>: ""
//
// TODO(dhsharp): This test runs into an odd situation: the same path is seen
// with multiple device/ino numbers. This is really a shortcoming of perf--
// it can only associate a buildid with a path. If the same path exists in
// multiple containers but refers to different files (device/inode), then
// it's hard to know what to do. Similarly, PerfParser associates a DSO name
// (path) with a single DSOInfo and device/inode info therein, although it
// tracks all threads the DSO name was seen in. This test is set up such that
// all MMAPs should be rejected, but in truth PerfParser only compares the
// device/inode of the file against the device/inode of one of the MMAPs.
// A better thing to do might be to track a
// map<tuple<maj,min,ino,path>, DSOInfo>, but even so, it will be impossible
// to store unambiguously in perf.data.
TEST(PerfParserTest, ReadsBuildidsInMountNamespace_DifferentDevOrIno) {
  if (!HaveCapability(CAP_SYS_ADMIN))
    return;  // Skip test.
  ScopedTempDir tmpdir("/tmp/quipper_tmp.");
  ScopedTempDir mntdir("/tmp/quipper_mnt.");
  RunInMountNamespaceThread thread(tmpdir.path(), mntdir.path());
  thread.Start();
  const pid_t pid = getpid();
  const pid_t tid = thread.tid();

  const string tmpfile = tmpdir.path() + "file_in_namespace";
  const string tmpfile_in_ns = mntdir.path() + "file_in_namespace";
  InitializeLibelf();
  testing::WriteElfWithBuildid(tmpfile, ".note.gnu.build-id",
                               "\xde\xad\xf0\x0d");
  // It's a trap! If "baadf00d" is seen, we read the wrong file.
  testing::WriteElfWithBuildid(tmpfile_in_ns, ".note.gnu.build-id",
                               "\xba\xad\xf0\x0d");
  struct stat tmp_stat;
  struct stat tmp_in_ns_stat;
  ASSERT_EQ(stat(tmpfile.c_str(), &tmp_stat), 0);
  ASSERT_EQ(stat(tmpfile_in_ns.c_str(), &tmp_in_ns_stat), 0);
  // inodes are often issued sequentially, so go backwards rather than forwards.
  const ino_t bad_ino = tmp_stat.st_ino - 1;
  ASSERT_NE(bad_ino, tmp_in_ns_stat.st_ino);

  // Create perf.data
  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_MMAP2
  // - Wrong major number
  testing::ExampleMmap2Event(
      pid, tid, 0x1c1000, 0x1000, 0, tmpfile_in_ns,
      testing::SampleInfo().Tid(pid, tid))
      .WithDeviceInfo(major(tmp_stat.st_dev)+1, minor(tmp_stat.st_dev),
                      tmp_stat.st_ino)
      .WriteTo(&input);                                            // 0
  // - Wrong minor number
  testing::ExampleMmap2Event(
      pid, tid, 0x1c2000, 0x1000, 0, tmpfile_in_ns,
      testing::SampleInfo().Tid(pid, tid))
      .WithDeviceInfo(major(tmp_stat.st_dev), minor(tmp_stat.st_dev)+1,
                      tmp_stat.st_ino)
      .WriteTo(&input);                                            // 1
  // - Wrong inode number
  testing::ExampleMmap2Event(
      pid, tid, 0x1c3000, 0x1000, 0, tmpfile_in_ns,
      testing::SampleInfo().Tid(pid, tid))
      .WithDeviceInfo(major(tmp_stat.st_dev), minor(tmp_stat.st_dev),
                      bad_ino)
      .WriteTo(&input);                                            // 2

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(pid, tid))  // 3
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c2000).Tid(pid, tid))  // 4
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c3000).Tid(pid, tid))  // 5
      .WriteTo(&input);

  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.read_missing_buildids = true;
  options.sample_mapping_percentage_threshold = 0;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(3, parser.stats().num_mmap_events);
  EXPECT_EQ(3, parser.stats().num_sample_events);
  EXPECT_EQ(3, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(6, events.size());

  // Buildid should not be found for any of the samples.
  for (int i : {3, 4, 5}) {
    EXPECT_EQ(tmpfile_in_ns, events[i].dso_and_offset.dso_name());
    EXPECT_EQ("", events[i].dso_and_offset.build_id());
  }

  thread.Join();
}

TEST(PerfParserTest, OverwriteBuildidIfAlreadyKnown) {
  ScopedTempDir tmpdir("/tmp/quipper_tmp.");
  const string known_file = tmpdir.path() + "buildid_already_known";
  const string known_file_to_overwrite =
      tmpdir.path() + "buildid_already_known_overwrite";
  const string unknown_file = tmpdir.path() + "buildid_not_known";
  InitializeLibelf();
  testing::WriteElfWithBuildid(known_file_to_overwrite, ".note.gnu.build-id",
                               "\xf0\x01\x57\xea");
  testing::WriteElfWithBuildid(unknown_file, ".note.gnu.build-id",
                               "\xc0\x01\xd0\x0d");

  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, known_file,
      testing::SampleInfo().Tid(1001)).WriteTo(&input);        // 0
  // becomes: 0x0000, 0x1000, 0
  testing::ExampleMmapEvent(
      1001, 0x1c2000, 0x2000, 0, known_file_to_overwrite,
      testing::SampleInfo().Tid(1001)).WriteTo(&input);        // 1
  // becomes: 0x1000, 0x2000, 0
  testing::ExampleMmapEvent(
      1001, 0x1c4000, 0x2000, 0x2000, unknown_file,
      testing::SampleInfo().Tid(1001)).WriteTo(&input);        // 2
  // becomes: 0x3000, 0x2000, 0x2000

  // PERF_RECORD_HEADER_BUILDID                                // N/A
  {
    string build_id_filename(known_file);
    build_id_filename.resize(Align<u64>(known_file.size()));  // null-pad
    const size_t event_size =
        sizeof(struct build_id_event) +
        build_id_filename.size();
    const struct build_id_event event = {
      .header = {
        .type = PERF_RECORD_HEADER_BUILD_ID,
        .misc = 0,
        .size = static_cast<u16>(event_size),
      },
      .pid = -1,
      .build_id = {0xde, 0xad, 0xbe, 0xef},
    };
    input.write(reinterpret_cast<const char*>(&event), sizeof(event));
    input.write(build_id_filename.data(), build_id_filename.size());
  }

  // PERF_RECORD_HEADER_BUILDID                                // N/A
  {
    string build_id_filename(known_file_to_overwrite);
                                                                 // null-pad
    build_id_filename.resize(Align<u64>(known_file_to_overwrite.size()));
    const size_t event_size =
        sizeof(struct build_id_event) +
        build_id_filename.size();
    const struct build_id_event event = {
      .header = {
        .type = PERF_RECORD_HEADER_BUILD_ID,
        .misc = 0,
        .size = static_cast<u16>(event_size),
      },
      .pid = -1,
      .build_id = {0xca, 0xfe, 0xba, 0xbe},
    };
    input.write(reinterpret_cast<const char*>(&event), sizeof(event));
    input.write(build_id_filename.data(), build_id_filename.size());
  }

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c100a).Tid(1001))  // 3
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c300b).Tid(1001))  // 4
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c400c).Tid(1001))  // 5
      .WriteTo(&input);

  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.read_missing_buildids = true;
  options.sample_mapping_percentage_threshold = 0;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(3, parser.stats().num_mmap_events);
  EXPECT_EQ(3, parser.stats().num_sample_events);
  EXPECT_EQ(3, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(6, events.size());

  EXPECT_EQ(known_file, events[3].dso_and_offset.dso_name());
  EXPECT_EQ("deadbeef00000000000000000000000000000000",
            events[3].dso_and_offset.build_id());
  EXPECT_EQ(known_file_to_overwrite, events[4].dso_and_offset.dso_name());
  EXPECT_EQ("f00157ea",
            events[4].dso_and_offset.build_id());
  EXPECT_EQ(unknown_file, events[5].dso_and_offset.dso_name());
  EXPECT_EQ("c001d00d", events[5].dso_and_offset.build_id());
}

TEST(PerfParserTest, OnlyReadsBuildidIfSampled) {
  ScopedTempDir tmpdir("/tmp/quipper_tmp.");
  const string unknown_file = tmpdir.path() + "buildid_not_known";
  InitializeLibelf();
  testing::WriteElfWithBuildid(unknown_file, ".note.gnu.build-id",
                               "\xc0\x01\xd0\x0d");

  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, unknown_file,
      testing::SampleInfo().Tid(1001)).WriteTo(&input);        // 0
  // becomes: 0x0000, 0x1000, 0

  // PERF_RECORD_SAMPLE
  // - Sample outside mmap
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c300a).Tid(1001))  // 1
      .WriteTo(&input);

  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.read_missing_buildids = true;
  options.sample_mapping_percentage_threshold = 0;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(1, parser.stats().num_mmap_events);
  EXPECT_EQ(1, parser.stats().num_sample_events);
  EXPECT_EQ(0, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(2, events.size());

  EXPECT_EQ("", events[1].dso_and_offset.dso_name());
  EXPECT_EQ("", events[1].dso_and_offset.build_id());

  std::map<string, string> filenames_to_build_ids;
  reader.GetFilenamesToBuildIDs(&filenames_to_build_ids);
  auto it = filenames_to_build_ids.find(unknown_file);
  EXPECT_EQ(filenames_to_build_ids.end(), it) << it->first << " "<< it->second;
}

TEST(PerfParserTest, HandlesFinishedRoundEventsAndSortsByTime) {
  // For now at least, we are ignoring PERF_RECORD_FINISHED_ROUND events.

  std::stringstream input;

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

  // data

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

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


  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent(                                // 1
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(1001).Time(12300020))
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(                                // 2
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(1001).Time(12300030))
      .WriteTo(&input);
  // PERF_RECORD_FINISHED_ROUND
  testing::FinishedRoundEvent().WriteTo(&input);                  // N/A

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent(                                // 3
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(1001).Time(12300050))
      .WriteTo(&input);
  testing::ExamplePerfSampleEvent(                                // 4
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(1001).Time(12300040))
      .WriteTo(&input);
  // PERF_RECORD_FINISHED_ROUND
  testing::FinishedRoundEvent().WriteTo(&input);                  // N/A

  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.sample_mapping_percentage_threshold = 0;
  options.sort_events_by_time = true;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(1, parser.stats().num_mmap_events);
  EXPECT_EQ(4, parser.stats().num_sample_events);
  EXPECT_EQ(4, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(5, events.size());

  EXPECT_EQ(PERF_RECORD_MMAP, events[0].event_ptr->header().type());
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[1].event_ptr->header().type());
  EXPECT_EQ(12300020, events[1].event_ptr->sample_event().sample_time_ns());
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[2].event_ptr->header().type());
  EXPECT_EQ(12300030, events[2].event_ptr->sample_event().sample_time_ns());
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[3].event_ptr->header().type());
  EXPECT_EQ(12300040, events[3].event_ptr->sample_event().sample_time_ns());
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[4].event_ptr->header().type());
  EXPECT_EQ(12300050, events[4].event_ptr->sample_event().sample_time_ns());
}

TEST(PerfParserTest, MmapCoversEntireAddressSpace) {
  std::stringstream input;

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

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

  // PERF_RECORD_MMAP, a kernel mapping that covers the whole space.
  const uint32_t kKernelMmapPid = UINT32_MAX;
  testing::ExampleMmapEvent(
      kKernelMmapPid, 0, UINT64_MAX, 0, "[kernel.kallsyms]_text",
      testing::SampleInfo().Tid(kKernelMmapPid, 0)).WriteTo(&input);

  // PERF_RECORD_MMAP, a shared object library.
  testing::ExampleMmapEvent(
      1234, 0x7f008e000000, 0x2000000, 0, "/usr/lib/libfoo.so",
      testing::SampleInfo().Tid(1234, 1234)).WriteTo(&input);

  // PERF_RECORD_SAMPLE, within library.
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x7f008e123456).Tid(1234, 1235))
      .WriteTo(&input);
  // PERF_RECORD_SAMPLE, within kernel.
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x8000819e).Tid(1234, 1235))
      .WriteTo(&input);
  // PERF_RECORD_SAMPLE, within library.
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x7f008fdeadbe).Tid(1234, 1235))
      .WriteTo(&input);
  // PERF_RECORD_SAMPLE, within kernel.
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0xffffffff8100cafe).Tid(1234, 1235))
      .WriteTo(&input);


  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.do_remap = true;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(2, parser.stats().num_mmap_events);
  EXPECT_EQ(4, parser.stats().num_sample_events);
  EXPECT_EQ(4, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(6, events.size());

  EXPECT_EQ(PERF_RECORD_MMAP, events[0].event_ptr->header().type());
  EXPECT_EQ("[kernel.kallsyms]_text",
            events[0].event_ptr->mmap_event().filename());
  EXPECT_EQ(PERF_RECORD_MMAP, events[1].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/libfoo.so",
            events[1].event_ptr->mmap_event().filename());

  // Sample from library.
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[2].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/libfoo.so", events[2].dso_and_offset.dso_name());
  EXPECT_EQ(0x123456, events[2].dso_and_offset.offset());

  // Sample from kernel.
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[3].event_ptr->header().type());
  EXPECT_EQ("[kernel.kallsyms]_text", events[3].dso_and_offset.dso_name());
  EXPECT_EQ(0x8000819e, events[3].dso_and_offset.offset());

  // Sample from library.
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[4].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/libfoo.so", events[4].dso_and_offset.dso_name());
  EXPECT_EQ(0x1deadbe, events[4].dso_and_offset.offset());

  // Sample from kernel.
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[5].event_ptr->header().type());
  EXPECT_EQ("[kernel.kallsyms]_text", events[5].dso_and_offset.dso_name());
  EXPECT_EQ(0xffffffff8100cafe, events[5].dso_and_offset.offset());
}

TEST(PerfParserTest, HugePagesMappings) {
  std::stringstream input;

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

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

  // PERF_RECORD_MMAP, a normal mapping.
  testing::ExampleMmapEvent(
      1234, 0x40000000, 0x18000, 0, "/usr/lib/libfoo.so",
      testing::SampleInfo().Tid(1234, 1234)).WriteTo(&input);

  // PERF_RECORD_SAMPLE, within library.
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x40000100).Tid(1234, 1235))
      .WriteTo(&input);

  // Split Chrome mapping #1, with a huge pages section in the middle.
  testing::ExampleMmapEvent(
      1234, 0x40018000, 0x8000, 0, "/opt/google/chrome/chrome",
      testing::SampleInfo().Tid(1234, 1234)).WriteTo(&input);
  testing::ExampleMmapEvent(
      1234, 0x40020000, 0x1e00000, 0, "//anon",
      testing::SampleInfo().Tid(1234, 1234)).WriteTo(&input);
  testing::ExampleMmapEvent(
      1234, 0x41e20000, 0x3fe0000, 0x1e08000, "/opt/google/chrome/chrome",
      testing::SampleInfo().Tid(1234, 1234)).WriteTo(&input);

  // Split Chrome mapping #2, starting with a huge pages section (no preceding
  // normal mapping).
  testing::ExampleMmapEvent(
      2345, 0x45e00000, 0x1e00000, 0, "//anon",
      testing::SampleInfo().Tid(2345, 2346)).WriteTo(&input);
  testing::ExampleMmapEvent(
      2345, 0x47c00000, 0x4000000, 0x1e00000, "/opt/google/chrome/chrome",
      testing::SampleInfo().Tid(2345, 2346)).WriteTo(&input);

  // PERF_RECORD_SAMPLE, within Chrome #1 (before huge pages mapping).
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x40018300).Tid(1234, 1235))
      .WriteTo(&input);
  // PERF_RECORD_SAMPLE, within Chrome #1 (within huge pages mapping).
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x40020400).Tid(1234, 1235))
      .WriteTo(&input);
  // PERF_RECORD_SAMPLE, within Chrome #1 (after huge pages mapping).
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x41e20500).Tid(1234, 1235))
      .WriteTo(&input);

  // PERF_RECORD_SAMPLE, within library.
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x40000700).Tid(1234, 1235))
      .WriteTo(&input);

  // PERF_RECORD_SAMPLE, within Chrome #2 (within huge pages mapping).
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x45e01300).Tid(2345, 2346))
      .WriteTo(&input);
  // PERF_RECORD_SAMPLE, within Chrome #2 (after huge pages mapping).
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x45e02f00).Tid(2345, 2346))
      .WriteTo(&input);

  //
  // Parse input.
  //

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

  PerfParserOptions options;
  options.combine_huge_pages_mappings = true;
  PerfParser parser(&reader, options);
  EXPECT_TRUE(parser.ParseRawEvents());

  EXPECT_EQ(3, parser.stats().num_mmap_events);
  EXPECT_EQ(7, parser.stats().num_sample_events);
  EXPECT_EQ(7, parser.stats().num_sample_events_mapped);

  const std::vector<ParsedEvent>& events = parser.parsed_events();
  ASSERT_EQ(10, events.size());

  EXPECT_EQ(PERF_RECORD_MMAP, events[0].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/libfoo.so", events[0].event_ptr->mmap_event().filename());
  EXPECT_EQ(0x40000000, events[0].event_ptr->mmap_event().start());
  EXPECT_EQ(0x18000, events[0].event_ptr->mmap_event().len());
  EXPECT_EQ(0x0, events[0].event_ptr->mmap_event().pgoff());

  // Sample from library.
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[1].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/libfoo.so", events[1].dso_and_offset.dso_name());
  EXPECT_EQ(0x100, events[1].dso_and_offset.offset());

  // The split Chrome mappings should have been combined.
  EXPECT_EQ(PERF_RECORD_MMAP, events[2].event_ptr->header().type());
  EXPECT_EQ("/opt/google/chrome/chrome",
            events[2].event_ptr->mmap_event().filename());
  EXPECT_EQ(0x40018000, events[2].event_ptr->mmap_event().start());
  EXPECT_EQ(0x5de8000, events[2].event_ptr->mmap_event().len());
  EXPECT_EQ(0x0, events[2].event_ptr->mmap_event().pgoff());

  EXPECT_EQ(PERF_RECORD_MMAP, events[3].event_ptr->header().type());
  EXPECT_EQ("/opt/google/chrome/chrome",
            events[3].event_ptr->mmap_event().filename());
  EXPECT_EQ(0x45e00000, events[3].event_ptr->mmap_event().start());
  EXPECT_EQ(0x5e00000, events[3].event_ptr->mmap_event().len());
  EXPECT_EQ(0x0, events[3].event_ptr->mmap_event().pgoff());

  // Sample from Chrome (before huge pages mapping).
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[4].event_ptr->header().type());
  EXPECT_EQ("/opt/google/chrome/chrome", events[4].dso_and_offset.dso_name());
  EXPECT_EQ(0x300, events[4].dso_and_offset.offset());

  // Sample from Chrome (within huge pages mapping).
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[5].event_ptr->header().type());
  EXPECT_EQ("/opt/google/chrome/chrome", events[5].dso_and_offset.dso_name());
  EXPECT_EQ(0x8400, events[5].dso_and_offset.offset());

  // Sample from Chrome (after huge pages mapping).
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[6].event_ptr->header().type());
  EXPECT_EQ("/opt/google/chrome/chrome", events[6].dso_and_offset.dso_name());
  EXPECT_EQ(0x1e08500, events[6].dso_and_offset.offset());

  // Sample from library.
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[7].event_ptr->header().type());
  EXPECT_EQ("/usr/lib/libfoo.so", events[7].dso_and_offset.dso_name());
  EXPECT_EQ(0x700, events[7].dso_and_offset.offset());

  // Sample from Chrome #2 (within huge pages mapping).
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[8].event_ptr->header().type());
  EXPECT_EQ("/opt/google/chrome/chrome", events[8].dso_and_offset.dso_name());
  EXPECT_EQ(0x1300, events[8].dso_and_offset.offset());

  // Sample from Chrome #2 (after huge pages mapping).
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[9].event_ptr->header().type());
  EXPECT_EQ("/opt/google/chrome/chrome", events[9].dso_and_offset.dso_name());
  EXPECT_EQ(0x2f00, events[9].dso_and_offset.offset());
}

}  // namespace quipper
