// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <byteswap.h>

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

namespace quipper {

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

TEST(PerfReaderTest, PipedData_IncompleteEventHeader) {
  std::stringstream input;

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

  // data

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

  // PERF_RECORD_HEADER_EVENT_TYPE
  const struct event_type_event event_type = {
    .header = {
      .type = PERF_RECORD_HEADER_EVENT_TYPE,
      .misc = 0,
      .size = sizeof(struct event_type_event),
    },
    .event_type = {
      /*event_id*/ 123,
      /*name*/ "cycles",
    },
  };
  input.write(reinterpret_cast<const char*>(&event_type), sizeof(event_type));

  // Incomplete data at the end:
  input << string(sizeof(struct perf_event_header) - 1, '\0');

  //
  // Parse input.
  //

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

  // Make sure the attr was recorded properly.
  ASSERT_EQ(1, pr.attrs().size());
  EXPECT_EQ(123, pr.attrs().Get(0).attr().config());
  ASSERT_EQ(1, pr.event_types().size());
  EXPECT_EQ("cycles", pr.event_types().Get(0).name());

  // Make sure metadata mask was set to indicate EVENT_TYPE was upgraded
  // to EVENT_DESC.
  EXPECT_EQ((1 << HEADER_EVENT_DESC), pr.metadata_mask());
}

TEST(PerfReaderTest, PipedData_IncompleteEventData) {
  std::stringstream input;

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

  // data

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

  // PERF_RECORD_HEADER_EVENT_TYPE
  const struct event_type_event event_type = {
    .header = {
      .type = PERF_RECORD_HEADER_EVENT_TYPE,
      .misc = 0,
      .size = sizeof(struct event_type_event),
    },
    .event_type = {
      /*event_id*/ 456,
      /*name*/ "instructions",
    },
  };
  input.write(reinterpret_cast<const char*>(&event_type), sizeof(event_type));

  // Incomplete data at the end:
  // Header:
  const struct perf_event_header incomplete_event_header = {
    .type = PERF_RECORD_SAMPLE,
    .misc = 0,
    .size = sizeof(perf_event_header) + 10,
  };
  input.write(reinterpret_cast<const char*>(&incomplete_event_header),
              sizeof(incomplete_event_header));
  // Incomplete event:
  input << string(3, '\0');

  //
  // Parse input.
  //

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

  // Make sure the attr was recorded properly.
  ASSERT_EQ(1, pr.attrs().size());
  EXPECT_EQ(456, pr.attrs().Get(0).attr().config());
  ASSERT_EQ(1, pr.event_types().size());
  EXPECT_EQ("instructions", pr.event_types().Get(0).name());

  // Make sure metadata mask was set to indicate EVENT_TYPE was upgraded
  // to EVENT_DESC.
  EXPECT_EQ((1 << HEADER_EVENT_DESC), pr.metadata_mask());
}

TEST(PerfReaderTest, CorruptedFiles) {
  for (const char* test_file :
       perf_test_files::GetCorruptedPerfPipedDataFiles()) {
    string input_perf_data = GetTestInputFilePath(test_file);
    LOG(INFO) << "Testing " << input_perf_data;
    ASSERT_TRUE(FileExists(input_perf_data)) << "Test file does not exist!";
    PerfReader pr;
    ASSERT_FALSE(pr.ReadFile(input_perf_data));
  }
}

TEST(PerfReaderTest, ReadsAndWritesTraceMetadata) {
  std::stringstream input;

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

  // header
  testing::ExamplePerfDataFileHeader file_header(1 << HEADER_TRACING_DATA);
  file_header
      .WithAttrCount(1)
      .WithDataSize(data_size);
  file_header.WriteTo(&input);
  const perf_file_header &header = file_header.header();

  // attrs
  CHECK_EQ(header.attrs.offset, static_cast<u64>(input.tellp()));
  testing::ExamplePerfFileAttr_Tracepoint(73).WriteTo(&input);

  // data
  ASSERT_EQ(header.data.offset, static_cast<u64>(input.tellp()));
  testing::ExamplePerfSampleEvent_Tracepoint().WriteTo(&input);
  ASSERT_EQ(file_header.data_end(), input.tellp());

  // metadata

  const unsigned int metadata_count = 1;

  // HEADER_TRACING_DATA
  testing::ExampleTracingMetadata tracing_metadata(
      file_header.data_end() + metadata_count*sizeof(perf_file_section));

  // write metadata index entries
  tracing_metadata.index_entry().WriteTo(&input);
  // write metadata
  tracing_metadata.data().WriteTo(&input);

  //
  // Parse input.
  //

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

  EXPECT_EQ(tracing_metadata.data().value(), pr.tracing_data());

  // Write it out and read it in again, it should still be good:
  std::vector<char> output_perf_data;
  EXPECT_TRUE(pr.WriteToVector(&output_perf_data));
  EXPECT_TRUE(pr.ReadFromVector(output_perf_data));
  EXPECT_EQ(tracing_metadata.data().value(), pr.tracing_data());
}

TEST(PerfReaderTest, ReadsTracingMetadataEvent) {
  std::stringstream input;

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

  // data

  const char raw_data[] = "\x17\x08\x44tracing0.5BLAHBLAHBLAH....";
  const string trace_metadata(raw_data, sizeof(raw_data)-1);

  const tracing_data_event trace_event = {
    .header = {
      .type = PERF_RECORD_HEADER_TRACING_DATA,
      .misc = 0,
      .size = sizeof(tracing_data_event),
    },
    .size = static_cast<u32>(trace_metadata.size()),
  };

  input.write(reinterpret_cast<const char*>(&trace_event), sizeof(trace_event));
  input.write(trace_metadata.data(), trace_metadata.size());

  //
  // Parse input.
  //

  PerfReader pr;
  ASSERT_TRUE(pr.ReadFromString(input.str()));
  EXPECT_EQ(trace_metadata, pr.tracing_data());

  // Write it out and read it in again, tracing_data() should still be correct.
  // NB: It does not get written as an event, but in a metadata section.
  std::vector<char> output_perf_data;
  EXPECT_TRUE(pr.WriteToVector(&output_perf_data));
  EXPECT_TRUE(pr.ReadFromVector(output_perf_data));
  EXPECT_EQ(trace_metadata, pr.tracing_data());
}

// Regression test for http://crbug.com/484393
TEST(PerfReaderTest, BranchStackMetadataIndexHasZeroSize) {
  std::stringstream input;

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

  // header
  testing::ExamplePerfDataFileHeader file_header(1 << HEADER_BRANCH_STACK);
  file_header
      .WithAttrCount(1)
      .WithDataSize(data_size);
  file_header.WriteTo(&input);
  const perf_file_header &header = file_header.header();

  // attrs
  CHECK_EQ(header.attrs.offset, static_cast<u64>(input.tellp()));
  testing::ExamplePerfFileAttr_Hardware(
      PERF_SAMPLE_BRANCH_STACK, false /*sample_id_all*/).WriteTo(&input);

  // data
  ASSERT_EQ(header.data.offset, static_cast<u64>(input.tellp()));
  testing::ExamplePerfSampleEvent_BranchStack().WriteTo(&input);
  ASSERT_EQ(file_header.data_end(), input.tellp());

  // metadata

  // HEADER_BRANCH_STACK
  const perf_file_section branch_stack_index = {
    .offset = file_header.data_end_offset(),
    .size = 0,
  };
  input.write(reinterpret_cast<const char*>(&branch_stack_index),
              sizeof(branch_stack_index));

  //
  // Parse input.
  //

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

  // Write it out again.
  // Initialize the buffer to a non-zero sentinel value so that the bytes
  // we are checking were written with zero must have been written.
  const size_t max_predicted_written_size = 1024;
  std::vector<char> output_perf_data(max_predicted_written_size, '\xaa');
  EXPECT_TRUE(pr.WriteToVector(&output_perf_data));
  EXPECT_LE(output_perf_data.size(), max_predicted_written_size)
      << "Bad prediction for written size";

  // Specifically check that the metadata index has zero in the size.
  const auto *output_header =
      reinterpret_cast<struct perf_file_header*>(output_perf_data.data());
  EXPECT_EQ(1 << HEADER_BRANCH_STACK, output_header->adds_features[0])
      << "Expected just a HEADER_BRANCH_STACK feature";
  const size_t metadata_offset =
      output_header->data.offset + output_header->data.size;
  const auto *output_feature_index =
      reinterpret_cast<struct perf_file_section*>(
          output_perf_data.data() + metadata_offset);
  EXPECT_EQ(0, output_feature_index[0].size)
      << "Regression: Expected zero size for the HEADER_BRANCH_STACK feature "
      << "metadata index";
}

// Regression test for http://crbug.com/427767
TEST(PerfReaderTest, CorrectlyReadsPerfEventAttrSize) {
  std::stringstream input;

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

  // data

  struct old_perf_event_attr {
    __u32 type;
    __u32 size;
    __u64 config;
    // union {
            __u64 sample_period;
    //      __u64 sample_freq;
    // };
    __u64 sample_type;
    __u64 read_format;
    // Skip the rest of the fields from perf_event_attr to simulate an
    // older, smaller version of the struct.
  };

  struct old_attr_event {
    struct perf_event_header header;
    struct old_perf_event_attr attr;
    u64 id[];
  };


  const old_attr_event attr = {
    .header = {
      .type = PERF_RECORD_HEADER_ATTR,
      .misc = 0,
      // A count of 8 ids is carefully selected to make the event exceed
      // 96 bytes (sizeof(perf_event_attr)) so that the test fails instead of
      // crashes with the old code.
      .size = sizeof(old_attr_event) + 8*sizeof(u64),
    },
    .attr = {
      .type = 0,
      .size = sizeof(old_perf_event_attr),
      .config = 0,
      .sample_period = 10000001,
      .sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME |
                     PERF_SAMPLE_ID | PERF_SAMPLE_CPU,
      .read_format = PERF_FORMAT_ID,
    },
  };

  input.write(reinterpret_cast<const char*>(&attr), sizeof(attr));
  for (u64 id : {301, 302, 303, 304, 305, 306, 307, 308})
    input.write(reinterpret_cast<const char*>(&id), sizeof(id));

  // Add some sample events so that there's something to over-read.
  const sample_event sample = {
    .header = {
      .type = PERF_RECORD_SAMPLE,
      .misc = 0,
      .size = sizeof(perf_event_header) + 5*sizeof(u64),
    }
  };
  // We don't care about the contents of the SAMPLE events, except for the ID,
  // which is needed to determine the attr for reading sample info.
  const u64 sample_event_array[] = {
    0,                                     // IP
    0,                                     // TID
    0,                                     // TIME
    308,                                   // ID
    0,                                     // CPU
  };

  for (int i = 0; i < 20; i++) {
    input.write(reinterpret_cast<const char*>(&sample), sizeof(sample));
    input.write(reinterpret_cast<const char*>(sample_event_array),
                sizeof(sample_event_array));
  }

  //
  // Parse input.
  //

  PerfReader pr;
  ASSERT_TRUE(pr.ReadFromString(input.str()));
  ASSERT_EQ(pr.attrs().size(), 1);
  const auto& actual_attr = pr.attrs().Get(0);
  ASSERT_EQ(8, actual_attr.ids().size());
  EXPECT_EQ(301, actual_attr.ids(0));
  EXPECT_EQ(302, actual_attr.ids(1));
  EXPECT_EQ(303, actual_attr.ids(2));
  EXPECT_EQ(304, actual_attr.ids(3));
}

TEST(PerfReaderTest, ReadsAndWritesSampleAndSampleIdAll) {
  using testing::PunU32U64;

  std::stringstream input;

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

  // data

  // PERF_RECORD_HEADER_ATTR
  const u64 sample_type =      // * == in sample_id_all
      PERF_SAMPLE_IP |
      PERF_SAMPLE_TID |        // *
      PERF_SAMPLE_TIME |       // *
      PERF_SAMPLE_ADDR |
      PERF_SAMPLE_ID |         // *
      PERF_SAMPLE_STREAM_ID |  // *
      PERF_SAMPLE_CPU |        // *
      PERF_SAMPLE_PERIOD;
  const size_t num_sample_event_bits = 8;
  const size_t num_sample_id_bits = 5;
  // not tested:
  // PERF_SAMPLE_READ |
  // PERF_SAMPLE_RAW |
  // PERF_SAMPLE_CALLCHAIN |
  // PERF_SAMPLE_BRANCH_STACK |
  testing::ExamplePerfEventAttrEvent_Hardware(sample_type,
                                              true /*sample_id_all*/)
      .WithId(401)
      .WriteTo(&input);

  // PERF_RECORD_SAMPLE
  const sample_event written_sample_event = {
    .header = {
      .type = PERF_RECORD_SAMPLE,
      .misc = PERF_RECORD_MISC_KERNEL,
      .size = sizeof(struct sample_event) + num_sample_event_bits*sizeof(u64),
    }
  };
  const u64 sample_event_array[] = {
    0xffffffff01234567,                    // IP
    PunU32U64{.v32 = {0x68d, 0x68e}}.v64,  // TID (u32 pid, tid)
    1415837014*1000000000ULL,              // TIME
    0x00007f999c38d15a,                    // ADDR
    401,                                   // ID
    1,                                     // STREAM_ID
    8,                                     // CPU
    10001,                                 // PERIOD
  };
  ASSERT_EQ(written_sample_event.header.size,
            sizeof(written_sample_event.header) + sizeof(sample_event_array));
  input.write(reinterpret_cast<const char*>(&written_sample_event),
              sizeof(written_sample_event));
  input.write(reinterpret_cast<const char*>(sample_event_array),
              sizeof(sample_event_array));

  // PERF_RECORD_MMAP
  ASSERT_EQ(40, offsetof(struct mmap_event, filename));
  const size_t mmap_event_size =
      offsetof(struct mmap_event, filename) +
      10+6 /* ==16, nearest 64-bit boundary for filename */ +
      num_sample_id_bits*sizeof(u64);

  struct mmap_event written_mmap_event = {
    .header = {
      .type = PERF_RECORD_MMAP,
      .misc = 0,
      .size = mmap_event_size,
    },
    .pid = 0x68d, .tid = 0x68d,
    .start = 0x1d000,
    .len = 0x1000,
    .pgoff = 0,
    // .filename = ..., // written separately
  };
  const char mmap_filename[10+6] = "/dev/zero";
  const u64 mmap_sample_id[] = {
    PunU32U64{.v32 = {0x68d, 0x68e}}.v64,  // TID (u32 pid, tid)
    1415911367*1000000000ULL,              // TIME
    401,                                   // ID
    2,                                     // STREAM_ID
    9,                                     // CPU
  };
  const size_t pre_mmap_offset = input.tellp();
  input.write(reinterpret_cast<const char*>(&written_mmap_event),
              offsetof(struct mmap_event, filename));
  input.write(mmap_filename, 10+6);
  input.write(reinterpret_cast<const char*>(mmap_sample_id),
              sizeof(mmap_sample_id));
  const size_t written_mmap_size =
      static_cast<size_t>(input.tellp()) - pre_mmap_offset;
  ASSERT_EQ(written_mmap_event.header.size,
            static_cast<u64>(written_mmap_size));

  //
  // Parse input.
  //

  PerfReader pr1;
  ASSERT_TRUE(pr1.ReadFromString(input.str()));
  // Write it out and read it in again, the two should have the same data.
  std::vector<char> output_perf_data;
  ASSERT_TRUE(pr1.WriteToVector(&output_perf_data));
  PerfReader pr2;
  ASSERT_TRUE(pr2.ReadFromVector(output_perf_data));

  // Test both versions:
  for (PerfReader* pr : {&pr1, &pr2}) {
    // PERF_RECORD_HEADER_ATTR is added to attr(), not events().
    EXPECT_EQ(2, pr->events().size());

    {
      const PerfEvent& event = pr->events().Get(0);
      EXPECT_EQ(PERF_RECORD_SAMPLE, event.header().type());

      const SampleEvent& sample = event.sample_event();
      EXPECT_EQ(0xffffffff01234567, sample.ip());
      EXPECT_EQ(0x68d, sample.pid());
      EXPECT_EQ(0x68e, sample.tid());
      EXPECT_EQ(1415837014*1000000000ULL, sample.sample_time_ns());
      EXPECT_EQ(0x00007f999c38d15a, sample.addr());
      EXPECT_EQ(401, sample.id());
      EXPECT_EQ(1, sample.stream_id());
      EXPECT_EQ(8, sample.cpu());
      EXPECT_EQ(10001, sample.period());
    }

    {
      const PerfEvent& event = pr->events().Get(1);
      EXPECT_EQ(PERF_RECORD_MMAP, event.header().type());

      const SampleInfo& sample = event.mmap_event().sample_info();
      EXPECT_EQ(0x68d, sample.pid());
      EXPECT_EQ(0x68e, sample.tid());
      EXPECT_EQ(1415911367*1000000000ULL, sample.sample_time_ns());
      EXPECT_EQ(401, sample.id());
      EXPECT_EQ(2, sample.stream_id());
      EXPECT_EQ(9, sample.cpu());
    }
  }
}

// Test that PERF_SAMPLE_IDENTIFIER is parsed correctly. This field
// is in a different place in PERF_RECORD_SAMPLE events compared to the
// struct sample_id placed at the end of all other events.
TEST(PerfReaderTest, ReadsAndWritesPerfSampleIdentifier) {
  std::stringstream input;

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

  // data

  // PERF_RECORD_HEADER_ATTR
  testing::ExamplePerfEventAttrEvent_Hardware(PERF_SAMPLE_IDENTIFIER |
                                              PERF_SAMPLE_IP |
                                              PERF_SAMPLE_TID,
                                              true /*sample_id_all*/)
      .WithIds({0xdeadbeef, 0xf00dbaad})
      .WriteTo(&input);

  // PERF_RECORD_SAMPLE
  const sample_event written_sample_event = {
    .header = {
      .type = PERF_RECORD_SAMPLE,
      .misc = PERF_RECORD_MISC_KERNEL,
      .size = sizeof(struct sample_event) + 3*sizeof(u64),
    }
  };
  const u64 sample_event_array[] = {
    0x00000000deadbeef,  // IDENTIFIER
    0x00007f999c38d15a,  // IP
    0x0000068d0000068d,  // TID (u32 pid, tid)
  };
  ASSERT_EQ(written_sample_event.header.size,
            sizeof(written_sample_event.header) + sizeof(sample_event_array));
  input.write(reinterpret_cast<const char*>(&written_sample_event),
              sizeof(written_sample_event));
  input.write(reinterpret_cast<const char*>(sample_event_array),
              sizeof(sample_event_array));

  // PERF_RECORD_MMAP
  ASSERT_EQ(40, offsetof(struct mmap_event, filename));
  const size_t mmap_event_size =
      offsetof(struct mmap_event, filename) +
      10+6 /* ==16, nearest 64-bit boundary for filename */ +
      2*sizeof(u64);

  struct mmap_event written_mmap_event = {
    .header = {
      .type = PERF_RECORD_MMAP,
      .misc = 0,
      .size = mmap_event_size,
    },
    .pid = 0x68d, .tid = 0x68d,
    .start = 0x1d000,
    .len = 0x1000,
    .pgoff = 0,
    // .filename = ..., // written separately
  };
  const char mmap_filename[10+6] = "/dev/zero";
  const u64 mmap_sample_id[] = {
    // NB: PERF_SAMPLE_IP is not part of sample_id
    0x0000068d0000068d,  // TID (u32 pid, tid)
    0x00000000f00dbaad,  // IDENTIFIER
  };
  const size_t pre_mmap_offset = input.tellp();
  input.write(reinterpret_cast<const char*>(&written_mmap_event),
              offsetof(struct mmap_event, filename));
  input.write(mmap_filename, 10+6);
  input.write(reinterpret_cast<const char*>(mmap_sample_id),
              sizeof(mmap_sample_id));
  const size_t written_mmap_size =
      static_cast<size_t>(input.tellp()) - pre_mmap_offset;
  ASSERT_EQ(written_mmap_event.header.size,
            static_cast<u64>(written_mmap_size));

  //
  // Parse input.
  //

  PerfReader pr1;
  ASSERT_TRUE(pr1.ReadFromString(input.str()));
  // Write it out and read it in again, the two should have the same data.
  std::vector<char> output_perf_data;
  ASSERT_TRUE(pr1.WriteToVector(&output_perf_data));
  PerfReader pr2;
  ASSERT_TRUE(pr2.ReadFromVector(output_perf_data));

  // Test both versions:
  for (PerfReader* pr : {&pr1, &pr2}) {
    // PERF_RECORD_HEADER_ATTR is added to attr(), not events().
    EXPECT_EQ(2, pr->events().size());

    const PerfEvent& ip_event = pr->events().Get(0);
    EXPECT_EQ(PERF_RECORD_SAMPLE, ip_event.header().type());
    EXPECT_EQ(0xdeadbeefULL, ip_event.sample_event().id());

    const PerfEvent& mmap_event = pr->events().Get(1);
    EXPECT_EQ(PERF_RECORD_MMAP, mmap_event.header().type());
    EXPECT_EQ(0xf00dbaadULL, mmap_event.mmap_event().sample_info().id());
  }
}

TEST(PerfReaderTest, ReadsAndWritesMmap2Events) {
  std::stringstream input;

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

  // data

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

  // PERF_RECORD_MMAP2
  ASSERT_EQ(72, offsetof(struct mmap2_event, filename));
  const size_t mmap_event_size =
      offsetof(struct mmap2_event, filename) +
      10+6; /* ==16, nearest 64-bit boundary for filename */

  struct mmap2_event written_mmap_event = {
    .header = {
      .type = PERF_RECORD_MMAP2,
      .misc = 0,
      .size = mmap_event_size,
    },
    .pid = 0x68d, .tid = 0x68d,
    .start = 0x1d000,
    .len = 0x1000,
    .pgoff = 0x2000,
    .maj = 6,
    .min = 7,
    .ino = 8,
    .ino_generation = 9,
    .prot = 1|2,  // == PROT_READ | PROT_WRITE
    .flags = 2,   // == MAP_PRIVATE
    // .filename = ..., // written separately
  };
  const char mmap_filename[10+6] = "/dev/zero";
  const size_t pre_mmap_offset = input.tellp();
  input.write(reinterpret_cast<const char*>(&written_mmap_event),
              offsetof(struct mmap2_event, filename));
  input.write(mmap_filename, 10+6);
  const size_t written_mmap_size =
      static_cast<size_t>(input.tellp()) - pre_mmap_offset;
  ASSERT_EQ(written_mmap_event.header.size,
            static_cast<u64>(written_mmap_size));

  //
  // Parse input.
  //

  PerfReader pr1;
  ASSERT_TRUE(pr1.ReadFromString(input.str()));
  // Write it out and read it in again, the two should have the same data.
  std::vector<char> output_perf_data;
  ASSERT_TRUE(pr1.WriteToVector(&output_perf_data));
  PerfReader pr2;
  ASSERT_TRUE(pr2.ReadFromVector(output_perf_data));

  // Test both versions:
  for (PerfReader* pr : {&pr1, &pr2}) {
    // PERF_RECORD_HEADER_ATTR is added to attr(), not events().
    EXPECT_EQ(1, pr->events().size());

    const PerfEvent& event = pr->events().Get(0);
    EXPECT_EQ(PERF_RECORD_MMAP2, event.header().type());
    EXPECT_EQ(0x68d, event.mmap_event().pid());
    EXPECT_EQ(0x68d, event.mmap_event().tid());
    EXPECT_EQ(0x1d000, event.mmap_event().start());
    EXPECT_EQ(0x1000, event.mmap_event().len());
    EXPECT_EQ(0x2000, event.mmap_event().pgoff());
    EXPECT_EQ(6, event.mmap_event().maj());
    EXPECT_EQ(7, event.mmap_event().min());
    EXPECT_EQ(8, event.mmap_event().ino());
    EXPECT_EQ(9, event.mmap_event().ino_generation());
    EXPECT_EQ(1|2, event.mmap_event().prot());
    EXPECT_EQ(2, event.mmap_event().flags());
  }
}

// Regression test for http://crbug.com/493533
TEST(PerfReaderTest, ReadsAllAvailableMetadataTypes) {
  std::stringstream input;

  const uint32_t features = (1 << HEADER_HOSTNAME) |
                            (1 << HEADER_OSRELEASE) |
                            (1 << HEADER_VERSION) |
                            (1 << HEADER_ARCH) |
                            (1 << HEADER_LAST_FEATURE);

  // header
  testing::ExamplePerfDataFileHeader file_header(features);
  file_header.WriteTo(&input);

  // metadata

  size_t metadata_offset =
      file_header.data_end() + 5 * sizeof(perf_file_section);

  // HEADER_HOSTNAME
  testing::ExampleStringMetadata hostname_metadata("hostname", metadata_offset);
  metadata_offset += hostname_metadata.size();

  // HEADER_OSRELEASE
  testing::ExampleStringMetadata osrelease_metadata("osrelease",
                                                    metadata_offset);
  metadata_offset += osrelease_metadata.size();

  // HEADER_VERSION
  testing::ExampleStringMetadata version_metadata("version", metadata_offset);
  metadata_offset += version_metadata.size();

  // HEADER_ARCH
  testing::ExampleStringMetadata arch_metadata("arch", metadata_offset);
  metadata_offset += arch_metadata.size();

  // HEADER_LAST_FEATURE -- this is just a dummy metadata that will be skipped
  // over. In practice, there will not actually be a metadata entry of type
  // HEADER_LAST_FEATURE. But use because it will never become a supported
  // metadata type.
  testing::ExampleStringMetadata last_feature("*unsupported*", metadata_offset);
  metadata_offset += last_feature.size();

  hostname_metadata.index_entry().WriteTo(&input);
  osrelease_metadata.index_entry().WriteTo(&input);
  version_metadata.index_entry().WriteTo(&input);
  arch_metadata.index_entry().WriteTo(&input);
  last_feature.index_entry().WriteTo(&input);

  hostname_metadata.WriteTo(&input);
  osrelease_metadata.WriteTo(&input);
  version_metadata.WriteTo(&input);
  arch_metadata.WriteTo(&input);
  last_feature.WriteTo(&input);

  //
  // Parse input.
  //

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

  // The dummy metadata should not have prevented the reading of the other
  // metadata.
  const auto& string_metadata = pr.string_metadata();
  EXPECT_EQ("hostname", string_metadata.hostname().value());
  EXPECT_EQ("osrelease", string_metadata.kernel_version().value());
  EXPECT_EQ("version", string_metadata.perf_version().value());
  EXPECT_EQ("arch", string_metadata.architecture().value());
}

// Regression test for http://crbug.com/493533
TEST(PerfReaderTest, ReadsAllAvailableMetadataTypesPiped) {
  std::stringstream input;

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

  // metadata

  // Provide these out of order. Order should not matter to the PerfReader, but
  // this tests whether the reader is capable of skipping an unsupported type.
  testing::ExampleStringMetadataEvent(PERF_RECORD_HEADER_HOSTNAME, "hostname")
      .WriteTo(&input);
  testing::ExampleStringMetadataEvent(PERF_RECORD_HEADER_OSRELEASE, "osrelease")
      .WriteTo(&input);
  testing::ExampleStringMetadataEvent(PERF_RECORD_HEADER_MAX, "*unsupported*")
      .WriteTo(&input);
  testing::ExampleStringMetadataEvent(PERF_RECORD_HEADER_VERSION, "version")
      .WriteTo(&input);
  testing::ExampleStringMetadataEvent(PERF_RECORD_HEADER_ARCH, "arch")
      .WriteTo(&input);

  //
  // Parse input.
  //

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

  // The dummy metadata should not have prevented the reading of the other
  // metadata.
  const auto& string_metadata = pr.string_metadata();
  EXPECT_EQ("hostname", string_metadata.hostname().value());
  EXPECT_EQ("osrelease", string_metadata.kernel_version().value());
  EXPECT_EQ("version", string_metadata.perf_version().value());
  EXPECT_EQ("arch", string_metadata.architecture().value());
}

TEST(PerfReaderTest, AttrsWithDifferentSampleTypes) {
  std::stringstream input;

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent sample_event_1(testing::SampleInfo()
      .Id(51)
      .Ip(0x00000000002c100a)
      .Tid(1002));
  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent sample_event_2(testing::SampleInfo()
      .Id(61)
      .Ip(0x00000000002c100b)
      .Tid(1002)
      .Time(1000006));
  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent sample_event_3(testing::SampleInfo()
      .Id(52)
      .Ip(0x00000000002c100c)
      .Tid(1002));

  const size_t data_size =
      sample_event_1.GetSize() +
      sample_event_2.GetSize() +
      sample_event_3.GetSize();
  const uint32_t features = 0;

  // header
  testing::ExamplePerfDataFileHeader file_header(features);
  file_header
      .WithAttrIdsCount(3)
      .WithAttrCount(2)
      .WithDataSize(data_size);
  file_header.WriteTo(&input);

  // attr ids
  testing::AttrIdsSection attr_ids(input.tellp());
  const auto id_section_1 = attr_ids.AddIds({51, 52});
  const auto id_section_2 = attr_ids.AddIds({61});
  attr_ids.WriteTo(&input);

  // attrs
  ASSERT_EQ(file_header.header().attrs.offset,
            static_cast<u64>(input.tellp()));
  testing::ExamplePerfFileAttr_Hardware(PERF_SAMPLE_IDENTIFIER |
                                        PERF_SAMPLE_IP |
                                        PERF_SAMPLE_TID,
                                        true /*sample_id_all*/)
      .WithIds(id_section_1)
      .WriteTo(&input);
  testing::ExamplePerfFileAttr_Hardware(PERF_SAMPLE_IDENTIFIER |
                                        PERF_SAMPLE_IP |
                                        PERF_SAMPLE_TID |
                                        PERF_SAMPLE_TIME,
                                        true /*sample_id_all*/)
      .WithIds(id_section_2)
      .WriteTo(&input);

  // data

  ASSERT_EQ(file_header.header().data.offset,
            static_cast<u64>(input.tellp()));
  sample_event_1.WriteTo(&input);
  sample_event_2.WriteTo(&input);
  sample_event_3.WriteTo(&input);
  ASSERT_EQ(file_header.header().data.offset + data_size,
            static_cast<u64>(input.tellp()));

  // no metadata

  //
  // Parse input.
  //
  PerfReader pr;
  ASSERT_TRUE(pr.ReadFromString(input.str()));

  // Make sure the attr ids were read correctly.
  ASSERT_EQ(2, pr.attrs().size());
  ASSERT_EQ(2, pr.attrs().Get(0).ids().size());
  EXPECT_EQ(51, pr.attrs().Get(0).ids(0));
  EXPECT_EQ(52, pr.attrs().Get(0).ids(1));
  ASSERT_EQ(1, pr.attrs().Get(1).ids().size());
  EXPECT_EQ(61, pr.attrs().Get(1).ids(0));

  // Verify events were read properly.
  ASSERT_EQ(3, pr.events().size());
  {
    const PerfEvent& event = pr.events().Get(0);
    EXPECT_EQ(PERF_RECORD_SAMPLE, event.header().type());

    const SampleEvent& sample = event.sample_event();
    EXPECT_EQ(51, sample.id());
    EXPECT_EQ(0x00000000002c100a, sample.ip());
    EXPECT_EQ(1002, sample.tid());
    // This event doesn't have a timestamp.
    EXPECT_FALSE(sample.has_sample_time_ns());
  }
  {
    const PerfEvent& event = pr.events().Get(1);
    EXPECT_EQ(PERF_RECORD_SAMPLE, event.header().type());

    const SampleEvent& sample = event.sample_event();
    EXPECT_EQ(61, sample.id());
    EXPECT_EQ(0x00000000002c100b, sample.ip());
    EXPECT_EQ(1002, sample.tid());
    EXPECT_EQ(1000006, sample.sample_time_ns());
  }
  {
    const PerfEvent& event = pr.events().Get(2);
    EXPECT_EQ(PERF_RECORD_SAMPLE, event.header().type());

    const SampleEvent& sample = event.sample_event();
    EXPECT_EQ(52, sample.id());
    EXPECT_EQ(0x00000000002c100c, sample.ip());
    EXPECT_EQ(1002, sample.tid());
    // This event doesn't have a timestamp.
    EXPECT_FALSE(sample.has_sample_time_ns());
  }
}

// Neither PERF_SAMPLE_ID nor PERF_SAMPLE_IDENTIFIER are set. We should
// fall back to using the first attr when looking for the sample_format.
TEST(PerfReaderTest, NoSampleIdField) {
  std::stringstream input;

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent sample_event(
      testing::SampleInfo().Ip(0x00000000002c100a).Tid(1002));

  const size_t data_size = sample_event.GetSize();
  const uint32_t features = 0;

  // header
  testing::ExamplePerfDataFileHeader file_header(features);
  file_header
      .WithAttrCount(1)
      .WithDataSize(data_size);
  file_header.WriteTo(&input);

  // attrs
  ASSERT_EQ(file_header.header().attrs.offset,
            static_cast<u64>(input.tellp()));
  testing::ExamplePerfFileAttr_Hardware(PERF_SAMPLE_IP | PERF_SAMPLE_TID,
                                        false /*sample_id_all*/)
      .WithConfig(456)
      .WriteTo(&input);

  // data

  ASSERT_EQ(file_header.header().data.offset,
            static_cast<u64>(input.tellp()));
  sample_event.WriteTo(&input);
  ASSERT_EQ(file_header.header().data.offset + data_size,
            static_cast<u64>(input.tellp()));

  // no metadata

  //
  // Parse input.
  //

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

  // Make sure the attr was recorded properly.
  ASSERT_EQ(1, pr.attrs().size());
  EXPECT_EQ(456, pr.attrs().Get(0).attr().config());

  // Verify subsequent sample event was read properly.
  ASSERT_EQ(1, pr.events().size());
  const PerfEvent& event = pr.events().Get(0);
  EXPECT_EQ(PERF_RECORD_SAMPLE, event.header().type());
  EXPECT_EQ(data_size, event.header().size());

  EXPECT_EQ(0x00000000002c100a, event.sample_event().ip());
  EXPECT_EQ(1002, event.sample_event().tid());
}

// When sample_id_all == false, non-sample events should not look for sample_id.
TEST(PerfReaderTest, SampleIdFalseMeansDontReadASampleId) {
  std::stringstream input;

  // PERF_RECORD_SAMPLE
  testing::ExamplePerfSampleEvent sample_event(
      testing::SampleInfo().Ip(0x00000000002c100a).Tid(1002).Id(48));

  // PERF_RECORD_MMAP
  testing::ExampleMmapEvent mmap_event(
      1001, 0x1c1000, 0x1000, 0, "/usr/lib/foo.so",
      // Write a sample_info even though we shouldn't (sample_id_all==false)
      // Use a bogus ID: if we look at the sample_id and look for an attr, it
      // should return an error.
      testing::SampleInfo().Tid(1001).Id(666));

  const size_t data_size =
      sample_event.GetSize() +
      mmap_event.GetSize();
  const uint32_t features = 0;

  // header
  testing::ExamplePerfDataFileHeader file_header(features);
  file_header
      .WithAttrIdsCount(1)
      .WithAttrCount(1)
      .WithDataSize(data_size);
  file_header.WriteTo(&input);

  // attr IDs
  testing::AttrIdsSection attr_ids(input.tellp());
  const auto id_section = attr_ids.AddId(48);
  attr_ids.WriteTo(&input);

  // attrs
  ASSERT_EQ(file_header.header().attrs.offset,
            static_cast<u64>(input.tellp()));
  testing::ExamplePerfFileAttr_Hardware(PERF_SAMPLE_IP |
                                        PERF_SAMPLE_TID |
                                        PERF_SAMPLE_ID,
                                        false /*sample_id_all*/)
      .WithIds(id_section)
      .WriteTo(&input);

  // data

  ASSERT_EQ(file_header.header().data.offset,
            static_cast<u64>(input.tellp()));
  sample_event.WriteTo(&input);
  mmap_event.WriteTo(&input);
  ASSERT_EQ(file_header.header().data.offset + data_size,
            static_cast<u64>(input.tellp()));

  // no metadata

  //
  // Parse input.
  //

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

  // Verify events were read properly.
  ASSERT_EQ(2, pr.events().size());
  {
    const PerfEvent& event = pr.events().Get(0);
    EXPECT_EQ(PERF_RECORD_SAMPLE, event.header().type());

    EXPECT_EQ(0x00000000002c100a, event.sample_event().ip());
    EXPECT_EQ(1002, event.sample_event().tid());
    EXPECT_EQ(48, event.sample_event().id());
  }

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

    // This event is malformed: it has junk at the end. Therefore, sample_info
    // should not have TID or ID fields.
    EXPECT_FALSE(event.mmap_event().sample_info().has_tid());
    EXPECT_FALSE(event.mmap_event().sample_info().has_id());
  }
}

