summaryrefslogtreecommitdiff
path: root/simpleperf/cmd_stat_test.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2020-06-19 15:16:31 -0700
committerYabin Cui <yabinc@google.com>2020-06-19 16:06:11 -0700
commitf53f7161dbf6f29f9b6e11333bbb64ea93ef9913 (patch)
tree1d16b802fd86bf0c8c9ba70e19e3c6e2f5aecf88 /simpleperf/cmd_stat_test.cpp
parent4d5330155d5e873d81e3764107c17a7228d99c0e (diff)
downloadextras-f53f7161dbf6f29f9b6e11333bbb64ea93ef9913.tar.gz
simpleperf: add --sort option in stat cmd.
In stat cmd, if --per-thread or --per-core is used, we need to sort entries belong to one event. So add --sort option to select sort keys (like in report cmd). Also make the default sort key to sort by cpu before sorting by count. Also adding cpu column in csv output when --per-core is used. Bug: 159159465 Test: run simpleperf_unit_test. Change-Id: I7d711c86ae3282cc40bdb8662f06f8058a205028
Diffstat (limited to 'simpleperf/cmd_stat_test.cpp')
-rw-r--r--simpleperf/cmd_stat_test.cpp164
1 files changed, 113 insertions, 51 deletions
diff --git a/simpleperf/cmd_stat_test.cpp b/simpleperf/cmd_stat_test.cpp
index 6b6196a9..0be03cf8 100644
--- a/simpleperf/cmd_stat_test.cpp
+++ b/simpleperf/cmd_stat_test.cpp
@@ -345,6 +345,10 @@ TEST(stat_cmd, per_core_option) {
TEST_IN_ROOT(StatCmd()->Run({"--per-core", "-a", "--duration", "0.1"}));
}
+TEST(stat_cmd, sort_option) {
+ ASSERT_TRUE(StatCmd()->Run({"--per-thread", "--per-core", "--sort", "cpu,count", "sleep", "0.1"}));
+}
+
TEST(stat_cmd, counter_sum) {
PerfCounter counter;
counter.value = 1;
@@ -371,30 +375,46 @@ TEST(stat_cmd, counter_sum) {
class StatCmdSummaryBuilderTest : public ::testing::Test {
protected:
- void AddCounter(int event_id, pid_t tid, int cpu, int value, int time_enabled, int time_running) {
- if (thread_map_.count(tid) == 0) {
- ThreadInfo& thread = thread_map_[tid];
- thread.pid = thread.tid = tid;
- thread.name = "thread" + std::to_string(tid);
+ struct CounterArg {
+ int event_id = 0;
+ int tid = 0;
+ int cpu = 0;
+ int value = 1;
+ int time_enabled = 1;
+ int time_running = 1;
+ };
+
+ void SetUp() override {
+ sort_keys_ = {"count_per_thread", "tid", "cpu", "count"};
+ }
+
+ void AddCounter(const CounterArg& arg) {
+ if (thread_map_.count(arg.tid) == 0) {
+ ThreadInfo& thread = thread_map_[arg.tid];
+ thread.pid = thread.tid = arg.tid;
+ thread.name = "thread" + std::to_string(arg.tid);
}
- if (event_id >= counters_.size()) {
- counters_.resize(event_id + 1);
- counters_[event_id].group_id = 0;
- counters_[event_id].event_name = "event" + std::to_string(event_id);
+ if (arg.event_id >= counters_.size()) {
+ counters_.resize(arg.event_id + 1);
+ counters_[arg.event_id].group_id = 0;
+ counters_[arg.event_id].event_name = "event" + std::to_string(arg.event_id);
}
- CountersInfo& info = counters_[event_id];
+ CountersInfo& info = counters_[arg.event_id];
info.counters.resize(info.counters.size() + 1);
CounterInfo& counter = info.counters.back();
- counter.tid = tid;
- counter.cpu = cpu;
+ counter.tid = arg.tid;
+ counter.cpu = arg.cpu;
counter.counter.id = 0;
- counter.counter.value = value;
- counter.counter.time_enabled = time_enabled;
- counter.counter.time_running = time_running;
+ counter.counter.value = arg.value;
+ counter.counter.time_enabled = arg.time_enabled;
+ counter.counter.time_running = arg.time_running;
}
std::vector<CounterSummary> BuildSummary(bool report_per_thread, bool report_per_core) {
- CounterSummaryBuilder builder(report_per_thread, report_per_core, false, thread_map_);
+ std::optional<SummaryComparator> comparator =
+ BuildSummaryComparator(sort_keys_, report_per_thread, report_per_core);
+ CounterSummaryBuilder builder(report_per_thread, report_per_core, false, thread_map_,
+ comparator);
for (auto& info : counters_) {
builder.AddCountersForOneEventType(info);
}
@@ -403,11 +423,12 @@ class StatCmdSummaryBuilderTest : public ::testing::Test {
std::unordered_map<pid_t, ThreadInfo> thread_map_;
std::vector<CountersInfo> counters_;
+ std::vector<std::string> sort_keys_;
};
TEST_F(StatCmdSummaryBuilderTest, multiple_events) {
- AddCounter(0, 0, 0, 1, 1, 1);
- AddCounter(1, 0, 0, 2, 2, 2);
+ AddCounter({.event_id = 0, .value = 1, .time_enabled = 1, .time_running = 1});
+ AddCounter({.event_id = 1, .value = 2, .time_enabled = 2, .time_running = 2});
std::vector<CounterSummary> summaries = BuildSummary(false, false);
ASSERT_EQ(summaries.size(), 2);
ASSERT_EQ(summaries[0].type_name, "event0");
@@ -419,10 +440,10 @@ TEST_F(StatCmdSummaryBuilderTest, multiple_events) {
}
TEST_F(StatCmdSummaryBuilderTest, default_aggregate) {
- AddCounter(0, 0, 0, 1, 1, 1);
- AddCounter(0, 0, 1, 1, 1, 1);
- AddCounter(0, 1, 0, 1, 1, 1);
- AddCounter(0, 1, 1, 2, 2, 1);
+ AddCounter({.tid = 0, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
+ AddCounter({.tid = 0, .cpu = 1, .value = 1, .time_enabled = 1, .time_running = 1});
+ AddCounter({.tid = 1, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
+ AddCounter({.tid = 1, .cpu = 1, .value = 2, .time_enabled = 2, .time_running = 1});
std::vector<CounterSummary> summaries = BuildSummary(false, false);
ASSERT_EQ(summaries.size(), 1);
ASSERT_EQ(summaries[0].count, 5);
@@ -430,10 +451,10 @@ TEST_F(StatCmdSummaryBuilderTest, default_aggregate) {
}
TEST_F(StatCmdSummaryBuilderTest, per_thread_aggregate) {
- AddCounter(0, 0, 0, 1, 1, 1);
- AddCounter(0, 0, 1, 1, 1, 1);
- AddCounter(0, 1, 0, 1, 1, 1);
- AddCounter(0, 1, 1, 2, 2, 1);
+ AddCounter({.tid = 0, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
+ AddCounter({.tid = 0, .cpu = 1, .value = 1, .time_enabled = 1, .time_running = 1});
+ AddCounter({.tid = 1, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
+ AddCounter({.tid = 1, .cpu = 1, .value = 2, .time_enabled = 2, .time_running = 1});
std::vector<CounterSummary> summaries = BuildSummary(true, false);
ASSERT_EQ(summaries.size(), 2);
ASSERT_EQ(summaries[0].thread->tid, 1);
@@ -447,47 +468,88 @@ TEST_F(StatCmdSummaryBuilderTest, per_thread_aggregate) {
}
TEST_F(StatCmdSummaryBuilderTest, per_core_aggregate) {
- AddCounter(0, 0, 0, 1, 1, 1);
- AddCounter(0, 0, 1, 1, 1, 1);
- AddCounter(0, 1, 0, 1, 1, 1);
- AddCounter(0, 1, 1, 2, 2, 1);
+ AddCounter({.tid = 0, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
+ AddCounter({.tid = 0, .cpu = 1, .value = 1, .time_enabled = 1, .time_running = 1});
+ AddCounter({.tid = 1, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
+ AddCounter({.tid = 1, .cpu = 1, .value = 2, .time_enabled = 2, .time_running = 1});
std::vector<CounterSummary> summaries = BuildSummary(false, true);
- ASSERT_EQ(summaries.size(), 2);
ASSERT_TRUE(summaries[0].thread == nullptr);
- ASSERT_EQ(summaries[0].cpu, 1);
- ASSERT_EQ(summaries[0].count, 3);
- ASSERT_NEAR(summaries[0].scale, 1.5, 1e-5);
+ ASSERT_EQ(summaries[0].cpu, 0);
+ ASSERT_EQ(summaries[0].count, 2);
+ ASSERT_NEAR(summaries[0].scale, 1.0, 1e-5);
+ ASSERT_EQ(summaries.size(), 2);
ASSERT_TRUE(summaries[1].thread == nullptr);
- ASSERT_EQ(summaries[1].cpu, 0);
- ASSERT_EQ(summaries[1].count, 2);
- ASSERT_NEAR(summaries[1].scale, 1.0, 1e-5);
+ ASSERT_EQ(summaries[1].cpu, 1);
+ ASSERT_EQ(summaries[1].count, 3);
+ ASSERT_NEAR(summaries[1].scale, 1.5, 1e-5);
}
TEST_F(StatCmdSummaryBuilderTest, per_thread_core_aggregate) {
- AddCounter(0, 0, 0, 1, 1, 1);
- AddCounter(0, 0, 1, 2, 1, 1);
- AddCounter(0, 1, 0, 3, 1, 1);
- AddCounter(0, 1, 1, 4, 2, 1);
+ AddCounter({.tid = 0, .cpu = 0, .value = 1, .time_enabled = 1, .time_running = 1});
+ AddCounter({.tid = 0, .cpu = 1, .value = 2, .time_enabled = 1, .time_running = 1});
+ AddCounter({.tid = 1, .cpu = 0, .value = 3, .time_enabled = 1, .time_running = 1});
+ AddCounter({.tid = 1, .cpu = 1, .value = 4, .time_enabled = 2, .time_running = 1});
std::vector<CounterSummary> summaries = BuildSummary(true, true);
ASSERT_EQ(summaries.size(), 4);
ASSERT_EQ(summaries[0].thread->tid, 1);
- ASSERT_EQ(summaries[0].cpu, 1);
- ASSERT_EQ(summaries[0].count, 4);
- ASSERT_NEAR(summaries[0].scale, 2.0, 1e-5);
+ ASSERT_EQ(summaries[0].cpu, 0);
+ ASSERT_EQ(summaries[0].count, 3);
+ ASSERT_NEAR(summaries[0].scale, 1.0, 1e-5);
ASSERT_EQ(summaries[1].thread->tid, 1);
- ASSERT_EQ(summaries[1].cpu, 0);
- ASSERT_EQ(summaries[1].count, 3);
- ASSERT_NEAR(summaries[1].scale, 1.0, 1e-5);
+ ASSERT_EQ(summaries[1].cpu, 1);
+ ASSERT_EQ(summaries[1].count, 4);
+ ASSERT_NEAR(summaries[1].scale, 2.0, 1e-5);
ASSERT_EQ(summaries[2].thread->tid, 0);
- ASSERT_EQ(summaries[2].cpu, 1);
- ASSERT_EQ(summaries[2].count, 2);
+ ASSERT_EQ(summaries[2].cpu, 0);
+ ASSERT_EQ(summaries[2].count, 1);
ASSERT_NEAR(summaries[2].scale, 1.0, 1e-5);
ASSERT_EQ(summaries[3].thread->tid, 0);
- ASSERT_EQ(summaries[3].cpu, 0);
- ASSERT_EQ(summaries[3].count, 1);
+ ASSERT_EQ(summaries[3].cpu, 1);
+ ASSERT_EQ(summaries[3].count, 2);
ASSERT_NEAR(summaries[3].scale, 1.0, 1e-5);
}
+TEST_F(StatCmdSummaryBuilderTest, sort_key_count) {
+ sort_keys_ = {"count"};
+ AddCounter({.tid = 0, .cpu = 0, .value = 1});
+ AddCounter({.tid = 1, .cpu = 1, .value = 2});
+ std::vector<CounterSummary> summaries = BuildSummary(true, true);
+ ASSERT_EQ(summaries[0].count, 2);
+ ASSERT_EQ(summaries[1].count, 1);
+}
+
+TEST_F(StatCmdSummaryBuilderTest, sort_key_count_per_thread) {
+ sort_keys_ = {"count_per_thread", "count"};
+ AddCounter({.tid = 0, .cpu = 0, .value = 1});
+ AddCounter({.tid = 0, .cpu = 1, .value = 5});
+ AddCounter({.tid = 1, .cpu = 0, .value = 3});
+ std::vector<CounterSummary> summaries = BuildSummary(true, true);
+ ASSERT_EQ(summaries[0].count, 5);
+ ASSERT_EQ(summaries[1].count, 1);
+ ASSERT_EQ(summaries[2].count, 3);
+}
+
+TEST_F(StatCmdSummaryBuilderTest, sort_key_cpu) {
+ sort_keys_ = {"cpu"};
+ AddCounter({.tid = 0, .cpu = 1, .value = 2});
+ AddCounter({.tid = 1, .cpu = 0, .value = 1});
+ std::vector<CounterSummary> summaries = BuildSummary(false, true);
+ ASSERT_EQ(summaries[0].cpu, 0);
+ ASSERT_EQ(summaries[1].cpu, 1);
+}
+
+TEST_F(StatCmdSummaryBuilderTest, sort_key_pid_tid_name) {
+ AddCounter({.tid = 0, .cpu = 0, .value = 1});
+ AddCounter({.tid = 1, .cpu = 0, .value = 2});
+
+ for (auto& key : std::vector<std::string>({"tid", "pid", "comm"})) {
+ sort_keys_ = {key};
+ std::vector<CounterSummary> summaries = BuildSummary(true, false);
+ ASSERT_EQ(summaries[0].count, 1) << "key = " << key;
+ ASSERT_EQ(summaries[1].count, 2) << "key = " << key;
+ }
+}
+
class StatCmdSummariesTest : public ::testing::Test {
protected:
void AddSummary(const std::string event_name, pid_t tid, int cpu, uint64_t count,