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