summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-prod (mdb) <android-build-team-robot@google.com>2018-07-13 19:56:24 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-07-13 19:56:24 +0000
commit33e777cb059ac9c31e8e6e3d1b83ce2b16b11fbd (patch)
tree6d8f3e78878f124dbfc30d2c9c7d219a01c679aa
parent49e547c4d9ac8e84a211caa334e0b586fd60acde (diff)
parent9b912784c037813cf3d4e41094573117888837ed (diff)
downloadextras-nougat-mr1-cts-release.tar.gz
-rw-r--r--simpleperf/cmd_record_test.cpp37
-rw-r--r--simpleperf/cmd_report_test.cpp1
-rw-r--r--simpleperf/cmd_stat_test.cpp1
-rw-r--r--simpleperf/environment.cpp13
-rw-r--r--simpleperf/environment.h2
-rw-r--r--simpleperf/environment_test.cpp7
-rw-r--r--simpleperf/test_util.h9
7 files changed, 70 insertions, 0 deletions
diff --git a/simpleperf/cmd_record_test.cpp b/simpleperf/cmd_record_test.cpp
index 8780cfcc..21eb8846 100644
--- a/simpleperf/cmd_record_test.cpp
+++ b/simpleperf/cmd_record_test.cpp
@@ -16,10 +16,12 @@
#include <gtest/gtest.h>
+#include <android-base/file.h>
#include <android-base/stringprintf.h>
#include <android-base/test_utils.h>
#include <memory>
+#include <regex>
#include "command.h"
#include "environment.h"
@@ -49,16 +51,19 @@ static bool RunRecordCmd(std::vector<std::string> v, const char* output_file = n
}
TEST(record_cmd, no_options) {
+ TEST_REQUIRE_HW_COUNTER();
ASSERT_TRUE(RunRecordCmd({}));
}
TEST(record_cmd, system_wide_option) {
+ TEST_REQUIRE_HW_COUNTER();
if (IsRoot()) {
ASSERT_TRUE(RunRecordCmd({"-a"}));
}
}
TEST(record_cmd, sample_period_option) {
+ TEST_REQUIRE_HW_COUNTER();
ASSERT_TRUE(RunRecordCmd({"-c", "100000"}));
}
@@ -67,16 +72,19 @@ TEST(record_cmd, event_option) {
}
TEST(record_cmd, freq_option) {
+ TEST_REQUIRE_HW_COUNTER();
ASSERT_TRUE(RunRecordCmd({"-f", "99"}));
ASSERT_TRUE(RunRecordCmd({"-F", "99"}));
}
TEST(record_cmd, output_file_option) {
+ TEST_REQUIRE_HW_COUNTER();
TemporaryFile tmpfile;
ASSERT_TRUE(RecordCmd()->Run({"-o", tmpfile.path, "sleep", SLEEP_SEC}));
}
TEST(record_cmd, dump_kernel_mmap) {
+ TEST_REQUIRE_HW_COUNTER();
TemporaryFile tmpfile;
ASSERT_TRUE(RunRecordCmd({}, tmpfile.path));
std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmpfile.path);
@@ -97,6 +105,7 @@ TEST(record_cmd, dump_kernel_mmap) {
}
TEST(record_cmd, dump_build_id_feature) {
+ TEST_REQUIRE_HW_COUNTER();
TemporaryFile tmpfile;
ASSERT_TRUE(RunRecordCmd({}, tmpfile.path));
std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmpfile.path);
@@ -113,6 +122,7 @@ TEST(record_cmd, tracepoint_event) {
}
TEST(record_cmd, branch_sampling) {
+ TEST_REQUIRE_HW_COUNTER();
if (IsBranchSamplingSupported()) {
ASSERT_TRUE(RunRecordCmd({"-b"}));
ASSERT_TRUE(RunRecordCmd({"-j", "any,any_call,any_ret,ind_call"}));
@@ -126,14 +136,34 @@ TEST(record_cmd, branch_sampling) {
}
TEST(record_cmd, event_modifier) {
+ TEST_REQUIRE_HW_COUNTER();
ASSERT_TRUE(RunRecordCmd({"-e", "cpu-cycles:u"}));
}
TEST(record_cmd, fp_callchain_sampling) {
+ TEST_REQUIRE_HW_COUNTER();
ASSERT_TRUE(RunRecordCmd({"--call-graph", "fp"}));
}
+bool HasHardwareCounter() {
+ static int has_hw_counter = -1;
+ if (has_hw_counter == -1) {
+ has_hw_counter = 1;
+#if defined(__arm__)
+ std::string cpu_info;
+ if (android::base::ReadFileToString("/proc/cpuinfo", &cpu_info)) {
+ std::string hardware = GetHardwareFromCpuInfo(cpu_info);
+ if (std::regex_search(hardware, std::regex(R"(i\.MX6.*Quad)"))) {
+ has_hw_counter = 0;
+ }
+ }
+#endif
+ }
+ return has_hw_counter == 1;
+}
+
TEST(record_cmd, dwarf_callchain_sampling) {
+ TEST_REQUIRE_HW_COUNTER();
if (IsDwarfCallChainSamplingSupported()) {
ASSERT_TRUE(RunRecordCmd({"--call-graph", "dwarf"}));
ASSERT_TRUE(RunRecordCmd({"--call-graph", "dwarf,16384"}));
@@ -145,6 +175,7 @@ TEST(record_cmd, dwarf_callchain_sampling) {
}
TEST(record_cmd, no_unwind_option) {
+ TEST_REQUIRE_HW_COUNTER();
if (IsDwarfCallChainSamplingSupported()) {
ASSERT_TRUE(RunRecordCmd({"--call-graph", "dwarf", "--no-unwind"}));
} else {
@@ -155,6 +186,7 @@ TEST(record_cmd, no_unwind_option) {
}
TEST(record_cmd, post_unwind_option) {
+ TEST_REQUIRE_HW_COUNTER();
if (IsDwarfCallChainSamplingSupported()) {
ASSERT_TRUE(RunRecordCmd({"--call-graph", "dwarf", "--post-unwind"}));
} else {
@@ -167,6 +199,7 @@ TEST(record_cmd, post_unwind_option) {
}
TEST(record_cmd, existing_processes) {
+ TEST_REQUIRE_HW_COUNTER();
std::vector<std::unique_ptr<Workload>> workloads;
CreateProcesses(2, &workloads);
std::string pid_list =
@@ -175,6 +208,7 @@ TEST(record_cmd, existing_processes) {
}
TEST(record_cmd, existing_threads) {
+ TEST_REQUIRE_HW_COUNTER();
std::vector<std::unique_ptr<Workload>> workloads;
CreateProcesses(2, &workloads);
// Process id can also be used as thread id in linux.
@@ -185,15 +219,18 @@ TEST(record_cmd, existing_threads) {
}
TEST(record_cmd, no_monitored_threads) {
+ TEST_REQUIRE_HW_COUNTER();
ASSERT_FALSE(RecordCmd()->Run({""}));
}
TEST(record_cmd, more_than_one_event_types) {
+ TEST_REQUIRE_HW_COUNTER();
ASSERT_TRUE(RunRecordCmd({"-e", "cpu-cycles,cpu-clock"}));
ASSERT_TRUE(RunRecordCmd({"-e", "cpu-cycles", "-e", "cpu-clock"}));
}
TEST(record_cmd, mmap_page_option) {
+ TEST_REQUIRE_HW_COUNTER();
ASSERT_TRUE(RunRecordCmd({"-m", "1"}));
ASSERT_FALSE(RunRecordCmd({"-m", "0"}));
ASSERT_FALSE(RunRecordCmd({"-m", "7"}));
diff --git a/simpleperf/cmd_report_test.cpp b/simpleperf/cmd_report_test.cpp
index bcf8b6e0..a98b75f3 100644
--- a/simpleperf/cmd_report_test.cpp
+++ b/simpleperf/cmd_report_test.cpp
@@ -268,6 +268,7 @@ static std::unique_ptr<Command> RecordCmd() {
}
TEST_F(ReportCommandTest, dwarf_callgraph) {
+ TEST_REQUIRE_HW_COUNTER();
if (IsDwarfCallChainSamplingSupported()) {
TemporaryFile tmp_file;
ASSERT_TRUE(RecordCmd()->Run({"-g", "-o", tmp_file.path, "sleep", SLEEP_SEC}));
diff --git a/simpleperf/cmd_stat_test.cpp b/simpleperf/cmd_stat_test.cpp
index 8786d8d3..6bf57ddb 100644
--- a/simpleperf/cmd_stat_test.cpp
+++ b/simpleperf/cmd_stat_test.cpp
@@ -51,6 +51,7 @@ TEST(stat_cmd, tracepoint_event) {
}
TEST(stat_cmd, event_modifier) {
+ TEST_REQUIRE_HW_COUNTER();
ASSERT_TRUE(StatCmd()->Run({"-e", "cpu-cycles:u,cpu-cycles:k", "sleep", "1"}));
}
diff --git a/simpleperf/environment.cpp b/simpleperf/environment.cpp
index a73aa1cc..4266932e 100644
--- a/simpleperf/environment.cpp
+++ b/simpleperf/environment.cpp
@@ -491,3 +491,16 @@ bool GetMaxSampleFrequency(uint64_t* max_sample_freq) {
}
return true;
}
+
+std::string GetHardwareFromCpuInfo(const std::string& cpu_info) {
+ for (auto& line : android::base::Split(cpu_info, "\n")) {
+ size_t pos = line.find(':');
+ if (pos != std::string::npos) {
+ std::string key = android::base::Trim(line.substr(0, pos));
+ if (key == "Hardware") {
+ return android::base::Trim(line.substr(pos + 1));
+ }
+ }
+ }
+ return "";
+}
diff --git a/simpleperf/environment.h b/simpleperf/environment.h
index 0b565ea4..241619e0 100644
--- a/simpleperf/environment.h
+++ b/simpleperf/environment.h
@@ -82,4 +82,6 @@ bool ProcessKernelSymbols(const std::string& symbol_file,
bool CheckPerfEventLimit();
bool GetMaxSampleFrequency(uint64_t* max_sample_freq);
+std::string GetHardwareFromCpuInfo(const std::string& cpu_info);
+
#endif // SIMPLE_PERF_ENVIRONMENT_H_
diff --git a/simpleperf/environment_test.cpp b/simpleperf/environment_test.cpp
index 6bca7b8d..ea59ee5b 100644
--- a/simpleperf/environment_test.cpp
+++ b/simpleperf/environment_test.cpp
@@ -72,3 +72,10 @@ TEST(environment, ProcessKernelSymbols) {
ASSERT_FALSE(ProcessKernelSymbols(
tempfile.path, std::bind(&KernelSymbolsMatch, std::placeholders::_1, expected_symbol)));
}
+
+TEST(environment, GetHardwareFromCpuInfo) {
+ std::string cpu_info = "CPU revision : 10\n\n"
+ "Hardware : Symbol i.MX6 Freeport_Plat Quad/DualLite (Device Tree)\n";
+ ASSERT_EQ("Symbol i.MX6 Freeport_Plat Quad/DualLite (Device Tree)",
+ GetHardwareFromCpuInfo(cpu_info));
+}
diff --git a/simpleperf/test_util.h b/simpleperf/test_util.h
index cfbe493a..64d3922d 100644
--- a/simpleperf/test_util.h
+++ b/simpleperf/test_util.h
@@ -26,3 +26,12 @@ void CreateProcesses(size_t count, std::vector<std::unique_ptr<Workload>>* workl
void ParseSymbol(const ElfFileSymbol& symbol, std::map<std::string, ElfFileSymbol>* symbols);
void CheckElfFileSymbols(const std::map<std::string, ElfFileSymbol>& symbols);
+
+bool HasHardwareCounter();
+#define TEST_REQUIRE_HW_COUNTER() \
+ do { \
+ if (!HasHardwareCounter()) { \
+ GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have hardware PMU counters."; \
+ return; \
+ } \
+ } while (0)