Skip to content

Commit b772426

Browse files
committed
simpleperf: support building cts test.
1. build cts test libraries. 2. change tests to use tmpfile instead of perf.data. 3. support extracting testdata from cts test file. Bug: 27387280 Change-Id: I7c5db77f3157d586d0c9beb446b247626e7cce36 (cherry picked from commit be7ec66)
1 parent 08663eb commit b772426

13 files changed

+371
-117
lines changed

simpleperf/Android.mk

+36
Original file line numberDiff line numberDiff line change
@@ -253,4 +253,40 @@ LOCAL_LDLIBS_linux := $(simpleperf_ldlibs_host_linux)
253253
LOCAL_MULTILIB := first
254254
include $(BUILD_HOST_NATIVE_TEST)
255255

256+
257+
# libsimpleperf_cts_test
258+
# =========================================================
259+
libsimpleperf_cts_test_src_files := \
260+
$(libsimpleperf_src_files) \
261+
$(libsimpleperf_src_files_linux) \
262+
$(simpleperf_unit_test_src_files) \
263+
$(simpleperf_unit_test_src_files_linux) \
264+
265+
# libsimpleperf_cts_test target
266+
include $(CLEAR_VARS)
267+
LOCAL_CLANG := true
268+
LOCAL_MODULE := libsimpleperf_cts_test
269+
LOCAL_CPPFLAGS := $(simpleperf_cppflags_target) -DIN_CTS_TEST
270+
LOCAL_SRC_FILES := $(libsimpleperf_cts_test_src_files)
271+
LOCAL_STATIC_LIBRARIES := $(simpleperf_static_libraries_target)
272+
LOCAL_SHARED_LIBRARIES := $(simpleperf_shared_libraries_target)
273+
LOCAL_MULTILIB := both
274+
include $(LLVM_DEVICE_BUILD_MK)
275+
include $(BUILD_STATIC_TEST_LIBRARY)
276+
277+
# libsimpleperf_cts_test linux host
278+
include $(CLEAR_VARS)
279+
LOCAL_CLANG := true
280+
LOCAL_MODULE := libsimpleperf_cts_test
281+
LOCAL_MODULE_HOST_OS := linux
282+
LOCAL_CPPFLAGS := $(simpleperf_cppflags_host) -DIN_CTS_TEST
283+
LOCAL_CPPFLAGS_linux := $(simpleperf_cppflags_host_linux)
284+
LOCAL_SRC_FILES := $(libsimpleperf_cts_test_src_files)
285+
LOCAL_STATIC_LIBRARIES := $(simpleperf_static_libraries_host)
286+
LOCAL_SHARED_LIBRARIES_linux := $(simpleperf_shared_libraries_host_linux)
287+
LOCAL_LDLIBS_linux := $(simpleperf_ldlibs_host_linux)
288+
LOCAL_MULTILIB := both
289+
include $(LLVM_HOST_BUILD_MK)
290+
include $(BUILD_HOST_STATIC_TEST_LIBRARY)
291+
256292
include $(call first-makefiles-under,$(LOCAL_PATH))

simpleperf/cmd_dumprecord_test.cpp

+5-20
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,12 @@
1717
#include <gtest/gtest.h>
1818

1919
#include "command.h"
20-
#include "test_util.h"
20+
#include "get_test_data.h"
2121

