// 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 "compat/string.h"
#include "compat/test.h"
#include "compat/thread.h"
#include "dso_test_utils.h"
#include "perf_data_utils.h"
#include "perf_parser.h"
#include "perf_reader.h"
#include "perf_serializer.h"
#include "perf_test_files.h"
#include "scoped_temp_path.h"
#include "test_perf_data.h"
#include "test_utils.h"

namespace quipper {

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

namespace {

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

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

void CopyActualEvents(const std::vector<ParsedEvent> &events,
                      PerfDataProto *out) {
  for (const auto &ev : events) {
    if (ev.event_ptr == nullptr) {
      continue;
    }
    *out->add_events() = *ev.event_ptr;
  }
}

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

class PerfDataFiles : public ::testing::TestWithParam<const char *> {};
class PerfPipedDataFiles : public ::testing::TestWithParam<const char *> {};

TEST_P(PerfDataFiles, NormalPerfData) {
  ScopedTempDir output_dir;
  ASSERT_FALSE(output_dir.path().empty());
  string output_path = output_dir.path();

  int seed = 0;
  string test_file = GetParam();
  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_P(PerfPipedDataFiles, PipedModePerfData) {
  ScopedTempDir output_dir;
  ASSERT_FALSE(output_dir.path().empty());
  string output_path = output_dir.path();

  int seed = 0;
  const string test_file = GetParam();
  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;
}

INSTANTIATE_TEST_CASE_P(
    PerfParserTest, PerfDataFiles,
    ::testing::ValuesIn(perf_test_files::GetPerfDataFiles()));
INSTANTIATE_TEST_CASE_P(
    PerfParserTest, PerfPipedDataFiles,
    ::testing::ValuesIn(perf_test_files::GetPerfPipedDataFiles()));

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))
      .WriteTo(&input);  // 4
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c100a).Tid(1001))
      .WriteTo(&input);  // 5
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c3fff).Tid(1001))
      .WriteTo(&input);  // 6
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c2bad).Tid(1001))
      .WriteTo(&input);  // 7 (not mapped)
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000002c100a).Tid(1002))
      .WriteTo(&input);  // 8
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000002c5bad).Tid(1002))
      .WriteTo(&input);  // 9 (not mapped)
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000002c300b).Tid(1002))
      .WriteTo(&input);  // 10

  // not mapped yet:
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000002c400b).Tid(1002))
      .WriteTo(&input);  // 11
  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))
      .WriteTo(&input);  // 13

  //
  // 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))
      .WriteTo(&input);  // 2
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c300a).Tid(1001))
      .WriteTo(&input);  // 3

  //
  // 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_(std::move(tmpdir)),
        mntdir_(std::move(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))
      .WriteTo(&input);  // 2

  //
  // 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_(std::move(tmpdir)), mntdir_(std::move(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))
      .WriteTo(&input);  // 1

  //
  // 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))
      .WriteTo(&input);  // 1

  //
  // 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))
      .WriteTo(&input);  // 1

  //
  // 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))
      .WriteTo(&input);  // 1

  //
  // 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>: ""
//
// 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))
      .WriteTo(&input);  // 3
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c2000).Tid(pid, tid))
      .WriteTo(&input);  // 4
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c3000).Tid(pid, tid))
      .WriteTo(&input);  // 5

  //
  // 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))
      .WriteTo(&input);  // 3
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c300b).Tid(1001))
      .WriteTo(&input);  // 4
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c400c).Tid(1001))
      .WriteTo(&input);  // 5

  //
  // 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))
      .WriteTo(&input);  // 1

  //
  // 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(
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(1001).Time(12300020))
      .WriteTo(&input);  // 1
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(1001).Time(12300030))
      .WriteTo(&input);  // 2
  // PERF_RECORD_FINISHED_ROUND
  testing::FinishedRoundEvent().WriteTo(&input);  // N/A

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(1001).Time(12300050))
      .WriteTo(&input);  // 3
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo().Ip(0x00000000001c1000).Tid(1001).Time(12300040))
      .WriteTo(&input);  // 4
  // 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, 0x1e8000, 0,
                            "/opt/google/chrome/chrome",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x40200000, 0x1c00000, 0, "//anon",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x41e00000, 0x4000000, 0x1de8000,
                            "/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.deduce_huge_page_mappings = true;
  options.combine_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());
}

