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/file.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, record_more_than_one_attr) { 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 AddEventType("cpu-clock"); 110 AddEventType("task-clock"); 111 ASSERT_TRUE(writer->WriteAttrSection(attr_ids_)); 112 113 ASSERT_TRUE(writer->Close()); 114 115 // Read from a record file. 116 std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmpfile_.path); 117 ASSERT_TRUE(reader != nullptr); 118 std::vector<EventAttrWithId> attrs = reader->AttrSection(); 119 ASSERT_EQ(3u, attrs.size()); 120 for (size_t i = 0; i < attrs.size(); ++i) { 121 ASSERT_EQ(0, memcmp(attrs[i].attr, attr_ids_[i].attr, sizeof(perf_event_attr))); 122 ASSERT_EQ(attrs[i].ids, attr_ids_[i].ids); 123 } 124 } 125 126 TEST_F(RecordFileTest, write_meta_info_feature_section) { 127 // Write to a record file. 128 std::unique_ptr<RecordFileWriter> writer = RecordFileWriter::CreateInstance(tmpfile_.path); 129 ASSERT_TRUE(writer != nullptr); 130 AddEventType("cpu-cycles"); 131 ASSERT_TRUE(writer->WriteAttrSection(attr_ids_)); 132 133 // Write meta_info feature section. 134 ASSERT_TRUE(writer->BeginWriteFeatures(1)); 135 std::unordered_map<std::string, std::string> info_map; 136 for (int i = 0; i < 100; ++i) { 137 std::string s = std::to_string(i); 138 info_map[s] = s + s; 139 } 140 ASSERT_TRUE(writer->WriteMetaInfoFeature(info_map)); 141 ASSERT_TRUE(writer->EndWriteFeatures()); 142 ASSERT_TRUE(writer->Close()); 143 144 // Read from a record file. 145 std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmpfile_.path); 146 ASSERT_TRUE(reader != nullptr); 147 ASSERT_EQ(reader->GetMetaInfoFeature(), info_map); 148 } 149