// 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 <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/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"

namespace quipper {

namespace {

void CheckChronologicalOrderOfEvents(const PerfReader& reader,
                                     const std::vector<ParsedEvent*>& events) {
  // Here a valid PerfReader is needed to read the sample info because
  // ReadPerfSampleInfo() uses the |sample_type_| member of PerfReader to
  // determine which sample info fields are present.
  struct perf_sample sample_info;
  CHECK(reader.ReadPerfSampleInfo(*events[0]->raw_event, &sample_info));
  uint64_t prev_time = sample_info.time;
  for (unsigned int i = 1; i < events.size(); ++i) {
    struct perf_sample sample_info;
    CHECK(reader.ReadPerfSampleInfo(*events[i]->raw_event, &sample_info));
    CHECK_LE(prev_time, sample_info.time);
    prev_time = sample_info.time;
  }
}

void ReadFileAndCheckInternals(const string& input_perf_data,
                               PerfParser* parser) {
  PerfParser::Options options;
  options.do_remap = true;
  parser->set_options(options);
  ASSERT_TRUE(parser->ReadFile(input_perf_data));
  parser->ParseRawEvents();

  // 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_TRUE(stats.did_remap);
}

}  // 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, Test1Cycle) {
  ScopedTempDir output_dir;
  ASSERT_FALSE(output_dir.path().empty());
  string output_path = output_dir.path();

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

    PerfParser parser(GetTestOptions());
    ASSERT_TRUE(parser.ReadFile(input_perf_data));
    parser.ParseRawEvents();

    CHECK_GT(parser.GetEventsSortedByTime().size(), 0U);
    CheckChronologicalOrderOfEvents(parser, parser.GetEventsSortedByTime());

    // 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 output_perf_data = output_path + test_file + ".parse.out";
    ASSERT_TRUE(parser.WriteFile(output_perf_data));

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

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

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

    PerfParser parser(GetTestOptions());
    ReadFileAndCheckInternals(input_perf_data, &parser);

    string output_perf_data = output_path + test_file + ".parse.remap.out";
    ASSERT_TRUE(parser.WriteFile(output_perf_data));

    // Remapped addresses should not match the original addresses.
    EXPECT_TRUE(CheckPerfDataAgainstBaseline(output_perf_data));

    PerfParser remap_parser(GetTestOptions());
    ReadFileAndCheckInternals(output_perf_data, &remap_parser);
    string output_perf_data2 = output_path + test_file + ".parse.remap2.out";
    ASSERT_TRUE(remap_parser.WriteFile(output_perf_data2));

    // Remapping again should produce the same addresses.
    EXPECT_TRUE(CheckPerfDataAgainstBaseline(output_perf_data2));
    EXPECT_TRUE(ComparePerfBuildIDLists(output_perf_data, output_perf_data2));
  }
}