// Regression test for http://crbug.com/496441
TEST(PerfReaderTest, LargePerfEventAttr) {
  std::stringstream input;

  const size_t attr_size = sizeof(perf_event_attr) + sizeof(u64);
  testing::ExamplePerfSampleEvent sample_event(
      testing::SampleInfo().Ip(0x00000000002c100a).Tid(1002));
  const size_t data_size = sample_event.GetSize();

  // header
  testing::ExamplePerfDataFileHeader file_header(0);
  file_header
      .WithCustomPerfEventAttrSize(attr_size)
      .WithAttrCount(1)
      .WithDataSize(data_size);
  file_header.WriteTo(&input);

  // attrs
  ASSERT_EQ(file_header.header().attrs.offset,
            static_cast<u64>(input.tellp()));
  testing::ExamplePerfFileAttr_Hardware(PERF_SAMPLE_IP | PERF_SAMPLE_TID,
                                        false /*sample_id_all*/)
      .WithAttrSize(attr_size)
      .WithConfig(456)
      .WriteTo(&input);

  // data

  ASSERT_EQ(file_header.header().data.offset, static_cast<u64>(input.tellp()));
  sample_event.WriteTo(&input);
  ASSERT_EQ(file_header.header().data.offset + data_size,
            static_cast<u64>(input.tellp()));

  // no metadata

  //
  // Parse input.
  //

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

  // Make sure the attr was recorded properly.
  EXPECT_EQ(1, pr.attrs().size());
  EXPECT_EQ(456, pr.attrs().Get(0).attr().config());

  // Verify subsequent sample event was read properly.
  ASSERT_EQ(1, pr.events().size());

  const PerfEvent& event = pr.events().Get(0);
  EXPECT_EQ(PERF_RECORD_SAMPLE, event.header().type());
  EXPECT_EQ(data_size, event.header().size());

  const SampleEvent& sample_info = event.sample_event();
  EXPECT_EQ(0x00000000002c100a, sample_info.ip());
  EXPECT_EQ(1002, sample_info.tid());
}

