gtest_main.cpp revision 516eb531137a50e2fd82108c5b7a43b87c103312
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 <errno.h> 20#include <stdarg.h> 21#include <stdio.h> 22#include <string.h> 23#include <sys/wait.h> 24#include <time.h> 25#include <unistd.h> 26 27#include <string> 28#include <tuple> 29#include <utility> 30#include <vector> 31 32namespace testing { 33namespace internal { 34 35// Reuse of testing::internal::ColoredPrintf in gtest. 36enum GTestColor { 37 COLOR_DEFAULT, 38 COLOR_RED, 39 COLOR_GREEN, 40 COLOR_YELLOW 41}; 42 43void ColoredPrintf(GTestColor color, const char* fmt, ...); 44 45} // namespace internal 46} // namespace testing 47 48using testing::internal::GTestColor; 49using testing::internal::COLOR_DEFAULT; 50using testing::internal::COLOR_RED; 51using testing::internal::COLOR_GREEN; 52using testing::internal::COLOR_YELLOW; 53using testing::internal::ColoredPrintf; 54 55constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_IN_MS = 60000; 56constexpr int DEFAULT_GLOBAL_TEST_RUN_WARNLINE_IN_MS = 2000; 57 58// The time each test can run before killed for the reason of timeout. 59// It takes effect only with --isolate option. 60static int global_test_run_deadline_in_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_IN_MS; 61 62// The time each test can run before be warned for too much running time. 63// It takes effect only with --isolate option. 64static int global_test_run_warnline_in_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_IN_MS; 65 66// Return deadline duration for a test, in ms. 67static int GetDeadlineInfo(const std::string& /*test_name*/) { 68 return global_test_run_deadline_in_ms; 69} 70 71// Return warnline duration for a test, in ms. 72static int GetWarnlineInfo(const std::string& /*test_name*/) { 73 return global_test_run_warnline_in_ms; 74} 75 76static void PrintHelpInfo() { 77 printf("Bionic Unit Test Options:\n" 78 " -j [JOB_COUNT]\n" 79 " Run up to JOB_COUNT tests in parallel.\n" 80 " Use isolation mode, Run each test in a separate process.\n" 81 " If JOB_COUNT is not given, it is set to the count of available processors.\n" 82 " --no-isolate\n" 83 " Don't use isolation mode, run all tests in a single process.\n" 84 " --deadline=[TIME_IN_MS]\n" 85 " Run each test in no longer than [TIME_IN_MS] time.\n" 86 " It takes effect only in isolation mode. Deafult deadline is 60000 ms.\n" 87 " --warnline=[TIME_IN_MS]\n" 88 " Test running longer than [TIME_IN_MS] will be warned.\n" 89 " It takes effect only in isolation mode. Default warnline is 2000 ms.\n" 90 "\nDefault bionic unit test option is -j.\n" 91 "\n"); 92} 93 94enum TestResult { 95 TEST_SUCCESS = 0, 96 TEST_FAILED, 97 TEST_TIMEOUT 98}; 99 100class TestCase { 101 public: 102 TestCase() {} // For std::vector<TestCase>. 103 explicit TestCase(const char* name) : name_(name) {} 104 105 const std::string& GetName() const { return name_; } 106 107 void AppendTest(const std::string& test_name) { 108 test_list_.push_back(std::make_tuple(test_name, TEST_FAILED, 0LL)); 109 } 110 111 size_t TestCount() const { return test_list_.size(); } 112 113 std::string GetTestName(size_t test_id) const { 114 VerifyTestId(test_id); 115 return name_ + "." + std::get<0>(test_list_[test_id]); 116 } 117 118 void SetTestResult(size_t test_id, TestResult result) { 119 VerifyTestId(test_id); 120 std::get<1>(test_list_[test_id]) = result; 121 } 122 123 TestResult GetTestResult(size_t test_id) const { 124 VerifyTestId(test_id); 125 return std::get<1>(test_list_[test_id]); 126 } 127 128 void SetTestTime(size_t test_id, int64_t elapsed_time) { 129 VerifyTestId(test_id); 130 std::get<2>(test_list_[test_id]) = elapsed_time; 131 } 132 133 int64_t GetTestTime(size_t test_id) const { 134 VerifyTestId(test_id); 135 return std::get<2>(test_list_[test_id]); 136 } 137 138 private: 139 void VerifyTestId(size_t test_id) const { 140 if(test_id >= test_list_.size()) { 141 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size()); 142 exit(1); 143 } 144 } 145 146 private: 147 const std::string name_; 148 std::vector<std::tuple<std::string, TestResult, int64_t> > test_list_; 149}; 150 151// TestResultPrinter is copied from part of external/gtest/src/gtest.cc:PrettyUnitTestResultPrinter. 152// The reason for copy is that PrettyUnitTestResultPrinter is defined and used in gtest.cc, which 153// is hard to reuse. 154// TestResultPrinter only print information for a single test, which is used in child process. 155// The information of test_iteration/environment/testcase is left for parent process to print. 156class TestResultPrinter : public testing::EmptyTestEventListener { 157 public: 158 TestResultPrinter() : pinfo_(NULL) {} 159 virtual void OnTestStart(const testing::TestInfo& test_info) { 160 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult. 161 } 162 virtual void OnTestPartResult(const testing::TestPartResult& result); 163 virtual void OnTestEnd(const testing::TestInfo& test_info); 164 165 private: 166 const testing::TestInfo* pinfo_; 167}; 168 169// Called after an assertion failure. 170void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) { 171 // If the test part succeeded, we don't need to do anything. 172 if (result.type() == testing::TestPartResult::kSuccess) 173 return; 174 175 // Print failure message from the assertion (e.g. expected this and got that). 176 char buf[1024]; 177 snprintf(buf, sizeof(buf), "%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), 178 result.line_number(), 179 pinfo_->test_case_name(), 180 pinfo_->name(), 181 result.message()); 182 183 // Use write() to skip line buffer of printf, thus can avoid getting interleaved when 184 // several processes are printing at the same time. 185 int towrite = strlen(buf); 186 char* p = buf; 187 while (towrite > 0) { 188 ssize_t write_count = write(fileno(stdout), p, towrite); 189 if (write_count == -1) { 190 if (errno != EINTR) { 191 fprintf(stderr, "write, errno = %d\n", errno); 192 break; 193 } 194 } else { 195 towrite -= write_count; 196 p += write_count; 197 } 198 } 199} 200 201void TestResultPrinter::OnTestEnd(const testing::TestInfo& test_info) { 202 if (test_info.result()->Passed()) { 203 ColoredPrintf(COLOR_GREEN, "[ OK ] "); 204 } else { 205 ColoredPrintf(COLOR_RED, "[ FAILED ] "); 206 } 207 printf("%s.%s", test_info.test_case_name(), test_info.name()); 208 if (test_info.result()->Failed()) { 209 const char* const type_param = test_info.type_param(); 210 const char* const value_param = test_info.value_param(); 211 if (type_param != NULL || value_param != NULL) { 212 printf(", where "); 213 if (type_param != NULL) { 214 printf("TypeParam = %s", type_param); 215 if (value_param != NULL) { 216 printf(" and "); 217 } 218 } 219 if (value_param != NULL) { 220 printf("GetParam() = %s", value_param); 221 } 222 } 223 } 224 225 if (testing::GTEST_FLAG(print_time)) { 226 printf(" (%lld ms)\n", test_info.result()->elapsed_time()); 227 } else { 228 printf("\n"); 229 } 230 fflush(stdout); 231} 232 233static int64_t NanoTime() { 234 struct timespec t; 235 t.tv_sec = t.tv_nsec = 0; 236 clock_gettime(CLOCK_MONOTONIC, &t); 237 return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec; 238} 239 240static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) { 241 std::string command; 242 for (int i = 0; i < argc; ++i) { 243 command += argv[i]; 244 command += " "; 245 } 246 command += "--gtest_list_tests"; 247 FILE* fp = popen(command.c_str(), "r"); 248 if (fp == NULL) { 249 perror("popen"); 250 return false; 251 } 252 253 char buf[200]; 254 while (fgets(buf, sizeof(buf), fp) != NULL) { 255 char* p = buf; 256 257 while (*p != '\0' && isspace(*p)) { 258 ++p; 259 } 260 if (*p == '\0') continue; 261 char* start = p; 262 while (*p != '\0' && !isspace(*p)) { 263 ++p; 264 } 265 char* end = p; 266 while (*p != '\0' && isspace(*p)) { 267 ++p; 268 } 269 if (*p != '\0') { 270 // This is not we want, gtest must meet with some error when parsing the arguments. 271 fprintf(stderr, "argument error, check with --help\n"); 272 return false; 273 } 274 *end = '\0'; 275 if (*(end - 1) == '.') { 276 *(end - 1) = '\0'; 277 testcase_list.push_back(TestCase(start)); 278 } else { 279 testcase_list.back().AppendTest(start); 280 } 281 } 282 int result = pclose(fp); 283 return (result != -1 && WEXITSTATUS(result) == 0); 284} 285 286// Part of the following *Print functions are copied from external/gtest/src/gtest.cc: 287// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter 288// is defined and used in gtest.cc, which is hard to reuse. 289static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration, 290 size_t iteration_count) { 291 if (iteration_count > 1) { 292 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration); 293 } 294 ColoredPrintf(COLOR_GREEN, "[==========] "); 295 296 size_t testcase_count = testcase_list.size(); 297 size_t test_count = 0; 298 for (const auto& testcase : testcase_list) { 299 test_count += testcase.TestCount(); 300 } 301 302 printf("Running %zu %s from %zu %s.\n", 303 test_count, (test_count == 1) ? "test" : "tests", 304 testcase_count, (testcase_count == 1) ? "test case" : "test cases"); 305 fflush(stdout); 306} 307 308static void OnTestTerminatedPrint(const TestCase& testcase, size_t test_id, int sig) { 309 ColoredPrintf(COLOR_RED, "[ FAILED ] "); 310 printf("%s terminated by signal: %s\n", testcase.GetTestName(test_id).c_str(), 311 strsignal(sig)); 312 fflush(stdout); 313} 314 315static void OnTestTimeoutPrint(const TestCase& testcase, size_t test_id) { 316 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] "); 317 printf("%s (killed by timeout at %lld ms)\n", testcase.GetTestName(test_id).c_str(), 318 testcase.GetTestTime(test_id) / 1000000LL); 319 fflush(stdout); 320} 321 322static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/, 323 int64_t elapsed_time) { 324 325 std::vector<std::string> fail_test_name_list; 326 std::vector<std::pair<std::string, int64_t>> timeout_test_list; 327 328 // For tests run exceed warnline but not timeout. 329 std::vector<std::tuple<std::string, int64_t, int>> timewarn_test_list; 330 size_t testcase_count = testcase_list.size(); 331 size_t test_count = 0; 332 size_t success_test_count = 0; 333 334 for (const auto& testcase : testcase_list) { 335 test_count += testcase.TestCount(); 336 for (size_t i = 0; i < testcase.TestCount(); ++i) { 337 TestResult result = testcase.GetTestResult(i); 338 if (result == TEST_SUCCESS) { 339 ++success_test_count; 340 } else if (result == TEST_FAILED) { 341 fail_test_name_list.push_back(testcase.GetTestName(i)); 342 } else if (result == TEST_TIMEOUT) { 343 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i), 344 testcase.GetTestTime(i))); 345 } 346 if (result != TEST_TIMEOUT && 347 testcase.GetTestTime(i) / 1000000 >= GetWarnlineInfo(testcase.GetTestName(i))) { 348 timewarn_test_list.push_back(std::make_tuple(testcase.GetTestName(i), 349 testcase.GetTestTime(i), 350 GetWarnlineInfo(testcase.GetTestName(i)))); 351 } 352 } 353 } 354 355 ColoredPrintf(COLOR_GREEN, "[==========] "); 356 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests", 357 testcase_count, (testcase_count == 1) ? "test case" : "test cases"); 358 if (testing::GTEST_FLAG(print_time)) { 359 printf(" (%lld ms total)", elapsed_time / 1000000LL); 360 } 361 printf("\n"); 362 ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); 363 printf("%zu %s.\n", success_test_count, (success_test_count == 1) ? "test" : "tests"); 364 365 // Print tests failed. 366 size_t fail_test_count = fail_test_name_list.size(); 367 if (fail_test_count > 0) { 368 ColoredPrintf(COLOR_RED, "[ FAILED ] "); 369 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests"); 370 for (const auto& name : fail_test_name_list) { 371 ColoredPrintf(COLOR_RED, "[ FAILED ] "); 372 printf("%s\n", name.c_str()); 373 } 374 } 375 376 // Print tests run timeout. 377 size_t timeout_test_count = timeout_test_list.size(); 378 if (timeout_test_count > 0) { 379 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] "); 380 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests"); 381 for (const auto& timeout_pair : timeout_test_list) { 382 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] "); 383 printf("%s (stopped at %lld ms)\n", timeout_pair.first.c_str(), 384 timeout_pair.second / 1000000LL); 385 } 386 } 387 388 // Print tests run exceed warnline. 389 size_t timewarn_test_count = timewarn_test_list.size(); 390 if (timewarn_test_count > 0) { 391 ColoredPrintf(COLOR_YELLOW, "[ TIMEWARN ] "); 392 printf("%zu %s, listed below:\n", timewarn_test_count, (timewarn_test_count == 1) ? "test" : "tests"); 393 for (const auto& timewarn_tuple : timewarn_test_list) { 394 ColoredPrintf(COLOR_YELLOW, "[ TIMEWARN ] "); 395 printf("%s (%lld ms, exceed warnline %d ms)\n", std::get<0>(timewarn_tuple).c_str(), 396 std::get<1>(timewarn_tuple) / 1000000LL, 397 std::get<2>(timewarn_tuple)); 398 } 399 } 400 401 if (fail_test_count > 0) { 402 printf("\n%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS"); 403 } 404 if (timeout_test_count > 0) { 405 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS"); 406 } 407 if (timewarn_test_count > 0) { 408 printf("%2zu TIMEWARN %s\n", timewarn_test_count, (timewarn_test_count == 1) ? "TEST" : "TESTS"); 409 } 410 fflush(stdout); 411} 412 413// Forked Child process, run the single test. 414static void ChildProcessFn(int argc, char** argv, const std::string& test_name) { 415 char** new_argv = new char*[argc + 1]; 416 memcpy(new_argv, argv, sizeof(char*) * argc); 417 418 char* filter_arg = new char [test_name.size() + 20]; 419 strcpy(filter_arg, "--gtest_filter="); 420 strcat(filter_arg, test_name.c_str()); 421 new_argv[argc] = filter_arg; 422 423 int new_argc = argc + 1; 424 testing::InitGoogleTest(&new_argc, new_argv); 425 int result = RUN_ALL_TESTS(); 426 exit(result); 427} 428 429struct ChildProcInfo { 430 pid_t pid; 431 int64_t start_time; 432 int64_t deadline_time; 433 size_t testcase_id, test_id; 434 bool done_flag; 435 bool timeout_flag; 436 int exit_status; 437 ChildProcInfo() : pid(0) {} 438}; 439 440static void WaitChildProcs(std::vector<ChildProcInfo>& child_proc_list) { 441 pid_t result; 442 int status; 443 bool loop_flag = true; 444 445 while (true) { 446 while ((result = waitpid(-1, &status, WNOHANG)) == -1) { 447 if (errno != EINTR) { 448 break; 449 } 450 } 451 452 if (result == -1) { 453 perror("waitpid"); 454 exit(1); 455 } else if (result == 0) { 456 // Check child timeout. 457 int64_t current_time = NanoTime(); 458 for (size_t i = 0; i < child_proc_list.size(); ++i) { 459 if (child_proc_list[i].deadline_time <= current_time) { 460 child_proc_list[i].done_flag = true; 461 child_proc_list[i].timeout_flag = true; 462 loop_flag = false; 463 } 464 } 465 } else { 466 // Check child finish. 467 for (size_t i = 0; i < child_proc_list.size(); ++i) { 468 if (child_proc_list[i].pid == result) { 469 child_proc_list[i].done_flag = true; 470 child_proc_list[i].timeout_flag = false; 471 child_proc_list[i].exit_status = status; 472 loop_flag = false; 473 break; 474 } 475 } 476 } 477 478 if (!loop_flag) break; 479 // sleep 1 ms to avoid busy looping. 480 timespec sleep_time; 481 sleep_time.tv_sec = 0; 482 sleep_time.tv_nsec = 1000000; 483 nanosleep(&sleep_time, NULL); 484 } 485} 486 487static TestResult WaitChildProc(pid_t pid) { 488 pid_t result; 489 int exit_status; 490 491 while ((result = waitpid(pid, &exit_status, 0)) == -1) { 492 if (errno != EINTR) { 493 break; 494 } 495 } 496 497 TestResult test_result = TEST_SUCCESS; 498 if (result != pid || WEXITSTATUS(exit_status) != 0) { 499 test_result = TEST_FAILED; 500 } 501 return test_result; 502} 503 504// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always 505// makes deadlock to use fork in multi-thread. 506static void RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list, 507 size_t iteration_count, size_t job_count) { 508 // Stop default result printer to avoid environment setup/teardown information for each test. 509 testing::UnitTest::GetInstance()->listeners().Release( 510 testing::UnitTest::GetInstance()->listeners().default_result_printer()); 511 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter); 512 513 for (size_t iteration = 1; iteration <= iteration_count; ++iteration) { 514 OnTestIterationStartPrint(testcase_list, iteration, iteration_count); 515 int64_t iteration_start_time = NanoTime(); 516 517 // Run up to job_count tests in parallel, each test in a child process. 518 std::vector<ChildProcInfo> child_proc_list(job_count); 519 520 // Next test to run is [next_testcase_id:next_test_id]. 521 size_t next_testcase_id = 0; 522 size_t next_test_id = 0; 523 524 // Record how many tests are finished. 525 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0); 526 size_t finished_testcase_count = 0; 527 528 while (finished_testcase_count < testcase_list.size()) { 529 // Fork up to job_count child processes. 530 for (auto& child_proc : child_proc_list) { 531 if (child_proc.pid == 0 && next_testcase_id < testcase_list.size()) { 532 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id); 533 pid_t pid = fork(); 534 if (pid == -1) { 535 perror("fork in RunTestInSeparateProc"); 536 exit(1); 537 } else if (pid == 0) { 538 // Run child process test, never return. 539 ChildProcessFn(argc, argv, test_name); 540 } 541 // Parent process 542 child_proc.pid = pid; 543 child_proc.start_time = NanoTime(); 544 child_proc.deadline_time = child_proc.start_time + GetDeadlineInfo(test_name) * 1000000LL; 545 child_proc.testcase_id = next_testcase_id; 546 child_proc.test_id = next_test_id; 547 child_proc.done_flag = false; 548 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) { 549 next_test_id = 0; 550 ++next_testcase_id; 551 } 552 } 553 } 554 555 // Wait for any child proc finish or timeout. 556 WaitChildProcs(child_proc_list); 557 558 // Collect result. 559 for (auto& child_proc : child_proc_list) { 560 if (child_proc.pid != 0 && child_proc.done_flag == true) { 561 size_t testcase_id = child_proc.testcase_id; 562 size_t test_id = child_proc.test_id; 563 TestCase& testcase = testcase_list[testcase_id]; 564 testcase.SetTestTime(test_id, NanoTime() - child_proc.start_time); 565 566 if (child_proc.timeout_flag) { 567 // Kill and wait the timeout child process. 568 kill(child_proc.pid, SIGKILL); 569 WaitChildProc(child_proc.pid); 570 testcase.SetTestResult(test_id, TEST_TIMEOUT); 571 OnTestTimeoutPrint(testcase, test_id); 572 573 } else if (WIFSIGNALED(child_proc.exit_status)) { 574 // Record signal terminated test as failed. 575 testcase.SetTestResult(test_id, TEST_FAILED); 576 OnTestTerminatedPrint(testcase, test_id, WTERMSIG(child_proc.exit_status)); 577 578 } else { 579 testcase.SetTestResult(test_id, WEXITSTATUS(child_proc.exit_status) == 0 ? 580 TEST_SUCCESS : TEST_FAILED); 581 // TestResultPrinter::OnTestEnd has already printed result for normal exit. 582 } 583 584 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) { 585 ++finished_testcase_count; 586 } 587 child_proc.pid = 0; 588 child_proc.done_flag = false; 589 } 590 } 591 } 592 593 OnTestIterationEndPrint(testcase_list, iteration, NanoTime() - iteration_start_time); 594 } 595} 596 597static size_t GetProcessorCount() { 598 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN)); 599} 600 601// Pick options not for gtest: There are two parts in argv, one part is handled by PickOptions() 602// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in 603// gtest. PickOptions() picks the first part of options and change them into flags and operations, 604// lefting the second part in argv. 605// Arguments: 606// argv is used to pass in all command arguments, and pass out only the part of options for gtest. 607// exit_flag is to indicate whether we need to run gtest workflow after PickOptions. 608// Return false if run error. 609static bool PickOptions(std::vector<char*>& argv, bool* exit_flag) { 610 *exit_flag = false; 611 for (size_t i = 1; i < argv.size() - 1; ++i) { 612 if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { 613 PrintHelpInfo(); 614 return true; 615 } 616 } 617 618 // Move --gtest_filter option to last, and add "-bionic_selftest*" to disable self test. 619 std::string gtest_filter_str = "--gtest_filter=-bionic_selftest*"; 620 for (size_t i = argv.size() - 2; i >= 1; --i) { 621 if (strncmp(argv[i], "--gtest_filter=", sizeof("--gtest_filter=") - 1) == 0) { 622 gtest_filter_str = std::string(argv[i]) + ":-bionic_selftest*"; 623 argv.erase(argv.begin() + i); 624 break; 625 } 626 } 627 argv.insert(argv.end() - 1, strdup(gtest_filter_str.c_str())); 628 629 // Init default bionic_gtest option. 630 bool isolate_option = true; 631 size_t job_count_option = GetProcessorCount(); 632 633 size_t deadline_option_len = strlen("--deadline="); 634 size_t warnline_option_len = strlen("--warnline="); 635 size_t gtest_color_option_len = strlen("--gtest_color="); 636 637 // Parse bionic_gtest specific options in arguments. 638 for (size_t i = 1; i < argv.size() - 1; ++i) { 639 if (strcmp(argv[i], "-j") == 0) { 640 isolate_option = true; // Enable isolation mode when -j is used. 641 int tmp; 642 if (argv[i + 1] != NULL && (tmp = atoi(argv[i + 1])) > 0) { 643 job_count_option = tmp; 644 argv.erase(argv.begin() + i); 645 } else { 646 job_count_option = GetProcessorCount(); 647 } 648 argv.erase(argv.begin() + i); 649 --i; 650 651 } else if (strcmp(argv[i], "--no-isolate") == 0) { 652 isolate_option = false; 653 argv.erase(argv.begin() + i); 654 --i; 655 656 } else if (strncmp(argv[i], "--deadline=", deadline_option_len) == 0) { 657 global_test_run_deadline_in_ms = atoi(argv[i] + deadline_option_len); 658 if (global_test_run_deadline_in_ms <= 0) { 659 fprintf(stderr, "value for --deadline option should be positive: %s\n", 660 argv[i] + deadline_option_len); 661 exit(1); 662 } 663 argv.erase(argv.begin() + i); 664 --i; 665 666 } else if (strncmp(argv[i], "--warnline=", warnline_option_len) == 0) { 667 global_test_run_warnline_in_ms = atoi(argv[i] + warnline_option_len); 668 if (global_test_run_warnline_in_ms <= 0) { 669 fprintf(stderr, "value for --warnline option should be positive: %s\n", 670 argv[i] + warnline_option_len); 671 exit(1); 672 } 673 argv.erase(argv.begin() + i); 674 --i; 675 676 } else if (strncmp(argv[i], "--gtest_color=", gtest_color_option_len) == 0) { 677 // If running in isolation mode, main process doesn't call testing::InitGoogleTest(&argc, argv). 678 // So we should parse gtest options for printing by ourselves. 679 testing::GTEST_FLAG(color) = argv[i] + gtest_color_option_len; 680 681 } else if (strcmp(argv[i], "--gtest_print_time=0") == 0) { 682 testing::GTEST_FLAG(print_time) = false; 683 684 } else if (strcmp(argv[i], "--gtest_list_tests") == 0) { 685 // Disable isolation mode in gtest_list_tests option. 686 isolate_option = false; 687 688 } else if (strcmp(argv[i], "--bionic-selftest") == 0) { 689 // This option is to enable "bionic_selftest*" for self test, and not shown in help informantion. 690 // Don't remove this option from argument list. 691 argv[argv.size() - 2] = strdup("--gtest_filter=bionic_selftest*"); 692 } 693 } 694 695 // Handle --gtest_repeat=[COUNT] option if we are in isolation mode. 696 // We should check and remove this option to avoid child process running single test for several 697 // iterations. 698 size_t gtest_repeat_count = 1; 699 if (isolate_option == true) { 700 int len = sizeof("--gtest_repeat=") - 1; 701 for (size_t i = 1; i < argv.size() - 1; ++i) { 702 if (strncmp(argv[i], "--gtest_repeat=", len) == 0) { 703 int tmp = atoi(argv[i] + len); 704 if (tmp < 0) { 705 fprintf(stderr, "error count for option --gtest_repeat=[COUNT]\n"); 706 return false; 707 } 708 gtest_repeat_count = tmp; 709 argv.erase(argv.begin() + i); 710 break; 711 } 712 } 713 } 714 715 // Add --no-isolate option in argv to suppress subprocess running in isolation mode again. 716 // As DeathTest will try to execve again, this option should always be set. 717 argv.insert(argv.begin() + 1, strdup("--no-isolate")); 718 719 // Run tests in isolation mode. 720 if (isolate_option) { 721 *exit_flag = true; 722 723 std::vector<TestCase> testcase_list; 724 int argc = static_cast<int>(argv.size()) - 1; 725 if (EnumerateTests(argc, argv.data(), testcase_list) == false) { 726 return false; 727 } 728 RunTestInSeparateProc(argc, argv.data(), testcase_list, gtest_repeat_count, job_count_option); 729 return true; 730 } 731 return true; 732} 733 734int main(int argc, char** argv) { 735 std::vector<char*> arg_list; 736 for (int i = 0; i < argc; ++i) { 737 arg_list.push_back(argv[i]); 738 } 739 arg_list.push_back(NULL); 740 741 bool exit_flag; 742 int return_result = 0; 743 744 if (PickOptions(arg_list, &exit_flag) == false) { 745 return_result = 1; 746 } else if (!exit_flag) { 747 argc = static_cast<int>(arg_list.size()) - 1; 748 testing::InitGoogleTest(&argc, arg_list.data()); 749 return_result = RUN_ALL_TESTS(); 750 } 751 return return_result; 752} 753 754//################################################################################ 755// Bionic Gtest self test, run this by --bionic-selftest option. 756 757TEST(bionic_selftest, test_success) { 758 ASSERT_EQ(1, 1); 759} 760 761TEST(bionic_selftest, test_fail) { 762 ASSERT_EQ(0, 1); 763} 764 765TEST(bionic_selftest, test_time_warn) { 766 sleep(4); 767} 768 769TEST(bionic_selftest, test_timeout) { 770 while (1) {} 771} 772 773TEST(bionic_selftest, test_signal_SEGV_terminated) { 774 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0"))); 775 *p = 3; 776} 777