TEST(PerfParserTest, Regression62446346) {
  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 infers the filename is "file", but at offset 0 for
  // hugepage-backed, anonymous mappings.
  //
  // vaddr start   - vaddr end     vaddr-size    elf-offset
  // [0x55a685bfb000-55a685dfb000) (0x200000)   @ 0]:          file
  // [0x55a685dfb000-55a687c00000) (0x1e05000)  @ 0x200000]:   file
  // [0x55a687c00000-55a6a5200000) (0x1d600000) @ 0]:          file
  // [0x55a6a5200000-55a6a6400000) (0x1200000)  @ 0x1f605000]: file
  // [0x55a6a6400000-55a6a6600000) (0x200000)   @ 0]:          file
  // [0x55a6a6600000-55a6a8800000) (0x2200000)  @ 0x20a05000]: file
  // [0x55a6a8800000-55a6a8a00000) (0x200000)   @ 0]:          file
  // [0x55a6a8a00000-55a6a90ca000) (0x6ca000)   @ 0x22e05000]: file
  // [0x55a6a90ca000-55a6a90cb000) (0x1000)     @ 0x234cf000]: file
  testing::ExampleMmapEvent(1234, 0x55a685bfb000, 0x200000, 0, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55a685dfb000, 0x1e05000, 0x200000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55a687c00000, 0x1d600000, 0, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55a6a5200000, 0x1200000, 0x1f605000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55a6a6400000, 0x200000, 0, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55a6a6600000, 0x2200000, 0x20a05000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55a6a8800000, 0x200000, 0, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55a6a8a00000, 0x6ca000, 0x22e05000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55a6a90ca000, 0x1000, 0x234cf000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);

  //
  // Parse input.
  //

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

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

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

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

  {
    PerfDataProto expected;
    {
      auto *ev = expected.add_events();
      ev->mutable_header()->set_type(PERF_RECORD_MMAP);
      ev->mutable_mmap_event()->set_filename("file");
      ev->mutable_mmap_event()->set_start(0x55a685bfb000);
      ev->mutable_mmap_event()->set_len(0x234d0000);
      ev->mutable_mmap_event()->set_pgoff(0x0);
    }

    PerfDataProto actual;
    for (const auto &ev : events) {
      if (ev.event_ptr == nullptr) {
        continue;
      }

      *actual.add_events() = *ev.event_ptr;
    }

    EXPECT_TRUE(PartiallyEqualsProto(actual, expected));
  }
  ASSERT_EQ(1, events.size());

  // Verify the header().size() entry is large enough to deserialize/serialize.
  for (const auto &ev : events) {
    malloced_unique_ptr<event_t> e(
        CallocMemoryForEvent(ev.event_ptr->header().size()));

    PerfSerializer serializer;
    ASSERT_TRUE(
        serializer.DeserializeMMapEvent(ev.event_ptr->mmap_event(), e.get()));

    PerfDataProto_MMapEvent roundtrip;
    ASSERT_TRUE(serializer.SerializeMMapEvent(*e, &roundtrip));
    // sample_info does not roundtrip through an event_t.
    EXPECT_TRUE(PartiallyEqualsProto(ev.event_ptr->mmap_event(), roundtrip));
  }
}

TEST(PerfParserTest, Regression62446346_Perf3_12_0_11) {
  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 infers the filename is "file", but at offset 0 for
  // hugepage-backed, anonymous mappings.
  //
  // vaddr start   - vaddr end     vaddr-size    elf-offset
  // [0x55bd43879000-0x55bd45000000) (0x 1787000) @ 0x       0]: file
  // [0x55bd45000000-0x55bd58c00000) (0x13c00000) @ 0x       0]: file
  // [0x55bd58c00000-0x55bd59800000) (0x  c00000) @ 0x15387000]: file
  // [0x55bd59800000-0x55bd59a00000) (0x  200000) @ 0x       0]: file
  // [0x55bd59a00000-0x55bd5b600000) (0x 1c00000) @ 0x16187000]: file
  // [0x55bd5b600000-0x55bd5b800000) (0x  200000) @ 0x       0]: file
  // [0x55bd5b800000-0x55bd5bcb5000) (0x  4b5000) @ 0x17f87000]: file

  testing::ExampleMmapEvent(1234, 0x55bd43879000, 0x1787000, 0, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55bd45000000, 0x13c00000, 0, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55bd58c00000, 0xc00000, 0x15387000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55bd59800000, 0x200000, 0, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55bd59a00000, 0x1c00000, 0x16187000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55bd5b600000, 0x200000, 0, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55bd5b800000, 0x4b5000, 0x17f87000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);

  //
  // Parse input.
  //

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

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

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

  PerfDataProto expected;
  {
    auto *ev = expected.add_events();
    ev->mutable_header()->set_type(PERF_RECORD_MMAP);
    ev->mutable_mmap_event()->set_filename("file");
    ev->mutable_mmap_event()->set_start(0x55bd43879000);
    ev->mutable_mmap_event()->set_len(0x55bd5bcb5000 - 0x55bd43879000);
    ev->mutable_mmap_event()->set_pgoff(0x0);
  }

  PerfDataProto actual;
  CopyActualEvents(parser.parsed_events(), &actual);
  EXPECT_TRUE(PartiallyEqualsProto(actual, expected));
  ASSERT_EQ(1, parser.parsed_events().size());
}