// Regression test for http://crbug.com/496441
TEST(PerfReaderTest, LargePerfEventAttrPiped) {
  std::stringstream input;

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

  // data

  // PERF_RECORD_HEADER_ATTR
  testing::ExamplePerfEventAttrEvent_Hardware(PERF_SAMPLE_IP | PERF_SAMPLE_TID,
                                              true /*sample_id_all*/)
      .WithAttrSize(sizeof(perf_event_attr) + sizeof(u64))
      .WithConfig(123)
      .WriteTo(&input);

  // PERF_RECORD_HEADER_EVENT_TYPE
  const struct event_type_event event_type = {
    .header = {
      .type = PERF_RECORD_HEADER_EVENT_TYPE,
      .misc = 0,
      .size = sizeof(struct event_type_event),
    },
    .event_type = {
      /*event_id*/ 123,
      /*name*/ "cycles",
    },
  };
  input.write(reinterpret_cast<const char*>(&event_type), sizeof(event_type));

  testing::ExamplePerfSampleEvent sample_event(
      testing::SampleInfo().Ip(0x00000000002c100a).Tid(1002));
  sample_event.WriteTo(&input);

  //
  // Parse input.
  //

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

  // Make sure the attr was recorded properly.
  EXPECT_EQ(1, pr.attrs().size());
  EXPECT_EQ(123, pr.attrs().Get(0).attr().config());
  ASSERT_EQ(1, pr.event_types().size());
  EXPECT_EQ("cycles", pr.event_types().Get(0).name());

  // Verify subsequent sample event was read properly.
  ASSERT_EQ(1, pr.events().size());

  const PerfEvent& event = pr.events().Get(0);
  EXPECT_EQ(PERF_RECORD_SAMPLE, event.header().type());
  EXPECT_EQ(sample_event.GetSize(), event.header().size());

  const SampleEvent& sample_info = event.sample_event();
  EXPECT_EQ(0x00000000002c100a, sample_info.ip());
  EXPECT_EQ(1002, sample_info.tid());
}