22-
class DumpRecordCommandTest : public ::testing::Test {
23-
protected:
24-
virtual void SetUp() {
25-
record_cmd = CreateCommandInstance("record");
26-
ASSERT_TRUE(record_cmd != nullptr);
27-
dumprecord_cmd = CreateCommandInstance("dump");
28-
ASSERT_TRUE(dumprecord_cmd != nullptr);
29-
}
30-
31-
std::unique_ptr<Command> record_cmd;
32-
std::unique_ptr<Command> dumprecord_cmd;
33-
};
34-
35-
TEST_F(DumpRecordCommandTest, no_options) {
36-
ASSERT_TRUE(record_cmd->Run({"-a", "sleep", SLEEP_SEC}));
37-
ASSERT_TRUE(dumprecord_cmd->Run({}));
22+
static std::unique_ptr<Command> DumpCmd() {
23+
return CreateCommandInstance("dump");
3824
}
3925

40-
TEST_F(DumpRecordCommandTest, record_file_option) {
41-
ASSERT_TRUE(record_cmd->Run({"-a", "-o", "perf2.data", "sleep", SLEEP_SEC}));
42-
ASSERT_TRUE(dumprecord_cmd->Run({"perf2.data"}));
26+
TEST(cmd_dump, record_file_option) {
27+
ASSERT_TRUE(DumpCmd()->Run({GetTestData("perf.data")}));
4328
}

simpleperf/cmd_record_test.cpp

+64-36
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@
1717
#include <gtest/gtest.h>
1818

1919
#include <android-base/stringprintf.h>
20+
#include <android-base/test_utils.h>
21+
22+
#include <memory>
2023

2124
#include "command.h"
2225
#include "environment.h"
2326
#include "event_selection_set.h"
27+
#include "get_test_data.h"
2428
#include "record.h"
2529
#include "record_file.h"
2630
#include "test_util.h"
@@ -31,34 +35,51 @@ static std::unique_ptr<Command> RecordCmd() {
3135
return CreateCommandInstance("record");
3236
}
3337

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+
3451
TEST(record_cmd, no_options) {
35-
ASSERT_TRUE(RecordCmd()->Run({"sleep", SLEEP_SEC}));
52+
ASSERT_TRUE(RunRecordCmd({}));
3653
}
3754

3855
TEST(record_cmd, system_wide_option) {
39-
ASSERT_TRUE(RecordCmd()->Run({"-a", "sleep", SLEEP_SEC}));
56+
if (IsRoot()) {
57+
ASSERT_TRUE(RunRecordCmd({"-a"}));
58+
}
4059
}
4160

4261
TEST(record_cmd, sample_period_option) {
43-
ASSERT_TRUE(RecordCmd()->Run({"-c", "100000", "sleep", SLEEP_SEC}));
62+
ASSERT_TRUE(RunRecordCmd({"-c", "100000"}));
4463
}
4564

4665
TEST(record_cmd, event_option) {
47-
ASSERT_TRUE(RecordCmd()->Run({"-e", "cpu-clock", "sleep", SLEEP_SEC}));
66+
ASSERT_TRUE(RunRecordCmd({"-e", "cpu-clock"}));
4867
}
4968

5069
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"}));
5372
}
5473

5574
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}));
5777
}
5878

5979
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);
6283
ASSERT_TRUE(reader != nullptr);
6384
std::vector<std::unique_ptr<Record>> records = reader->DataSection();
6485
ASSERT_GT(records.size(), 0U);
@@ -76,44 +97,47 @@ TEST(record_cmd, dump_kernel_mmap) {
7697
}
7798

7899
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);
81103
ASSERT_TRUE(reader != nullptr);
82104
const FileHeader& file_header = reader->FileHeader();
83105
ASSERT_TRUE(file_header.features[FEAT_BUILD_ID / 8] & (1 << (FEAT_BUILD_ID % 8)));
84106
ASSERT_GT(reader->FeatureSectionDescriptors().size(), 0u);
85107
}
86108

87109
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+
}
89113
}
90114

91115
TEST(record_cmd, branch_sampling) {
92116
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"}));
98122
} else {
99123
GTEST_LOG_(INFO)
100124
<< "This test does nothing as branch stack sampling is not supported on this device.";
101125
}
102126
}
103127

104128
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"}));
106130
}
107131

108132
TEST(record_cmd, fp_callchain_sampling) {
109-
ASSERT_TRUE(RecordCmd()->Run({"--call-graph", "fp", "sleep", SLEEP_SEC}));
133+
ASSERT_TRUE(RunRecordCmd({"--call-graph", "fp"}));
110134
}
111135

