17
17
#include < gtest/gtest.h>
18
18
19
19
#include < android-base/stringprintf.h>
20
+ #include < android-base/test_utils.h>
21
+
22
+ #include < memory>
20
23
21
24
#include " command.h"
22
25
#include " environment.h"
23
26
#include " event_selection_set.h"
27
+ #include " get_test_data.h"
24
28
#include " record.h"
25
29
#include " record_file.h"
26
30
#include " test_util.h"
@@ -31,34 +35,51 @@ static std::unique_ptr<Command> RecordCmd() {
31
35
return CreateCommandInstance (" record" );
32
36
}
33
37
38
+ static bool RunRecordCmd (std::vector<std::string> v, const char * output_file = nullptr ) {
39
+ std::unique_ptr<TemporaryFile> tmpfile ;
40
+ std::string out_file;
41
+ if (output_file != nullptr ) {
42
+ out_file = output_file;
43
+ } else {
44
+ tmpfile .reset (new TemporaryFile);
45
+ out_file = tmpfile ->path ;
46
+ }
47
+ v.insert (v.end (), {" -o" , out_file, " sleep" , SLEEP_SEC});
48
+ return RecordCmd ()->Run (v);
49
+ }
50
+
34
51
TEST (record_cmd, no_options) {
35
- ASSERT_TRUE (RecordCmd ()-> Run ({ " sleep " , SLEEP_SEC }));
52
+ ASSERT_TRUE (RunRecordCmd ({ }));
36
53
}
37
54
38
55
TEST (record_cmd, system_wide_option) {
39
- ASSERT_TRUE (RecordCmd ()->Run ({" -a" , " sleep" , SLEEP_SEC}));
56
+ if (IsRoot ()) {
57
+ ASSERT_TRUE (RunRecordCmd ({" -a" }));
58
+ }
40
59
}
41
60
42
61
TEST (record_cmd, sample_period_option) {
43
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -c" , " 100000" , " sleep " , SLEEP_SEC }));
62
+ ASSERT_TRUE (RunRecordCmd ( {" -c" , " 100000" }));
44
63
}
45
64
46
65
TEST (record_cmd, event_option) {
47
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -e" , " cpu-clock" , " sleep " , SLEEP_SEC }));
66
+ ASSERT_TRUE (RunRecordCmd ( {" -e" , " cpu-clock" }));
48
67
}
49
68
50
69
TEST (record_cmd, freq_option) {
51
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -f" , " 99" , " sleep " , SLEEP_SEC }));
52
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -F" , " 99" , " sleep " , SLEEP_SEC }));
70
+ ASSERT_TRUE (RunRecordCmd ( {" -f" , " 99" }));
71
+ ASSERT_TRUE (RunRecordCmd ( {" -F" , " 99" }));
53
72
}
54
73
55
74
TEST (record_cmd, output_file_option) {
56
- ASSERT_TRUE (RecordCmd ()->Run ({" -o" , " perf2.data" , " sleep" , SLEEP_SEC}));
75
+ TemporaryFile tmpfile ;
76
+ ASSERT_TRUE (RecordCmd ()->Run ({" -o" , tmpfile .path , " sleep" , SLEEP_SEC}));
57
77
}
58
78
59
79
TEST (record_cmd, dump_kernel_mmap) {
60
- ASSERT_TRUE (RecordCmd ()->Run ({" sleep" , SLEEP_SEC}));
61
- std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance (" perf.data" );
80
+ TemporaryFile tmpfile ;
81
+ ASSERT_TRUE (RunRecordCmd ({}, tmpfile .path ));
82
+ std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance (tmpfile .path );
62
83
ASSERT_TRUE (reader != nullptr );
63
84
std::vector<std::unique_ptr<Record>> records = reader->DataSection ();
64
85
ASSERT_GT (records.size (), 0U );
@@ -76,44 +97,47 @@ TEST(record_cmd, dump_kernel_mmap) {
76
97
}
77
98
78
99
TEST (record_cmd, dump_build_id_feature) {
79
- ASSERT_TRUE (RecordCmd ()->Run ({" sleep" , SLEEP_SEC}));
80
- std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance (" perf.data" );
100
+ TemporaryFile tmpfile ;
101
+ ASSERT_TRUE (RunRecordCmd ({}, tmpfile .path ));
102
+ std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance (tmpfile .path );
81
103
ASSERT_TRUE (reader != nullptr );
82
104
const FileHeader& file_header = reader->FileHeader ();
83
105
ASSERT_TRUE (file_header.features [FEAT_BUILD_ID / 8 ] & (1 << (FEAT_BUILD_ID % 8 )));
84
106
ASSERT_GT (reader->FeatureSectionDescriptors ().size (), 0u );
85
107
}
86
108
87
109
TEST (record_cmd, tracepoint_event) {
88
- ASSERT_TRUE (RecordCmd ()->Run ({" -a" , " -e" , " sched:sched_switch" , " sleep" , SLEEP_SEC}));
110
+ if (IsRoot ()) {
111
+ ASSERT_TRUE (RunRecordCmd ({" -a" , " -e" , " sched:sched_switch" }));
112
+ }
89
113
}
90
114
91
115
TEST (record_cmd, branch_sampling) {
92
116
if (IsBranchSamplingSupported ()) {
93
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -a " , " -b " , " sleep " , SLEEP_SEC }));
94
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -j" , " any,any_call,any_ret,ind_call" , " sleep " , SLEEP_SEC }));
95
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -j" , " any,k" , " sleep " , SLEEP_SEC }));
96
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -j" , " any,u" , " sleep " , SLEEP_SEC }));
97
- ASSERT_FALSE (RecordCmd ()-> Run ( {" -j" , " u" , " sleep " , SLEEP_SEC }));
117
+ ASSERT_TRUE (RunRecordCmd ( {" -b " }));
118
+ ASSERT_TRUE (RunRecordCmd ( {" -j" , " any,any_call,any_ret,ind_call" }));
119
+ ASSERT_TRUE (RunRecordCmd ( {" -j" , " any,k" }));
120
+ ASSERT_TRUE (RunRecordCmd ( {" -j" , " any,u" }));
121
+ ASSERT_FALSE (RunRecordCmd ( {" -j" , " u" }));
98
122
} else {
99
123
GTEST_LOG_ (INFO)
100
124
<< " This test does nothing as branch stack sampling is not supported on this device." ;
101
125
}
102
126
}
103
127
104
128
TEST (record_cmd, event_modifier) {
105
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -e" , " cpu-cycles:u" , " sleep " , SLEEP_SEC }));
129
+ ASSERT_TRUE (RunRecordCmd ( {" -e" , " cpu-cycles:u" }));
106
130
}
107
131
108
132
TEST (record_cmd, fp_callchain_sampling) {
109
- ASSERT_TRUE (RecordCmd ()-> Run ( {" --call-graph" , " fp" , " sleep " , SLEEP_SEC }));
133
+ ASSERT_TRUE (RunRecordCmd ( {" --call-graph" , " fp" }));
110
134
}
111
135
112
136
TEST (record_cmd, dwarf_callchain_sampling) {
113
137
if (IsDwarfCallChainSamplingSupported ()) {
114
- ASSERT_TRUE (RecordCmd ()-> Run ( {" --call-graph" , " dwarf" , " sleep " , SLEEP_SEC }));
115
- ASSERT_TRUE (RecordCmd ()-> Run ( {" --call-graph" , " dwarf,16384" , " sleep " , SLEEP_SEC }));
116
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -g" , " sleep " , SLEEP_SEC }));
138
+ ASSERT_TRUE (RunRecordCmd ( {" --call-graph" , " dwarf" }));
139
+ ASSERT_TRUE (RunRecordCmd ( {" --call-graph" , " dwarf,16384" }));
140
+ ASSERT_TRUE (RunRecordCmd ( {" -g" }));
117
141
} else {
118
142
GTEST_LOG_ (INFO)
119
143
<< " This test does nothing as dwarf callchain sampling is not supported on this device." ;
@@ -122,32 +146,33 @@ TEST(record_cmd, dwarf_callchain_sampling) {
122
146
123
147
TEST (record_cmd, no_unwind_option) {
124
148
if (IsDwarfCallChainSamplingSupported ()) {
125
- ASSERT_TRUE (RecordCmd ()-> Run ( {" --call-graph" , " dwarf" , " --no-unwind" , " sleep " , SLEEP_SEC }));
149
+ ASSERT_TRUE (RunRecordCmd ( {" --call-graph" , " dwarf" , " --no-unwind" }));
126
150
} else {
127
151
GTEST_LOG_ (INFO)
128
152
<< " This test does nothing as dwarf callchain sampling is not supported on this device." ;
129
153
}
130
- ASSERT_FALSE (RecordCmd ()-> Run ( {" --no-unwind" , " sleep " , SLEEP_SEC }));
154
+ ASSERT_FALSE (RunRecordCmd ( {" --no-unwind" }));
131
155
}
132
156
133
157
TEST (record_cmd, post_unwind_option) {
134
158
if (IsDwarfCallChainSamplingSupported ()) {
135
- ASSERT_TRUE (RecordCmd ()-> Run ( {" --call-graph" , " dwarf" , " --post-unwind" , " sleep " , SLEEP_SEC }));
159
+ ASSERT_TRUE (RunRecordCmd ( {" --call-graph" , " dwarf" , " --post-unwind" }));
136
160
} else {
137
161
GTEST_LOG_ (INFO)
138
162
<< " This test does nothing as dwarf callchain sampling is not supported on this device." ;
139
163
}
140
- ASSERT_FALSE (RecordCmd ()-> Run ( {" --post-unwind" , " sleep " , SLEEP_SEC }));
164
+ ASSERT_FALSE (RunRecordCmd ( {" --post-unwind" }));
141
165
ASSERT_FALSE (
142
- RecordCmd ()-> Run ( {" --call-graph" , " dwarf" , " --no-unwind" , " --post-unwind" , " sleep " , SLEEP_SEC }));
166
+ RunRecordCmd ( {" --call-graph" , " dwarf" , " --no-unwind" , " --post-unwind" }));
143
167
}
144
168
145
169
TEST (record_cmd, existing_processes) {
146
170
std::vector<std::unique_ptr<Workload>> workloads;
147
171
CreateProcesses (2 , &workloads);
148
172
std::string pid_list =
149
173
android::base::StringPrintf (" %d,%d" , workloads[0 ]->GetPid (), workloads[1 ]->GetPid ());
150
- ASSERT_TRUE (RecordCmd ()->Run ({" -p" , pid_list}));
174
+ TemporaryFile tmpfile ;
175
+ ASSERT_TRUE (RecordCmd ()->Run ({" -p" , pid_list, " -o" , tmpfile .path }));
151
176
}
152
177
153
178
TEST (record_cmd, existing_threads) {
@@ -156,25 +181,28 @@ TEST(record_cmd, existing_threads) {
156
181
// Process id can also be used as thread id in linux.
157
182
std::string tid_list =
158
183
android::base::StringPrintf (" %d,%d" , workloads[0 ]->GetPid (), workloads[1 ]->GetPid ());
159
- ASSERT_TRUE (RecordCmd ()->Run ({" -t" , tid_list}));
184
+ TemporaryFile tmpfile ;
185
+ ASSERT_TRUE (RecordCmd ()->Run ({" -t" , tid_list, " -o" , tmpfile .path }));
160
186
}
161
187
162
188
TEST (record_cmd, no_monitored_threads) {
163
189
ASSERT_FALSE (RecordCmd ()->Run ({" " }));
164
190
}
165
191
166
192
TEST (record_cmd, more_than_one_event_types) {
167
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -e" , " cpu-cycles,cpu-clock" , " sleep " , SLEEP_SEC }));
168
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -e" , " cpu-cycles" , " -e" , " cpu-clock" , " sleep " , SLEEP_SEC }));
193
+ ASSERT_TRUE (RunRecordCmd ( {" -e" , " cpu-cycles,cpu-clock" }));
194
+ ASSERT_TRUE (RunRecordCmd ( {" -e" , " cpu-cycles" , " -e" , " cpu-clock" }));
169
195
}
170
196
171
197
TEST (record_cmd, cpu_option) {
172
- ASSERT_TRUE (RecordCmd ()->Run ({" --cpu" , " 0" , " sleep" , SLEEP_SEC}));
173
- ASSERT_TRUE (RecordCmd ()->Run ({" --cpu" , " 0" , " -a" , " sleep" , SLEEP_SEC}));
198
+ ASSERT_TRUE (RunRecordCmd ({" --cpu" , " 0" }));
199
+ if (IsRoot ()) {
200
+ ASSERT_TRUE (RunRecordCmd ({" --cpu" , " 0" , " -a" }));
201
+ }
174
202
}
175
203
176
204
TEST (record_cmd, mmap_page_option) {
177
- ASSERT_TRUE (RecordCmd ()-> Run ( {" -m" , " 1" , " sleep " , SLEEP_SEC }));
178
- ASSERT_FALSE (RecordCmd ()-> Run ( {" -m" , " 0" , " sleep " , SLEEP_SEC }));
179
- ASSERT_FALSE (RecordCmd ()-> Run ( {" -m" , " 7" , " sleep " , SLEEP_SEC }));
205
+ ASSERT_TRUE (RunRecordCmd ( {" -m" , " 1" }));
206
+ ASSERT_FALSE (RunRecordCmd ( {" -m" , " 0" }));
207
+ ASSERT_FALSE (RunRecordCmd ( {" -m" , " 7" }));
180
208
}
0 commit comments