// Regression test for http://crbug.com/496441
TEST(PerfReaderTest, SmallPerfEventAttr) {
  std::stringstream input;

  const size_t attr_size = sizeof(perf_event_attr) - sizeof(u64);
  testing::ExamplePerfSampleEvent sample_event(
      testing::SampleInfo().Ip(0x00000000002c100a).Tid(1002));
  const size_t data_size = sample_event.GetSize();

  // header
  testing::ExamplePerfDataFileHeader file_header(0);
  file_header
      .WithCustomPerfEventAttrSize(attr_size)
      .WithAttrCount(1)
      .WithDataSize(data_size);
  file_header.WriteTo(&input);

  // attrs
  CHECK_EQ(file_header.header().attrs.offset,
           static_cast<u64>(input.tellp()));
  testing::ExamplePerfFileAttr_Hardware(PERF_SAMPLE_IP | PERF_SAMPLE_TID,
                                        false /*sample_id_all*/)
      .WithAttrSize(attr_size)
      .WithConfig(456)
      .WriteTo(&input);

  // data

  ASSERT_EQ(file_header.header().data.offset,
            static_cast<u64>(input.tellp()));
  sample_event.WriteTo(&input);
  ASSERT_EQ(file_header.header().data.offset + data_size,
            static_cast<u64>(input.tellp()));

  // no metadata

  //
  // Parse input.
  //

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

  // Make sure the attr was recorded properly.
  EXPECT_EQ(1, pr.attrs().size());
  EXPECT_EQ(456, pr.attrs().Get(0).attr().config());

  // Verify subsequent sample event was read properly.
  ASSERT_EQ(1, pr.events().size());

  const PerfEvent& event = pr.events().Get(0);
  EXPECT_EQ(PERF_RECORD_SAMPLE, event.header().type());
  EXPECT_EQ(data_size, event.header().size());

  const SampleEvent& sample_info = event.sample_event();
  EXPECT_EQ(0x00000000002c100a, sample_info.ip());
  EXPECT_EQ(1002, sample_info.tid());
}

