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