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