TEST(PerfParserTest, Regression62446346_Perf3_12_0_14) {
  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 infers the filename is "file", but at offset 0 for
  // hugepage-backed, anonymous mappings.
  //
  // vaddr start   - vaddr end     vaddr-size    elf-offset
  // [0x55bd43879000-0x55bd45000000) (0x 1787000) @ 0x       0]: file
  // [0x55bd45000000-0x55bd58c00000) (0x13c00000) @ 0x 1787000]: file
  // [0x55bd58c00000-0x55bd59800000) (0x  c00000) @ 0x15387000]: file
  // [0x55bd59800000-0x55bd59a00000) (0x  200000) @ 0x15f87000]: file
  // [0x55bd59a00000-0x55bd5b600000) (0x 1c00000) @ 0x16187000]: file
  // [0x55bd5b600000-0x55bd5b800000) (0x  200000) @ 0x17d87000]: file
  // [0x55bd5b800000-0x55bd5bcb5000) (0x  4b5000) @ 0x17f87000]: file

  testing::ExampleMmapEvent(1234, 0x55bd43879000, 0x1787000, 0, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55bd45000000, 0x13c00000, 0x1787000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55bd58c00000, 0xc00000, 0x15387000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55bd59800000, 0x200000, 0x15f87000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55bd59a00000, 0x1c00000, 0x16187000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55bd5b600000, 0x200000, 0x17d87000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x55bd5b800000, 0x4b5000, 0x17f87000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);

  //
  // Parse input.
  //

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

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

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

  PerfDataProto expected;
  {
    auto *ev = expected.add_events();
    ev->mutable_header()->set_type(PERF_RECORD_MMAP);
    ev->mutable_mmap_event()->set_filename("file");
    ev->mutable_mmap_event()->set_start(0x55bd43879000);
    ev->mutable_mmap_event()->set_len(0x55bd5bcb5000 - 0x55bd43879000);
    ev->mutable_mmap_event()->set_pgoff(0x0);
  }

  PerfDataProto actual;
  CopyActualEvents(parser.parsed_events(), &actual);
  EXPECT_TRUE(PartiallyEqualsProto(actual, expected));
  EXPECT_EQ(1, parser.parsed_events().size());
}

TEST(PerfParserTest, DiscontiguousMappings) {
  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);

  // vaddr start   - vaddr end     vaddr-size    elf-offset
  // [0x7f489000-0x80200000) (0xd77000)   @ 0]:          file
  // [0x80200000-0x80400000) (0x200000)   @ 0]:          file
  // [0x80400000-0x80474000) (0x47000)    @ 0x1a00000]:  file
  testing::ExampleMmapEvent(1234, 0x7f489000, 0xd77000, 0, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x80200000, 0x200000, 0, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);
  testing::ExampleMmapEvent(1234, 0x80400000, 0x47000, 0x1a00000, "file",
                            testing::SampleInfo().Tid(1234, 1234))
      .WriteTo(&input);

  //
  // Parse input.
  //

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

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

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

  // The first two mappings should not combine, since we cannot know if the
  // middle one follows the first, or preceeds the last in the binary.
  PerfDataProto expected;
  {
    auto *ev = expected.add_events();
    ev->mutable_header()->set_type(PERF_RECORD_MMAP);
    ev->mutable_mmap_event()->set_filename("file");
    ev->mutable_mmap_event()->set_start(0x7f489000);
    ev->mutable_mmap_event()->set_len(0xd77000);
    ev->mutable_mmap_event()->set_pgoff(0x0);
  }
  {
    auto *ev = expected.add_events();
    ev->mutable_header()->set_type(PERF_RECORD_MMAP);
    ev->mutable_mmap_event()->set_filename("file");
    ev->mutable_mmap_event()->set_start(0x80200000);
    ev->mutable_mmap_event()->set_len(0x200000);
    ev->mutable_mmap_event()->set_pgoff(0x0);
  }
  {
    auto *ev = expected.add_events();
    ev->mutable_header()->set_type(PERF_RECORD_MMAP);
    ev->mutable_mmap_event()->set_filename("file");
    ev->mutable_mmap_event()->set_start(0x80400000);
    ev->mutable_mmap_event()->set_len(0x47000);
    ev->mutable_mmap_event()->set_pgoff(0x1a00000);
  }

  PerfDataProto actual;
  CopyActualEvents(parser.parsed_events(), &actual);

  EXPECT_TRUE(PartiallyEqualsProto(actual, expected));
  EXPECT_EQ(3, parser.parsed_events().size());
}
}  // namespace quipper
