Home | History | Annotate | Download | only in simpleperf
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <gtest/gtest.h>
     18 
     19 #include <string.h>
     20 
     21 #include <memory>
     22 
     23 #include <android-base/test_utils.h>
     24 
     25 #include "environment.h"
     26 #include "event_attr.h"
     27 #include "event_type.h"
     28 #include "record.h"
     29 #include "record_file.h"
     30 
     31 #include "record_equal_test.h"
     32 
     33 using namespace PerfFileFormat;
     34 
     35 class RecordFileTest : public ::testing::Test {
     36  protected:
     37   void AddEventType(const std::string& event_type_str) {
     38     std::unique_ptr<EventTypeAndModifier> event_type_modifier = ParseEventType(event_type_str);
     39     ASSERT_TRUE(event_type_modifier != nullptr);
     40     perf_event_attr attr = CreateDefaultPerfEventAttr(event_type_modifier->event_type);
     41     attr.sample_id_all = 1;
     42     attrs_.push_back(std::unique_ptr<perf_event_attr>(new perf_event_attr(attr)));
     43     EventAttrWithId attr_id;
     44     attr_id.attr = attrs_.back().get();
     45     attr_id.ids.push_back(attrs_.size());  // Fake id.
     46     attr_ids_.push_back(attr_id);
     47   }
     48 
     49   TemporaryFile tmpfile_;
     50   std::vector<std::unique_ptr<perf_event_attr>> attrs_;
     51   std::vector<EventAttrWithId> attr_ids_;
     52 };
     53 
     54 TEST_F(RecordFileTest, smoke) {
     55   // Write to a record file.
     56   std::unique_ptr<RecordFileWriter> writer = RecordFileWriter::CreateInstance(tmpfile_.path);
     57   ASSERT_TRUE(writer != nullptr);
     58 
     59   // Write attr section.
     60   AddEventType("cpu-cycles");
     61   ASSERT_TRUE(writer->WriteAttrSection(attr_ids_));
     62 
     63   // Write data section.
     64   MmapRecord mmap_record(*(attr_ids_[0].attr), true, 1, 1, 0x1000, 0x2000,
     65                          0x3000, "mmap_record_example", attr_ids_[0].ids[0]);
     66   ASSERT_TRUE(writer->WriteRecord(mmap_record));
     67 
     68   // Write feature section.
     69   ASSERT_TRUE(writer->BeginWriteFeatures(1));
     70   char p[BuildId::Size()];
     71   for (size_t i = 0; i < BuildId::Size(); ++i) {
     72     p[i] = i;
     73   }
     74   BuildId build_id(p);
     75   std::vector<BuildIdRecord> build_id_records;
     76   build_id_records.push_back(BuildIdRecord(false, getpid(), build_id, "init"));
     77   ASSERT_TRUE(writer->WriteBuildIdFeature(build_id_records));
     78   ASSERT_TRUE(writer->EndWriteFeatures());
     79   ASSERT_TRUE(writer->Close());
     80 
     81   // Read from a record file.
     82   std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmpfile_.path);
     83   ASSERT_TRUE(reader != nullptr);
     84   std::vector<EventAttrWithId> attrs = reader->AttrSection();
     85   ASSERT_EQ(1u, attrs.size());
     86   ASSERT_EQ(0, memcmp(attrs[0].attr, attr_ids_[0].attr, sizeof(perf_event_attr)));
     87   ASSERT_EQ(attrs[0].ids, attr_ids_[0].ids);
     88 
     89   // Read and check data section.
     90   std::vector<std::unique_ptr<Record>> records = reader->DataSection();
     91   ASSERT_EQ(1u, records.size());
     92   CheckRecordEqual(mmap_record, *records[0]);
     93 
     94   // Read and check feature section.
     95   std::vector<BuildIdRecord> read_build_id_records = reader->ReadBuildIdFeature();
     96   ASSERT_EQ(1u, read_build_id_records.size());
     97   CheckRecordEqual(read_build_id_records[0], build_id_records[0]);
     98 
     99   ASSERT_TRUE(reader->Close());
    100 }
    101 
    102 TEST_F(RecordFileTest, records_sorted_by_time) {
    103   // Write to a record file.
    104   std::unique_ptr<RecordFileWriter> writer = RecordFileWriter::CreateInstance(tmpfile_.path);
    105   ASSERT_TRUE(writer != nullptr);
    106 
    107   // Write attr section.
    108   AddEventType("cpu-cycles");
    109   attrs_[0]->sample_id_all = 1;
    110   attrs_[0]->sample_type |= PERF_SAMPLE_TIME;
    111   ASSERT_TRUE(writer->WriteAttrSection(attr_ids_));
    112 
    113   // Write data section.
    114   MmapRecord r1(*(attr_ids_[0].attr), true, 1, 1, 0x100, 0x2000, 0x3000, "mmap_record1",
    115                 attr_ids_[0].ids[0], 2);
    116   MmapRecord r2(*(attr_ids_[0].attr), true, 1, 1, 0x100, 0x2000, 0x3000, "mmap_record1",
    117                 attr_ids_[0].ids[0], 1);
    118   MmapRecord r3(*(attr_ids_[0].attr), true, 1, 1, 0x100, 0x2000, 0x3000, "mmap_record1",
    119                 attr_ids_[0].ids[0], 3);
    120   ASSERT_TRUE(writer->WriteRecord(r1));
    121   ASSERT_TRUE(writer->WriteRecord(r2));
    122   ASSERT_TRUE(writer->WriteRecord(r3));
    123   ASSERT_TRUE(writer->Close());
    124 
    125   // Read from a record file.
    126   std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmpfile_.path);
    127   ASSERT_TRUE(reader != nullptr);
    128   std::vector<std::unique_ptr<Record>> records = reader->DataSection();
    129   ASSERT_EQ(3u, records.size());
    130   CheckRecordEqual(r2, *records[0]);
    131   CheckRecordEqual(r1, *records[1]);
    132   CheckRecordEqual(r3, *records[2]);
    133 
    134   ASSERT_TRUE(reader->Close());
    135 }
    136 
    137 TEST_F(RecordFileTest, record_more_than_one_attr) {
    138   // Write to a record file.
    139   std::unique_ptr<RecordFileWriter> writer = RecordFileWriter::CreateInstance(tmpfile_.path);
    140   ASSERT_TRUE(writer != nullptr);
    141 
    142   // Write attr section.
    143   AddEventType("cpu-cycles");
    144   AddEventType("cpu-clock");
    145   AddEventType("task-clock");
    146   ASSERT_TRUE(writer->WriteAttrSection(attr_ids_));
    147 
    148   ASSERT_TRUE(writer->Close());
    149 
    150   // Read from a record file.
    151   std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmpfile_.path);
    152   ASSERT_TRUE(reader != nullptr);
    153   std::vector<EventAttrWithId> attrs = reader->AttrSection();
    154   ASSERT_EQ(3u, attrs.size());
    155   for (size_t i = 0; i < attrs.size(); ++i) {
    156     ASSERT_EQ(0, memcmp(attrs[i].attr, attr_ids_[i].attr, sizeof(perf_event_attr)));
    157     ASSERT_EQ(attrs[i].ids, attr_ids_[i].ids);
    158   }
    159 }
    160