// Regression test for http://crbug.com/496441
TEST(PerfReaderTest, SmallPerfEventAttrPiped) {
  std::stringstream input;

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

  // data

  // PERF_RECORD_HEADER_ATTR
  testing::ExamplePerfEventAttrEvent_Hardware(PERF_SAMPLE_IP | PERF_SAMPLE_TID,
                                              true /*sample_id_all*/)
      .WithAttrSize(sizeof(perf_event_attr) - sizeof(u64))
      .WithConfig(123)
      .WriteTo(&input);

  // PERF_RECORD_HEADER_EVENT_TYPE
  const struct event_type_event event_type = {
    .header = {
      .type = PERF_RECORD_HEADER_EVENT_TYPE,
      .misc = 0,
      .size = sizeof(struct event_type_event),
    },
    .event_type = {
      /*event_id*/ 123,
      /*name*/ "cycles",
    },
  };
  input.write(reinterpret_cast<const char*>(&event_type), sizeof(event_type));

  testing::ExamplePerfSampleEvent sample_event(
      testing::SampleInfo().Ip(0x00000000002c100a).Tid(1002));
  sample_event.WriteTo(&input);

  //
  // Parse input.
  //

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

  // Make sure the attr was recorded properly.
  EXPECT_EQ(1, pr.attrs().size());
  EXPECT_EQ(123, pr.attrs().Get(0).attr().config());
  ASSERT_EQ(1, pr.event_types().size());
  EXPECT_EQ("cycles", pr.event_types().Get(0).name());

  // Verify subsequent sample event was read properly.
  ASSERT_EQ(1, pr.events().size());

  const PerfEvent& event = pr.events().Get(0);
  EXPECT_EQ(PERF_RECORD_SAMPLE, event.header().type());
  EXPECT_EQ(sample_event.GetSize(), event.header().size());

  const SampleEvent& sample_info = event.sample_event();
  EXPECT_EQ(0x00000000002c100a, sample_info.ip());
  EXPECT_EQ(1002, sample_info.tid());
}