112136
TEST(record_cmd, dwarf_callchain_sampling) {
113137
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"}));
117141
} else {
118142
GTEST_LOG_(INFO)
119143
<< "This test does nothing as dwarf callchain sampling is not supported on this device.";
@@ -122,32 +146,33 @@ TEST(record_cmd, dwarf_callchain_sampling) {
122146

123147
TEST(record_cmd, no_unwind_option) {
124148
if (IsDwarfCallChainSamplingSupported()) {
125-
ASSERT_TRUE(RecordCmd()->Run({"--call-graph", "dwarf", "--no-unwind", "sleep", SLEEP_SEC}));
149+
ASSERT_TRUE(RunRecordCmd({"--call-graph", "dwarf", "--no-unwind"}));
126150
} else {
127151
GTEST_LOG_(INFO)
128152
<< "This test does nothing as dwarf callchain sampling is not supported on this device.";
129153
}
130-
ASSERT_FALSE(RecordCmd()->Run({"--no-unwind", "sleep", SLEEP_SEC}));
154+
ASSERT_FALSE(RunRecordCmd({"--no-unwind"}));
131155
}
132156

133157
TEST(record_cmd, post_unwind_option) {
134158
if (IsDwarfCallChainSamplingSupported()) {
135-
ASSERT_TRUE(RecordCmd()->Run({"--call-graph", "dwarf", "--post-unwind", "sleep", SLEEP_SEC}));
159+
ASSERT_TRUE(RunRecordCmd({"--call-graph", "dwarf", "--post-unwind"}));
136160
} else {
137161
GTEST_LOG_(INFO)
138162
<< "This test does nothing as dwarf callchain sampling is not supported on this device.";
139163
}
140-
ASSERT_FALSE(RecordCmd()->Run({"--post-unwind", "sleep", SLEEP_SEC}));
164+
ASSERT_FALSE(RunRecordCmd({"--post-unwind"}));
141165
ASSERT_FALSE(
142-
RecordCmd()->Run({"--call-graph", "dwarf", "--no-unwind", "--post-unwind", "sleep", SLEEP_SEC}));
166+
RunRecordCmd({"--call-graph", "dwarf", "--no-unwind", "--post-unwind"}));
143167
}
144168

145169
TEST(record_cmd, existing_processes) {
146170
std::vector<std::unique_ptr<Workload>> workloads;
147171
CreateProcesses(2, &workloads);
148172
std::string pid_list =
149173
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}));
151176
}
152177

153178
TEST(record_cmd, existing_threads) {
@@ -156,25 +181,28 @@ TEST(record_cmd, existing_threads) {
156181
// Process id can also be used as thread id in linux.
157182
std::string tid_list =
158183
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}));
160186
}
161187

162188
TEST(record_cmd, no_monitored_threads) {
163189
ASSERT_FALSE(RecordCmd()->Run({""}));
164190
}
165191

166192
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"}));
169195
}
170196

171197
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+
}
174202
}
175203

176204
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"}));
180208
}

simpleperf/cmd_stat_test.cpp

+11-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <android-base/stringprintf.h>
2020

2121
#include "command.h"
22+
#include "get_test_data.h"
2223
#include "test_util.h"
2324

