From 54237f895a611440ad3d6bca377e0a930ee93e1d Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Thu, 18 Jan 2018 21:20:36 -0800 Subject: Perfprofd: Clean up test logging helper Clean up, in preparation for a potential move to libbase. Test: mmma system/extras/perfprofd Test: perfprofd_test Change-Id: I1bdeffc6b69bd8c2513e1b2fce103bbae1c53dad --- perfprofd/tests/perfprofd_test.cc | 228 +++++++++++++++++++------------------- 1 file changed, 115 insertions(+), 113 deletions(-) (limited to 'perfprofd/tests/perfprofd_test.cc') diff --git a/perfprofd/tests/perfprofd_test.cc b/perfprofd/tests/perfprofd_test.cc index c36ea7d7..d6a8f219 100644 --- a/perfprofd/tests/perfprofd_test.cc +++ b/perfprofd/tests/perfprofd_test.cc @@ -16,7 +16,9 @@ #include #include +#include #include +#include #include #include @@ -33,6 +35,7 @@ #include #include #include +#include #include #include "config.h" @@ -53,91 +56,45 @@ namespace { using android::base::LogId; using android::base::LogSeverity; -static std::vector* gTestLogMessages = nullptr; - -static void TestLogFunction(LogId log_id ATTRIBUTE_UNUSED, - LogSeverity severity, - const char* tag, - const char* file ATTRIBUTE_UNUSED, - unsigned int line ATTRIBUTE_UNUSED, - const char* message) { - constexpr char log_characters[] = "VDIWEFF"; - char severity_char = log_characters[severity]; - gTestLogMessages->push_back(android::base::StringPrintf("%c: %s", severity_char, message)); -} - -static void InitTestLog() { - CHECK(gTestLogMessages == nullptr); - gTestLogMessages = new std::vector(); -} -static void ClearTestLog() { - CHECK(gTestLogMessages != nullptr); - delete gTestLogMessages; - gTestLogMessages = nullptr; -} -static std::string JoinTestLog(const char* delimiter) { - CHECK(gTestLogMessages != nullptr); - return android::base::Join(*gTestLogMessages, delimiter); -} - -} // namespace - -// Path to perf executable on device -#define PERFPATH "/system/bin/perf" - -// Temporary config file that we will emit for the daemon to read -#define CONFIGFILE "perfprofd.conf" - -class PerfProfdTest : public testing::Test { - protected: - void SetUp() override { - InitTestLog(); - android::base::SetLogger(TestLogFunction); - create_dirs(); +class TestLogHelper { + public: + void Install() { + using namespace std::placeholders; + android::base::SetLogger( + std::bind(&TestLogHelper::TestLogFunction, this, _1, _2, _3, _4, _5, _6)); } - void TearDown() override { - android::base::SetLogger(android::base::StderrLogger); - ClearTestLog(); + std::string JoinTestLog(const char* delimiter) { + std::unique_lock ul(lock_); + return android::base::Join(test_log_messages_, delimiter); + } - // TODO: proper management of test files. For now, use old system() code. - if (!HasFailure()) { - for (const auto dir : { &dest_dir, &conf_dir }) { - std::string cmd("rm -rf "); - cmd += *dir; - int ret = system(cmd.c_str()); - CHECK_EQ(0, ret); - } - } else { - std::cerr << "Failed test: conf_dir=" << conf_dir << " dest_dir=" << dest_dir; - } + private: + void TestLogFunction(LogId log_id ATTRIBUTE_UNUSED, + LogSeverity severity, + const char* tag, + const char* file ATTRIBUTE_UNUSED, + unsigned int line ATTRIBUTE_UNUSED, + const char* message) { + std::unique_lock ul(lock_); + constexpr char log_characters[] = "VDIWEFF"; + char severity_char = log_characters[severity]; + test_log_messages_.push_back(android::base::StringPrintf("%c: %s", severity_char, message)); } - protected: - // test_dir is the directory containing the test executable and - // any files associated with the test (will be created by the harness). - std::string test_dir; + private: + std::mutex lock_; - // dest_dir is a temporary directory that we're using as the destination directory. - // It is backed by temp_dir1. - std::string dest_dir; + std::vector test_log_messages_; +}; - // conf_dir is a temporary directory that we're using as the configuration directory. - // It is backed by temp_dir2. - std::string conf_dir; +} // namespace - private: - void create_dirs() { - temp_dir1.reset(new TemporaryDir()); - temp_dir2.reset(new TemporaryDir()); - dest_dir = temp_dir1->path; - conf_dir = temp_dir2->path; - test_dir = android::base::Dirname(gExecutableRealpath); - } +// Path to perf executable on device +#define PERFPATH "/system/bin/perf" - std::unique_ptr temp_dir1; - std::unique_ptr temp_dir2; -}; +// Temporary config file that we will emit for the daemon to read +#define CONFIGFILE "perfprofd.conf" static bool bothWhiteSpace(char lhs, char rhs) { @@ -195,6 +152,79 @@ static std::string expandVars(const std::string &str) { #endif } +class PerfProfdTest : public testing::Test { + protected: + virtual void SetUp() { + test_logger.Install(); + create_dirs(); + } + + virtual void TearDown() { + android::base::SetLogger(android::base::StderrLogger); + + // TODO: proper management of test files. For now, use old system() code. + for (const auto dir : { &dest_dir, &conf_dir }) { + std::string cmd("rm -rf "); + cmd += *dir; + int ret = system(cmd.c_str()); + CHECK_EQ(0, ret); + } + } + + protected: + // + // Check to see if the log messages emitted by the daemon + // match the expected result. By default we use a partial + // match, e.g. if we see the expected excerpt anywhere in the + // result, it's a match (for exact match, set exact to true) + // + void CompareLogMessages(const std::string& expected, + const char* testpoint, + bool exactMatch = false) { + std::string sqexp = squeezeWhite(expected, "expected"); + std::string sqact = squeezeWhite(test_logger.JoinTestLog(" "), "actual"); + if (exactMatch) { + EXPECT_STREQ(sqexp.c_str(), sqact.c_str()); + } else { + std::size_t foundpos = sqact.find(sqexp); + bool wasFound = true; + if (foundpos == std::string::npos) { + std::cerr << testpoint << ": expected result not found\n"; + std::cerr << " Actual: \"" << sqact << "\"\n"; + std::cerr << " Expected: \"" << sqexp << "\"\n"; + wasFound = false; + } + EXPECT_TRUE(wasFound); + } + } + + // test_dir is the directory containing the test executable and + // any files associated with the test (will be created by the harness). + std::string test_dir; + + // dest_dir is a temporary directory that we're using as the destination directory. + // It is backed by temp_dir1. + std::string dest_dir; + + // conf_dir is a temporary directory that we're using as the configuration directory. + // It is backed by temp_dir2. + std::string conf_dir; + + TestLogHelper test_logger; + + private: + void create_dirs() { + temp_dir1.reset(new TemporaryDir()); + temp_dir2.reset(new TemporaryDir()); + dest_dir = temp_dir1->path; + conf_dir = temp_dir2->path; + test_dir = android::base::Dirname(gExecutableRealpath); + } + + std::unique_ptr temp_dir1; + std::unique_ptr temp_dir2; +}; + /// /// Helper class to kick off a run of the perfprofd daemon with a specific /// config file. @@ -364,34 +394,6 @@ static std::string encodedModuleSamplesToString(const wireless_android_play_play #define RAW_RESULT(x) #x -// -// Check to see if the log messages emitted by the daemon -// match the expected result. By default we use a partial -// match, e.g. if we see the expected excerpt anywhere in the -// result, it's a match (for exact match, set exact to true) -// -static void compareLogMessages(const std::string &actual, - const std::string &expected, - const char *testpoint, - bool exactMatch=false) -{ - std::string sqexp = squeezeWhite(expected, "expected"); - std::string sqact = squeezeWhite(actual, "actual"); - if (exactMatch) { - EXPECT_STREQ(sqexp.c_str(), sqact.c_str()); - } else { - std::size_t foundpos = sqact.find(sqexp); - bool wasFound = true; - if (foundpos == std::string::npos) { - std::cerr << testpoint << ": expected result not found\n"; - std::cerr << " Actual: \"" << sqact << "\"\n"; - std::cerr << " Expected: \"" << sqexp << "\"\n"; - wasFound = false; - } - EXPECT_TRUE(wasFound); - } -} - TEST_F(PerfProfdTest, TestUtil) { EXPECT_EQ("", replaceAll("", "", "")); @@ -432,7 +434,7 @@ TEST_F(PerfProfdTest, MissingGMS) ); // check to make sure entire log matches - compareLogMessages(JoinTestLog(" "), expected, "MissingGMS"); + CompareLogMessages(expected, "MissingGMS"); } @@ -468,7 +470,7 @@ TEST_F(PerfProfdTest, MissingOptInSemaphoreFile) I: profile collection skipped (missing config directory) ); // check to make sure log excerpt matches - compareLogMessages(JoinTestLog(" "), expected, "MissingOptInSemaphoreFile"); + CompareLogMessages(expected, "MissingOptInSemaphoreFile"); } TEST_F(PerfProfdTest, MissingPerfExecutable) @@ -505,7 +507,7 @@ TEST_F(PerfProfdTest, MissingPerfExecutable) I: profile collection skipped (missing 'perf' executable) ); // check to make sure log excerpt matches - compareLogMessages(JoinTestLog(" "), expected, "MissingPerfExecutable"); + CompareLogMessages(expected, "MissingPerfExecutable"); } TEST_F(PerfProfdTest, BadPerfRun) @@ -543,7 +545,7 @@ TEST_F(PerfProfdTest, BadPerfRun) ); // check to make sure log excerpt matches - compareLogMessages(JoinTestLog(" "), expected, "BadPerfRun"); + CompareLogMessages(expected, "BadPerfRun"); } TEST_F(PerfProfdTest, ConfigFileParsing) @@ -581,7 +583,7 @@ TEST_F(PerfProfdTest, ConfigFileParsing) ); // check to make sure log excerpt matches - compareLogMessages(JoinTestLog(" "), expected, "ConfigFileParsing"); + CompareLogMessages(expected, "ConfigFileParsing"); } TEST_F(PerfProfdTest, ProfileCollectionAnnotations) @@ -620,7 +622,7 @@ TEST_F(PerfProfdTest, BasicRunWithCannedPerf) // Kick off encoder and check return code PROFILE_RESULT result = encode_to_proto(input_perf_data, encoded_file_path(dest_dir, 0).c_str(), config, 0, nullptr); - ASSERT_EQ(OK_PROFILE_COLLECTION, result) << JoinTestLog(" "); + ASSERT_EQ(OK_PROFILE_COLLECTION, result) << test_logger.JoinTestLog(" "); // Read and decode the resulting perf.data.encoded file wireless_android_play_playlog::AndroidPerfProfile encodedProfile; @@ -895,7 +897,7 @@ TEST_F(PerfProfdTest, BasicRunWithLivePerf) I: finishing Android Wide Profiling daemon ); // check to make sure log excerpt matches - compareLogMessages(JoinTestLog(" "), expandVars(expected), "BasicRunWithLivePerf", true); + CompareLogMessages(expandVars(expected), "BasicRunWithLivePerf", true); } TEST_F(PerfProfdTest, MultipleRunWithLivePerf) @@ -964,7 +966,7 @@ TEST_F(PerfProfdTest, MultipleRunWithLivePerf) I: finishing Android Wide Profiling daemon ); // check to make sure log excerpt matches - compareLogMessages(JoinTestLog(" "), expandVars(expected), "BasicRunWithLivePerf", true); + CompareLogMessages(expandVars(expected), "BasicRunWithLivePerf", true); } TEST_F(PerfProfdTest, CallChainRunWithLivePerf) @@ -1018,7 +1020,7 @@ TEST_F(PerfProfdTest, CallChainRunWithLivePerf) I: finishing Android Wide Profiling daemon ); // check to make sure log excerpt matches - compareLogMessages(JoinTestLog(" "), expandVars(expected), "CallChainRunWithLivePerf", true); + CompareLogMessages(expandVars(expected), "CallChainRunWithLivePerf", true); } int main(int argc, char **argv) { -- cgit v1.2.3