TEST(PerfReaderTest, CrossEndianAttrs) {
  for (bool is_cross_endian : {true, false}) {
    LOG(INFO) << "Testing with cross endianness = " << is_cross_endian;

    std::stringstream input;

    // header
    const uint32_t features = 0;
    testing::ExamplePerfDataFileHeader file_header(features);
    file_header
        .WithAttrCount(3)
        .WithCrossEndianness(is_cross_endian)
        .WriteTo(&input);

    // attrs
    CHECK_EQ(file_header.header().attrs.offset,
             static_cast<u64>(input.tellp()));
    // Provide two attrs with different sample_id_all values to test the
    // correctness of byte swapping of the bit fields.
    testing::ExamplePerfFileAttr_Hardware(PERF_SAMPLE_IP | PERF_SAMPLE_TID,
                                          true /*sample_id_all*/)
        .WithConfig(123)
        .WithCrossEndianness(is_cross_endian)
        .WriteTo(&input);
    testing::ExamplePerfFileAttr_Hardware(PERF_SAMPLE_IP | PERF_SAMPLE_TID,
                                          true /*sample_id_all*/)
        .WithConfig(456)
        .WithCrossEndianness(is_cross_endian)
        .WriteTo(&input);
    testing::ExamplePerfFileAttr_Hardware(PERF_SAMPLE_IP | PERF_SAMPLE_TID,
                                          false /*sample_id_all*/)
        .WithConfig(456)
        .WithCrossEndianness(is_cross_endian)
        .WriteTo(&input);

    // No data.
    // No metadata.

    // Read data.

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

    // Make sure the attr was recorded properly.
    EXPECT_EQ(3, pr.attrs().size());

    const auto& attr0 = pr.attrs().Get(0).attr();
    EXPECT_EQ(123, attr0.config());
    EXPECT_EQ(1, attr0.sample_period());
    EXPECT_EQ(PERF_SAMPLE_IP | PERF_SAMPLE_TID, attr0.sample_type());
    EXPECT_TRUE(attr0.sample_id_all());
    EXPECT_EQ(2, attr0.precise_ip());

    const auto& attr1 = pr.attrs().Get(1).attr();
    EXPECT_EQ(456, attr1.config());
    EXPECT_EQ(1, attr1.sample_period());
    EXPECT_EQ(PERF_SAMPLE_IP | PERF_SAMPLE_TID, attr1.sample_type());
    EXPECT_TRUE(attr1.sample_id_all());
    EXPECT_EQ(2, attr1.precise_ip());

    const auto& attr2 = pr.attrs().Get(2).attr();
    EXPECT_EQ(456, attr2.config());
    EXPECT_EQ(1, attr2.sample_period());
    EXPECT_EQ(PERF_SAMPLE_IP | PERF_SAMPLE_TID, attr2.sample_type());
    EXPECT_FALSE(attr2.sample_id_all());
    EXPECT_EQ(2, attr2.precise_ip());
  }
}

