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