OSDN Git Service

Simpleperf: support multiple event types in record command.
[android-x86/system-extras.git] / simpleperf / record_file_test.cpp
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 #include "environment.h"
21 #include "event_attr.h"
22 #include "event_type.h"
23 #include "record.h"
24 #include "record_file.h"
25
26 #include "record_equal_test.h"
27
28 using namespace PerfFileFormat;
29
30 class RecordFileTest : public ::testing::Test {
31  protected:
32   virtual void SetUp() {
33     filename_ = "temporary.record_file";
34   }
35
36   void AddEventType(const std::string& event_type_str) {
37     std::unique_ptr<EventTypeAndModifier> event_type_modifier = ParseEventType(event_type_str);
38     ASSERT_TRUE(event_type_modifier != nullptr);
39     perf_event_attr attr = CreateDefaultPerfEventAttr(event_type_modifier->event_type);
40     attrs_.push_back(attr);
41     AttrWithId attr_id;
42     attr_id.attr = &attrs_[attrs_.size() - 1];
43     attr_id.ids.push_back(attrs_.size());  // Fake id.
44     attr_ids_.push_back(attr_id);
45   }
46
47   std::string filename_;
48   std::vector<perf_event_attr> attrs_;
49   std::vector<AttrWithId> attr_ids_;
50 };
51
52 TEST_F(RecordFileTest, smoke) {
53   // Write to a record file.
54   std::unique_ptr<RecordFileWriter> writer = RecordFileWriter::CreateInstance(filename_);
55   ASSERT_TRUE(writer != nullptr);
56
57   // Write attr section.
58   AddEventType("cpu-cycles");
59   ASSERT_TRUE(writer->WriteAttrSection(attr_ids_));
60
61   // Write data section.
62   MmapRecord mmap_record =
63       CreateMmapRecord(attrs_[0], true, 1, 1, 0x1000, 0x2000, 0x3000, "mmap_record_example");
64   ASSERT_TRUE(writer->WriteData(mmap_record.BinaryFormat()));
65
66   // Check data section that has been written.
67   std::vector<std::unique_ptr<Record>> records;
68   ASSERT_TRUE(writer->ReadDataSection(&records));
69   ASSERT_EQ(1u, records.size());
70   CheckRecordEqual(mmap_record, *records[0]);
71
72   // Write feature section.
73   ASSERT_TRUE(writer->WriteFeatureHeader(1));
74   char p[BuildId::Size()];
75   for (size_t i = 0; i < BuildId::Size(); ++i) {
76     p[i] = i;
77   }
78   BuildId build_id(p);
79   BuildIdRecord build_id_record = CreateBuildIdRecord(false, getpid(), build_id, "init");
80   ASSERT_TRUE(writer->WriteBuildIdFeature({build_id_record}));
81   ASSERT_TRUE(writer->Close());
82
83   // Read from a record file.
84   std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(filename_);
85   ASSERT_TRUE(reader != nullptr);
86   const FileHeader* file_header = reader->FileHeader();
87   ASSERT_TRUE(file_header != nullptr);
88   std::vector<const FileAttr*> file_attrs = reader->AttrSection();
89   ASSERT_EQ(1u, file_attrs.size());
90   ASSERT_EQ(0, memcmp(&file_attrs[0]->attr, attr_ids_[0].attr, sizeof(perf_event_attr)));
91   std::vector<uint64_t> ids = reader->IdsForAttr(file_attrs[0]);
92   ASSERT_EQ(ids, attr_ids_[0].ids);
93
94   // Read and check data section.
95   records = reader->DataSection();
96   ASSERT_EQ(1u, records.size());
97   CheckRecordEqual(mmap_record, *records[0]);
98
99   // Read and check feature section.
100   ASSERT_TRUE(file_header->features[FEAT_BUILD_ID / 8] & (1 << (FEAT_BUILD_ID % 8)));
101   std::map<int, SectionDesc> sections = reader->FeatureSectionDescriptors();
102   ASSERT_EQ(1u, sections.size());
103   ASSERT_TRUE(sections.find(FEAT_BUILD_ID) != sections.end());
104   const perf_event_header* header = reinterpret_cast<const perf_event_header*>(
105       reader->DataAtOffset(sections[FEAT_BUILD_ID].offset));
106   ASSERT_TRUE(header != nullptr);
107   ASSERT_EQ(sections[FEAT_BUILD_ID].size, header->size);
108   CheckRecordEqual(build_id_record, BuildIdRecord(header));
109
110   ASSERT_TRUE(reader->Close());
111 }
112
113 TEST_F(RecordFileTest, records_sorted_by_time) {
114   // Write to a record file.
115   std::unique_ptr<RecordFileWriter> writer = RecordFileWriter::CreateInstance(filename_);
116   ASSERT_TRUE(writer != nullptr);
117
118   // Write attr section.
119   AddEventType("cpu-cycles");
120   attrs_[0].sample_id_all = 1;
121   attrs_[0].sample_type |= PERF_SAMPLE_TIME;
122   ASSERT_TRUE(writer->WriteAttrSection(attr_ids_));
123
124   // Write data section.
125   MmapRecord r1 = CreateMmapRecord(attrs_[0], true, 1, 1, 0x100, 0x2000, 0x3000, "mmap_record1");
126   MmapRecord r2 = r1;
127   MmapRecord r3 = r1;
128   r1.sample_id.time_data.time = 2;
129   r2.sample_id.time_data.time = 1;
130   r3.sample_id.time_data.time = 3;
131   ASSERT_TRUE(writer->WriteData(r1.BinaryFormat()));
132   ASSERT_TRUE(writer->WriteData(r2.BinaryFormat()));
133   ASSERT_TRUE(writer->WriteData(r3.BinaryFormat()));
134   ASSERT_TRUE(writer->Close());
135
136   // Read from a record file.
137   std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(filename_);
138   ASSERT_TRUE(reader != nullptr);
139   std::vector<std::unique_ptr<Record>> records = reader->DataSection();
140   ASSERT_EQ(3u, records.size());
141   CheckRecordEqual(r2, *records[0]);
142   CheckRecordEqual(r1, *records[1]);
143   CheckRecordEqual(r3, *records[2]);
144
145   ASSERT_TRUE(reader->Close());
146 }
147
148 TEST_F(RecordFileTest, record_more_than_one_attr) {
149   // Write to a record file.
150   std::unique_ptr<RecordFileWriter> writer = RecordFileWriter::CreateInstance(filename_);
151   ASSERT_TRUE(writer != nullptr);
152
153   // Write attr section.
154   AddEventType("cpu-cycles");
155   AddEventType("cpu-clock");
156   AddEventType("task-clock");
157   ASSERT_TRUE(writer->WriteAttrSection(attr_ids_));
158
159   ASSERT_TRUE(writer->Close());
160
161   // Read from a record file.
162   std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(filename_);
163   ASSERT_TRUE(reader != nullptr);
164   std::vector<const FileAttr*> file_attrs = reader->AttrSection();
165   ASSERT_EQ(3u, file_attrs.size());
166   for (size_t i = 0; i < file_attrs.size(); ++i) {
167     ASSERT_EQ(0, memcmp(&file_attrs[i]->attr, attr_ids_[i].attr, sizeof(perf_event_attr)));
168     std::vector<uint64_t> ids = reader->IdsForAttr(file_attrs[i]);
169     ASSERT_EQ(ids, attr_ids_[i].ids);
170   }
171 }