2425
static std::unique_ptr<Command> StatCmd() {
@@ -34,19 +35,23 @@ TEST(stat_cmd, event_option) {
3435
}
3536

3637
TEST(stat_cmd, system_wide_option) {
37-
ASSERT_TRUE(StatCmd()->Run({"-a", "sleep", "1"}));
38+
if (IsRoot()) {
39+
ASSERT_TRUE(StatCmd()->Run({"-a", "sleep", "1"}));
40+
}
3841
}
3942

4043
TEST(stat_cmd, verbose_option) {
4144
ASSERT_TRUE(StatCmd()->Run({"--verbose", "sleep", "1"}));
4245
}
4346

4447
TEST(stat_cmd, tracepoint_event) {
45-
ASSERT_TRUE(StatCmd()->Run({"-a", "-e", "sched:sched_switch", "sleep", "1"}));
48+
if (IsRoot()) {
49+
ASSERT_TRUE(StatCmd()->Run({"-a", "-e", "sched:sched_switch", "sleep", "1"}));
50+
}
4651
}
4752

4853
TEST(stat_cmd, event_modifier) {
49-
ASSERT_TRUE(StatCmd()->Run({"-e", "cpu-cycles:u,sched:sched_switch:k", "sleep", "1"}));
54+
ASSERT_TRUE(StatCmd()->Run({"-e", "cpu-cycles:u,cpu-cycles:k", "sleep", "1"}));
5055
}
5156

5257
void CreateProcesses(size_t count, std::vector<std::unique_ptr<Workload>>* workloads) {
@@ -82,5 +87,7 @@ TEST(stat_cmd, no_monitored_threads) {
8287

8388
TEST(stat_cmd, cpu_option) {
8489
ASSERT_TRUE(StatCmd()->Run({"--cpu", "0", "sleep", "1"}));
85-
ASSERT_TRUE(StatCmd()->Run({"--cpu", "0", "-a", "sleep", "1"}));
90+
if (IsRoot()) {
91+
ASSERT_TRUE(StatCmd()->Run({"--cpu", "0", "-a", "sleep", "1"}));
92+
}
8693
}

simpleperf/environment_test.cpp

+21-10
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <functional>
2020
#include <android-base/file.h>
21+
#include <android-base/test_utils.h>
2122

2223
#include "environment.h"
2324

@@ -28,36 +29,46 @@ TEST(environment, GetCpusFromString) {
2829
ASSERT_EQ(GetCpusFromString("1,0-3,3,4"), std::vector<int>({0, 1, 2, 3, 4}));
2930
}
3031

31-
static bool FindKernelSymbol(const KernelSymbol& sym1, const KernelSymbol& sym2) {
32-
return sym1.addr == sym2.addr && sym1.type == sym2.type && strcmp(sym1.name, sym2.name) == 0 &&
33-
((sym1.module == nullptr && sym2.module == nullptr) ||
34-
(strcmp(sym1.module, sym2.module) == 0));
32+
static bool ModulesMatch(const char* p, const char* q) {
33+
if (p == nullptr && q == nullptr) {
34+
return true;
35+
}
36+
if (p != nullptr && q != nullptr) {
37+
return strcmp(p, q) == 0;
38+
}
39+
return false;
40+
}
41+
42+
static bool KernelSymbolsMatch(const KernelSymbol& sym1, const KernelSymbol& sym2) {
43+
return sym1.addr == sym2.addr &&
44+
sym1.type == sym2.type &&
45+
strcmp(sym1.name, sym2.name) == 0 &&
46+
ModulesMatch(sym1.module, sym2.module);
3547
}
3648

3749
TEST(environment, ProcessKernelSymbols) {
3850
std::string data =
3951
"ffffffffa005c4e4 d __warned.41698 [libsas]\n"
4052
"aaaaaaaaaaaaaaaa T _text\n"
4153
"cccccccccccccccc c ccccc\n";
42-
const char* tempfile = "tempfile_process_kernel_symbols";
43-
ASSERT_TRUE(android::base::WriteStringToFile(data, tempfile));
54+
TemporaryFile tempfile;
55+
ASSERT_TRUE(android::base::WriteStringToFile(data, tempfile.path));
4456
KernelSymbol expected_symbol;
4557
expected_symbol.addr = 0xffffffffa005c4e4ULL;
4658
expected_symbol.type = 'd';
4759
expected_symbol.name = "__warned.41698";
4860
expected_symbol.module = "libsas";
4961
ASSERT_TRUE(ProcessKernelSymbols(
50-
tempfile, std::bind(&FindKernelSymbol, std::placeholders::_1, expected_symbol)));
62+
tempfile.path, std::bind(&KernelSymbolsMatch, std::placeholders::_1, expected_symbol)));
5163

5264
expected_symbol.addr = 0xaaaaaaaaaaaaaaaaULL;
5365
expected_symbol.type = 'T';
5466
expected_symbol.name = "_text";
5567
expected_symbol.module = nullptr;
5668
ASSERT_TRUE(ProcessKernelSymbols(
57-
tempfile, std::bind(&FindKernelSymbol, std::placeholders::_1, expected_symbol)));
69+
tempfile.path, std::bind(&KernelSymbolsMatch, std::placeholders::_1, expected_symbol)));
5870

5971
expected_symbol.name = "non_existent_symbol";
6072
ASSERT_FALSE(ProcessKernelSymbols(
61-
tempfile, std::bind(&FindKernelSymbol, std::placeholders::_1, expected_symbol)));
62-
ASSERT_EQ(0, unlink(tempfile));
73+
tempfile.path, std::bind(&KernelSymbolsMatch, std::placeholders::_1, expected_symbol)));
6374
}

0 commit comments

Comments
 (0)