gtest_main.cpp revision daaaed18ce1d2f2da9d2240e974922299d937670
1/* 2 * Copyright (C) 2014 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 <gtest/gtest.h> 18 19#include <ctype.h> 20#include <errno.h> 21#include <fcntl.h> 22#include <inttypes.h> 23#include <limits.h> 24#include <signal.h> 25#include <stdarg.h> 26#include <stdio.h> 27#include <string.h> 28#include <sys/wait.h> 29#include <unistd.h> 30 31#include <chrono> 32#include <string> 33#include <tuple> 34#include <utility> 35#include <vector> 36 37#ifndef TEMP_FAILURE_RETRY 38 39/* Used to retry syscalls that can return EINTR. */ 40#define TEMP_FAILURE_RETRY(exp) ({ \ 41 __typeof__(exp) _rc; \ 42 do { \ 43 _rc = (exp); \ 44 } while (_rc == -1 && errno == EINTR); \ 45 _rc; }) 46 47#endif 48 49namespace testing { 50namespace internal { 51 52// Reuse of testing::internal::ColoredPrintf in gtest. 53enum GTestColor { 54 COLOR_DEFAULT, 55 COLOR_RED, 56 COLOR_GREEN, 57 COLOR_YELLOW 58}; 59 60void ColoredPrintf(GTestColor color, const char* fmt, ...); 61 62} // namespace internal 63} // namespace testing 64 65using testing::internal::GTestColor; 66using testing::internal::COLOR_DEFAULT; 67using testing::internal::COLOR_RED; 68using testing::internal::COLOR_GREEN; 69using testing::internal::COLOR_YELLOW; 70using testing::internal::ColoredPrintf; 71 72constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 90000; 73constexpr int DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS = 2000; 74 75// The time each test can run before killed for the reason of timeout. 76// It takes effect only with --isolate option. 77static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS; 78 79// The time each test can run before be warned for too much running time. 80// It takes effect only with --isolate option. 81static int global_test_run_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS; 82 83// Return deadline duration for a test, in ms. 84static int GetDeadlineInfo(const std::string& /*test_name*/) { 85 return global_test_run_deadline_ms; 86} 87 88// Return warnline duration for a test, in ms. 89static int GetWarnlineInfo(const std::string& /*test_name*/) { 90 return global_test_run_warnline_ms; 91} 92 93static void PrintHelpInfo() { 94 printf("Bionic Unit Test Options:\n" 95 " -j [JOB_COUNT] or -j[JOB_COUNT]\n" 96 " Run up to JOB_COUNT tests in parallel.\n" 97 " Use isolation mode, Run each test in a separate process.\n" 98 " If JOB_COUNT is not given, it is set to the count of available processors.\n" 99 " --no-isolate\n" 100 " Don't use isolation mode, run all tests in a single process.\n" 101 " --deadline=[TIME_IN_MS]\n" 102 " Run each test in no longer than [TIME_IN_MS] time.\n" 103 " It takes effect only in isolation mode. Deafult deadline is 60000 ms.\n" 104 " --warnline=[TIME_IN_MS]\n" 105 " Test running longer than [TIME_IN_MS] will be warned.\n" 106 " It takes effect only in isolation mode. Default warnline is 2000 ms.\n" 107 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n" 108 " Used as a synonym for --gtest_filter option in gtest.\n" 109 "Default bionic unit test option is -j.\n" 110 "In isolation mode, you can send SIGQUIT to the parent process to show current\n" 111 "running tests, or send SIGINT to the parent process to stop testing and\n" 112 "clean up current running tests.\n" 113 "\n"); 114} 115 116enum TestResult { 117 TEST_SUCCESS = 0, 118 TEST_FAILED, 119 TEST_TIMEOUT 120}; 121 122class Test { 123 public: 124 Test() {} // For std::vector<Test>. 125 explicit Test(const char* name) : name_(name) {} 126 127 const std::string& GetName() const { return name_; } 128 129 void SetResult(TestResult result) { result_ = result; } 130 131 TestResult GetResult() const { return result_; } 132 133 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; } 134 135 int64_t GetTestTime() const { return elapsed_time_ns_; } 136 137 void AppendTestOutput(const std::string& s) { output_ += s; } 138 139 const std::string& GetTestOutput() const { return output_; } 140 141 private: 142 const std::string name_; 143 TestResult result_; 144 int64_t elapsed_time_ns_; 145 std::string output_; 146}; 147 148class TestCase { 149 public: 150 TestCase() {} // For std::vector<TestCase>. 151 explicit TestCase(const char* name) : name_(name) {} 152 153 const std::string& GetName() const { return name_; } 154 155 void AppendTest(const char* test_name) { 156 test_list_.push_back(Test(test_name)); 157 } 158 159 size_t TestCount() const { return test_list_.size(); } 160 161 std::string GetTestName(size_t test_id) const { 162 VerifyTestId(test_id); 163 return name_ + "." + test_list_[test_id].GetName(); 164 } 165 166 Test& GetTest(size_t test_id) { 167 VerifyTestId(test_id); 168 return test_list_[test_id]; 169 } 170 171 const Test& GetTest(size_t test_id) const { 172 VerifyTestId(test_id); 173 return test_list_[test_id]; 174 } 175 176 void SetTestResult(size_t test_id, TestResult result) { 177 VerifyTestId(test_id); 178 test_list_[test_id].SetResult(result); 179 } 180 181 TestResult GetTestResult(size_t test_id) const { 182 VerifyTestId(test_id); 183 return test_list_[test_id].GetResult(); 184 } 185 186 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) { 187 VerifyTestId(test_id); 188 test_list_[test_id].SetTestTime(elapsed_time_ns); 189 } 190 191 int64_t GetTestTime(size_t test_id) const { 192 VerifyTestId(test_id); 193 return test_list_[test_id].GetTestTime(); 194 } 195 196 private: 197 void VerifyTestId(size_t test_id) const { 198 if(test_id >= test_list_.size()) { 199 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size()); 200 exit(1); 201 } 202 } 203 204 private: 205 const std::string name_; 206 std::vector<Test> test_list_; 207}; 208 209class TestResultPrinter : public testing::EmptyTestEventListener { 210 public: 211 TestResultPrinter() : pinfo_(NULL) {} 212 virtual void OnTestStart(const testing::TestInfo& test_info) { 213 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult. 214 } 215 virtual void OnTestPartResult(const testing::TestPartResult& result); 216 217 private: 218 const testing::TestInfo* pinfo_; 219}; 220 221// Called after an assertion failure. 222void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) { 223 // If the test part succeeded, we don't need to do anything. 224 if (result.type() == testing::TestPartResult::kSuccess) 225 return; 226 227 // Print failure message from the assertion (e.g. expected this and got that). 228 printf("%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), result.line_number(), 229 pinfo_->test_case_name(), pinfo_->name(), result.message()); 230 fflush(stdout); 231} 232 233static int64_t NanoTime() { 234 std::chrono::nanoseconds duration(std::chrono::steady_clock::now().time_since_epoch()); 235 return static_cast<int64_t>(duration.count()); 236} 237 238static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) { 239 std::string command; 240 for (int i = 0; i < argc; ++i) { 241 command += argv[i]; 242 command += " "; 243 } 244 command += "--gtest_list_tests"; 245 FILE* fp = popen(command.c_str(), "r"); 246 if (fp == NULL) { 247 perror("popen"); 248 return false; 249 } 250 251 char buf[200]; 252 while (fgets(buf, sizeof(buf), fp) != NULL) { 253 char* p = buf; 254 255 while (*p != '\0' && isspace(*p)) { 256 ++p; 257 } 258 if (*p == '\0') continue; 259 char* start = p; 260 while (*p != '\0' && !isspace(*p)) { 261 ++p; 262 } 263 char* end = p; 264 while (*p != '\0' && isspace(*p)) { 265 ++p; 266 } 267 if (*p != '\0' && *p != '#') { 268 // This is not we want, gtest must meet with some error when parsing the arguments. 269 fprintf(stderr, "argument error, check with --help\n"); 270 return false; 271 } 272 *end = '\0'; 273 if (*(end - 1) == '.') { 274 *(end - 1) = '\0'; 275 testcase_list.push_back(TestCase(start)); 276 } else { 277 testcase_list.back().AppendTest(start); 278 } 279 } 280 int result = pclose(fp); 281 return (result != -1 && WEXITSTATUS(result) == 0); 282} 283 284// Part of the following *Print functions are copied from external/gtest/src/gtest.cc: 285// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter 286// is defined and used in gtest.cc, which is hard to reuse. 287static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration, 288 int iteration_count) { 289 if (iteration_count != 1) { 290 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration); 291 } 292 ColoredPrintf(COLOR_GREEN, "[==========] "); 293 294 size_t testcase_count = testcase_list.size(); 295 size_t test_count = 0; 296 for (const auto& testcase : testcase_list) { 297 test_count += testcase.TestCount(); 298 } 299 300 printf("Running %zu %s from %zu %s.\n", 301 test_count, (test_count == 1) ? "test" : "tests", 302 testcase_count, (testcase_count == 1) ? "test case" : "test cases"); 303 fflush(stdout); 304} 305 306// bionic cts test needs gtest output format. 307#if defined(USING_GTEST_OUTPUT_FORMAT) 308 309static void OnTestEndPrint(const TestCase& testcase, size_t test_id) { 310 ColoredPrintf(COLOR_GREEN, "[ RUN ] "); 311 printf("%s\n", testcase.GetTestName(test_id).c_str()); 312 313 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput(); 314 printf("%s", test_output.c_str()); 315 316 TestResult result = testcase.GetTestResult(test_id); 317 if (result == TEST_SUCCESS) { 318 ColoredPrintf(COLOR_GREEN, "[ OK ] "); 319 } else { 320 ColoredPrintf(COLOR_RED, "[ FAILED ] "); 321 } 322 printf("%s", testcase.GetTestName(test_id).c_str()); 323 if (testing::GTEST_FLAG(print_time)) { 324 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000); 325 } 326 printf("\n"); 327 fflush(stdout); 328} 329 330#else // !defined(USING_GTEST_OUTPUT_FORMAT) 331 332static void OnTestEndPrint(const TestCase& testcase, size_t test_id) { 333 TestResult result = testcase.GetTestResult(test_id); 334 if (result == TEST_SUCCESS) { 335 ColoredPrintf(COLOR_GREEN, "[ OK ] "); 336 } else if (result == TEST_FAILED) { 337 ColoredPrintf(COLOR_RED, "[ FAILED ] "); 338 } else if (result == TEST_TIMEOUT) { 339 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] "); 340 } 341 342 printf("%s", testcase.GetTestName(test_id).c_str()); 343 if (testing::GTEST_FLAG(print_time)) { 344 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000); 345 } 346 printf("\n"); 347 348 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput(); 349 printf("%s", test_output.c_str()); 350 fflush(stdout); 351} 352 353#endif // !defined(USING_GTEST_OUTPUT_FORMAT) 354 355static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/, 356 int64_t elapsed_time_ns) { 357 358 std::vector<std::string> fail_test_name_list; 359 std::vector<std::pair<std::string, int64_t>> timeout_test_list; 360 361 // For tests run exceed warnline but not timeout. 362 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list; 363 size_t testcase_count = testcase_list.size(); 364 size_t test_count = 0; 365 size_t success_test_count = 0; 366 367 for (const auto& testcase : testcase_list) { 368 test_count += testcase.TestCount(); 369 for (size_t i = 0; i < testcase.TestCount(); ++i) { 370 TestResult result = testcase.GetTestResult(i); 371 if (result == TEST_SUCCESS) { 372 ++success_test_count; 373 } else if (result == TEST_FAILED) { 374 fail_test_name_list.push_back(testcase.GetTestName(i)); 375 } else if (result == TEST_TIMEOUT) { 376 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i), 377 testcase.GetTestTime(i))); 378 } 379 if (result != TEST_TIMEOUT && 380 testcase.GetTestTime(i) / 1000000 >= GetWarnlineInfo(testcase.GetTestName(i))) { 381 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i), 382 testcase.GetTestTime(i), 383 GetWarnlineInfo(testcase.GetTestName(i)))); 384 } 385 } 386 } 387 388 ColoredPrintf(COLOR_GREEN, "[==========] "); 389 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests", 390 testcase_count, (testcase_count == 1) ? "test case" : "test cases"); 391 if (testing::GTEST_FLAG(print_time)) { 392 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000); 393 } 394 printf("\n"); 395 ColoredPrintf(COLOR_GREEN, "[ PASS ] "); 396 printf("%zu %s.\n", success_test_count, (success_test_count == 1) ? "test" : "tests"); 397 398 // Print tests failed. 399 size_t fail_test_count = fail_test_name_list.size(); 400 if (fail_test_count > 0) { 401 ColoredPrintf(COLOR_RED, "[ FAIL ] "); 402 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests"); 403 for (const auto& name : fail_test_name_list) { 404 ColoredPrintf(COLOR_RED, "[ FAIL ] "); 405 printf("%s\n", name.c_str()); 406 } 407 } 408 409 // Print tests run timeout. 410 size_t timeout_test_count = timeout_test_list.size(); 411 if (timeout_test_count > 0) { 412 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] "); 413 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests"); 414 for (const auto& timeout_pair : timeout_test_list) { 415 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] "); 416 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(), 417 timeout_pair.second / 1000000); 418 } 419 } 420 421 // Print tests run exceed warnline. 422 size_t slow_test_count = slow_test_list.size(); 423 if (slow_test_count > 0) { 424 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] "); 425 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests"); 426 for (const auto& slow_tuple : slow_test_list) { 427 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] "); 428 printf("%s (%" PRId64 " ms, exceed warnline %d ms)\n", std::get<0>(slow_tuple).c_str(), 429 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple)); 430 } 431 } 432 433 if (fail_test_count > 0) { 434 printf("\n%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS"); 435 } 436 if (timeout_test_count > 0) { 437 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS"); 438 } 439 if (slow_test_count > 0) { 440 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS"); 441 } 442 fflush(stdout); 443} 444 445// Output xml file when --gtest_output is used, write this function as we can't reuse 446// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally 447// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in 448// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter. 449void OnTestIterationEndXmlPrint(const std::string& xml_output_filename, 450 const std::vector<TestCase>& testcase_list, 451 time_t epoch_iteration_start_time, 452 int64_t elapsed_time_ns) { 453 FILE* fp = fopen(xml_output_filename.c_str(), "w"); 454 if (fp == NULL) { 455 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno)); 456 exit(1); 457 } 458 459 size_t total_test_count = 0; 460 size_t total_failed_count = 0; 461 std::vector<size_t> failed_count_list(testcase_list.size(), 0); 462 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0); 463 for (size_t i = 0; i < testcase_list.size(); ++i) { 464 auto& testcase = testcase_list[i]; 465 total_test_count += testcase.TestCount(); 466 for (size_t j = 0; j < testcase.TestCount(); ++j) { 467 if (testcase.GetTestResult(j) != TEST_SUCCESS) { 468 ++failed_count_list[i]; 469 } 470 elapsed_time_list[i] += testcase.GetTestTime(j); 471 } 472 total_failed_count += failed_count_list[i]; 473 } 474 475 const tm* time_struct = localtime(&epoch_iteration_start_time); 476 char timestamp[40]; 477 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d", 478 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday, 479 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec); 480 481 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp); 482 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"", 483 total_test_count, total_failed_count); 484 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9); 485 for (size_t i = 0; i < testcase_list.size(); ++i) { 486 auto& testcase = testcase_list[i]; 487 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"", 488 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]); 489 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9); 490 491 for (size_t j = 0; j < testcase.TestCount(); ++j) { 492 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"", 493 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9, 494 testcase.GetName().c_str()); 495 if (testcase.GetTestResult(j) == TEST_SUCCESS) { 496 fputs(" />\n", fp); 497 } else { 498 fputs(">\n", fp); 499 const std::string& test_output = testcase.GetTest(j).GetTestOutput(); 500 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", test_output.c_str()); 501 fputs(" </failure>\n", fp); 502 fputs(" </testcase>\n", fp); 503 } 504 } 505 506 fputs(" </testsuite>\n", fp); 507 } 508 fputs("</testsuites>\n", fp); 509 fclose(fp); 510} 511 512static bool sigint_flag; 513static bool sigquit_flag; 514 515static void signal_handler(int sig) { 516 if (sig == SIGINT) { 517 sigint_flag = true; 518 } else if (sig == SIGQUIT) { 519 sigquit_flag = true; 520 } 521} 522 523static bool RegisterSignalHandler() { 524 sigint_flag = false; 525 sigquit_flag = false; 526 sig_t ret = signal(SIGINT, signal_handler); 527 if (ret != SIG_ERR) { 528 ret = signal(SIGQUIT, signal_handler); 529 } 530 if (ret == SIG_ERR) { 531 perror("RegisterSignalHandler"); 532 return false; 533 } 534 return true; 535} 536 537static bool UnregisterSignalHandler() { 538 sig_t ret = signal(SIGINT, SIG_DFL); 539 if (ret != SIG_ERR) { 540 ret = signal(SIGQUIT, SIG_DFL); 541 } 542 if (ret == SIG_ERR) { 543 perror("UnregisterSignalHandler"); 544 return false; 545 } 546 return true; 547} 548 549struct ChildProcInfo { 550 pid_t pid; 551 int64_t start_time_ns; 552 int64_t end_time_ns; 553 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout. 554 size_t testcase_id, test_id; 555 bool finished; 556 bool timed_out; 557 int exit_status; 558 int child_read_fd; // File descriptor to read child test failure info. 559}; 560 561// Forked Child process, run the single test. 562static void ChildProcessFn(int argc, char** argv, const std::string& test_name) { 563 char** new_argv = new char*[argc + 2]; 564 memcpy(new_argv, argv, sizeof(char*) * argc); 565 566 char* filter_arg = new char [test_name.size() + 20]; 567 strcpy(filter_arg, "--gtest_filter="); 568 strcat(filter_arg, test_name.c_str()); 569 new_argv[argc] = filter_arg; 570 new_argv[argc + 1] = NULL; 571 572 int new_argc = argc + 1; 573 testing::InitGoogleTest(&new_argc, new_argv); 574 int result = RUN_ALL_TESTS(); 575 exit(result); 576} 577 578#if defined(__APPLE__) 579 580static int pipe2(int pipefd[2], int flags) { 581 int ret = pipe(pipefd); 582 if (ret != -1) { 583 ret = fcntl(pipefd[0], F_SETFL, flags); 584 } 585 if (ret != -1) { 586 ret = fcntl(pipefd[1], F_SETFL, flags); 587 } 588 return ret; 589} 590 591#endif 592 593static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id, 594 int argc, char** argv) { 595 int pipefd[2]; 596 int ret = pipe2(pipefd, O_NONBLOCK); 597 if (ret == -1) { 598 perror("pipe2 in RunTestInSeparateProc"); 599 exit(1); 600 } 601 pid_t pid = fork(); 602 if (pid == -1) { 603 perror("fork in RunTestInSeparateProc"); 604 exit(1); 605 } else if (pid == 0) { 606 // In child process, run a single test. 607 close(pipefd[0]); 608 close(STDOUT_FILENO); 609 close(STDERR_FILENO); 610 dup2(pipefd[1], STDOUT_FILENO); 611 dup2(pipefd[1], STDERR_FILENO); 612 613 if (!UnregisterSignalHandler()) { 614 exit(1); 615 } 616 ChildProcessFn(argc, argv, test_name); 617 // Unreachable. 618 } 619 // In parent process, initialize child process info. 620 close(pipefd[1]); 621 ChildProcInfo child_proc; 622 child_proc.child_read_fd = pipefd[0]; 623 child_proc.pid = pid; 624 child_proc.start_time_ns = NanoTime(); 625 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetDeadlineInfo(test_name) * 1000000LL; 626 child_proc.testcase_id = testcase_id; 627 child_proc.test_id = test_id; 628 child_proc.finished = false; 629 return child_proc; 630} 631 632static void HandleSignals(std::vector<TestCase>& testcase_list, 633 std::vector<ChildProcInfo>& child_proc_list) { 634 if (sigquit_flag) { 635 sigquit_flag = false; 636 // Print current running tests. 637 printf("List of current running tests:\n"); 638 for (auto& child_proc : child_proc_list) { 639 if (child_proc.pid != 0) { 640 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id); 641 int64_t current_time_ns = NanoTime(); 642 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000; 643 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms); 644 } 645 } 646 } else if (sigint_flag) { 647 sigint_flag = false; 648 // Kill current running tests. 649 for (auto& child_proc : child_proc_list) { 650 if (child_proc.pid != 0) { 651 // Send SIGKILL to ensure the child process can be killed unconditionally. 652 kill(child_proc.pid, SIGKILL); 653 } 654 } 655 // SIGINT kills the parent process as well. 656 exit(1); 657 } 658} 659 660static bool CheckChildProcExit(pid_t exit_pid, int exit_status, 661 std::vector<ChildProcInfo>& child_proc_list) { 662 for (size_t i = 0; i < child_proc_list.size(); ++i) { 663 if (child_proc_list[i].pid == exit_pid) { 664 child_proc_list[i].finished = true; 665 child_proc_list[i].timed_out = false; 666 child_proc_list[i].exit_status = exit_status; 667 child_proc_list[i].end_time_ns = NanoTime(); 668 return true; 669 } 670 } 671 return false; 672} 673 674static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) { 675 int64_t current_time_ns = NanoTime(); 676 size_t timeout_child_count = 0; 677 for (size_t i = 0; i < child_proc_list.size(); ++i) { 678 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) { 679 child_proc_list[i].finished = true; 680 child_proc_list[i].timed_out = true; 681 child_proc_list[i].end_time_ns = current_time_ns; 682 ++timeout_child_count; 683 } 684 } 685 return timeout_child_count; 686} 687 688static void WaitChildProcs(std::vector<TestCase>& testcase_list, 689 std::vector<ChildProcInfo>& child_proc_list) { 690 size_t finished_child_count = 0; 691 while (true) { 692 int status; 693 pid_t result; 694 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) { 695 if (CheckChildProcExit(result, status, child_proc_list)) { 696 ++finished_child_count; 697 } 698 } 699 700 if (result == -1) { 701 if (errno == ECHILD) { 702 // This happens when we have no running child processes. 703 return; 704 } else { 705 perror("waitpid"); 706 exit(1); 707 } 708 } else if (result == 0) { 709 finished_child_count += CheckChildProcTimeout(child_proc_list); 710 } 711 712 if (finished_child_count > 0) { 713 return; 714 } 715 716 HandleSignals(testcase_list, child_proc_list); 717 718 // sleep 1 ms to avoid busy looping. 719 timespec sleep_time; 720 sleep_time.tv_sec = 0; 721 sleep_time.tv_nsec = 1000000; 722 nanosleep(&sleep_time, NULL); 723 } 724} 725 726static TestResult WaitForOneChild(pid_t pid) { 727 int exit_status; 728 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0)); 729 730 TestResult test_result = TEST_SUCCESS; 731 if (result != pid || WEXITSTATUS(exit_status) != 0) { 732 test_result = TEST_FAILED; 733 } 734 return test_result; 735} 736 737static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) { 738 int test_id = child_proc.test_id; 739 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns); 740 if (child_proc.timed_out) { 741 // The child process marked as timed_out has not exited, and we should kill it manually. 742 kill(child_proc.pid, SIGKILL); 743 WaitForOneChild(child_proc.pid); 744 } 745 746 while (true) { 747 char buf[1024]; 748 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1)); 749 if (bytes_read > 0) { 750 buf[bytes_read] = '\0'; 751 testcase.GetTest(test_id).AppendTestOutput(buf); 752 } else if (bytes_read == 0) { 753 break; // Read end. 754 } else { 755 if (errno == EAGAIN) { 756 // No data is available. This rarely happens, only when the child process created other 757 // processes which have not exited so far. But the child process has already exited or 758 // been killed, so the test has finished, and we shouldn't wait further. 759 break; 760 } 761 perror("read child_read_fd in RunTestInSeparateProc"); 762 exit(1); 763 } 764 } 765 close(child_proc.child_read_fd); 766 767 if (child_proc.timed_out) { 768 testcase.SetTestResult(test_id, TEST_TIMEOUT); 769 char buf[1024]; 770 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n", 771 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000); 772 testcase.GetTest(test_id).AppendTestOutput(buf); 773 774 } else if (WIFSIGNALED(child_proc.exit_status)) { 775 // Record signal terminated test as failed. 776 testcase.SetTestResult(test_id, TEST_FAILED); 777 char buf[1024]; 778 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n", 779 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status))); 780 testcase.GetTest(test_id).AppendTestOutput(buf); 781 782 } else { 783 testcase.SetTestResult(test_id, WEXITSTATUS(child_proc.exit_status) == 0 ? 784 TEST_SUCCESS : TEST_FAILED); 785 } 786} 787 788// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always 789// makes deadlock to use fork in multi-thread. 790// Returns true if all tests run successfully, otherwise return false. 791static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list, 792 int iteration_count, size_t job_count, 793 const std::string& xml_output_filename) { 794 // Stop default result printer to avoid environment setup/teardown information for each test. 795 testing::UnitTest::GetInstance()->listeners().Release( 796 testing::UnitTest::GetInstance()->listeners().default_result_printer()); 797 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter); 798 799 if (!RegisterSignalHandler()) { 800 exit(1); 801 } 802 803 bool all_tests_passed = true; 804 805 for (size_t iteration = 1; 806 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count); 807 ++iteration) { 808 OnTestIterationStartPrint(testcase_list, iteration, iteration_count); 809 int64_t iteration_start_time_ns = NanoTime(); 810 time_t epoch_iteration_start_time = time(NULL); 811 812 // Run up to job_count tests in parallel, each test in a child process. 813 std::vector<ChildProcInfo> child_proc_list; 814 815 // Next test to run is [next_testcase_id:next_test_id]. 816 size_t next_testcase_id = 0; 817 size_t next_test_id = 0; 818 819 // Record how many tests are finished. 820 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0); 821 size_t finished_testcase_count = 0; 822 823 while (finished_testcase_count < testcase_list.size()) { 824 // run up to job_count child processes. 825 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) { 826 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id); 827 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id, 828 argc, argv); 829 child_proc_list.push_back(child_proc); 830 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) { 831 next_test_id = 0; 832 ++next_testcase_id; 833 } 834 } 835 836 // Wait for any child proc finish or timeout. 837 WaitChildProcs(testcase_list, child_proc_list); 838 839 // Collect result. 840 auto it = child_proc_list.begin(); 841 while (it != child_proc_list.end()) { 842 auto& child_proc = *it; 843 if (child_proc.finished == true) { 844 size_t testcase_id = child_proc.testcase_id; 845 size_t test_id = child_proc.test_id; 846 TestCase& testcase = testcase_list[testcase_id]; 847 848 CollectChildTestResult(child_proc, testcase); 849 OnTestEndPrint(testcase, test_id); 850 851 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) { 852 ++finished_testcase_count; 853 } 854 if (testcase.GetTestResult(test_id) != TEST_SUCCESS) { 855 all_tests_passed = false; 856 } 857 858 it = child_proc_list.erase(it); 859 } else { 860 ++it; 861 } 862 } 863 } 864 865 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns; 866 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns); 867 if (!xml_output_filename.empty()) { 868 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time, 869 elapsed_time_ns); 870 } 871 } 872 873 if (!UnregisterSignalHandler()) { 874 exit(1); 875 } 876 877 return all_tests_passed; 878} 879 880static size_t GetDefaultJobCount() { 881#if defined(JOB_COUNT_FIXED) 882 return JOB_COUNT_FIXED; 883#else 884 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN)); 885#endif 886} 887 888static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) { 889 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the 890 // test program via a valid path that contains at least one path separator. 891 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode, 892 // and execve() doesn't read environment variable PATH, so execve() will not success 893 // until we specify the absolute path or relative path of the test program directly. 894 if (strchr(args[0], '/') == NULL) { 895 char path[PATH_MAX]; 896 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path)); 897 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) { 898 perror("readlink"); 899 exit(1); 900 } 901 path[path_len] = '\0'; 902 args[0] = strdup(path); 903 } 904} 905 906static void AddGtestFilterSynonym(std::vector<char*>& args) { 907 // Support --gtest-filter as a synonym for --gtest_filter. 908 for (size_t i = 1; i < args.size(); ++i) { 909 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) { 910 args[i][7] = '_'; 911 } 912 } 913} 914 915struct IsolationTestOptions { 916 bool isolate; 917 size_t job_count; 918 int test_deadline_ms; 919 int test_warnline_ms; 920 std::string gtest_color; 921 bool gtest_print_time; 922 int gtest_repeat; 923 std::string gtest_output; 924}; 925 926// Pick options not for gtest: There are two parts in args, one part is used in isolation test mode 927// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in 928// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second 929// part in args. 930// Arguments: 931// args is used to pass in all command arguments, and pass out only the part of options for gtest. 932// options is used to pass out test options in isolation mode. 933// Return false if there is error in arguments. 934static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) { 935 for (size_t i = 1; i < args.size(); ++i) { 936 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) { 937 PrintHelpInfo(); 938 options.isolate = false; 939 return true; 940 } 941 } 942 943 AddPathSeparatorInTestProgramPath(args); 944 AddGtestFilterSynonym(args); 945 946 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests. 947 bool enable_selftest = false; 948 for (size_t i = 1; i < args.size(); ++i) { 949 if (strcmp(args[i], "--bionic-selftest") == 0) { 950 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info. 951 // Don't remove this option from arguments. 952 enable_selftest = true; 953 } 954 } 955 std::string gtest_filter_str; 956 for (size_t i = args.size() - 1; i >= 1; --i) { 957 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) { 958 gtest_filter_str = std::string(args[i]); 959 args.erase(args.begin() + i); 960 break; 961 } 962 } 963 if (enable_selftest == true) { 964 args.push_back(strdup("--gtest_filter=bionic_selftest*")); 965 } else { 966 if (gtest_filter_str == "") { 967 gtest_filter_str = "--gtest_filter=-bionic_selftest*"; 968 } else { 969 // Find if '-' for NEGATIVE_PATTERNS exists. 970 if (gtest_filter_str.find(":-") != std::string::npos) { 971 gtest_filter_str += ":bionic_selftest*"; 972 } else { 973 gtest_filter_str += ":-bionic_selftest*"; 974 } 975 } 976 args.push_back(strdup(gtest_filter_str.c_str())); 977 } 978 979 options.isolate = true; 980 // Parse arguments that make us can't run in isolation mode. 981 for (size_t i = 1; i < args.size(); ++i) { 982 if (strcmp(args[i], "--no-isolate") == 0) { 983 options.isolate = false; 984 } else if (strcmp(args[i], "--gtest_list_tests") == 0) { 985 options.isolate = false; 986 } 987 } 988 989 // Stop parsing if we will not run in isolation mode. 990 if (options.isolate == false) { 991 return true; 992 } 993 994 // Init default isolation test options. 995 options.job_count = GetDefaultJobCount(); 996 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS; 997 options.test_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS; 998 options.gtest_color = testing::GTEST_FLAG(color); 999 options.gtest_print_time = testing::GTEST_FLAG(print_time); 1000 options.gtest_repeat = testing::GTEST_FLAG(repeat); 1001 options.gtest_output = testing::GTEST_FLAG(output); 1002 1003 // Parse arguments speficied for isolation mode. 1004 for (size_t i = 1; i < args.size(); ++i) { 1005 if (strncmp(args[i], "-j", strlen("-j")) == 0) { 1006 char* p = args[i] + strlen("-j"); 1007 int count = 0; 1008 if (*p != '\0') { 1009 // Argument like -j5. 1010 count = atoi(p); 1011 } else if (args.size() > i + 1) { 1012 // Arguments like -j 5. 1013 count = atoi(args[i + 1]); 1014 ++i; 1015 } 1016 if (count <= 0) { 1017 fprintf(stderr, "invalid job count: %d\n", count); 1018 return false; 1019 } 1020 options.job_count = static_cast<size_t>(count); 1021 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) { 1022 int time_ms = atoi(args[i] + strlen("--deadline=")); 1023 if (time_ms <= 0) { 1024 fprintf(stderr, "invalid deadline: %d\n", time_ms); 1025 return false; 1026 } 1027 options.test_deadline_ms = time_ms; 1028 } else if (strncmp(args[i], "--warnline=", strlen("--warnline=")) == 0) { 1029 int time_ms = atoi(args[i] + strlen("--warnline=")); 1030 if (time_ms <= 0) { 1031 fprintf(stderr, "invalid warnline: %d\n", time_ms); 1032 return false; 1033 } 1034 options.test_warnline_ms = time_ms; 1035 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) { 1036 options.gtest_color = args[i] + strlen("--gtest_color="); 1037 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) { 1038 options.gtest_print_time = false; 1039 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) { 1040 // If the value of gtest_repeat is < 0, then it indicates the tests 1041 // should be repeated forever. 1042 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat=")); 1043 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test. 1044 args.erase(args.begin() + i); 1045 --i; 1046 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) { 1047 std::string output = args[i] + strlen("--gtest_output="); 1048 // generate output xml file path according to the strategy in gtest. 1049 bool success = true; 1050 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) { 1051 output = output.substr(strlen("xml:")); 1052 if (output.size() == 0) { 1053 success = false; 1054 } 1055 // Make absolute path. 1056 if (success && output[0] != '/') { 1057 char* cwd = getcwd(NULL, 0); 1058 if (cwd != NULL) { 1059 output = std::string(cwd) + "/" + output; 1060 free(cwd); 1061 } else { 1062 success = false; 1063 } 1064 } 1065 // Add file name if output is a directory. 1066 if (success && output.back() == '/') { 1067 output += "test_details.xml"; 1068 } 1069 } 1070 if (success) { 1071 options.gtest_output = output; 1072 } else { 1073 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]); 1074 return false; 1075 } 1076 1077 // Remove --gtest_output=xxx from arguments, so child process will not write xml file. 1078 args.erase(args.begin() + i); 1079 --i; 1080 } 1081 } 1082 1083 // Add --no-isolate in args to prevent child process from running in isolation mode again. 1084 // As DeathTest will try to call execve(), this argument should always be added. 1085 args.insert(args.begin() + 1, strdup("--no-isolate")); 1086 return true; 1087} 1088 1089int main(int argc, char** argv) { 1090 std::vector<char*> arg_list; 1091 for (int i = 0; i < argc; ++i) { 1092 arg_list.push_back(argv[i]); 1093 } 1094 1095 IsolationTestOptions options; 1096 if (PickOptions(arg_list, options) == false) { 1097 return 1; 1098 } 1099 1100 if (options.isolate == true) { 1101 // Set global variables. 1102 global_test_run_deadline_ms = options.test_deadline_ms; 1103 global_test_run_warnline_ms = options.test_warnline_ms; 1104 testing::GTEST_FLAG(color) = options.gtest_color.c_str(); 1105 testing::GTEST_FLAG(print_time) = options.gtest_print_time; 1106 std::vector<TestCase> testcase_list; 1107 1108 argc = static_cast<int>(arg_list.size()); 1109 arg_list.push_back(NULL); 1110 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) { 1111 return 1; 1112 } 1113 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list, 1114 options.gtest_repeat, options.job_count, options.gtest_output); 1115 return all_test_passed ? 0 : 1; 1116 } else { 1117 argc = static_cast<int>(arg_list.size()); 1118 arg_list.push_back(NULL); 1119 testing::InitGoogleTest(&argc, arg_list.data()); 1120 return RUN_ALL_TESTS(); 1121 } 1122} 1123 1124//################################################################################ 1125// Bionic Gtest self test, run this by --bionic-selftest option. 1126 1127TEST(bionic_selftest, test_success) { 1128 ASSERT_EQ(1, 1); 1129} 1130 1131TEST(bionic_selftest, test_fail) { 1132 ASSERT_EQ(0, 1); 1133} 1134 1135TEST(bionic_selftest, test_time_warn) { 1136 sleep(4); 1137} 1138 1139TEST(bionic_selftest, test_timeout) { 1140 while (1) {} 1141} 1142 1143TEST(bionic_selftest, test_signal_SEGV_terminated) { 1144 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0"))); 1145 *p = 3; 1146} 1147 1148class bionic_selftest_DeathTest : public ::testing::Test { 1149 protected: 1150 virtual void SetUp() { 1151 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; 1152 } 1153}; 1154 1155static void deathtest_helper_success() { 1156 ASSERT_EQ(1, 1); 1157 exit(0); 1158} 1159 1160TEST_F(bionic_selftest_DeathTest, success) { 1161 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), ""); 1162} 1163 1164static void deathtest_helper_fail() { 1165 ASSERT_EQ(1, 0); 1166} 1167 1168TEST_F(bionic_selftest_DeathTest, fail) { 1169 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), ""); 1170} 1171