1 /*
2 * Copyright (C) 2020 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 "MapRecordReader.h"
18
19 #include <optional>
20
21 #include <gtest/gtest.h>
22
23 #include "environment.h"
24 #include "event_attr.h"
25 #include "event_type.h"
26
27 using namespace simpleperf;
28
29 // @CddTest = 6.1/C-0-2
30 class MapRecordReaderTest : public ::testing::Test {
31 protected:
CreateMapRecordReader()32 bool CreateMapRecordReader() {
33 const EventType* event_type = FindEventTypeByName("cpu-clock");
34 if (event_type == nullptr) {
35 return false;
36 }
37 attr_ = CreateDefaultPerfEventAttr(*event_type);
38 reader_.emplace(attr_, 0, true);
39 reader_->SetCallback([this](Record* r) { return CountRecord(r); });
40 return true;
41 }
42
CountRecord(Record * r)43 bool CountRecord(Record* r) {
44 if (r->type() == PERF_RECORD_MMAP || r->type() == PERF_RECORD_MMAP2) {
45 map_record_count_++;
46 } else if (r->type() == PERF_RECORD_COMM) {
47 comm_record_count_++;
48 }
49 return true;
50 }
51
52 perf_event_attr attr_;
53 std::optional<MapRecordReader> reader_;
54 size_t map_record_count_ = 0;
55 size_t comm_record_count_ = 0;
56 };
57
58 // @CddTest = 6.1/C-0-2
TEST_F(MapRecordReaderTest,ReadKernelMaps)59 TEST_F(MapRecordReaderTest, ReadKernelMaps) {
60 ASSERT_TRUE(CreateMapRecordReader());
61 ASSERT_TRUE(reader_->ReadKernelMaps());
62 ASSERT_GT(map_record_count_, 0);
63 }
64
65 // @CddTest = 6.1/C-0-2
TEST_F(MapRecordReaderTest,ReadProcessMaps)66 TEST_F(MapRecordReaderTest, ReadProcessMaps) {
67 ASSERT_TRUE(CreateMapRecordReader());
68 ASSERT_TRUE(reader_->ReadProcessMaps(getpid(), 0));
69 ASSERT_GT(map_record_count_, 0);
70 ASSERT_GT(comm_record_count_, 0);
71 }
72
73 // @CddTest = 6.1/C-0-2
TEST_F(MapRecordReaderTest,MapRecordThread)74 TEST_F(MapRecordReaderTest, MapRecordThread) {
75 #ifdef __ANDROID__
76 std::string tmpdir = "/data/local/tmp";
77 #else
78 std::string tmpdir = "/tmp";
79 #endif
80 auto scoped_temp_files = ScopedTempFiles::Create(tmpdir);
81 ASSERT_TRUE(scoped_temp_files);
82 ASSERT_TRUE(CreateMapRecordReader());
83 MapRecordThread thread(*reader_);
84 ASSERT_TRUE(thread.Join());
85 std::vector<char> buffer;
86 ASSERT_TRUE(thread.ReadMapRecordData([&](const char* data, size_t size) {
87 buffer.insert(buffer.end(), data, data + size);
88 return true;
89 }));
90 std::vector<std::unique_ptr<Record>> records =
91 ReadRecordsFromBuffer(attr_, buffer.data(), buffer.size());
92 for (auto& r : records) {
93 ASSERT_TRUE(CountRecord(r.get()));
94 }
95 ASSERT_GT(map_record_count_, 0);
96 ASSERT_GT(comm_record_count_, 0);
97 }
98