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 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 34 static void DoSomeWork() { 35 for (volatile int i = 0; i < 100000000; ++i) { 36 } 37 } 38 39 TEST(counter, add_event) { 40 std::unique_ptr<PerfEventSet> perf(PerfEventSet::CreateInstance( 41 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 64 TEST(counter, different_targets) { 65 auto test_function = [](std::function<void(PerfEventSet*)> set_target_func) { 66 std::unique_ptr<PerfEventSet> perf(PerfEventSet::CreateInstance( 67 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) { 85 ASSERT_TRUE(perf->MonitorCurrentProcess()); 86 }); 87 test_function([](PerfEventSet* perf) { 88 ASSERT_TRUE(perf->MonitorCurrentThread()); 89 }); 90 test_function([](PerfEventSet* perf) { 91 ASSERT_TRUE(perf->MonitorThreadsInCurrentProcess({getpid()})); 92 }); 93 } 94 95 TEST(counter, start_stop_multiple_times) { 96 const size_t TEST_COUNT = 10; 97 std::unique_ptr<PerfEventSet> perf(PerfEventSet::CreateInstance( 98 PerfEventSet::Type::kPerfForCounting)); 99 ASSERT_TRUE(perf); 100 ASSERT_TRUE(perf->AddEvent("cpu-cycles")); 101 ASSERT_TRUE(perf->MonitorCurrentProcess()); 102 Counter prev_counter; 103 for (size_t i = 0; i < TEST_COUNT; ++i) { 104 ASSERT_TRUE(perf->StartCounters()); 105 DoSomeWork(); 106 ASSERT_TRUE(perf->StopCounters()); 107 std::vector<Counter> counters; 108 ASSERT_TRUE(perf->ReadCounters(&counters)); 109 ASSERT_EQ(counters.size(), 1u); 110 ASSERT_EQ(counters[0].event, "cpu-cycles"); 111 ASSERT_GT(counters[0].value, 0u); 112 ASSERT_GT(counters[0].time_enabled_in_ns, 0u); 113 ASSERT_GT(counters[0].time_running_in_ns, 0u); 114 ASSERT_LE(counters[0].time_running_in_ns, counters[0].time_enabled_in_ns); 115 if (i > 0u) { 116 ASSERT_GT(counters[0].value, prev_counter.value); 117 ASSERT_GT(counters[0].time_enabled_in_ns, prev_counter.time_enabled_in_ns); 118 ASSERT_GT(counters[0].time_running_in_ns, prev_counter.time_running_in_ns); 119 } 120 prev_counter = counters[0]; 121 } 122 } 123 124 TEST(counter, no_change_after_stop) { 125 std::unique_ptr<PerfEventSet> perf(PerfEventSet::CreateInstance( 126 PerfEventSet::Type::kPerfForCounting)); 127 ASSERT_TRUE(perf); 128 ASSERT_TRUE(perf->AddEvent("cpu-cycles")); 129 ASSERT_TRUE(perf->MonitorCurrentProcess()); 130 ASSERT_TRUE(perf->StartCounters()); 131 DoSomeWork(); 132 ASSERT_TRUE(perf->StopCounters()); 133 std::vector<Counter> counters; 134 ASSERT_TRUE(perf->ReadCounters(&counters)); 135 ASSERT_EQ(counters.size(), 1u); 136 ASSERT_EQ(counters[0].event, "cpu-cycles"); 137 ASSERT_GT(counters[0].value, 0u); 138 ASSERT_GT(counters[0].time_enabled_in_ns, 0u); 139 ASSERT_GT(counters[0].time_running_in_ns, 0u); 140 ASSERT_LE(counters[0].time_running_in_ns, counters[0].time_enabled_in_ns); 141 Counter prev_counter = counters[0]; 142 DoSomeWork(); 143 ASSERT_TRUE(perf->ReadCounters(&counters)); 144 ASSERT_EQ(counters.size(), 1u); 145 ASSERT_EQ(counters[0].value, prev_counter.value); 146 ASSERT_EQ(counters[0].time_enabled_in_ns, prev_counter.time_enabled_in_ns); 147 ASSERT_EQ(counters[0].time_running_in_ns, prev_counter.time_running_in_ns); 148 } 149