blob: a7670300db8ed5ce1e9982aa51cf12ebfe8600e9 [file] [log] [blame]
Yabin Cui2672dea2015-05-21 12:17:23 -07001/*
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
Yabin Cui6e51bef2016-02-23 21:41:03 -080019#include <set>
20#include <unordered_map>
21
Yabin Cuib1a885b2016-02-14 19:18:02 -080022#include <android-base/file.h>
Yabin Cui6e51bef2016-02-23 21:41:03 -080023#include <android-base/strings.h>
Yabin Cuib1a885b2016-02-14 19:18:02 -080024#include <android-base/test_utils.h>
25
Yabin Cui2672dea2015-05-21 12:17:23 -070026#include "command.h"
Yabin Cuib1a885b2016-02-14 19:18:02 -080027#include "get_test_data.h"
Yabin Cui8f680f62016-03-18 18:47:43 -070028#include "perf_regs.h"
Yabin Cuib1a885b2016-02-14 19:18:02 -080029#include "read_apk.h"
Yabin Cui6e51bef2016-02-23 21:41:03 -080030#include "test_util.h"
Yabin Cui2672dea2015-05-21 12:17:23 -070031
32static std::unique_ptr<Command> ReportCmd() {
33 return CreateCommandInstance("report");
34}
35
36class ReportCommandTest : public ::testing::Test {
37 protected:
Yabin Cui767dd172016-06-02 21:02:43 -070038 void Report(
Chih-Hung Hsieha2b49092016-07-27 15:22:01 -070039 const std::string& perf_data,
Yabin Cui767dd172016-06-02 21:02:43 -070040 const std::vector<std::string>& add_args = std::vector<std::string>()) {
Yabin Cui6e51bef2016-02-23 21:41:03 -080041 ReportRaw(GetTestData(perf_data), add_args);
Yabin Cui2672dea2015-05-21 12:17:23 -070042 }
Yabin Cui6e51bef2016-02-23 21:41:03 -080043
Yabin Cui767dd172016-06-02 21:02:43 -070044 void ReportRaw(
Chih-Hung Hsieha2b49092016-07-27 15:22:01 -070045 const std::string& perf_data,
Yabin Cui767dd172016-06-02 21:02:43 -070046 const std::vector<std::string>& add_args = std::vector<std::string>()) {
Yabin Cui6e51bef2016-02-23 21:41:03 -080047 success = false;
Yabin Cuif560a6f2016-12-14 17:43:26 -080048 TemporaryFile tmp_file;
Yabin Cui767dd172016-06-02 21:02:43 -070049 std::vector<std::string> args = {
50 "-i", perf_data, "--symfs", GetTestDataDir(), "-o", tmp_file.path};
Yabin Cui6e51bef2016-02-23 21:41:03 -080051 args.insert(args.end(), add_args.begin(), add_args.end());
52 ASSERT_TRUE(ReportCmd()->Run(args));
53 ASSERT_TRUE(android::base::ReadFileToString(tmp_file.path, &content));
54 ASSERT_TRUE(!content.empty());
55 std::vector<std::string> raw_lines = android::base::Split(content, "\n");
56 lines.clear();
57 for (const auto& line : raw_lines) {
58 std::string s = android::base::Trim(line);
59 if (!s.empty()) {
60 lines.push_back(s);
61 }
62 }
63 ASSERT_GE(lines.size(), 2u);
64 success = true;
65 }
66
Yabin Cui6e51bef2016-02-23 21:41:03 -080067 std::string content;
68 std::vector<std::string> lines;
69 bool success;
Yabin Cui2672dea2015-05-21 12:17:23 -070070};
71
Yabin Cui6e51bef2016-02-23 21:41:03 -080072TEST_F(ReportCommandTest, no_option) {
73 Report(PERF_DATA);
74 ASSERT_TRUE(success);
75 ASSERT_NE(content.find("GlobalFunc"), std::string::npos);
Yabin Cui2672dea2015-05-21 12:17:23 -070076}
77
Yabin Cui05400532016-03-17 21:18:53 -070078TEST_F(ReportCommandTest, report_symbol_from_elf_file_with_mini_debug_info) {
79 Report(PERF_DATA_WITH_MINI_DEBUG_INFO);
80 ASSERT_TRUE(success);
81 ASSERT_NE(content.find("GlobalFunc"), std::string::npos);
82}
83
Yabin Cui2672dea2015-05-21 12:17:23 -070084TEST_F(ReportCommandTest, sort_option_pid) {
Yabin Cui6e51bef2016-02-23 21:41:03 -080085 Report(PERF_DATA, {"--sort", "pid"});
86 ASSERT_TRUE(success);
87 size_t line_index = 0;
Yabin Cui767dd172016-06-02 21:02:43 -070088 while (line_index < lines.size() &&
89 lines[line_index].find("Pid") == std::string::npos) {
Yabin Cui6e51bef2016-02-23 21:41:03 -080090 line_index++;
91 }
92 ASSERT_LT(line_index + 2, lines.size());
Yabin Cui2672dea2015-05-21 12:17:23 -070093}
94
Yabin Cui6e51bef2016-02-23 21:41:03 -080095TEST_F(ReportCommandTest, sort_option_more_than_one) {
96 Report(PERF_DATA, {"--sort", "comm,pid,dso,symbol"});
97 ASSERT_TRUE(success);
98 size_t line_index = 0;
Yabin Cui767dd172016-06-02 21:02:43 -070099 while (line_index < lines.size() &&
100 lines[line_index].find("Overhead") == std::string::npos) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800101 line_index++;
102 }
103 ASSERT_LT(line_index + 1, lines.size());
104 ASSERT_NE(lines[line_index].find("Command"), std::string::npos);
105 ASSERT_NE(lines[line_index].find("Pid"), std::string::npos);
106 ASSERT_NE(lines[line_index].find("Shared Object"), std::string::npos);
107 ASSERT_NE(lines[line_index].find("Symbol"), std::string::npos);
108 ASSERT_EQ(lines[line_index].find("Tid"), std::string::npos);
Yabin Cui2672dea2015-05-21 12:17:23 -0700109}
Yabin Cui8a530e32015-06-23 20:42:01 -0700110
Yabin Cuiecb9a302015-07-01 10:00:52 -0700111TEST_F(ReportCommandTest, children_option) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800112 Report(CALLGRAPH_FP_PERF_DATA, {"--children", "--sort", "symbol"});
113 ASSERT_TRUE(success);
114 std::unordered_map<std::string, std::pair<double, double>> map;
115 for (size_t i = 0; i < lines.size(); ++i) {
116 char name[1024];
117 std::pair<double, double> pair;
Yabin Cui767dd172016-06-02 21:02:43 -0700118 if (sscanf(lines[i].c_str(), "%lf%%%lf%%%s", &pair.first, &pair.second,
119 name) == 3) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800120 map.insert(std::make_pair(name, pair));
121 }
122 }
123 ASSERT_NE(map.find("GlobalFunc"), map.end());
124 ASSERT_NE(map.find("main"), map.end());
125 auto func_pair = map["GlobalFunc"];
126 auto main_pair = map["main"];
127 ASSERT_GE(main_pair.first, func_pair.first);
128 ASSERT_GE(func_pair.first, func_pair.second);
129 ASSERT_GE(func_pair.second, main_pair.second);
130}
131
132static bool CheckCalleeMode(std::vector<std::string>& lines) {
133 bool found = false;
Yabin Cuidcb2a3e2017-05-18 17:11:32 -0700134 for (size_t i = 0; i + 1 < lines.size(); ++i) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800135 if (lines[i].find("GlobalFunc") != std::string::npos &&
Yabin Cuidcb2a3e2017-05-18 17:11:32 -0700136 lines[i + 1].find("main") != std::string::npos) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800137 found = true;
138 break;
139 }
140 }
141 return found;
142}
143
144static bool CheckCallerMode(std::vector<std::string>& lines) {
145 bool found = false;
Yabin Cuidcb2a3e2017-05-18 17:11:32 -0700146 for (size_t i = 0; i + 1 < lines.size(); ++i) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800147 if (lines[i].find("main") != std::string::npos &&
Yabin Cuidcb2a3e2017-05-18 17:11:32 -0700148 lines[i + 1].find("GlobalFunc") != std::string::npos) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800149 found = true;
150 break;
151 }
152 }
153 return found;
Yabin Cuiecb9a302015-07-01 10:00:52 -0700154}
155
156TEST_F(ReportCommandTest, callgraph_option) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800157 Report(CALLGRAPH_FP_PERF_DATA, {"-g"});
158 ASSERT_TRUE(success);
Yabin Cui8a599d72016-07-21 18:32:53 -0700159 ASSERT_TRUE(CheckCallerMode(lines));
Yabin Cui6e51bef2016-02-23 21:41:03 -0800160 Report(CALLGRAPH_FP_PERF_DATA, {"-g", "callee"});
161 ASSERT_TRUE(success);
162 ASSERT_TRUE(CheckCalleeMode(lines));
163 Report(CALLGRAPH_FP_PERF_DATA, {"-g", "caller"});
164 ASSERT_TRUE(success);
165 ASSERT_TRUE(CheckCallerMode(lines));
166}
167
Yabin Cui767dd172016-06-02 21:02:43 -0700168static bool AllItemsWithString(std::vector<std::string>& lines,
169 const std::vector<std::string>& strs) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800170 size_t line_index = 0;
Yabin Cui767dd172016-06-02 21:02:43 -0700171 while (line_index < lines.size() &&
172 lines[line_index].find("Overhead") == std::string::npos) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800173 line_index++;
174 }
175 if (line_index == lines.size() || line_index + 1 == lines.size()) {
176 return false;
177 }
178 line_index++;
179 for (; line_index < lines.size(); ++line_index) {
180 bool exist = false;
181 for (auto& s : strs) {
182 if (lines[line_index].find(s) != std::string::npos) {
183 exist = true;
184 break;
185 }
186 }
187 if (!exist) {
188 return false;
189 }
190 }
191 return true;
Yabin Cuiecb9a302015-07-01 10:00:52 -0700192}
193
Yabin Cui38e573e2015-08-06 11:25:09 -0700194TEST_F(ReportCommandTest, pid_filter_option) {
Yabin Cui861f6552016-08-08 14:42:25 -0700195 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--sort", "pid"});
Yabin Cui6e51bef2016-02-23 21:41:03 -0800196 ASSERT_TRUE(success);
Yabin Cui861f6552016-08-08 14:42:25 -0700197 ASSERT_FALSE(AllItemsWithString(lines, {"17441"}));
198 ASSERT_FALSE(AllItemsWithString(lines, {"17441", "17443"}));
199 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS,
200 {"--sort", "pid", "--pids", "17441"});
Yabin Cui6e51bef2016-02-23 21:41:03 -0800201 ASSERT_TRUE(success);
Yabin Cui861f6552016-08-08 14:42:25 -0700202 ASSERT_TRUE(AllItemsWithString(lines, {"17441"}));
203 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS,
204 {"--sort", "pid", "--pids", "17441,17443"});
205 ASSERT_TRUE(success);
206 ASSERT_TRUE(AllItemsWithString(lines, {"17441", "17443"}));
207
208 // Test that --pids option is not the same as --tids option.
209 // Thread 17445 and 17441 are in process 17441.
210 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS,
211 {"--sort", "tid", "--pids", "17441"});
212 ASSERT_TRUE(success);
213 ASSERT_NE(content.find("17441"), std::string::npos);
214 ASSERT_NE(content.find("17445"), std::string::npos);
215}
216
217TEST_F(ReportCommandTest, wrong_pid_filter_option) {
218 ASSERT_EXIT(
219 {
220 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--pids", "2,bogus"});
221 exit(success ? 0 : 1);
222 },
223 testing::ExitedWithCode(1), "invalid id in --pids option: bogus");
Yabin Cui38e573e2015-08-06 11:25:09 -0700224}
225
226TEST_F(ReportCommandTest, tid_filter_option) {
Yabin Cui861f6552016-08-08 14:42:25 -0700227 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--sort", "tid"});
Yabin Cui6e51bef2016-02-23 21:41:03 -0800228 ASSERT_TRUE(success);
Yabin Cui861f6552016-08-08 14:42:25 -0700229 ASSERT_FALSE(AllItemsWithString(lines, {"17441"}));
230 ASSERT_FALSE(AllItemsWithString(lines, {"17441", "17445"}));
231 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS,
232 {"--sort", "tid", "--tids", "17441"});
Yabin Cui6e51bef2016-02-23 21:41:03 -0800233 ASSERT_TRUE(success);
Yabin Cui861f6552016-08-08 14:42:25 -0700234 ASSERT_TRUE(AllItemsWithString(lines, {"17441"}));
235 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS,
236 {"--sort", "tid", "--tids", "17441,17445"});
237 ASSERT_TRUE(success);
238 ASSERT_TRUE(AllItemsWithString(lines, {"17441", "17445"}));
239}
240
241TEST_F(ReportCommandTest, wrong_tid_filter_option) {
242 ASSERT_EXIT(
243 {
244 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--tids", "2,bogus"});
245 exit(success ? 0 : 1);
246 },
247 testing::ExitedWithCode(1), "invalid id in --tids option: bogus");
Yabin Cui38e573e2015-08-06 11:25:09 -0700248}
249
250TEST_F(ReportCommandTest, comm_filter_option) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800251 Report(PERF_DATA, {"--sort", "comm"});
252 ASSERT_TRUE(success);
253 ASSERT_FALSE(AllItemsWithString(lines, {"t1"}));
254 ASSERT_FALSE(AllItemsWithString(lines, {"t1", "t2"}));
255 Report(PERF_DATA, {"--sort", "comm", "--comms", "t1"});
256 ASSERT_TRUE(success);
257 ASSERT_TRUE(AllItemsWithString(lines, {"t1"}));
258 Report(PERF_DATA, {"--sort", "comm", "--comms", "t1,t2"});
259 ASSERT_TRUE(success);
260 ASSERT_TRUE(AllItemsWithString(lines, {"t1", "t2"}));
Yabin Cui38e573e2015-08-06 11:25:09 -0700261}
262
263TEST_F(ReportCommandTest, dso_filter_option) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800264 Report(PERF_DATA, {"--sort", "dso"});
265 ASSERT_TRUE(success);
266 ASSERT_FALSE(AllItemsWithString(lines, {"/t1"}));
267 ASSERT_FALSE(AllItemsWithString(lines, {"/t1", "/t2"}));
268 Report(PERF_DATA, {"--sort", "dso", "--dsos", "/t1"});
269 ASSERT_TRUE(success);
270 ASSERT_TRUE(AllItemsWithString(lines, {"/t1"}));
271 Report(PERF_DATA, {"--sort", "dso", "--dsos", "/t1,/t2"});
272 ASSERT_TRUE(success);
273 ASSERT_TRUE(AllItemsWithString(lines, {"/t1", "/t2"}));
Yabin Cui38e573e2015-08-06 11:25:09 -0700274}
275
Yabin Cuif79fbd12016-07-06 12:26:13 -0700276TEST_F(ReportCommandTest, symbol_filter_option) {
277 Report(PERF_DATA_WITH_SYMBOLS, {"--sort", "symbol"});
278 ASSERT_TRUE(success);
Yabin Cui05ef2ea2016-07-11 13:50:01 -0700279 ASSERT_FALSE(AllItemsWithString(lines, {"func2(int, int)"}));
280 ASSERT_FALSE(AllItemsWithString(lines, {"main", "func2(int, int)"}));
Yabin Cuif79fbd12016-07-06 12:26:13 -0700281 Report(PERF_DATA_WITH_SYMBOLS,
Yabin Cui05ef2ea2016-07-11 13:50:01 -0700282 {"--sort", "symbol", "--symbols", "func2(int, int)"});
Yabin Cuif79fbd12016-07-06 12:26:13 -0700283 ASSERT_TRUE(success);
Yabin Cui05ef2ea2016-07-11 13:50:01 -0700284 ASSERT_TRUE(AllItemsWithString(lines, {"func2(int, int)"}));
Yabin Cuif79fbd12016-07-06 12:26:13 -0700285 Report(PERF_DATA_WITH_SYMBOLS,
Yabin Cui05ef2ea2016-07-11 13:50:01 -0700286 {"--sort", "symbol", "--symbols", "main;func2(int, int)"});
Yabin Cuif79fbd12016-07-06 12:26:13 -0700287 ASSERT_TRUE(success);
Yabin Cui05ef2ea2016-07-11 13:50:01 -0700288 ASSERT_TRUE(AllItemsWithString(lines, {"main", "func2(int, int)"}));
Yabin Cuif79fbd12016-07-06 12:26:13 -0700289}
290
Yabin Cui6e51bef2016-02-23 21:41:03 -0800291TEST_F(ReportCommandTest, use_branch_address) {
292 Report(BRANCH_PERF_DATA, {"-b", "--sort", "symbol_from,symbol_to"});
293 std::set<std::pair<std::string, std::string>> hit_set;
294 bool after_overhead = false;
295 for (const auto& line : lines) {
296 if (!after_overhead && line.find("Overhead") != std::string::npos) {
297 after_overhead = true;
298 } else if (after_overhead) {
299 char from[80];
300 char to[80];
301 if (sscanf(line.c_str(), "%*f%%%s%s", from, to) == 2) {
302 hit_set.insert(std::make_pair<std::string, std::string>(from, to));
303 }
304 }
Yabin Cui8a530e32015-06-23 20:42:01 -0700305 }
Yabin Cui767dd172016-06-02 21:02:43 -0700306 ASSERT_NE(hit_set.find(std::make_pair<std::string, std::string>(
307 "GlobalFunc", "CalledFunc")),
Yabin Cui6e51bef2016-02-23 21:41:03 -0800308 hit_set.end());
Yabin Cui767dd172016-06-02 21:02:43 -0700309 ASSERT_NE(hit_set.find(std::make_pair<std::string, std::string>(
310 "CalledFunc", "GlobalFunc")),
Yabin Cui6e51bef2016-02-23 21:41:03 -0800311 hit_set.end());
Yabin Cui8a530e32015-06-23 20:42:01 -0700312}
Yabin Cui3c8c2132015-08-13 20:30:20 -0700313
Yabin Cui8f680f62016-03-18 18:47:43 -0700314TEST_F(ReportCommandTest, report_symbols_of_nativelib_in_apk) {
315 Report(NATIVELIB_IN_APK_PERF_DATA);
316 ASSERT_TRUE(success);
Yabin Cui767dd172016-06-02 21:02:43 -0700317 ASSERT_NE(content.find(GetUrlInApk(APK_FILE, NATIVELIB_IN_APK)),
318 std::string::npos);
Yabin Cui8f680f62016-03-18 18:47:43 -0700319 ASSERT_NE(content.find("Func2"), std::string::npos);
320}
321
Yabin Cui2d6efe42016-04-01 20:22:35 -0700322TEST_F(ReportCommandTest, report_more_than_one_event_types) {
323 Report(PERF_DATA_WITH_TWO_EVENT_TYPES);
324 ASSERT_TRUE(success);
Yabin Cuiada97db2017-02-23 15:54:11 -0800325 size_t pos = 0;
326 ASSERT_NE(pos = content.find("cpu-cycles", pos), std::string::npos);
327 ASSERT_NE(pos = content.find("Samples:", pos), std::string::npos);
328 ASSERT_NE(pos = content.find("cpu-clock", pos), std::string::npos);
329 ASSERT_NE(pos = content.find("Samples:", pos), std::string::npos);
Yabin Cui2d6efe42016-04-01 20:22:35 -0700330}
331
Yabin Cuib4212972016-05-25 14:08:05 -0700332TEST_F(ReportCommandTest, report_kernel_symbol) {
333 Report(PERF_DATA_WITH_KERNEL_SYMBOL);
334 ASSERT_TRUE(success);
Yabin Cui1761a272016-06-23 17:11:14 -0700335 ASSERT_NE(content.find("perf_event_aux"), std::string::npos);
Yabin Cuib4212972016-05-25 14:08:05 -0700336}
337
Yabin Cui767dd172016-06-02 21:02:43 -0700338TEST_F(ReportCommandTest, report_dumped_symbols) {
339 Report(PERF_DATA_WITH_SYMBOLS);
340 ASSERT_TRUE(success);
Yabin Cui05ef2ea2016-07-11 13:50:01 -0700341 ASSERT_NE(content.find("main"), std::string::npos);
Yabin Cuic855ecc2016-07-11 17:04:54 -0700342 Report(PERF_DATA_WITH_SYMBOLS_FOR_NONZERO_MINVADDR_DSO);
343 ASSERT_TRUE(success);
Yabin Cuic5b4a312016-10-24 13:38:38 -0700344 ASSERT_NE(content.find("memcpy"), std::string::npos);
Yabin Cui767dd172016-06-02 21:02:43 -0700345}
346
Yabin Cuie2f10782016-12-15 12:00:44 -0800347TEST_F(ReportCommandTest, report_dumped_symbols_with_symfs_dir) {
348 // Check if we can report symbols when they appear both in perf.data and symfs dir.
349 Report(PERF_DATA_WITH_SYMBOLS, {"--symfs", GetTestDataDir()});
350 ASSERT_TRUE(success);
351 ASSERT_NE(content.find("main"), std::string::npos);
352}
353
Yabin Cui16f93102018-11-13 11:09:20 -0800354TEST_F(ReportCommandTest, report_without_symfs_dir) {
355 TemporaryFile tmpfile;
356 ASSERT_TRUE(ReportCmd()->Run({"-i", GetTestData(PERF_DATA), "-o", tmpfile.path}));
357}
358
Yabin Cui9970a232016-06-29 12:18:11 -0700359TEST_F(ReportCommandTest, report_sort_vaddr_in_file) {
360 Report(PERF_DATA, {"--sort", "vaddr_in_file"});
361 ASSERT_TRUE(success);
362 ASSERT_NE(content.find("VaddrInFile"), std::string::npos);
363}
364
Yabin Cuieec606c2016-07-07 13:53:33 -0700365TEST_F(ReportCommandTest, check_build_id) {
366 Report(PERF_DATA_FOR_BUILD_ID_CHECK,
367 {"--symfs", GetTestData(CORRECT_SYMFS_FOR_BUILD_ID_CHECK)});
368 ASSERT_TRUE(success);
369 ASSERT_NE(content.find("main"), std::string::npos);
370 ASSERT_EXIT(
371 {
372 Report(PERF_DATA_FOR_BUILD_ID_CHECK,
373 {"--symfs", GetTestData(WRONG_SYMFS_FOR_BUILD_ID_CHECK)});
374 if (!success) {
375 exit(1);
376 }
377 if (content.find("main") != std::string::npos) {
378 exit(2);
379 }
380 exit(0);
381 },
Yabin Cui40b70ff2018-04-09 14:06:08 -0700382 testing::ExitedWithCode(0), "failed to read symbols from /elf_for_build_id_check");
Yabin Cuieec606c2016-07-07 13:53:33 -0700383}
384
Yabin Cui15475e62016-07-14 13:26:19 -0700385TEST_F(ReportCommandTest, no_show_ip_option) {
386 Report(PERF_DATA);
387 ASSERT_TRUE(success);
388 ASSERT_EQ(content.find("unknown"), std::string::npos);
389 Report(PERF_DATA, {"--no-show-ip"});
390 ASSERT_TRUE(success);
391 ASSERT_NE(content.find("unknown"), std::string::npos);
392}
393
Yabin Cuidec43c12016-07-29 16:40:40 -0700394TEST_F(ReportCommandTest, no_symbol_table_warning) {
395 ASSERT_EXIT(
396 {
397 Report(PERF_DATA,
398 {"--symfs", GetTestData(SYMFS_FOR_NO_SYMBOL_TABLE_WARNING)});
399 if (!success) {
400 exit(1);
401 }
402 if (content.find("GlobalFunc") != std::string::npos) {
403 exit(2);
404 }
405 exit(0);
406 },
407 testing::ExitedWithCode(0), "elf doesn't contain symbol table");
408}
409
410TEST_F(ReportCommandTest, read_elf_file_warning) {
411 ASSERT_EXIT(
412 {
413 Report(PERF_DATA,
414 {"--symfs", GetTestData(SYMFS_FOR_READ_ELF_FILE_WARNING)});
415 if (!success) {
416 exit(1);
417 }
418 if (content.find("GlobalFunc") != std::string::npos) {
419 exit(2);
420 }
421 exit(0);
422 },
Yabin Cui40b70ff2018-04-09 14:06:08 -0700423 testing::ExitedWithCode(0), "failed to read symbols from /elf: File not found");
Yabin Cuidec43c12016-07-29 16:40:40 -0700424}
425
Yabin Cuieafa7182016-08-30 13:13:17 -0700426TEST_F(ReportCommandTest, report_data_generated_by_linux_perf) {
427 Report(PERF_DATA_GENERATED_BY_LINUX_PERF);
428 ASSERT_TRUE(success);
429}
430
Yabin Cuic0565bb2016-09-29 15:59:33 -0700431TEST_F(ReportCommandTest, max_stack_and_percent_limit_option) {
432 Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, {"-g"});
433 ASSERT_TRUE(success);
434 ASSERT_NE(content.find("89.03"), std::string::npos);
435
436 Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, {"-g", "--max-stack", "0"});
437 ASSERT_TRUE(success);
438 ASSERT_EQ(content.find("89.03"), std::string::npos);
Yabin Cuidcb2a3e2017-05-18 17:11:32 -0700439 Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, {"-g", "--max-stack", "2"});
Yabin Cuic0565bb2016-09-29 15:59:33 -0700440 ASSERT_TRUE(success);
441 ASSERT_NE(content.find("89.03"), std::string::npos);
442
443 Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT,
444 {"-g", "--percent-limit", "90"});
445 ASSERT_TRUE(success);
446 ASSERT_EQ(content.find("89.03"), std::string::npos);
447 Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT,
448 {"-g", "--percent-limit", "70"});
449 ASSERT_TRUE(success);
450 ASSERT_NE(content.find("89.03"), std::string::npos);
451}
452
Yabin Cui18385c42016-12-09 14:51:04 -0800453TEST_F(ReportCommandTest, kallsyms_option) {
454 Report(PERF_DATA, {"--kallsyms", GetTestData("kallsyms")});
455 ASSERT_TRUE(success);
456 ASSERT_NE(content.find("FakeKernelSymbol"), std::string::npos);
457}
458
Yabin Cui044861b2016-12-13 17:49:19 -0800459TEST_F(ReportCommandTest, invalid_perf_data) {
460 ASSERT_FALSE(ReportCmd()->Run({"-i", GetTestData(INVALID_PERF_DATA)}));
461}
462
Yabin Cuiafe99a52017-02-23 16:27:09 -0800463TEST_F(ReportCommandTest, raw_period_option) {
464 Report(PERF_DATA, {"--raw-period"});
465 ASSERT_TRUE(success);
466 ASSERT_NE(content.find("GlobalFunc"), std::string::npos);
Chih-Hung Hsiehf6d5b0d2017-08-03 14:04:06 -0700467 ASSERT_EQ(content.find('%'), std::string::npos);
Yabin Cuiafe99a52017-02-23 16:27:09 -0800468}
469
Yabin Cuidcb2a3e2017-05-18 17:11:32 -0700470TEST_F(ReportCommandTest, full_callgraph_option) {
471 Report(CALLGRAPH_FP_PERF_DATA, {"-g"});
Yabin Cui0c093f32017-04-19 11:48:44 -0700472 ASSERT_TRUE(success);
473 ASSERT_NE(content.find("skipped in brief callgraph mode"), std::string::npos);
Yabin Cuidcb2a3e2017-05-18 17:11:32 -0700474 Report(CALLGRAPH_FP_PERF_DATA, {"-g", "--full-callgraph"});
475 ASSERT_TRUE(success);
476 ASSERT_EQ(content.find("skipped in brief callgraph mode"), std::string::npos);
Yabin Cui0c093f32017-04-19 11:48:44 -0700477}
478
Yabin Cui68b83832017-07-19 17:54:57 -0700479TEST_F(ReportCommandTest, report_offcpu_time) {
480 Report(PERF_DATA_WITH_TRACE_OFFCPU, {"--children"});
481 ASSERT_TRUE(success);
482 ASSERT_NE(content.find("Time in ns"), std::string::npos);
483 bool found = false;
484 for (auto& line : lines) {
485 if (line.find("SleepFunction") != std::string::npos) {
Yabin Cui8b5a3522018-06-18 17:44:27 -0700486 ASSERT_NE(line.find("38.76%"), std::string::npos);
Yabin Cui68b83832017-07-19 17:54:57 -0700487 found = true;
488 break;
489 }
490 }
491 ASSERT_TRUE(found);
492}
493
Yabin Cui8cd92332018-03-21 14:34:29 -0700494TEST_F(ReportCommandTest, report_big_trace_data) {
495 Report(PERF_DATA_WITH_BIG_TRACE_DATA);
496 ASSERT_TRUE(success);
497}
498
Yabin Cui19e6b6d2016-03-10 11:49:57 -0800499#if defined(__linux__)
Yabin Cui003b2452016-09-29 15:32:45 -0700500#include "event_selection_set.h"
Yabin Cui6e51bef2016-02-23 21:41:03 -0800501
502static std::unique_ptr<Command> RecordCmd() {
503 return CreateCommandInstance("record");
Yabin Cui3c8c2132015-08-13 20:30:20 -0700504}
Yabin Cuib1a885b2016-02-14 19:18:02 -0800505
Yabin Cui6e51bef2016-02-23 21:41:03 -0800506TEST_F(ReportCommandTest, dwarf_callgraph) {
Yabin Cui8faa6152018-06-07 15:52:57 -0700507 TEST_REQUIRE_HW_COUNTER();
Yabin Cui64a9ecd2017-09-13 13:21:32 -0700508 OMIT_TEST_ON_NON_NATIVE_ABIS();
Yabin Cuid18c42e2017-07-12 14:50:07 -0700509 ASSERT_TRUE(IsDwarfCallChainSamplingSupported());
510 std::vector<std::unique_ptr<Workload>> workloads;
511 CreateProcesses(1, &workloads);
512 std::string pid = std::to_string(workloads[0]->GetPid());
513 TemporaryFile tmp_file;
514 ASSERT_TRUE(
515 RecordCmd()->Run({"-p", pid, "-g", "-o", tmp_file.path, "sleep", SLEEP_SEC}));
516 ReportRaw(tmp_file.path, {"-g"});
517 ASSERT_TRUE(success);
Yabin Cui6e51bef2016-02-23 21:41:03 -0800518}
519
Yabin Cui8f680f62016-03-18 18:47:43 -0700520TEST_F(ReportCommandTest, report_dwarf_callgraph_of_nativelib_in_apk) {
Yabin Cui6e75e1b2018-02-06 13:42:16 -0800521 Report(NATIVELIB_IN_APK_PERF_DATA, {"-g"});
522 ASSERT_NE(content.find(GetUrlInApk(APK_FILE, NATIVELIB_IN_APK)),
523 std::string::npos);
524 ASSERT_NE(content.find("Func2"), std::string::npos);
525 ASSERT_NE(content.find("Func1"), std::string::npos);
526 ASSERT_NE(content.find("GlobalFunc"), std::string::npos);
Yabin Cui8f680f62016-03-18 18:47:43 -0700527}
528
Yabin Cuid3cb3b02017-07-24 14:59:46 -0700529TEST_F(ReportCommandTest, exclude_kernel_callchain) {
Yabin Cui8faa6152018-06-07 15:52:57 -0700530 TEST_REQUIRE_HW_COUNTER();
Yabin Cuid3cb3b02017-07-24 14:59:46 -0700531 TEST_REQUIRE_HOST_ROOT();
Yabin Cui64a9ecd2017-09-13 13:21:32 -0700532 OMIT_TEST_ON_NON_NATIVE_ABIS();
Yabin Cuid3cb3b02017-07-24 14:59:46 -0700533 std::vector<std::unique_ptr<Workload>> workloads;
534 CreateProcesses(1, &workloads);
535 std::string pid = std::to_string(workloads[0]->GetPid());
536 TemporaryFile tmpfile;
537 ASSERT_TRUE(RecordCmd()->Run({"--trace-offcpu", "-e", "cpu-cycles:u", "-p", pid,
538 "--duration", "2", "-o", tmpfile.path, "-g"}));
539 ReportRaw(tmpfile.path, {"-g"});
540 ASSERT_TRUE(success);
541 ASSERT_EQ(content.find("[kernel.kallsyms]"), std::string::npos);
542}
543
Yabin Cui6e51bef2016-02-23 21:41:03 -0800544#endif