• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
49 static std::string g_executable_path;
50 
get_executable_path()51 const std::string& get_executable_path() {
52   return g_executable_path;
53 }
54 
55 namespace testing {
56 namespace internal {
57 
58 // Reuse of testing::internal::ColoredPrintf in gtest.
59 enum GTestColor {
60   COLOR_DEFAULT,
61   COLOR_RED,
62   COLOR_GREEN,
63   COLOR_YELLOW
64 };
65 
66 void ColoredPrintf(GTestColor color, const char* fmt, ...);
67 
68 }  // namespace internal
69 }  // namespace testing
70 
71 using testing::internal::GTestColor;
72 using testing::internal::COLOR_DEFAULT;
73 using testing::internal::COLOR_RED;
74 using testing::internal::COLOR_GREEN;
75 using testing::internal::COLOR_YELLOW;
76 using testing::internal::ColoredPrintf;
77 
78 constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 90000;
79 constexpr 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.
83 static 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.
87 static int global_test_run_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
88 
89 // Return deadline duration for a test, in ms.
GetDeadlineInfo(const std::string &)90 static 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.
GetWarnlineInfo(const std::string &)95 static int GetWarnlineInfo(const std::string& /*test_name*/) {
96   return global_test_run_warnline_ms;
97 }
98 
PrintHelpInfo()99 static 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 
122 enum TestResult {
123   TEST_SUCCESS = 0,
124   TEST_FAILED,
125   TEST_TIMEOUT
126 };
127 
128 class Test {
129  public:
Test()130   Test() {} // For std::vector<Test>.
Test(const char * name)131   explicit Test(const char* name) : name_(name) {}
132 
GetName() const133   const std::string& GetName() const { return name_; }
134 
SetResult(TestResult result)135   void SetResult(TestResult result) { result_ = result; }
136 
GetResult() const137   TestResult GetResult() const { return result_; }
138 
SetTestTime(int64_t elapsed_time_ns)139   void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
140 
GetTestTime() const141   int64_t GetTestTime() const { return elapsed_time_ns_; }
142 
AppendTestOutput(const std::string & s)143   void AppendTestOutput(const std::string& s) { output_ += s; }
144 
GetTestOutput() const145   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 
154 class TestCase {
155  public:
TestCase()156   TestCase() {} // For std::vector<TestCase>.
TestCase(const char * name)157   explicit TestCase(const char* name) : name_(name) {}
158 
GetName() const159   const std::string& GetName() const { return name_; }
160 
AppendTest(const char * test_name)161   void AppendTest(const char* test_name) {
162     test_list_.push_back(Test(test_name));
163   }
164 
TestCount() const165   size_t TestCount() const { return test_list_.size(); }
166 
GetTestName(size_t test_id) const167   std::string GetTestName(size_t test_id) const {
168     VerifyTestId(test_id);
169     return name_ + "." + test_list_[test_id].GetName();
170   }
171 
GetTest(size_t test_id)172   Test& GetTest(size_t test_id) {
173     VerifyTestId(test_id);
174     return test_list_[test_id];
175   }
176 
GetTest(size_t test_id) const177   const Test& GetTest(size_t test_id) const {
178     VerifyTestId(test_id);
179     return test_list_[test_id];
180   }
181 
SetTestResult(size_t test_id,TestResult result)182   void SetTestResult(size_t test_id, TestResult result) {
183     VerifyTestId(test_id);
184     test_list_[test_id].SetResult(result);
185   }
186 
GetTestResult(size_t test_id) const187   TestResult GetTestResult(size_t test_id) const {
188     VerifyTestId(test_id);
189     return test_list_[test_id].GetResult();
190   }
191 
SetTestTime(size_t test_id,int64_t elapsed_time_ns)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 
GetTestTime(size_t test_id) const197   int64_t GetTestTime(size_t test_id) const {
198     VerifyTestId(test_id);
199     return test_list_[test_id].GetTestTime();
200   }
201 
202  private:
VerifyTestId(size_t test_id) const203   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 
215 class TestResultPrinter : public testing::EmptyTestEventListener {
216  public:
TestResultPrinter()217   TestResultPrinter() : pinfo_(NULL) {}
OnTestStart(const testing::TestInfo & test_info)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.
OnTestPartResult(const testing::TestPartResult & result)228 void 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 
NanoTime()239 static 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 
EnumerateTests(int argc,char ** argv,std::vector<TestCase> & testcase_list)244 static 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.
OnTestIterationStartPrint(const std::vector<TestCase> & testcase_list,size_t iteration,int iteration_count)293 static 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 
OnTestEndPrint(const TestCase & testcase,size_t test_id)315 static 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 
OnTestEndPrint(const TestCase & testcase,size_t test_id)338 static 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 
OnTestIterationEndPrint(const std::vector<TestCase> & testcase_list,size_t,int64_t elapsed_time_ns)361 static 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 
XmlEscape(const std::string & xml)451 std::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.
OnTestIterationEndXmlPrint(const std::string & xml_output_filename,const std::vector<TestCase> & testcase_list,time_t epoch_iteration_start_time,int64_t elapsed_time_ns)485 void 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 
549 static bool sigint_flag;
550 static bool sigquit_flag;
551 
signal_handler(int sig)552 static 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 
RegisterSignalHandler()560 static 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 
UnregisterSignalHandler()574 static 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 
586 struct 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.
ChildProcessFn(int argc,char ** argv,const std::string & test_name)599 static 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 
RunChildProcess(const std::string & test_name,int testcase_id,int test_id,int argc,char ** argv)615 static 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 
HandleSignals(std::vector<TestCase> & testcase_list,std::vector<ChildProcInfo> & child_proc_list)657 static 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 
CheckChildProcExit(pid_t exit_pid,int exit_status,std::vector<ChildProcInfo> & child_proc_list)685 static 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 
CheckChildProcTimeout(std::vector<ChildProcInfo> & child_proc_list)699 static 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 
ReadChildProcOutput(std::vector<TestCase> & testcase_list,std::vector<ChildProcInfo> & child_proc_list)713 static 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 
WaitChildProcs(std::vector<TestCase> & testcase_list,std::vector<ChildProcInfo> & child_proc_list)737 static 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 
WaitForOneChild(pid_t pid)776 static 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 
CollectChildTestResult(const ChildProcInfo & child_proc,TestCase & testcase)787 static 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.
RunTestInSeparateProc(int argc,char ** argv,std::vector<TestCase> & testcase_list,int iteration_count,size_t job_count,const std::string & xml_output_filename)827 static 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 
GetDefaultJobCount()916 static size_t GetDefaultJobCount() {
917   return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
918 }
919 
AddPathSeparatorInTestProgramPath(std::vector<char * > & args)920 static 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 
AddGtestFilterSynonym(std::vector<char * > & args)931 static 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 
940 struct 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.
PickOptions(std::vector<char * > & args,IsolationTestOptions & options)959 static 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 
get_proc_self_exe()1114 static 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 
main(int argc,char ** argv)1125 int 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 
TEST(bionic_selftest,test_success)1164 TEST(bionic_selftest, test_success) {
1165   ASSERT_EQ(1, 1);
1166 }
1167 
TEST(bionic_selftest,test_fail)1168 TEST(bionic_selftest, test_fail) {
1169   ASSERT_EQ(0, 1);
1170 }
1171 
TEST(bionic_selftest,test_time_warn)1172 TEST(bionic_selftest, test_time_warn) {
1173   sleep(4);
1174 }
1175 
TEST(bionic_selftest,test_timeout)1176 TEST(bionic_selftest, test_timeout) {
1177   while (1) {}
1178 }
1179 
TEST(bionic_selftest,test_signal_SEGV_terminated)1180 TEST(bionic_selftest, test_signal_SEGV_terminated) {
1181   char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1182   *p = 3;
1183 }
1184 
1185 class bionic_selftest_DeathTest : public ::testing::Test {
1186  protected:
SetUp()1187   virtual void SetUp() {
1188     ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1189   }
1190 };
1191 
deathtest_helper_success()1192 static void deathtest_helper_success() {
1193   ASSERT_EQ(1, 1);
1194   exit(0);
1195 }
1196 
TEST_F(bionic_selftest_DeathTest,success)1197 TEST_F(bionic_selftest_DeathTest, success) {
1198   ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1199 }
1200 
deathtest_helper_fail()1201 static void deathtest_helper_fail() {
1202   ASSERT_EQ(1, 0);
1203 }
1204 
TEST_F(bionic_selftest_DeathTest,fail)1205 TEST_F(bionic_selftest_DeathTest, fail) {
1206   ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1207 }
1208