TEST(PerfReaderTest, CrossEndianNormalPerfData) {
  // data
  // Do this before header to compute the total data size.
  std::stringstream input_data;
  testing::ExampleMmapEvent(
      1234, 0x0000000000810000, 0x10000, 0x2000, "/usr/lib/foo.so",
      testing::SampleInfo().Tid(bswap_32(1234), bswap_32(1235)))
      .WithCrossEndianness(true)
      .WriteTo(&input_data);
  testing::ExampleForkEvent(
      1236, 1234, 1237, 1235, 30ULL * 1000000000,
      testing::SampleInfo().Tid(bswap_32(1236), bswap_32(1237)))
      .WithCrossEndianness(true)
      .WriteTo(&input_data);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo()
          .Ip(bswap_64(0x0000000000810100))
          .Tid(bswap_32(1234), bswap_32(1235)))
      .WithCrossEndianness(true)
      .WriteTo(&input_data);
  testing::ExamplePerfSampleEvent(
      testing::SampleInfo()
          .Ip(bswap_64(0x000000000081ff00))
          .Tid(bswap_32(1236), bswap_32(1237)))
      .WithCrossEndianness(true)
      .WriteTo(&input_data);

  std::stringstream input;

  // header
  const size_t data_size = input_data.str().size();
  const uint32_t features = (1 << HEADER_HOSTNAME) | (1 << HEADER_OSRELEASE);
  testing::ExamplePerfDataFileHeader file_header(features);
  file_header
      .WithAttrCount(1)
      .WithDataSize(data_size)
      .WithCrossEndianness(true)
      .WriteTo(&input);

  // attrs
  CHECK_EQ(file_header.header().attrs.offset,
           static_cast<u64>(input.tellp()));
  testing::ExamplePerfFileAttr_Hardware(PERF_SAMPLE_IP | PERF_SAMPLE_TID,
                                        true /*sample_id_all*/)
      .WithConfig(456)
      .WithCrossEndianness(true)
      .WriteTo(&input);

  // Write data.

  u64 data_offset = file_header.header().data.offset;
  ASSERT_EQ(data_offset, static_cast<u64>(input.tellp()));
  input << input_data.str();
  ASSERT_EQ(data_offset + data_size, static_cast<u64>(input.tellp()));

  // metadata
  size_t metadata_offset =
      file_header.data_end() + 2 * sizeof(perf_file_section);

  // HEADER_HOSTNAME
  testing::ExampleStringMetadata hostname_metadata("hostname", metadata_offset);
  hostname_metadata.WithCrossEndianness(true);
  metadata_offset += hostname_metadata.size();

  // HEADER_OSRELEASE
  testing::ExampleStringMetadata osrelease_metadata("osrelease",
                                                    metadata_offset);
  osrelease_metadata.WithCrossEndianness(true);
  metadata_offset += osrelease_metadata.size();

  hostname_metadata.index_entry().WriteTo(&input);
  osrelease_metadata.index_entry().WriteTo(&input);

  hostname_metadata.WriteTo(&input);
  osrelease_metadata.WriteTo(&input);


  //
  // Parse input.
  //

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

  // Make sure the attr was recorded properly.
  EXPECT_EQ(1, pr.attrs().size());
  EXPECT_EQ(456, pr.attrs().Get(0).attr().config());
  EXPECT_TRUE(pr.attrs().Get(0).attr().sample_id_all());

  // Verify perf events.
  ASSERT_EQ(4, pr.events().size());

  {
    const PerfEvent& event = pr.events().Get(0);
    EXPECT_EQ(PERF_RECORD_MMAP, event.header().type());
    EXPECT_EQ(1234, event.mmap_event().pid());
    EXPECT_EQ(1234, event.mmap_event().tid());
    EXPECT_EQ(string("/usr/lib/foo.so"), event.mmap_event().filename());
    EXPECT_EQ(0x0000000000810000, event.mmap_event().start());
    EXPECT_EQ(0x10000, event.mmap_event().len());
    EXPECT_EQ(0x2000, event.mmap_event().pgoff());
  }

  {
    const PerfEvent& event = pr.events().Get(1);
    EXPECT_EQ(PERF_RECORD_FORK, event.header().type());
    EXPECT_EQ(1236, event.fork_event().pid());
    EXPECT_EQ(1234, event.fork_event().ppid());
    EXPECT_EQ(1237, event.fork_event().tid());
    EXPECT_EQ(1235, event.fork_event().ptid());
    EXPECT_EQ(30ULL * 1000000000, event.fork_event().fork_time_ns());
  }

  {
    const PerfEvent& event = pr.events().Get(2);
    EXPECT_EQ(PERF_RECORD_SAMPLE, event.header().type());

    const SampleEvent& sample_info = event.sample_event();
    EXPECT_EQ(0x0000000000810100, sample_info.ip());
    EXPECT_EQ(1234, sample_info.pid());
    EXPECT_EQ(1235, sample_info.tid());
  }

  {
    const PerfEvent& event = pr.events().Get(3);
    EXPECT_EQ(PERF_RECORD_SAMPLE, event.header().type());

    const SampleEvent& sample_info = event.sample_event();
    EXPECT_EQ(0x000000000081ff00, sample_info.ip());
    EXPECT_EQ(1236, sample_info.pid());
    EXPECT_EQ(1237, sample_info.tid());
  }
}

TEST(PerfReaderTest, MetadataMaskInitialized) {
  // The metadata mask is actually an array of uint64's. The accessors/mutator
  // in PerfReader depend on it being initialized.
  PerfReader reader;
  ASSERT_EQ(1U, reader.proto().metadata_mask().size());
  EXPECT_EQ(0U, reader.metadata_mask());
}

}  // namespace quipper