TEST(PerfParserTest, TestPipedProcessing) {
  for (const char* test_file : perf_test_files::kPerfPipedDataFiles) {
    string input_perf_data = GetTestInputFilePath(test_file);
    LOG(INFO) << "Testing " << input_perf_data;

    PerfParser parser(GetTestOptions());
    ReadFileAndCheckInternals(input_perf_data, &parser);
  }
}

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.
  //

  PerfParser::Options options;
  options.sample_mapping_percentage_threshold = 0;
  options.do_remap = true;
  PerfParser parser(options);
  EXPECT_TRUE(parser.ReadFromString(input.str()));
  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].raw_event->header.type);
  EXPECT_EQ("/usr/lib/foo.so", string(events[0].raw_event->mmap.filename));
  EXPECT_EQ(0x0000, events[0].raw_event->mmap.start);
  EXPECT_EQ(0x1000, events[0].raw_event->mmap.len);
  EXPECT_EQ(0, events[0].raw_event->mmap.pgoff);

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

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

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

  // SAMPLEs

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[4].raw_event->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].raw_event->sample.array[0]);

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[5].raw_event->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].raw_event->sample.array[0]);

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[6].raw_event->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].raw_event->sample.array[0]);

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[7].raw_event->header.type);
  EXPECT_EQ(0x00000000001c2bad, events[7].raw_event->sample.array[0]);

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[8].raw_event->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].raw_event->sample.array[0]);

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[9].raw_event->header.type);
  EXPECT_EQ(0x00000000002c5bad, events[9].raw_event->sample.array[0]);

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[10].raw_event->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].raw_event->sample.array[0]);

  // not mapped yet:
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[11].raw_event->header.type);
  EXPECT_EQ(0x00000000002c400b, events[11].raw_event->sample.array[0]);

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

  EXPECT_EQ(PERF_RECORD_SAMPLE, events[13].raw_event->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].raw_event->sample.array[0]);
}

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.
  //

  PerfParser::Options options;
  options.sample_mapping_percentage_threshold = 0;
  PerfParser parser(options);
  EXPECT_TRUE(parser.ReadFromString(input.str()));
  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());
}

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.
  //

  PerfParser::Options options;
  options.sample_mapping_percentage_threshold = 0;
  options.do_remap = true;
  PerfParser parser(options);
  EXPECT_TRUE(parser.ReadFromString(input.str()));
  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());

  struct perf_sample sample;

  EXPECT_EQ(PERF_RECORD_MMAP, events[0].raw_event->header.type);
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[1].raw_event->header.type);
  parser.ReadPerfSampleInfo(*events[1].raw_event, &sample);
  EXPECT_EQ(12300020, sample.time);
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[2].raw_event->header.type);
  parser.ReadPerfSampleInfo(*events[2].raw_event, &sample);
  EXPECT_EQ(12300030, sample.time);
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[3].raw_event->header.type);
  parser.ReadPerfSampleInfo(*events[3].raw_event, &sample);
  EXPECT_EQ(12300050, sample.time);
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[4].raw_event->header.type);
  parser.ReadPerfSampleInfo(*events[4].raw_event, &sample);
  EXPECT_EQ(12300040, sample.time);

  const std::vector<ParsedEvent*>& sorted_events =
      parser.GetEventsSortedByTime();
  ASSERT_EQ(5, sorted_events.size());

  EXPECT_EQ(PERF_RECORD_MMAP, sorted_events[0]->raw_event->header.type);
  EXPECT_EQ(PERF_RECORD_SAMPLE, sorted_events[1]->raw_event->header.type);
  parser.ReadPerfSampleInfo(*sorted_events[1]->raw_event, &sample);
  EXPECT_EQ(12300020, sample.time);
  EXPECT_EQ(PERF_RECORD_SAMPLE, sorted_events[2]->raw_event->header.type);
  parser.ReadPerfSampleInfo(*sorted_events[2]->raw_event, &sample);
  EXPECT_EQ(12300030, sample.time);
  EXPECT_EQ(PERF_RECORD_SAMPLE, sorted_events[3]->raw_event->header.type);
  parser.ReadPerfSampleInfo(*sorted_events[3]->raw_event, &sample);
  EXPECT_EQ(12300040, sample.time);
  EXPECT_EQ(PERF_RECORD_SAMPLE, sorted_events[4]->raw_event->header.type);
  parser.ReadPerfSampleInfo(*sorted_events[4]->raw_event, &sample);
  EXPECT_EQ(12300050, sample.time);
}

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.
  //

  PerfParser::Options options;
  options.do_remap = true;
  PerfParser parser(options);
  EXPECT_TRUE(parser.ReadFromString(input.str()));
  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].raw_event->header.type);
  EXPECT_EQ(string("[kernel.kallsyms]_text"),
            events[0].raw_event->mmap.filename);
  EXPECT_EQ(PERF_RECORD_MMAP, events[1].raw_event->header.type);
  EXPECT_EQ(string("/usr/lib/libfoo.so"), events[1].raw_event->mmap.filename);

  // Sample from library.
  EXPECT_EQ(PERF_RECORD_SAMPLE, events[2].raw_event->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].raw_event->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].raw_event->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].raw_event->header.type);
  EXPECT_EQ("[kernel.kallsyms]_text", events[5].dso_and_offset.dso_name());
  EXPECT_EQ(0xffffffff8100cafe, events[5].dso_and_offset.offset());
}

}  // namespace quipper

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