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("<");
459 break;
460 case '>':
461 escaped.append(">");
462 break;
463 case '&':
464 escaped.append("&");
465 break;
466 case '\'':
467 escaped.append("'");
468 break;
469 case '"':
470 escaped.append(""");
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