Home | History | Annotate | Download | only in simpleperf
      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