Add automatic running of tests on bionic changes.

malloc debug and malloc hooks have been broken for a long time
and no one noticed. So add them to be run by default on bionic
changes since that provides the most coverage.

Change the malloc debug and malloc hooks tests to support isolated
runs.

Changed the name of the malloc hooks unit tests to system tests
because they weren't really unit tests.

Changed the verify leak malloc debug tests to print out extra
information so it is possible to figure out what sized allocation
failed.

Test: Ran tests.
Change-Id: Idea4c864f1d62598148ee78d7c9397e45234b1ca
This commit is contained in:
Christopher Ferris 2019-11-11 14:17:44 -08:00
parent 17dfa33200
commit e4619f7719
4 changed files with 28 additions and 7 deletions

View file

@ -2,6 +2,12 @@
"presubmit": [ "presubmit": [
{ {
"name": "CtsBionicTestCases" "name": "CtsBionicTestCases"
},
{
"name": "malloc_debug_system_tests"
},
{
"name": "malloc_hooks_system_tests"
} }
] ]
} }

View file

@ -165,6 +165,7 @@ cc_test {
// ============================================================== // ==============================================================
cc_test { cc_test {
name: "malloc_debug_system_tests", name: "malloc_debug_system_tests",
isolated: true,
include_dirs: [ include_dirs: [
"bionic/libc", "bionic/libc",
@ -189,4 +190,5 @@ cc_test {
"-Werror", "-Werror",
"-O0", "-O0",
], ],
test_suites: ["general-tests"],
} }

View file

@ -50,6 +50,14 @@
static constexpr time_t kTimeoutSeconds = 10; static constexpr time_t kTimeoutSeconds = 10;
extern "C" bool GetInitialArgs(const char*** args, size_t* num_args) {
static const char* initial_args[] = {"--slow_threshold_ms=30000",
"--deadline_threshold_ms=1200000"};
*args = initial_args;
*num_args = 2;
return true;
}
static void Exec(const char* test_name, const char* debug_options, pid_t* pid, int exit_code = 0, static void Exec(const char* test_name, const char* debug_options, pid_t* pid, int exit_code = 0,
time_t timeout_seconds = kTimeoutSeconds) { time_t timeout_seconds = kTimeoutSeconds) {
int fds[2]; int fds[2];
@ -71,6 +79,9 @@ static void Exec(const char* test_name, const char* debug_options, pid_t* pid, i
args.push_back("--gtest_also_run_disabled_tests"); args.push_back("--gtest_also_run_disabled_tests");
std::string filter_arg = std::string("--gtest_filter=") + test_name; std::string filter_arg = std::string("--gtest_filter=") + test_name;
args.push_back(filter_arg.c_str()); args.push_back(filter_arg.c_str());
// Need this because some code depends on exit codes from the test run
// but the isolation runner does not support that.
args.push_back("--no_isolate");
args.push_back(nullptr); args.push_back(nullptr);
execv(args[0], reinterpret_cast<char* const*>(const_cast<char**>(args.data()))); execv(args[0], reinterpret_cast<char* const*>(const_cast<char**>(args.data())));
exit(20); exit(20);
@ -179,14 +190,14 @@ static void FindStrings(pid_t pid, std::vector<const char*> match_strings,
time_t timeout_seconds = kTimeoutSeconds) { time_t timeout_seconds = kTimeoutSeconds) {
std::string log_str; std::string log_str;
time_t start = time(nullptr); time_t start = time(nullptr);
bool found_all; std::string missing_match;
while (true) { while (true) {
GetLogStr(pid, &log_str); GetLogStr(pid, &log_str);
found_all = true; missing_match.clear();
// Look for the expected strings. // Look for the expected strings.
for (auto str : match_strings) { for (auto str : match_strings) {
if (log_str.find(str) == std::string::npos) { if (log_str.find(str) == std::string::npos) {
found_all = false; missing_match = str;
break; break;
} }
} }
@ -195,14 +206,14 @@ static void FindStrings(pid_t pid, std::vector<const char*> match_strings,
for (auto str : no_match_strings) { for (auto str : no_match_strings) {
ASSERT_TRUE(log_str.find(str) == std::string::npos) << "Unexpectedly found '" << str << "' in log output:\n" << log_str; ASSERT_TRUE(log_str.find(str) == std::string::npos) << "Unexpectedly found '" << str << "' in log output:\n" << log_str;
} }
if (found_all) { if (missing_match.empty()) {
return; return;
} }
if ((time(nullptr) - start) > timeout_seconds) { if ((time(nullptr) - start) > timeout_seconds) {
break; break;
} }
} }
ASSERT_TRUE(found_all) << "Didn't find expected log output:\n" << log_str; ASSERT_EQ("", missing_match) << "Didn't find expected log output:\n" << log_str;
} }
TEST(MallocTests, DISABLED_smoke) {} TEST(MallocTests, DISABLED_smoke) {}
@ -413,7 +424,7 @@ static void VerifyLeak(const char* test_prefix) {
pid_t pid; pid_t pid;
SCOPED_TRACE(testing::Message() << functions[i].name << " expected size " << functions[i].size); SCOPED_TRACE(testing::Message() << functions[i].name << " expected size " << functions[i].size);
std::string test = std::string("MallocTests.DISABLED_") + test_prefix + functions[i].name; std::string test = std::string("MallocTests.DISABLED_") + test_prefix + functions[i].name;
EXPECT_NO_FATAL_FAILURE(Exec(test.c_str(), "verbose backtrace leak_track", &pid)); ASSERT_NO_FATAL_FAILURE(Exec(test.c_str(), "verbose backtrace leak_track", &pid));
std::string expected_leak = android::base::StringPrintf("leaked block of size %zu at", functions[i].size); std::string expected_leak = android::base::StringPrintf("leaked block of size %zu at", functions[i].size);
EXPECT_NO_FATAL_FAILURE(FindStrings( EXPECT_NO_FATAL_FAILURE(FindStrings(

View file

@ -47,7 +47,8 @@ cc_library {
// Unit Tests // Unit Tests
// ============================================================== // ==============================================================
cc_test { cc_test {
name: "malloc_hooks_unit_tests", name: "malloc_hooks_system_tests",
isolated: true,
srcs: [ srcs: [
"tests/malloc_hooks_tests.cpp", "tests/malloc_hooks_tests.cpp",
@ -70,4 +71,5 @@ cc_test {
"-Wall", "-Wall",
"-Werror", "-Werror",
], ],
test_suites: ["general-tests"],
} }