blob: f445bd5a381193fdb24d31626cd3a7e4953531b2 [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 Cui767dd172016-06-02 21:02:43 -070048 std::vector<std::string> args = {
49 "-i", perf_data, "--symfs", GetTestDataDir(), "-o", tmp_file.path};
Yabin Cui6e51bef2016-02-23 21:41:03 -080050 args.insert(args.end(), add_args.begin(), add_args.end());
51 ASSERT_TRUE(ReportCmd()->Run(args));
52 ASSERT_TRUE(android::base::ReadFileToString(tmp_file.path, &content));
53 ASSERT_TRUE(!content.empty());
54 std::vector<std::string> raw_lines = android::base::Split(content, "\n");
55 lines.clear();
56 for (const auto& line : raw_lines) {
57 std::string s = android::base::Trim(line);
58 if (!s.empty()) {
59 lines.push_back(s);
60 }
61 }
62 ASSERT_GE(lines.size(), 2u);
63 success = true;
64 }
65
66 TemporaryFile tmp_file;
67 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;
134 for (size_t i = 0; i + 2 < lines.size(); ++i) {
135 if (lines[i].find("GlobalFunc") != std::string::npos &&
Chih-Hung Hsieha2b49092016-07-27 15:22:01 -0700136 lines[i + 1].find('|') != std::string::npos &&
Yabin Cui6e51bef2016-02-23 21:41:03 -0800137 lines[i + 2].find("main") != std::string::npos) {
138 found = true;
139 break;
140 }
141 }
142 return found;
143}
144
145static bool CheckCallerMode(std::vector<std::string>& lines) {
146 bool found = false;
147 for (size_t i = 0; i + 2 < lines.size(); ++i) {
148 if (lines[i].find("main") != std::string::npos &&
Chih-Hung Hsieha2b49092016-07-27 15:22:01 -0700149 lines[i + 1].find('|') != std::string::npos &&
Yabin Cui6e51bef2016-02-23 21:41:03 -0800150 lines[i + 2].find("GlobalFunc") != std::string::npos) {
151 found = true;
152 break;
153 }
154 }
155 return found;
Yabin Cuiecb9a302015-07-01 10:00:52 -0700156}
157
158TEST_F(ReportCommandTest, callgraph_option) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800159 Report(CALLGRAPH_FP_PERF_DATA, {"-g"});
160 ASSERT_TRUE(success);
Yabin Cui8a599d72016-07-21 18:32:53 -0700161 ASSERT_TRUE(CheckCallerMode(lines));
Yabin Cui6e51bef2016-02-23 21:41:03 -0800162 Report(CALLGRAPH_FP_PERF_DATA, {"-g", "callee"});
163 ASSERT_TRUE(success);
164 ASSERT_TRUE(CheckCalleeMode(lines));
165 Report(CALLGRAPH_FP_PERF_DATA, {"-g", "caller"});
166 ASSERT_TRUE(success);
167 ASSERT_TRUE(CheckCallerMode(lines));
168}
169
Yabin Cui767dd172016-06-02 21:02:43 -0700170static bool AllItemsWithString(std::vector<std::string>& lines,
171 const std::vector<std::string>& strs) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800172 size_t line_index = 0;
Yabin Cui767dd172016-06-02 21:02:43 -0700173 while (line_index < lines.size() &&
174 lines[line_index].find("Overhead") == std::string::npos) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800175 line_index++;
176 }
177 if (line_index == lines.size() || line_index + 1 == lines.size()) {
178 return false;
179 }
180 line_index++;
181 for (; line_index < lines.size(); ++line_index) {
182 bool exist = false;
183 for (auto& s : strs) {
184 if (lines[line_index].find(s) != std::string::npos) {
185 exist = true;
186 break;
187 }
188 }
189 if (!exist) {
190 return false;
191 }
192 }
193 return true;
Yabin Cuiecb9a302015-07-01 10:00:52 -0700194}
195
Yabin Cui38e573e2015-08-06 11:25:09 -0700196TEST_F(ReportCommandTest, pid_filter_option) {
Yabin Cui861f6552016-08-08 14:42:25 -0700197 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--sort", "pid"});
Yabin Cui6e51bef2016-02-23 21:41:03 -0800198 ASSERT_TRUE(success);
Yabin Cui861f6552016-08-08 14:42:25 -0700199 ASSERT_FALSE(AllItemsWithString(lines, {"17441"}));
200 ASSERT_FALSE(AllItemsWithString(lines, {"17441", "17443"}));
201 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS,
202 {"--sort", "pid", "--pids", "17441"});
Yabin Cui6e51bef2016-02-23 21:41:03 -0800203 ASSERT_TRUE(success);
Yabin Cui861f6552016-08-08 14:42:25 -0700204 ASSERT_TRUE(AllItemsWithString(lines, {"17441"}));
205 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS,
206 {"--sort", "pid", "--pids", "17441,17443"});
207 ASSERT_TRUE(success);
208 ASSERT_TRUE(AllItemsWithString(lines, {"17441", "17443"}));
209
210 // Test that --pids option is not the same as --tids option.
211 // Thread 17445 and 17441 are in process 17441.
212 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS,
213 {"--sort", "tid", "--pids", "17441"});
214 ASSERT_TRUE(success);
215 ASSERT_NE(content.find("17441"), std::string::npos);
216 ASSERT_NE(content.find("17445"), std::string::npos);
217}
218
219TEST_F(ReportCommandTest, wrong_pid_filter_option) {
220 ASSERT_EXIT(
221 {
222 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--pids", "2,bogus"});
223 exit(success ? 0 : 1);
224 },
225 testing::ExitedWithCode(1), "invalid id in --pids option: bogus");
Yabin Cui38e573e2015-08-06 11:25:09 -0700226}
227
228TEST_F(ReportCommandTest, tid_filter_option) {
Yabin Cui861f6552016-08-08 14:42:25 -0700229 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--sort", "tid"});
Yabin Cui6e51bef2016-02-23 21:41:03 -0800230 ASSERT_TRUE(success);
Yabin Cui861f6552016-08-08 14:42:25 -0700231 ASSERT_FALSE(AllItemsWithString(lines, {"17441"}));
232 ASSERT_FALSE(AllItemsWithString(lines, {"17441", "17445"}));
233 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS,
234 {"--sort", "tid", "--tids", "17441"});
Yabin Cui6e51bef2016-02-23 21:41:03 -0800235 ASSERT_TRUE(success);
Yabin Cui861f6552016-08-08 14:42:25 -0700236 ASSERT_TRUE(AllItemsWithString(lines, {"17441"}));
237 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS,
238 {"--sort", "tid", "--tids", "17441,17445"});
239 ASSERT_TRUE(success);
240 ASSERT_TRUE(AllItemsWithString(lines, {"17441", "17445"}));
241}
242
243TEST_F(ReportCommandTest, wrong_tid_filter_option) {
244 ASSERT_EXIT(
245 {
246 Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--tids", "2,bogus"});
247 exit(success ? 0 : 1);
248 },
249 testing::ExitedWithCode(1), "invalid id in --tids option: bogus");
Yabin Cui38e573e2015-08-06 11:25:09 -0700250}
251
252TEST_F(ReportCommandTest, comm_filter_option) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800253 Report(PERF_DATA, {"--sort", "comm"});
254 ASSERT_TRUE(success);
255 ASSERT_FALSE(AllItemsWithString(lines, {"t1"}));
256 ASSERT_FALSE(AllItemsWithString(lines, {"t1", "t2"}));
257 Report(PERF_DATA, {"--sort", "comm", "--comms", "t1"});
258 ASSERT_TRUE(success);
259 ASSERT_TRUE(AllItemsWithString(lines, {"t1"}));
260 Report(PERF_DATA, {"--sort", "comm", "--comms", "t1,t2"});
261 ASSERT_TRUE(success);
262 ASSERT_TRUE(AllItemsWithString(lines, {"t1", "t2"}));
Yabin Cui38e573e2015-08-06 11:25:09 -0700263}
264
265TEST_F(ReportCommandTest, dso_filter_option) {
Yabin Cui6e51bef2016-02-23 21:41:03 -0800266 Report(PERF_DATA, {"--sort", "dso"});
267 ASSERT_TRUE(success);
268 ASSERT_FALSE(AllItemsWithString(lines, {"/t1"}));
269 ASSERT_FALSE(AllItemsWithString(lines, {"/t1", "/t2"}));
270 Report(PERF_DATA, {"--sort", "dso", "--dsos", "/t1"});
271 ASSERT_TRUE(success);
272 ASSERT_TRUE(AllItemsWithString(lines, {"/t1"}));
273 Report(PERF_DATA, {"--sort", "dso", "--dsos", "/t1,/t2"});
274 ASSERT_TRUE(success);
275 ASSERT_TRUE(AllItemsWithString(lines, {"/t1", "/t2"}));
Yabin Cui38e573e2015-08-06 11:25:09 -0700276}
277
Yabin Cuif79fbd12016-07-06 12:26:13 -0700278TEST_F(ReportCommandTest, symbol_filter_option) {
279 Report(PERF_DATA_WITH_SYMBOLS, {"--sort", "symbol"});
280 ASSERT_TRUE(success);
Yabin Cui05ef2ea2016-07-11 13:50:01 -0700281 ASSERT_FALSE(AllItemsWithString(lines, {"func2(int, int)"}));
282 ASSERT_FALSE(AllItemsWithString(lines, {"main", "func2(int, int)"}));
Yabin Cuif79fbd12016-07-06 12:26:13 -0700283 Report(PERF_DATA_WITH_SYMBOLS,
Yabin Cui05ef2ea2016-07-11 13:50:01 -0700284 {"--sort", "symbol", "--symbols", "func2(int, int)"});
Yabin Cuif79fbd12016-07-06 12:26:13 -0700285 ASSERT_TRUE(success);
Yabin Cui05ef2ea2016-07-11 13:50:01 -0700286 ASSERT_TRUE(AllItemsWithString(lines, {"func2(int, int)"}));
Yabin Cuif79fbd12016-07-06 12:26:13 -0700287 Report(PERF_DATA_WITH_SYMBOLS,
Yabin Cui05ef2ea2016-07-11 13:50:01 -0700288 {"--sort", "symbol", "--symbols", "main;func2(int, int)"});
Yabin Cuif79fbd12016-07-06 12:26:13 -0700289 ASSERT_TRUE(success);
Yabin Cui05ef2ea2016-07-11 13:50:01 -0700290 ASSERT_TRUE(AllItemsWithString(lines, {"main", "func2(int, int)"}));
Yabin Cuif79fbd12016-07-06 12:26:13 -0700291}
292
Yabin Cui6e51bef2016-02-23 21:41:03 -0800293TEST_F(ReportCommandTest, use_branch_address) {
294 Report(BRANCH_PERF_DATA, {"-b", "--sort", "symbol_from,symbol_to"});
295 std::set<std::pair<std::string, std::string>> hit_set;
296 bool after_overhead = false;
297 for (const auto& line : lines) {
298 if (!after_overhead && line.find("Overhead") != std::string::npos) {
299 after_overhead = true;
300 } else if (after_overhead) {
301 char from[80];
302 char to[80];
303 if (sscanf(line.c_str(), "%*f%%%s%s", from, to) == 2) {
304 hit_set.insert(std::make_pair<std::string, std::string>(from, to));
305 }
306 }
Yabin Cui8a530e32015-06-23 20:42:01 -0700307 }
Yabin Cui767dd172016-06-02 21:02:43 -0700308 ASSERT_NE(hit_set.find(std::make_pair<std::string, std::string>(
309 "GlobalFunc", "CalledFunc")),
Yabin Cui6e51bef2016-02-23 21:41:03 -0800310 hit_set.end());
Yabin Cui767dd172016-06-02 21:02:43 -0700311 ASSERT_NE(hit_set.find(std::make_pair<std::string, std::string>(
312 "CalledFunc", "GlobalFunc")),
Yabin Cui6e51bef2016-02-23 21:41:03 -0800313 hit_set.end());
Yabin Cui8a530e32015-06-23 20:42:01 -0700314}
Yabin Cui3c8c2132015-08-13 20:30:20 -0700315
Yabin Cui8f680f62016-03-18 18:47:43 -0700316TEST_F(ReportCommandTest, report_symbols_of_nativelib_in_apk) {
317 Report(NATIVELIB_IN_APK_PERF_DATA);
318 ASSERT_TRUE(success);
Yabin Cui767dd172016-06-02 21:02:43 -0700319 ASSERT_NE(content.find(GetUrlInApk(APK_FILE, NATIVELIB_IN_APK)),
320 std::string::npos);
Yabin Cui8f680f62016-03-18 18:47:43 -0700321 ASSERT_NE(content.find("Func2"), std::string::npos);
322}
323
Yabin Cui2d6efe42016-04-01 20:22:35 -0700324TEST_F(ReportCommandTest, report_more_than_one_event_types) {
325 Report(PERF_DATA_WITH_TWO_EVENT_TYPES);
326 ASSERT_TRUE(success);
327 ASSERT_NE(content.find("cpu-cycles"), std::string::npos);
328 ASSERT_NE(content.find("cpu-clock"), std::string::npos);
329}
330
Yabin Cuib4212972016-05-25 14:08:05 -0700331TEST_F(ReportCommandTest, report_kernel_symbol) {
332 Report(PERF_DATA_WITH_KERNEL_SYMBOL);
333 ASSERT_TRUE(success);
Yabin Cui1761a272016-06-23 17:11:14 -0700334 ASSERT_NE(content.find("perf_event_aux"), std::string::npos);
Yabin Cuib4212972016-05-25 14:08:05 -0700335}
336
Yabin Cui767dd172016-06-02 21:02:43 -0700337TEST_F(ReportCommandTest, report_dumped_symbols) {
338 Report(PERF_DATA_WITH_SYMBOLS);
339 ASSERT_TRUE(success);
Yabin Cui05ef2ea2016-07-11 13:50:01 -0700340 ASSERT_NE(content.find("main"), std::string::npos);
Yabin Cuic855ecc2016-07-11 17:04:54 -0700341 Report(PERF_DATA_WITH_SYMBOLS_FOR_NONZERO_MINVADDR_DSO);
342 ASSERT_TRUE(success);
Yabin Cuic5b4a312016-10-24 13:38:38 -0700343 ASSERT_NE(content.find("memcpy"), std::string::npos);
Yabin Cui767dd172016-06-02 21:02:43 -0700344}
345
Yabin Cuie2f10782016-12-15 12:00:44 -0800346TEST_F(ReportCommandTest, report_dumped_symbols_with_symfs_dir) {
347 // Check if we can report symbols when they appear both in perf.data and symfs dir.
348 Report(PERF_DATA_WITH_SYMBOLS, {"--symfs", GetTestDataDir()});
349 ASSERT_TRUE(success);
350 ASSERT_NE(content.find("main"), std::string::npos);
351}
352
Yabin Cui9970a232016-06-29 12:18:11 -0700353TEST_F(ReportCommandTest, report_sort_vaddr_in_file) {
354 Report(PERF_DATA, {"--sort", "vaddr_in_file"});
355 ASSERT_TRUE(success);
356 ASSERT_NE(content.find("VaddrInFile"), std::string::npos);
357}
358
Yabin Cuieec606c2016-07-07 13:53:33 -0700359TEST_F(ReportCommandTest, check_build_id) {
360 Report(PERF_DATA_FOR_BUILD_ID_CHECK,
361 {"--symfs", GetTestData(CORRECT_SYMFS_FOR_BUILD_ID_CHECK)});
362 ASSERT_TRUE(success);
363 ASSERT_NE(content.find("main"), std::string::npos);
364 ASSERT_EXIT(
365 {
366 Report(PERF_DATA_FOR_BUILD_ID_CHECK,
367 {"--symfs", GetTestData(WRONG_SYMFS_FOR_BUILD_ID_CHECK)});
368 if (!success) {
369 exit(1);
370 }
371 if (content.find("main") != std::string::npos) {
372 exit(2);
373 }
374 exit(0);
375 },
Yabin Cuidec43c12016-07-29 16:40:40 -0700376 testing::ExitedWithCode(0), "Build id mismatch");
Yabin Cuieec606c2016-07-07 13:53:33 -0700377}
378
Yabin Cui15475e62016-07-14 13:26:19 -0700379TEST_F(ReportCommandTest, no_show_ip_option) {
380 Report(PERF_DATA);
381 ASSERT_TRUE(success);
382 ASSERT_EQ(content.find("unknown"), std::string::npos);
383 Report(PERF_DATA, {"--no-show-ip"});
384 ASSERT_TRUE(success);
385 ASSERT_NE(content.find("unknown"), std::string::npos);
386}
387
Yabin Cuidec43c12016-07-29 16:40:40 -0700388TEST_F(ReportCommandTest, no_symbol_table_warning) {
389 ASSERT_EXIT(
390 {
391 Report(PERF_DATA,
392 {"--symfs", GetTestData(SYMFS_FOR_NO_SYMBOL_TABLE_WARNING)});
393 if (!success) {
394 exit(1);
395 }
396 if (content.find("GlobalFunc") != std::string::npos) {
397 exit(2);
398 }
399 exit(0);
400 },
401 testing::ExitedWithCode(0), "elf doesn't contain symbol table");
402}
403
404TEST_F(ReportCommandTest, read_elf_file_warning) {
405 ASSERT_EXIT(
406 {
407 Report(PERF_DATA,
408 {"--symfs", GetTestData(SYMFS_FOR_READ_ELF_FILE_WARNING)});
409 if (!success) {
410 exit(1);
411 }
412 if (content.find("GlobalFunc") != std::string::npos) {
413 exit(2);
414 }
415 exit(0);
416 },
417 testing::ExitedWithCode(0), "elf: Read failed");
418}
419
Yabin Cuieafa7182016-08-30 13:13:17 -0700420TEST_F(ReportCommandTest, report_data_generated_by_linux_perf) {
421 Report(PERF_DATA_GENERATED_BY_LINUX_PERF);
422 ASSERT_TRUE(success);
423}
424
Yabin Cuic0565bb2016-09-29 15:59:33 -0700425TEST_F(ReportCommandTest, max_stack_and_percent_limit_option) {
426 Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, {"-g"});
427 ASSERT_TRUE(success);
428 ASSERT_NE(content.find("89.03"), std::string::npos);
429
430 Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, {"-g", "--max-stack", "0"});
431 ASSERT_TRUE(success);
432 ASSERT_EQ(content.find("89.03"), std::string::npos);
433 Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, {"-g", "--max-stack", "1"});
434 ASSERT_TRUE(success);
435 ASSERT_NE(content.find("89.03"), std::string::npos);
436
437 Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT,
438 {"-g", "--percent-limit", "90"});
439 ASSERT_TRUE(success);
440 ASSERT_EQ(content.find("89.03"), std::string::npos);
441 Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT,
442 {"-g", "--percent-limit", "70"});
443 ASSERT_TRUE(success);
444 ASSERT_NE(content.find("89.03"), std::string::npos);
445}
446
Yabin Cui18385c42016-12-09 14:51:04 -0800447TEST_F(ReportCommandTest, kallsyms_option) {
448 Report(PERF_DATA, {"--kallsyms", GetTestData("kallsyms")});
449 ASSERT_TRUE(success);
450 ASSERT_NE(content.find("FakeKernelSymbol"), std::string::npos);
451}
452
Yabin Cui044861b2016-12-13 17:49:19 -0800453TEST_F(ReportCommandTest, invalid_perf_data) {
454 ASSERT_FALSE(ReportCmd()->Run({"-i", GetTestData(INVALID_PERF_DATA)}));
455}
456
Yabin Cui19e6b6d2016-03-10 11:49:57 -0800457#if defined(__linux__)
Yabin Cui003b2452016-09-29 15:32:45 -0700458#include "event_selection_set.h"
Yabin Cui6e51bef2016-02-23 21:41:03 -0800459
460static std::unique_ptr<Command> RecordCmd() {
461 return CreateCommandInstance("record");
Yabin Cui3c8c2132015-08-13 20:30:20 -0700462}
Yabin Cuib1a885b2016-02-14 19:18:02 -0800463
Yabin Cui6e51bef2016-02-23 21:41:03 -0800464TEST_F(ReportCommandTest, dwarf_callgraph) {
Yabin Cui19e6b6d2016-03-10 11:49:57 -0800465 if (IsDwarfCallChainSamplingSupported()) {
Yabin Cui5be914d2016-11-29 15:21:13 -0800466 std::vector<std::unique_ptr<Workload>> workloads;
467 CreateProcesses(1, &workloads);
468 std::string pid = std::to_string(workloads[0]->GetPid());
Yabin Cui19e6b6d2016-03-10 11:49:57 -0800469 TemporaryFile tmp_file;
Yabin Cui767dd172016-06-02 21:02:43 -0700470 ASSERT_TRUE(
Yabin Cui5be914d2016-11-29 15:21:13 -0800471 RecordCmd()->Run({"-p", pid, "-g", "-o", tmp_file.path, "sleep", SLEEP_SEC}));
Yabin Cui19e6b6d2016-03-10 11:49:57 -0800472 ReportRaw(tmp_file.path, {"-g"});
473 ASSERT_TRUE(success);
474 } else {
Yabin Cui767dd172016-06-02 21:02:43 -0700475 GTEST_LOG_(INFO) << "This test does nothing as dwarf callchain sampling is "
476 "not supported on this device.";
Yabin Cui19e6b6d2016-03-10 11:49:57 -0800477 }
Yabin Cui6e51bef2016-02-23 21:41:03 -0800478}
479
Yabin Cui8f680f62016-03-18 18:47:43 -0700480TEST_F(ReportCommandTest, report_dwarf_callgraph_of_nativelib_in_apk) {
Yabin Cui767dd172016-06-02 21:02:43 -0700481 // NATIVELIB_IN_APK_PERF_DATA is recorded on arm64, so can only report
482 // callgraph on arm64.
Yabin Cui8f680f62016-03-18 18:47:43 -0700483 if (GetBuildArch() == ARCH_ARM64) {
484 Report(NATIVELIB_IN_APK_PERF_DATA, {"-g"});
Yabin Cui767dd172016-06-02 21:02:43 -0700485 ASSERT_NE(content.find(GetUrlInApk(APK_FILE, NATIVELIB_IN_APK)),
486 std::string::npos);
Yabin Cui8f680f62016-03-18 18:47:43 -0700487 ASSERT_NE(content.find("Func2"), std::string::npos);
488 ASSERT_NE(content.find("Func1"), std::string::npos);
489 ASSERT_NE(content.find("GlobalFunc"), std::string::npos);
490 } else {
Yabin Cui767dd172016-06-02 21:02:43 -0700491 GTEST_LOG_(INFO)
492 << "This test does nothing as it is only run on arm64 devices";
Yabin Cui8f680f62016-03-18 18:47:43 -0700493 }
494}
495
Yabin Cui6e51bef2016-02-23 21:41:03 -0800496#endif