• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 "simpleperf.h"
18 
19 #include <gtest/gtest.h>
20 
21 #include <memory>
22 
23 using namespace simpleperf;
24 
TEST(get_all_events,smoke)25 TEST(get_all_events, smoke) {
26   std::vector<std::string> events = GetAllEvents();
27   ASSERT_GT(events.size(), 0u);
28   ASSERT_NE(std::find(events.begin(), events.end(), "cpu-cycles"), events.end());
29   ASSERT_TRUE(IsEventSupported("cpu-cycles"));
30   ASSERT_TRUE(IsEventSupported("cpu-cycles:u"));
31   ASSERT_TRUE(IsEventSupported("cpu-cycles:k"));
32 }
33 
DoSomeWork()34 static void DoSomeWork() {
35   for (volatile int i = 0; i < 100000000; ++i) {
36   }
37 }
38 
TEST(counter,add_event)39 TEST(counter, add_event) {
40   std::unique_ptr<PerfEventSet> perf(
41       PerfEventSet::CreateInstance(PerfEventSet::Type::kPerfForCounting));
42   ASSERT_TRUE(perf);
43   ASSERT_TRUE(perf->AddEvent("cpu-cycles"));
44   ASSERT_TRUE(perf->AddEvent("cpu-cycles:u"));
45   ASSERT_TRUE(perf->AddEvent("cpu-cycles:k"));
46   ASSERT_TRUE(perf->MonitorCurrentProcess());
47   ASSERT_TRUE(perf->StartCounters());
48   DoSomeWork();
49   ASSERT_TRUE(perf->StopCounters());
50   std::vector<Counter> counters;
51   ASSERT_TRUE(perf->ReadCounters(&counters));
52   ASSERT_EQ(counters.size(), 3u);
53   ASSERT_EQ(counters[0].event, "cpu-cycles");
54   ASSERT_EQ(counters[1].event, "cpu-cycles:u");
55   ASSERT_EQ(counters[2].event, "cpu-cycles:k");
56   for (auto& counter : counters) {
57     ASSERT_GE(counter.value, 0u);
58     ASSERT_GE(counter.time_enabled_in_ns, 0u);
59     ASSERT_GE(counter.time_running_in_ns, 0u);
60     ASSERT_LE(counter.time_running_in_ns, counter.time_enabled_in_ns);
61   }
62 }
63 
TEST(counter,different_targets)64 TEST(counter, different_targets) {
65   auto test_function = [](std::function<void(PerfEventSet*)> set_target_func) {
66     std::unique_ptr<PerfEventSet> perf(
67         PerfEventSet::CreateInstance(PerfEventSet::Type::kPerfForCounting));
68     ASSERT_TRUE(perf);
69     ASSERT_TRUE(perf->AddEvent("cpu-cycles"));
70     set_target_func(perf.get());
71     ASSERT_TRUE(perf->MonitorCurrentProcess());
72     ASSERT_TRUE(perf->StartCounters());
73     DoSomeWork();
74     ASSERT_TRUE(perf->StopCounters());
75     std::vector<Counter> counters;
76     ASSERT_TRUE(perf->ReadCounters(&counters));
77     ASSERT_EQ(counters.size(), 1u);
78     ASSERT_EQ(counters[0].event, "cpu-cycles");
79     ASSERT_GT(counters[0].value, 0u);
80     ASSERT_GT(counters[0].time_enabled_in_ns, 0u);
81     ASSERT_GT(counters[0].time_running_in_ns, 0u);
82     ASSERT_LE(counters[0].time_running_in_ns, counters[0].time_enabled_in_ns);
83   };
84   test_function([](PerfEventSet* perf) { ASSERT_TRUE(perf->MonitorCurrentProcess()); });
85   test_function([](PerfEventSet* perf) { ASSERT_TRUE(perf->MonitorCurrentThread()); });
86   test_function(
87       [](PerfEventSet* perf) { ASSERT_TRUE(perf->MonitorThreadsInCurrentProcess({getpid()})); });
88 }
89 
TEST(counter,start_stop_multiple_times)90 TEST(counter, start_stop_multiple_times) {
91   const size_t TEST_COUNT = 10;
92   std::unique_ptr<PerfEventSet> perf(
93       PerfEventSet::CreateInstance(PerfEventSet::Type::kPerfForCounting));
94   ASSERT_TRUE(perf);
95   ASSERT_TRUE(perf->AddEvent("cpu-cycles"));
96   ASSERT_TRUE(perf->MonitorCurrentProcess());
97   Counter prev_counter;
98   for (size_t i = 0; i < TEST_COUNT; ++i) {
99     ASSERT_TRUE(perf->StartCounters());
100     DoSomeWork();
101     ASSERT_TRUE(perf->StopCounters());
102     std::vector<Counter> counters;
103     ASSERT_TRUE(perf->ReadCounters(&counters));
104     ASSERT_EQ(counters.size(), 1u);
105     ASSERT_EQ(counters[0].event, "cpu-cycles");
106     ASSERT_GT(counters[0].value, 0u);
107     ASSERT_GT(counters[0].time_enabled_in_ns, 0u);
108     ASSERT_GT(counters[0].time_running_in_ns, 0u);
109     ASSERT_LE(counters[0].time_running_in_ns, counters[0].time_enabled_in_ns);
110     if (i > 0u) {
111       ASSERT_GT(counters[0].value, prev_counter.value);
112       ASSERT_GT(counters[0].time_enabled_in_ns, prev_counter.time_enabled_in_ns);
113       ASSERT_GT(counters[0].time_running_in_ns, prev_counter.time_running_in_ns);
114     }
115     prev_counter = counters[0];
116   }
117 }
118 
TEST(counter,no_change_after_stop)119 TEST(counter, no_change_after_stop) {
120   std::unique_ptr<PerfEventSet> perf(
121       PerfEventSet::CreateInstance(PerfEventSet::Type::kPerfForCounting));
122   ASSERT_TRUE(perf);
123   ASSERT_TRUE(perf->AddEvent("cpu-cycles"));
124   ASSERT_TRUE(perf->MonitorCurrentProcess());
125   ASSERT_TRUE(perf->StartCounters());
126   DoSomeWork();
127   ASSERT_TRUE(perf->StopCounters());
128   std::vector<Counter> counters;
129   ASSERT_TRUE(perf->ReadCounters(&counters));
130   ASSERT_EQ(counters.size(), 1u);
131   ASSERT_EQ(counters[0].event, "cpu-cycles");
132   ASSERT_GT(counters[0].value, 0u);
133   ASSERT_GT(counters[0].time_enabled_in_ns, 0u);
134   ASSERT_GT(counters[0].time_running_in_ns, 0u);
135   ASSERT_LE(counters[0].time_running_in_ns, counters[0].time_enabled_in_ns);
136   Counter prev_counter = counters[0];
137   DoSomeWork();
138   ASSERT_TRUE(perf->ReadCounters(&counters));
139   ASSERT_EQ(counters.size(), 1u);
140   ASSERT_EQ(counters[0].value, prev_counter.value);
141   ASSERT_EQ(counters[0].time_enabled_in_ns, prev_counter.time_enabled_in_ns);
142   ASSERT_EQ(counters[0].time_running_in_ns, prev_counter.time_running_in_ns);
143 }
144