1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker *
4*288bf522SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker *
8*288bf522SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker *
10*288bf522SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker */
16*288bf522SAndroid Build Coastguard Worker
17*288bf522SAndroid Build Coastguard Worker #include <gtest/gtest.h>
18*288bf522SAndroid Build Coastguard Worker
19*288bf522SAndroid Build Coastguard Worker #include <android-base/file.h>
20*288bf522SAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
21*288bf522SAndroid Build Coastguard Worker #include <android-base/strings.h>
22*288bf522SAndroid Build Coastguard Worker
23*288bf522SAndroid Build Coastguard Worker #include <thread>
24*288bf522SAndroid Build Coastguard Worker
25*288bf522SAndroid Build Coastguard Worker #include "ProbeEvents.h"
26*288bf522SAndroid Build Coastguard Worker #include "cmd_stat_impl.h"
27*288bf522SAndroid Build Coastguard Worker #include "command.h"
28*288bf522SAndroid Build Coastguard Worker #include "environment.h"
29*288bf522SAndroid Build Coastguard Worker #include "event_selection_set.h"
30*288bf522SAndroid Build Coastguard Worker #include "get_test_data.h"
31*288bf522SAndroid Build Coastguard Worker #include "test_util.h"
32*288bf522SAndroid Build Coastguard Worker
33*288bf522SAndroid Build Coastguard Worker using namespace simpleperf;
34*288bf522SAndroid Build Coastguard Worker
StatCmd()35*288bf522SAndroid Build Coastguard Worker static std::unique_ptr<Command> StatCmd() {
36*288bf522SAndroid Build Coastguard Worker return CreateCommandInstance("stat");
37*288bf522SAndroid Build Coastguard Worker }
38*288bf522SAndroid Build Coastguard Worker
39*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,no_options)40*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, no_options) {
41*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"sleep", "1"}));
42*288bf522SAndroid Build Coastguard Worker }
43*288bf522SAndroid Build Coastguard Worker
44*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,event_option)45*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, event_option) {
46*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"-e", "cpu-clock,task-clock", "sleep", "1"}));
47*288bf522SAndroid Build Coastguard Worker }
48*288bf522SAndroid Build Coastguard Worker
49*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,system_wide_option)50*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, system_wide_option) {
51*288bf522SAndroid Build Coastguard Worker TEST_IN_ROOT(ASSERT_TRUE(StatCmd()->Run({"-a", "sleep", "1"})));
52*288bf522SAndroid Build Coastguard Worker }
53*288bf522SAndroid Build Coastguard Worker
54*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,verbose_option)55*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, verbose_option) {
56*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--verbose", "sleep", "1"}));
57*288bf522SAndroid Build Coastguard Worker }
58*288bf522SAndroid Build Coastguard Worker
59*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,tracepoint_event)60*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, tracepoint_event) {
61*288bf522SAndroid Build Coastguard Worker TEST_IN_ROOT(ASSERT_TRUE(StatCmd()->Run({"-a", "-e", "sched:sched_switch", "sleep", "1"})));
62*288bf522SAndroid Build Coastguard Worker }
63*288bf522SAndroid Build Coastguard Worker
64*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,rN_event)65*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, rN_event) {
66*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_HW_COUNTER();
67*288bf522SAndroid Build Coastguard Worker OMIT_TEST_ON_NON_NATIVE_ABIS();
68*288bf522SAndroid Build Coastguard Worker size_t event_number;
69*288bf522SAndroid Build Coastguard Worker if (GetTargetArch() == ARCH_ARM64 || GetTargetArch() == ARCH_ARM) {
70*288bf522SAndroid Build Coastguard Worker // As in D5.10.2 of the ARMv8 manual, ARM defines the event number space for PMU. part of the
71*288bf522SAndroid Build Coastguard Worker // space is for common event numbers (which will stay the same for all ARM chips), part of the
72*288bf522SAndroid Build Coastguard Worker // space is for implementation defined events. Here 0x08 is a common event for instructions.
73*288bf522SAndroid Build Coastguard Worker event_number = 0x08;
74*288bf522SAndroid Build Coastguard Worker } else if (GetTargetArch() == ARCH_X86_32 || GetTargetArch() == ARCH_X86_64) {
75*288bf522SAndroid Build Coastguard Worker // As in volume 3 chapter 19 of the Intel manual, 0x00c0 is the event number for instruction.
76*288bf522SAndroid Build Coastguard Worker event_number = 0x00c0;
77*288bf522SAndroid Build Coastguard Worker } else if (GetTargetArch() == ARCH_RISCV64) {
78*288bf522SAndroid Build Coastguard Worker // RISCV_PMU_INSTRET = 1
79*288bf522SAndroid Build Coastguard Worker event_number = 0x1;
80*288bf522SAndroid Build Coastguard Worker } else {
81*288bf522SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "Omit arch " << GetTargetArch();
82*288bf522SAndroid Build Coastguard Worker return;
83*288bf522SAndroid Build Coastguard Worker }
84*288bf522SAndroid Build Coastguard Worker std::string event_name = android::base::StringPrintf("r%zx", event_number);
85*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"-e", event_name, "sleep", "1"}));
86*288bf522SAndroid Build Coastguard Worker }
87*288bf522SAndroid Build Coastguard Worker
88*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,pmu_event)89*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, pmu_event) {
90*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_PMU_COUNTER();
91*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_HW_COUNTER();
92*288bf522SAndroid Build Coastguard Worker std::string event_string;
93*288bf522SAndroid Build Coastguard Worker if (GetTargetArch() == ARCH_X86_64) {
94*288bf522SAndroid Build Coastguard Worker event_string = "cpu/instructions/";
95*288bf522SAndroid Build Coastguard Worker } else if (GetTargetArch() == ARCH_ARM64) {
96*288bf522SAndroid Build Coastguard Worker event_string = "armv8_pmuv3/inst_retired/";
97*288bf522SAndroid Build Coastguard Worker } else if (GetTargetArch() == ARCH_RISCV64) {
98*288bf522SAndroid Build Coastguard Worker event_string = "cpu/instructions/";
99*288bf522SAndroid Build Coastguard Worker } else {
100*288bf522SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "Omit arch " << GetTargetArch();
101*288bf522SAndroid Build Coastguard Worker return;
102*288bf522SAndroid Build Coastguard Worker }
103*288bf522SAndroid Build Coastguard Worker TEST_IN_ROOT(ASSERT_TRUE(StatCmd()->Run({"-a", "-e", event_string, "sleep", "1"})));
104*288bf522SAndroid Build Coastguard Worker }
105*288bf522SAndroid Build Coastguard Worker
106*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,event_modifier)107*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, event_modifier) {
108*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_HW_COUNTER();
109*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"-e", "cpu-cycles:u,cpu-cycles:k", "sleep", "1"}));
110*288bf522SAndroid Build Coastguard Worker }
111*288bf522SAndroid Build Coastguard Worker
RunWorkloadFunction()112*288bf522SAndroid Build Coastguard Worker void RunWorkloadFunction() {
113*288bf522SAndroid Build Coastguard Worker while (true) {
114*288bf522SAndroid Build Coastguard Worker for (volatile int i = 0; i < 10000; ++i)
115*288bf522SAndroid Build Coastguard Worker ;
116*288bf522SAndroid Build Coastguard Worker usleep(1);
117*288bf522SAndroid Build Coastguard Worker }
118*288bf522SAndroid Build Coastguard Worker }
119*288bf522SAndroid Build Coastguard Worker
CreateProcesses(size_t count,std::vector<std::unique_ptr<Workload>> * workloads)120*288bf522SAndroid Build Coastguard Worker void CreateProcesses(size_t count, std::vector<std::unique_ptr<Workload>>* workloads) {
121*288bf522SAndroid Build Coastguard Worker workloads->clear();
122*288bf522SAndroid Build Coastguard Worker // Create workloads run longer than profiling time.
123*288bf522SAndroid Build Coastguard Worker for (size_t i = 0; i < count; ++i) {
124*288bf522SAndroid Build Coastguard Worker std::unique_ptr<Workload> workload;
125*288bf522SAndroid Build Coastguard Worker workload = Workload::CreateWorkload(RunWorkloadFunction);
126*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(workload != nullptr);
127*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(workload->Start());
128*288bf522SAndroid Build Coastguard Worker workloads->push_back(std::move(workload));
129*288bf522SAndroid Build Coastguard Worker }
130*288bf522SAndroid Build Coastguard Worker }
131*288bf522SAndroid Build Coastguard Worker
132*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,existing_processes)133*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, existing_processes) {
134*288bf522SAndroid Build Coastguard Worker std::vector<std::unique_ptr<Workload>> workloads;
135*288bf522SAndroid Build Coastguard Worker CreateProcesses(2, &workloads);
136*288bf522SAndroid Build Coastguard Worker std::string pid_list =
137*288bf522SAndroid Build Coastguard Worker android::base::StringPrintf("%d,%d", workloads[0]->GetPid(), workloads[1]->GetPid());
138*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"-p", pid_list, "sleep", "1"}));
139*288bf522SAndroid Build Coastguard Worker }
140*288bf522SAndroid Build Coastguard Worker
141*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,existing_threads)142*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, existing_threads) {
143*288bf522SAndroid Build Coastguard Worker std::vector<std::unique_ptr<Workload>> workloads;
144*288bf522SAndroid Build Coastguard Worker CreateProcesses(2, &workloads);
145*288bf522SAndroid Build Coastguard Worker // Process id can be used as thread id in linux.
146*288bf522SAndroid Build Coastguard Worker std::string tid_list =
147*288bf522SAndroid Build Coastguard Worker android::base::StringPrintf("%d,%d", workloads[0]->GetPid(), workloads[1]->GetPid());
148*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"-t", tid_list, "sleep", "1"}));
149*288bf522SAndroid Build Coastguard Worker }
150*288bf522SAndroid Build Coastguard Worker
151*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,no_monitored_threads)152*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, no_monitored_threads) {
153*288bf522SAndroid Build Coastguard Worker ASSERT_FALSE(StatCmd()->Run({}));
154*288bf522SAndroid Build Coastguard Worker ASSERT_FALSE(StatCmd()->Run({""}));
155*288bf522SAndroid Build Coastguard Worker }
156*288bf522SAndroid Build Coastguard Worker
157*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,group_option)158*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, group_option) {
159*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_HW_COUNTER();
160*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--group", "cpu-clock,page-faults", "sleep", "1"}));
161*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--group", "cpu-cycles,instructions", "--group",
162*288bf522SAndroid Build Coastguard Worker "cpu-cycles:u,instructions:u", "--group",
163*288bf522SAndroid Build Coastguard Worker "cpu-cycles:k,instructions:k", "sleep", "1"}));
164*288bf522SAndroid Build Coastguard Worker }
165*288bf522SAndroid Build Coastguard Worker
166*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,auto_generated_summary)167*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, auto_generated_summary) {
168*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_HW_COUNTER();
169*288bf522SAndroid Build Coastguard Worker TemporaryFile tmp_file;
170*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run(
171*288bf522SAndroid Build Coastguard Worker {"--group", "instructions:u,instructions:k", "-o", tmp_file.path, "sleep", "1"}));
172*288bf522SAndroid Build Coastguard Worker std::string s;
173*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tmp_file.path, &s));
174*288bf522SAndroid Build Coastguard Worker size_t pos = s.find("instructions:u");
175*288bf522SAndroid Build Coastguard Worker ASSERT_NE(s.npos, pos);
176*288bf522SAndroid Build Coastguard Worker pos = s.find("instructions:k", pos);
177*288bf522SAndroid Build Coastguard Worker ASSERT_NE(s.npos, pos);
178*288bf522SAndroid Build Coastguard Worker pos += strlen("instructions:k");
179*288bf522SAndroid Build Coastguard Worker // Check if the summary of instructions is generated.
180*288bf522SAndroid Build Coastguard Worker ASSERT_NE(s.npos, s.find("instructions", pos));
181*288bf522SAndroid Build Coastguard Worker }
182*288bf522SAndroid Build Coastguard Worker
183*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,duration_option)184*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, duration_option) {
185*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--duration", "1.2", "-p", std::to_string(getpid()), "--in-app"}));
186*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--duration", "1", "sleep", "2"}));
187*288bf522SAndroid Build Coastguard Worker }
188*288bf522SAndroid Build Coastguard Worker
189*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,interval_option)190*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, interval_option) {
191*288bf522SAndroid Build Coastguard Worker TemporaryFile tmp_file;
192*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run(
193*288bf522SAndroid Build Coastguard Worker {"--interval", "500.0", "--duration", "1.2", "-o", tmp_file.path, "sleep", "2"}));
194*288bf522SAndroid Build Coastguard Worker std::string s;
195*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tmp_file.path, &s));
196*288bf522SAndroid Build Coastguard Worker size_t count = 0;
197*288bf522SAndroid Build Coastguard Worker size_t pos = 0;
198*288bf522SAndroid Build Coastguard Worker std::string subs = "statistics:";
199*288bf522SAndroid Build Coastguard Worker while ((pos = s.find(subs, pos)) != s.npos) {
200*288bf522SAndroid Build Coastguard Worker pos += subs.size();
201*288bf522SAndroid Build Coastguard Worker ++count;
202*288bf522SAndroid Build Coastguard Worker }
203*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(count, 2UL);
204*288bf522SAndroid Build Coastguard Worker }
205*288bf522SAndroid Build Coastguard Worker
206*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,interval_option_in_system_wide)207*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, interval_option_in_system_wide) {
208*288bf522SAndroid Build Coastguard Worker TEST_IN_ROOT(ASSERT_TRUE(StatCmd()->Run({"-a", "--interval", "100", "--duration", "0.3"})));
209*288bf522SAndroid Build Coastguard Worker }
210*288bf522SAndroid Build Coastguard Worker
211*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,interval_only_values_option)212*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, interval_only_values_option) {
213*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--interval", "500", "--interval-only-values", "sleep", "2"}));
214*288bf522SAndroid Build Coastguard Worker TEST_IN_ROOT(ASSERT_TRUE(
215*288bf522SAndroid Build Coastguard Worker StatCmd()->Run({"-a", "--interval", "100", "--interval-only-values", "--duration", "0.3"})));
216*288bf522SAndroid Build Coastguard Worker }
217*288bf522SAndroid Build Coastguard Worker
218*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,no_modifier_for_clock_events)219*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, no_modifier_for_clock_events) {
220*288bf522SAndroid Build Coastguard Worker for (const std::string& e : {"cpu-clock", "task-clock"}) {
221*288bf522SAndroid Build Coastguard Worker for (const std::string& m : {"u", "k"}) {
222*288bf522SAndroid Build Coastguard Worker ASSERT_FALSE(StatCmd()->Run({"-e", e + ":" + m, "sleep", "0.1"}))
223*288bf522SAndroid Build Coastguard Worker << "event " << e << ":" << m;
224*288bf522SAndroid Build Coastguard Worker }
225*288bf522SAndroid Build Coastguard Worker }
226*288bf522SAndroid Build Coastguard Worker }
227*288bf522SAndroid Build Coastguard Worker
228*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,handle_SIGHUP)229*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, handle_SIGHUP) {
230*288bf522SAndroid Build Coastguard Worker std::thread thread([]() {
231*288bf522SAndroid Build Coastguard Worker sleep(1);
232*288bf522SAndroid Build Coastguard Worker kill(getpid(), SIGHUP);
233*288bf522SAndroid Build Coastguard Worker });
234*288bf522SAndroid Build Coastguard Worker thread.detach();
235*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"sleep", "1000000"}));
236*288bf522SAndroid Build Coastguard Worker }
237*288bf522SAndroid Build Coastguard Worker
238*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,stop_when_no_more_targets)239*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, stop_when_no_more_targets) {
240*288bf522SAndroid Build Coastguard Worker std::atomic<int> tid(0);
241*288bf522SAndroid Build Coastguard Worker std::thread thread([&]() {
242*288bf522SAndroid Build Coastguard Worker tid = gettid();
243*288bf522SAndroid Build Coastguard Worker sleep(1);
244*288bf522SAndroid Build Coastguard Worker });
245*288bf522SAndroid Build Coastguard Worker thread.detach();
246*288bf522SAndroid Build Coastguard Worker while (tid == 0)
247*288bf522SAndroid Build Coastguard Worker ;
248*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"-t", std::to_string(tid), "--in-app"}));
249*288bf522SAndroid Build Coastguard Worker }
250*288bf522SAndroid Build Coastguard Worker
251*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,sample_rate_should_be_zero)252*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, sample_rate_should_be_zero) {
253*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_HW_COUNTER();
254*288bf522SAndroid Build Coastguard Worker EventSelectionSet set(true);
255*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(set.AddEventType("cpu-cycles"));
256*288bf522SAndroid Build Coastguard Worker set.AddMonitoredProcesses({getpid()});
257*288bf522SAndroid Build Coastguard Worker set.SetCpusForNewEvents({-1});
258*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(set.OpenEventFiles());
259*288bf522SAndroid Build Coastguard Worker const EventAttrIds& attrs = set.GetEventAttrWithId();
260*288bf522SAndroid Build Coastguard Worker ASSERT_GT(attrs.size(), 0u);
261*288bf522SAndroid Build Coastguard Worker for (auto& attr : attrs) {
262*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(attr.attr.sample_period, 0u);
263*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(attr.attr.sample_freq, 0u);
264*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(attr.attr.freq, 0u);
265*288bf522SAndroid Build Coastguard Worker }
266*288bf522SAndroid Build Coastguard Worker }
267*288bf522SAndroid Build Coastguard Worker
268*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,calculating_cpu_frequency)269*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, calculating_cpu_frequency) {
270*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_HW_COUNTER();
271*288bf522SAndroid Build Coastguard Worker CaptureStdout capture;
272*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(capture.Start());
273*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--csv", "--group", "task-clock,cpu-cycles", "sleep", "1"}));
274*288bf522SAndroid Build Coastguard Worker std::string output = capture.Finish();
275*288bf522SAndroid Build Coastguard Worker double task_clock_in_ms = 0;
276*288bf522SAndroid Build Coastguard Worker uint64_t cpu_cycle_count = 0;
277*288bf522SAndroid Build Coastguard Worker double cpu_frequency = 0;
278*288bf522SAndroid Build Coastguard Worker for (auto& line : android::base::Split(output, "\n")) {
279*288bf522SAndroid Build Coastguard Worker if (line.find("task-clock") != std::string::npos) {
280*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(sscanf(line.c_str(), "%lf(ms)", &task_clock_in_ms), 1);
281*288bf522SAndroid Build Coastguard Worker } else if (line.find("cpu-cycles") != std::string::npos) {
282*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(
283*288bf522SAndroid Build Coastguard Worker sscanf(line.c_str(), "%" SCNu64 ",cpu-cycles,%lf", &cpu_cycle_count, &cpu_frequency), 2);
284*288bf522SAndroid Build Coastguard Worker }
285*288bf522SAndroid Build Coastguard Worker }
286*288bf522SAndroid Build Coastguard Worker ASSERT_NE(task_clock_in_ms, 0.0f);
287*288bf522SAndroid Build Coastguard Worker ASSERT_NE(cpu_cycle_count, 0u);
288*288bf522SAndroid Build Coastguard Worker ASSERT_NE(cpu_frequency, 0.0f);
289*288bf522SAndroid Build Coastguard Worker double calculated_frequency = cpu_cycle_count / task_clock_in_ms / 1e6;
290*288bf522SAndroid Build Coastguard Worker // Accept error up to 1e-3. Because the stat cmd print values with precision 1e-6.
291*288bf522SAndroid Build Coastguard Worker ASSERT_NEAR(cpu_frequency, calculated_frequency, 1e-3);
292*288bf522SAndroid Build Coastguard Worker }
293*288bf522SAndroid Build Coastguard Worker
294*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,set_comm_in_another_thread)295*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, set_comm_in_another_thread) {
296*288bf522SAndroid Build Coastguard Worker // Test a kernel bug which was fixed in 3.15. If kernel panic happens, please cherry pick kernel
297*288bf522SAndroid Build Coastguard Worker // patch: e041e328c4b41e perf: Fix perf_event_comm() vs. exec() assumption
298*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_HW_COUNTER();
299*288bf522SAndroid Build Coastguard Worker
300*288bf522SAndroid Build Coastguard Worker for (size_t loop = 0; loop < 3; ++loop) {
301*288bf522SAndroid Build Coastguard Worker std::atomic<int> child_tid(0);
302*288bf522SAndroid Build Coastguard Worker std::atomic<bool> stop_child(false);
303*288bf522SAndroid Build Coastguard Worker std::thread child([&]() {
304*288bf522SAndroid Build Coastguard Worker child_tid = gettid();
305*288bf522SAndroid Build Coastguard Worker // stay on a cpu to make the monitored events of the child thread on that cpu.
306*288bf522SAndroid Build Coastguard Worker while (!stop_child) {
307*288bf522SAndroid Build Coastguard Worker }
308*288bf522SAndroid Build Coastguard Worker });
309*288bf522SAndroid Build Coastguard Worker
310*288bf522SAndroid Build Coastguard Worker while (child_tid == 0) {
311*288bf522SAndroid Build Coastguard Worker }
312*288bf522SAndroid Build Coastguard Worker
313*288bf522SAndroid Build Coastguard Worker {
314*288bf522SAndroid Build Coastguard Worker EventSelectionSet set(true);
315*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(set.AddEventType("cpu-cycles"));
316*288bf522SAndroid Build Coastguard Worker set.AddMonitoredThreads({child_tid});
317*288bf522SAndroid Build Coastguard Worker set.SetCpusForNewEvents({-1});
318*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(set.OpenEventFiles());
319*288bf522SAndroid Build Coastguard Worker
320*288bf522SAndroid Build Coastguard Worker EventSelectionSet set2(true);
321*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(set2.AddEventType("instructions"));
322*288bf522SAndroid Build Coastguard Worker set2.AddMonitoredThreads({gettid()});
323*288bf522SAndroid Build Coastguard Worker set2.SetCpusForNewEvents({-1});
324*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(set2.OpenEventFiles());
325*288bf522SAndroid Build Coastguard Worker
326*288bf522SAndroid Build Coastguard Worker // For kernels with the bug, setting comm will make the monitored events of the child thread
327*288bf522SAndroid Build Coastguard Worker // on the cpu of the current thread.
328*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFile("child",
329*288bf522SAndroid Build Coastguard Worker "/proc/" + std::to_string(child_tid) + "/comm"));
330*288bf522SAndroid Build Coastguard Worker // Release monitored events. For kernels with the bug, the events still exist on the cpu of
331*288bf522SAndroid Build Coastguard Worker // the child thread.
332*288bf522SAndroid Build Coastguard Worker }
333*288bf522SAndroid Build Coastguard Worker
334*288bf522SAndroid Build Coastguard Worker stop_child = true;
335*288bf522SAndroid Build Coastguard Worker child.join();
336*288bf522SAndroid Build Coastguard Worker // Sleep 1s to enter and exit cpu idle, which may abort the kernel.
337*288bf522SAndroid Build Coastguard Worker sleep(1);
338*288bf522SAndroid Build Coastguard Worker }
339*288bf522SAndroid Build Coastguard Worker }
340*288bf522SAndroid Build Coastguard Worker
TestStatingApps(const std::string & app_name)341*288bf522SAndroid Build Coastguard Worker static void TestStatingApps(const std::string& app_name) {
342*288bf522SAndroid Build Coastguard Worker // Bring the app to foreground.
343*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(Workload::RunCmd({"am", "start", app_name + "/.MainActivity"}));
344*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--app", app_name, "--duration", "3"}));
345*288bf522SAndroid Build Coastguard Worker }
346*288bf522SAndroid Build Coastguard Worker
347*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,app_option_for_debuggable_app)348*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, app_option_for_debuggable_app) {
349*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_APPS();
350*288bf522SAndroid Build Coastguard Worker SetRunInAppToolForTesting(true, false);
351*288bf522SAndroid Build Coastguard Worker TestStatingApps("com.android.simpleperf.debuggable");
352*288bf522SAndroid Build Coastguard Worker SetRunInAppToolForTesting(false, true);
353*288bf522SAndroid Build Coastguard Worker TestStatingApps("com.android.simpleperf.debuggable");
354*288bf522SAndroid Build Coastguard Worker }
355*288bf522SAndroid Build Coastguard Worker
356*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,app_option_for_profileable_app)357*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, app_option_for_profileable_app) {
358*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_APPS();
359*288bf522SAndroid Build Coastguard Worker SetRunInAppToolForTesting(false, true);
360*288bf522SAndroid Build Coastguard Worker TestStatingApps("com.android.simpleperf.profileable");
361*288bf522SAndroid Build Coastguard Worker }
362*288bf522SAndroid Build Coastguard Worker
363*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,use_devfreq_counters_option)364*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, use_devfreq_counters_option) {
365*288bf522SAndroid Build Coastguard Worker #if defined(__ANDROID__)
366*288bf522SAndroid Build Coastguard Worker TEST_IN_ROOT(StatCmd()->Run({"--use-devfreq-counters", "sleep", "0.1"}));
367*288bf522SAndroid Build Coastguard Worker #else
368*288bf522SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test tests an option only available on Android.";
369*288bf522SAndroid Build Coastguard Worker #endif
370*288bf522SAndroid Build Coastguard Worker }
371*288bf522SAndroid Build Coastguard Worker
372*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,per_thread_option)373*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, per_thread_option) {
374*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--per-thread", "sleep", "0.1"}));
375*288bf522SAndroid Build Coastguard Worker TEST_IN_ROOT(StatCmd()->Run({"--per-thread", "-a", "--duration", "0.1"}));
376*288bf522SAndroid Build Coastguard Worker }
377*288bf522SAndroid Build Coastguard Worker
378*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,per_core_option)379*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, per_core_option) {
380*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--per-core", "sleep", "0.1"}));
381*288bf522SAndroid Build Coastguard Worker TEST_IN_ROOT(StatCmd()->Run({"--per-core", "-a", "--duration", "0.1"}));
382*288bf522SAndroid Build Coastguard Worker }
383*288bf522SAndroid Build Coastguard Worker
384*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,sort_option)385*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, sort_option) {
386*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(
387*288bf522SAndroid Build Coastguard Worker StatCmd()->Run({"--per-thread", "--per-core", "--sort", "cpu,count", "sleep", "0.1"}));
388*288bf522SAndroid Build Coastguard Worker }
389*288bf522SAndroid Build Coastguard Worker
390*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,counter_sum)391*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, counter_sum) {
392*288bf522SAndroid Build Coastguard Worker PerfCounter counter;
393*288bf522SAndroid Build Coastguard Worker counter.value = 1;
394*288bf522SAndroid Build Coastguard Worker counter.time_enabled = 2;
395*288bf522SAndroid Build Coastguard Worker counter.time_running = 3;
396*288bf522SAndroid Build Coastguard Worker CounterSum a;
397*288bf522SAndroid Build Coastguard Worker a.FromCounter(counter);
398*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(a.value, 1);
399*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(a.time_enabled, 2);
400*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(a.time_running, 3);
401*288bf522SAndroid Build Coastguard Worker CounterSum b = a + a;
402*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(b.value, 2);
403*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(b.time_enabled, 4);
404*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(b.time_running, 6);
405*288bf522SAndroid Build Coastguard Worker CounterSum c = a - a;
406*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(c.value, 0);
407*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(c.time_enabled, 0);
408*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(c.time_running, 0);
409*288bf522SAndroid Build Coastguard Worker b.ToCounter(counter);
410*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(counter.value, 2);
411*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(counter.time_enabled, 4);
412*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(counter.time_running, 6);
413*288bf522SAndroid Build Coastguard Worker }
414*288bf522SAndroid Build Coastguard Worker
415*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,print_hw_counter_option)416*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, print_hw_counter_option) {
417*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--print-hw-counter"}));
418*288bf522SAndroid Build Coastguard Worker }
419*288bf522SAndroid Build Coastguard Worker
420*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,record_different_counters_for_different_cpus)421*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, record_different_counters_for_different_cpus) {
422*288bf522SAndroid Build Coastguard Worker std::vector<int> online_cpus = GetOnlineCpus();
423*288bf522SAndroid Build Coastguard Worker ASSERT_FALSE(online_cpus.empty());
424*288bf522SAndroid Build Coastguard Worker std::string cpu0 = std::to_string(online_cpus[0]);
425*288bf522SAndroid Build Coastguard Worker std::string cpu1 = std::to_string(online_cpus.back());
426*288bf522SAndroid Build Coastguard Worker
427*288bf522SAndroid Build Coastguard Worker CaptureStdout capture;
428*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(capture.Start());
429*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--csv", "--cpu", cpu0, "-e", "cpu-clock", "--cpu", cpu1, "-e",
430*288bf522SAndroid Build Coastguard Worker "task-clock", "--verbose", "sleep", SLEEP_SEC}));
431*288bf522SAndroid Build Coastguard Worker std::string output = capture.Finish();
432*288bf522SAndroid Build Coastguard Worker bool has_cpu_clock = false;
433*288bf522SAndroid Build Coastguard Worker bool has_task_clock = false;
434*288bf522SAndroid Build Coastguard Worker for (auto& line : android::base::Split(output, "\n")) {
435*288bf522SAndroid Build Coastguard Worker if (android::base::StartsWith(line, "cpu-clock,")) {
436*288bf522SAndroid Build Coastguard Worker ASSERT_NE(line.find("cpu," + cpu0 + ","), line.npos) << output;
437*288bf522SAndroid Build Coastguard Worker has_cpu_clock = true;
438*288bf522SAndroid Build Coastguard Worker } else if (android::base::StartsWith(line, "task-clock,")) {
439*288bf522SAndroid Build Coastguard Worker ASSERT_NE(line.find("cpu," + cpu1 + ","), line.npos) << output;
440*288bf522SAndroid Build Coastguard Worker has_task_clock = true;
441*288bf522SAndroid Build Coastguard Worker }
442*288bf522SAndroid Build Coastguard Worker }
443*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(has_cpu_clock) << output;
444*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(has_task_clock) << output;
445*288bf522SAndroid Build Coastguard Worker }
446*288bf522SAndroid Build Coastguard Worker
447*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,kprobe_option)448*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, kprobe_option) {
449*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_ROOT();
450*288bf522SAndroid Build Coastguard Worker EventSelectionSet event_selection_set(false);
451*288bf522SAndroid Build Coastguard Worker ProbeEvents probe_events(event_selection_set);
452*288bf522SAndroid Build Coastguard Worker if (!probe_events.IsKprobeSupported()) {
453*288bf522SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "Skip this test as kprobe isn't supported by the kernel.";
454*288bf522SAndroid Build Coastguard Worker return;
455*288bf522SAndroid Build Coastguard Worker }
456*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"-e", "kprobes:myprobe", "--kprobe", "p:myprobe do_sys_openat2", "-a",
457*288bf522SAndroid Build Coastguard Worker "--duration", SLEEP_SEC}));
458*288bf522SAndroid Build Coastguard Worker // A default kprobe event is created if not given an explicit --kprobe option.
459*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"-e", "kprobes:do_sys_openat2", "-a", "--duration", SLEEP_SEC}));
460*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run({"--group", "kprobes:do_sys_openat2", "-a", "--duration", SLEEP_SEC}));
461*288bf522SAndroid Build Coastguard Worker }
462*288bf522SAndroid Build Coastguard Worker
463*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(stat_cmd,tp_filter_option)464*288bf522SAndroid Build Coastguard Worker TEST(stat_cmd, tp_filter_option) {
465*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_HOST_ROOT();
466*288bf522SAndroid Build Coastguard Worker TEST_REQUIRE_TRACEPOINT_EVENTS();
467*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(StatCmd()->Run(
468*288bf522SAndroid Build Coastguard Worker {"-e", "sched:sched_switch", "--tp-filter", "prev_comm != sleep", "sleep", SLEEP_SEC}));
469*288bf522SAndroid Build Coastguard Worker }
470*288bf522SAndroid Build Coastguard Worker
471*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
472*288bf522SAndroid Build Coastguard Worker class StatCmdSummaryBuilderTest : public ::testing::Test {
473*288bf522SAndroid Build Coastguard Worker protected:
474*288bf522SAndroid Build Coastguard Worker struct CounterArg {
475*288bf522SAndroid Build Coastguard Worker int event_id = 0;
476*288bf522SAndroid Build Coastguard Worker int tid = 0;
477*288bf522SAndroid Build Coastguard Worker int cpu = 0;
478*288bf522SAndroid Build Coastguard Worker int value = 1;
479*288bf522SAndroid Build Coastguard Worker int time_enabled = 1;
480*288bf522SAndroid Build Coastguard Worker int time_running = 1;
481*288bf522SAndroid Build Coastguard Worker };
482*288bf522SAndroid Build Coastguard Worker
SetUp()483*288bf522SAndroid Build Coastguard Worker void SetUp() override { sort_keys_ = {"count_per_thread", "tid", "cpu", "count"}; }
484*288bf522SAndroid Build Coastguard Worker
AddCounter(const CounterArg & arg)485*288bf522SAndroid Build Coastguard Worker void AddCounter(const CounterArg& arg) {
486*288bf522SAndroid Build Coastguard Worker if (thread_map_.count(arg.tid) == 0) {
487*288bf522SAndroid Build Coastguard Worker ThreadInfo& thread = thread_map_[arg.tid];
488*288bf522SAndroid Build Coastguard Worker thread.pid = thread.tid = arg.tid;
489*288bf522SAndroid Build Coastguard Worker thread.name = "thread" + std::to_string(arg.tid);
490*288bf522SAndroid Build Coastguard Worker }
491*288bf522SAndroid Build Coastguard Worker if (arg.event_id >= counters_.size()) {
492*288bf522SAndroid Build Coastguard Worker counters_.resize(arg.event_id + 1);
493*288bf522SAndroid Build Coastguard Worker counters_[arg.event_id].group_id = 0;
494*288bf522SAndroid Build Coastguard Worker counters_[arg.event_id].event_name = "event" + std::to_string(arg.event_id);
495*288bf522SAndroid Build Coastguard Worker }
496*288bf522SAndroid Build Coastguard Worker CountersInfo& info = counters_[arg.event_id];
497*288bf522SAndroid Build Coastguard Worker info.counters.resize(info.counters.size() + 1);
498*288bf522SAndroid Build Coastguard Worker CounterInfo& counter = info.counters.back();
499*288bf522SAndroid Build Coastguard Worker counter.tid = arg.tid;
500*288bf522SAndroid Build Coastguard Worker counter.cpu = arg.cpu;
501*288bf522SAndroid Build Coastguard Worker counter.counter.id = 0;
502*288bf522SAndroid Build Coastguard Worker counter.counter.value = arg.value;
503*288bf522SAndroid Build Coastguard Worker counter.counter.time_enabled = arg.time_enabled;
504*288bf522SAndroid Build Coastguard Worker counter.counter.time_running = arg.time_running;
505*288bf522SAndroid Build Coastguard Worker }
506*288bf522SAndroid Build Coastguard Worker
BuildSummary(bool report_per_thread,bool report_per_core)507*288bf522SAndroid Build Coastguard Worker std::vector<CounterSummary> BuildSummary(bool report_per_thread, bool report_per_core) {
508*288bf522SAndroid Build Coastguard Worker std::optional<SummaryComparator> comparator =
509*288bf522SAndroid Build Coastguard Worker BuildSummaryComparator(sort_keys_, report_per_thread, report_per_core);
510*288bf522SAndroid Build Coastguard Worker CounterSummaryBuilder builder(report_per_thread, report_per_core, false, thread_map_,
511*288bf522SAndroid Build Coastguard Worker comparator);
512*288bf522SAndroid Build Coastguard Worker for (auto& info : counters_) {
513*288bf522SAndroid Build Coastguard Worker builder.AddCountersForOneEventType(info);
514*288bf522SAndroid Build Coastguard Worker }
515*288bf522SAndroid Build Coastguard Worker return builder.Build();
516*288bf522SAndroid Build Coastguard Worker }
517*288bf522SAndroid Build Coastguard Worker
518*288bf522SAndroid Build Coastguard Worker std::unordered_map<pid_t, ThreadInfo> thread_map_;
519*288bf522SAndroid Build Coastguard Worker std::vector<CountersInfo> counters_;
520*288bf522SAndroid Build Coastguard Worker std::vector<std::string> sort_keys_;
521*288bf522SAndroid Build Coastguard Worker };
522*288bf522SAndroid Build Coastguard Worker
523*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST_F(StatCmdSummaryBuilderTest,multiple_events)524*288bf522SAndroid Build Coastguard Worker TEST_F(StatCmdSummaryBuilderTest, multiple_events) {
525*288bf522SAndroid Build Coastguard Worker AddCounter({.event_id = 0, .value = 1, .time_enabled = 1, .time_running = 1});
526*288bf522SAndroid Build Coastguard Worker AddCounter({.event_id = 1, .value = 2, .time_enabled = 2, .time_running = 2});
527*288bf522SAndroid Build Coastguard Worker std::vector<CounterSummary> summaries = BuildSummary(false, false);
528*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries.size(), 2);
529*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].type_name, "event0");
530*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].count, 1);
531*288bf522SAndroid Build Coastguard Worker ASSERT_NEAR(summaries[0].scale, 1.0, 1e-5);
532*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].type_name, "event1");
533*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].count, 2);
534*288bf522SAndroid Build Coastguard Worker ASSERT_NEAR(summaries[1].scale, 1.0, 1e-5);
535*288bf522SAndroid Build Coastguard Worker }
536*288bf522SAndroid Build Coastguard Worker
537*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST_F(StatCmdSummaryBuilderTest,default_aggregate)538*288bf522SAndroid Build Coastguard Worker TEST_F(StatCmdSummaryBuilderTest, default_aggregate) {
539*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
540*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 1, .value = 1, .time_enabled = 1, .time_running = 1});
541*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 1, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
542*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 1, .cpu = 1, .value = 2, .time_enabled = 2, .time_running = 1});
543*288bf522SAndroid Build Coastguard Worker std::vector<CounterSummary> summaries = BuildSummary(false, false);
544*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries.size(), 1);
545*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].count, 5);
546*288bf522SAndroid Build Coastguard Worker ASSERT_NEAR(summaries[0].scale, 1.25, 1e-5);
547*288bf522SAndroid Build Coastguard Worker }
548*288bf522SAndroid Build Coastguard Worker
549*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST_F(StatCmdSummaryBuilderTest,per_thread_aggregate)550*288bf522SAndroid Build Coastguard Worker TEST_F(StatCmdSummaryBuilderTest, per_thread_aggregate) {
551*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
552*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 1, .value = 1, .time_enabled = 1, .time_running = 1});
553*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 1, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
554*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 1, .cpu = 1, .value = 2, .time_enabled = 2, .time_running = 1});
555*288bf522SAndroid Build Coastguard Worker std::vector<CounterSummary> summaries = BuildSummary(true, false);
556*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries.size(), 2);
557*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].thread->tid, 1);
558*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].cpu, -1);
559*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].count, 3);
560*288bf522SAndroid Build Coastguard Worker ASSERT_NEAR(summaries[0].scale, 1.5, 1e-5);
561*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].thread->tid, 0);
562*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].cpu, -1);
563*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].count, 2);
564*288bf522SAndroid Build Coastguard Worker ASSERT_NEAR(summaries[1].scale, 1.0, 1e-5);
565*288bf522SAndroid Build Coastguard Worker }
566*288bf522SAndroid Build Coastguard Worker
567*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST_F(StatCmdSummaryBuilderTest,per_core_aggregate)568*288bf522SAndroid Build Coastguard Worker TEST_F(StatCmdSummaryBuilderTest, per_core_aggregate) {
569*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
570*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 1, .value = 1, .time_enabled = 1, .time_running = 1});
571*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 1, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
572*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 1, .cpu = 1, .value = 2, .time_enabled = 2, .time_running = 1});
573*288bf522SAndroid Build Coastguard Worker std::vector<CounterSummary> summaries = BuildSummary(false, true);
574*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(summaries[0].thread == nullptr);
575*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].cpu, 0);
576*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].count, 2);
577*288bf522SAndroid Build Coastguard Worker ASSERT_NEAR(summaries[0].scale, 1.0, 1e-5);
578*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries.size(), 2);
579*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(summaries[1].thread == nullptr);
580*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].cpu, 1);
581*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].count, 3);
582*288bf522SAndroid Build Coastguard Worker ASSERT_NEAR(summaries[1].scale, 1.5, 1e-5);
583*288bf522SAndroid Build Coastguard Worker }
584*288bf522SAndroid Build Coastguard Worker
585*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST_F(StatCmdSummaryBuilderTest,per_thread_core_aggregate)586*288bf522SAndroid Build Coastguard Worker TEST_F(StatCmdSummaryBuilderTest, per_thread_core_aggregate) {
587*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
588*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 1, .value = 2, .time_enabled = 1, .time_running = 1});
589*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 1, .cpu = 0, .value = 3, .time_enabled = 1, .time_running = 1});
590*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 1, .cpu = 1, .value = 4, .time_enabled = 2, .time_running = 1});
591*288bf522SAndroid Build Coastguard Worker std::vector<CounterSummary> summaries = BuildSummary(true, true);
592*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries.size(), 4);
593*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].thread->tid, 1);
594*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].cpu, 0);
595*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].count, 3);
596*288bf522SAndroid Build Coastguard Worker ASSERT_NEAR(summaries[0].scale, 1.0, 1e-5);
597*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].thread->tid, 1);
598*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].cpu, 1);
599*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].count, 4);
600*288bf522SAndroid Build Coastguard Worker ASSERT_NEAR(summaries[1].scale, 2.0, 1e-5);
601*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[2].thread->tid, 0);
602*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[2].cpu, 0);
603*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[2].count, 1);
604*288bf522SAndroid Build Coastguard Worker ASSERT_NEAR(summaries[2].scale, 1.0, 1e-5);
605*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[3].thread->tid, 0);
606*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[3].cpu, 1);
607*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[3].count, 2);
608*288bf522SAndroid Build Coastguard Worker ASSERT_NEAR(summaries[3].scale, 1.0, 1e-5);
609*288bf522SAndroid Build Coastguard Worker }
610*288bf522SAndroid Build Coastguard Worker
611*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST_F(StatCmdSummaryBuilderTest,sort_key_count)612*288bf522SAndroid Build Coastguard Worker TEST_F(StatCmdSummaryBuilderTest, sort_key_count) {
613*288bf522SAndroid Build Coastguard Worker sort_keys_ = {"count"};
614*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 0, .value = 1});
615*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 1, .cpu = 1, .value = 2});
616*288bf522SAndroid Build Coastguard Worker std::vector<CounterSummary> summaries = BuildSummary(true, true);
617*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].count, 2);
618*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].count, 1);
619*288bf522SAndroid Build Coastguard Worker }
620*288bf522SAndroid Build Coastguard Worker
621*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST_F(StatCmdSummaryBuilderTest,sort_key_count_per_thread)622*288bf522SAndroid Build Coastguard Worker TEST_F(StatCmdSummaryBuilderTest, sort_key_count_per_thread) {
623*288bf522SAndroid Build Coastguard Worker sort_keys_ = {"count_per_thread", "count"};
624*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 0, .value = 1});
625*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 1, .value = 5});
626*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 1, .cpu = 0, .value = 3});
627*288bf522SAndroid Build Coastguard Worker std::vector<CounterSummary> summaries = BuildSummary(true, true);
628*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].count, 5);
629*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].count, 1);
630*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[2].count, 3);
631*288bf522SAndroid Build Coastguard Worker }
632*288bf522SAndroid Build Coastguard Worker
633*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST_F(StatCmdSummaryBuilderTest,sort_key_cpu)634*288bf522SAndroid Build Coastguard Worker TEST_F(StatCmdSummaryBuilderTest, sort_key_cpu) {
635*288bf522SAndroid Build Coastguard Worker sort_keys_ = {"cpu"};
636*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 1, .value = 2});
637*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 1, .cpu = 0, .value = 1});
638*288bf522SAndroid Build Coastguard Worker std::vector<CounterSummary> summaries = BuildSummary(false, true);
639*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].cpu, 0);
640*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].cpu, 1);
641*288bf522SAndroid Build Coastguard Worker }
642*288bf522SAndroid Build Coastguard Worker
643*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST_F(StatCmdSummaryBuilderTest,sort_key_pid_tid_name)644*288bf522SAndroid Build Coastguard Worker TEST_F(StatCmdSummaryBuilderTest, sort_key_pid_tid_name) {
645*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 0, .cpu = 0, .value = 1});
646*288bf522SAndroid Build Coastguard Worker AddCounter({.tid = 1, .cpu = 0, .value = 2});
647*288bf522SAndroid Build Coastguard Worker
648*288bf522SAndroid Build Coastguard Worker for (auto& key : std::vector<std::string>({"tid", "pid", "comm"})) {
649*288bf522SAndroid Build Coastguard Worker sort_keys_ = {key};
650*288bf522SAndroid Build Coastguard Worker std::vector<CounterSummary> summaries = BuildSummary(true, false);
651*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[0].count, 1) << "key = " << key;
652*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(summaries[1].count, 2) << "key = " << key;
653*288bf522SAndroid Build Coastguard Worker }
654*288bf522SAndroid Build Coastguard Worker }
655*288bf522SAndroid Build Coastguard Worker
656*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
657*288bf522SAndroid Build Coastguard Worker class StatCmdSummariesTest : public ::testing::Test {
658*288bf522SAndroid Build Coastguard Worker protected:
AddSummary(const std::string event_name,pid_t tid,int cpu,uint64_t count,uint64_t runtime_in_ns)659*288bf522SAndroid Build Coastguard Worker void AddSummary(const std::string event_name, pid_t tid, int cpu, uint64_t count,
660*288bf522SAndroid Build Coastguard Worker uint64_t runtime_in_ns) {
661*288bf522SAndroid Build Coastguard Worker ThreadInfo* thread = nullptr;
662*288bf522SAndroid Build Coastguard Worker if (tid != -1) {
663*288bf522SAndroid Build Coastguard Worker thread = &thread_map_[tid];
664*288bf522SAndroid Build Coastguard Worker }
665*288bf522SAndroid Build Coastguard Worker summary_v_.emplace_back(event_name, "", 0, thread, cpu, count, runtime_in_ns, 1.0, false,
666*288bf522SAndroid Build Coastguard Worker false);
667*288bf522SAndroid Build Coastguard Worker }
668*288bf522SAndroid Build Coastguard Worker
GetComment(size_t index)669*288bf522SAndroid Build Coastguard Worker const std::string* GetComment(size_t index) {
670*288bf522SAndroid Build Coastguard Worker if (!summaries_) {
671*288bf522SAndroid Build Coastguard Worker summaries_.reset(new CounterSummaries(std::move(summary_v_), false));
672*288bf522SAndroid Build Coastguard Worker summaries_->GenerateComments(1.0);
673*288bf522SAndroid Build Coastguard Worker }
674*288bf522SAndroid Build Coastguard Worker if (index < summaries_->Summaries().size()) {
675*288bf522SAndroid Build Coastguard Worker return &(summaries_->Summaries()[index].comment);
676*288bf522SAndroid Build Coastguard Worker }
677*288bf522SAndroid Build Coastguard Worker return nullptr;
678*288bf522SAndroid Build Coastguard Worker }
679*288bf522SAndroid Build Coastguard Worker
680*288bf522SAndroid Build Coastguard Worker std::unordered_map<pid_t, ThreadInfo> thread_map_;
681*288bf522SAndroid Build Coastguard Worker std::vector<CounterSummary> summary_v_;
682*288bf522SAndroid Build Coastguard Worker std::unique_ptr<CounterSummaries> summaries_;
683*288bf522SAndroid Build Coastguard Worker };
684*288bf522SAndroid Build Coastguard Worker
685*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST_F(StatCmdSummariesTest,task_clock_comment)686*288bf522SAndroid Build Coastguard Worker TEST_F(StatCmdSummariesTest, task_clock_comment) {
687*288bf522SAndroid Build Coastguard Worker AddSummary("task-clock", -1, -1, 1e9, 0);
688*288bf522SAndroid Build Coastguard Worker AddSummary("task-clock", 0, -1, 2e9, 0);
689*288bf522SAndroid Build Coastguard Worker AddSummary("task-clock", -1, 0, 0.5e9, 0);
690*288bf522SAndroid Build Coastguard Worker AddSummary("task-clock", 1, 1, 3e9, 0);
691*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(*GetComment(0), "1.000000 cpus used");
692*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(*GetComment(1), "2.000000 cpus used");
693*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(*GetComment(2), "0.500000 cpus used");
694*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(*GetComment(3), "3.000000 cpus used");
695*288bf522SAndroid Build Coastguard Worker }
696*288bf522SAndroid Build Coastguard Worker
697*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST_F(StatCmdSummariesTest,cpu_cycles_comment)698*288bf522SAndroid Build Coastguard Worker TEST_F(StatCmdSummariesTest, cpu_cycles_comment) {
699*288bf522SAndroid Build Coastguard Worker AddSummary("cpu-cycles", -1, -1, 100, 100);
700*288bf522SAndroid Build Coastguard Worker AddSummary("cpu-cycles", 0, -1, 200, 100);
701*288bf522SAndroid Build Coastguard Worker AddSummary("cpu-cycles", -1, 0, 50, 100);
702*288bf522SAndroid Build Coastguard Worker AddSummary("cpu-cycles", 1, 1, 300, 100);
703*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(*GetComment(0), "1.000000 GHz");
704*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(*GetComment(1), "2.000000 GHz");
705*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(*GetComment(2), "0.500000 GHz");
706*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(*GetComment(3), "3.000000 GHz");
707*288bf522SAndroid Build Coastguard Worker }
708*288bf522SAndroid Build Coastguard Worker
709*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST_F(StatCmdSummariesTest,rate_comment)710*288bf522SAndroid Build Coastguard Worker TEST_F(StatCmdSummariesTest, rate_comment) {
711*288bf522SAndroid Build Coastguard Worker AddSummary("branch-misses", -1, -1, 1e9, 1e9);
712*288bf522SAndroid Build Coastguard Worker AddSummary("branch-misses", 0, -1, 1e6, 1e9);
713*288bf522SAndroid Build Coastguard Worker AddSummary("branch-misses", -1, 0, 1e3, 1e9);
714*288bf522SAndroid Build Coastguard Worker AddSummary("branch-misses", 1, 1, 1, 1e9);
715*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(*GetComment(0), "1.000 G/sec");
716*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(*GetComment(1), "1.000 M/sec");
717*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(*GetComment(2), "1.000 K/sec");
718*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(*GetComment(3), "1.000 /sec");
719*288bf522SAndroid Build Coastguard Worker }
720