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