blob: 6c5023bfda6f32f795dbaf3460f7e7e77ca63a0b [file] [log] [blame]
Yabin Cui294d1e22014-12-07 20:43:37 -08001/*
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 <errno.h>
20#include <stdarg.h>
21#include <stdio.h>
22#include <string.h>
23#include <sys/wait.h>
24#include <time.h>
25#include <unistd.h>
26
27#include <string>
28#include <tuple>
29#include <utility>
30#include <vector>
31
32namespace testing {
33namespace internal {
34
35// Reuse of testing::internal::ColoredPrintf in gtest.
36enum GTestColor {
37 COLOR_DEFAULT,
38 COLOR_RED,
39 COLOR_GREEN,
40 COLOR_YELLOW
41};
42
43void ColoredPrintf(GTestColor color, const char* fmt, ...);
44
Yabin Cuibe837362015-01-02 18:45:37 -080045} // namespace internal
46} // namespace testing
Yabin Cui294d1e22014-12-07 20:43:37 -080047
48using testing::internal::GTestColor;
49using testing::internal::COLOR_DEFAULT;
50using testing::internal::COLOR_RED;
51using testing::internal::COLOR_GREEN;
52using testing::internal::COLOR_YELLOW;
53using testing::internal::ColoredPrintf;
54
55constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_IN_MS = 60000;
56constexpr int DEFAULT_GLOBAL_TEST_RUN_WARNLINE_IN_MS = 2000;
57
58// The time each test can run before killed for the reason of timeout.
59// It takes effect only with --isolate option.
60static int global_test_run_deadline_in_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_IN_MS;
61
62// The time each test can run before be warned for too much running time.
63// It takes effect only with --isolate option.
64static int global_test_run_warnline_in_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_IN_MS;
65
66// Return deadline duration for a test, in ms.
67static int GetDeadlineInfo(const std::string& /*test_name*/) {
68 return global_test_run_deadline_in_ms;
69}
70
71// Return warnline duration for a test, in ms.
72static int GetWarnlineInfo(const std::string& /*test_name*/) {
73 return global_test_run_warnline_in_ms;
74}
75
Yabin Cuibe837362015-01-02 18:45:37 -080076static void PrintHelpInfo() {
77 printf("Bionic Unit Test Options:\n"
78 " -j [JOB_COUNT]\n"
79 " Run up to JOB_COUNT tests in parallel.\n"
80 " Use isolation mode, Run each test in a separate process.\n"
81 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
82 " --no-isolate\n"
83 " Don't use isolation mode, run all tests in a single process.\n"
84 " --deadline=[TIME_IN_MS]\n"
85 " Run each test in no longer than [TIME_IN_MS] time.\n"
86 " It takes effect only in isolation mode. Deafult deadline is 60000 ms.\n"
87 " --warnline=[TIME_IN_MS]\n"
88 " Test running longer than [TIME_IN_MS] will be warned.\n"
89 " It takes effect only in isolation mode. Default warnline is 2000 ms.\n"
90 "\nDefault bionic unit test option is -j.\n"
91 "\n");
92}
93
Yabin Cui294d1e22014-12-07 20:43:37 -080094enum TestResult {
95 TEST_SUCCESS = 0,
96 TEST_FAILED,
97 TEST_TIMEOUT
98};
99
100class TestCase {
101 public:
102 TestCase() {} // For std::vector<TestCase>.
103 explicit TestCase(const char* name) : name_(name) {}
104
105 const std::string& GetName() const { return name_; }
106
107 void AppendTest(const std::string& test_name) {
108 test_list_.push_back(std::make_tuple(test_name, TEST_FAILED, 0LL));
109 }
110
Yabin Cuibe837362015-01-02 18:45:37 -0800111 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800112
Yabin Cuibe837362015-01-02 18:45:37 -0800113 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800114 VerifyTestId(test_id);
115 return name_ + "." + std::get<0>(test_list_[test_id]);
116 }
117
Yabin Cuibe837362015-01-02 18:45:37 -0800118 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800119 VerifyTestId(test_id);
120 std::get<1>(test_list_[test_id]) = result;
121 }
122
Yabin Cuibe837362015-01-02 18:45:37 -0800123 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800124 VerifyTestId(test_id);
125 return std::get<1>(test_list_[test_id]);
126 }
127
Yabin Cuibe837362015-01-02 18:45:37 -0800128 void SetTestTime(size_t test_id, int64_t elapsed_time) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800129 VerifyTestId(test_id);
130 std::get<2>(test_list_[test_id]) = elapsed_time;
131 }
132
Yabin Cuibe837362015-01-02 18:45:37 -0800133 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800134 VerifyTestId(test_id);
135 return std::get<2>(test_list_[test_id]);
136 }
137
138 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800139 void VerifyTestId(size_t test_id) const {
140 if(test_id >= test_list_.size()) {
141 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800142 exit(1);
143 }
144 }
145
146 private:
147 const std::string name_;
148 std::vector<std::tuple<std::string, TestResult, int64_t> > test_list_;
149};
150
151// TestResultPrinter is copied from part of external/gtest/src/gtest.cc:PrettyUnitTestResultPrinter.
152// The reason for copy is that PrettyUnitTestResultPrinter is defined and used in gtest.cc, which
153// is hard to reuse.
154// TestResultPrinter only print information for a single test, which is used in child process.
155// The information of test_iteration/environment/testcase is left for parent process to print.
156class TestResultPrinter : public testing::EmptyTestEventListener {
157 public:
158 TestResultPrinter() : pinfo_(NULL) {}
159 virtual void OnTestStart(const testing::TestInfo& test_info) {
160 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
161 }
162 virtual void OnTestPartResult(const testing::TestPartResult& result);
163 virtual void OnTestEnd(const testing::TestInfo& test_info);
164
165 private:
166 const testing::TestInfo* pinfo_;
167};
168
169// Called after an assertion failure.
170void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
171 // If the test part succeeded, we don't need to do anything.
172 if (result.type() == testing::TestPartResult::kSuccess)
173 return;
174
175 // Print failure message from the assertion (e.g. expected this and got that).
176 char buf[1024];
177 snprintf(buf, sizeof(buf), "%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(),
178 result.line_number(),
179 pinfo_->test_case_name(),
180 pinfo_->name(),
181 result.message());
182
183 // Use write() to skip line buffer of printf, thus can avoid getting interleaved when
184 // several processes are printing at the same time.
185 int towrite = strlen(buf);
186 char* p = buf;
187 while (towrite > 0) {
Yabin Cuibe837362015-01-02 18:45:37 -0800188 ssize_t write_count = write(fileno(stdout), p, towrite);
189 if (write_count == -1) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800190 if (errno != EINTR) {
191 fprintf(stderr, "write, errno = %d\n", errno);
192 break;
193 }
194 } else {
Yabin Cuibe837362015-01-02 18:45:37 -0800195 towrite -= write_count;
196 p += write_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800197 }
198 }
199}
200
201void TestResultPrinter::OnTestEnd(const testing::TestInfo& test_info) {
202 if (test_info.result()->Passed()) {
203 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
204 } else {
205 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
206 }
207 printf("%s.%s", test_info.test_case_name(), test_info.name());
208 if (test_info.result()->Failed()) {
209 const char* const type_param = test_info.type_param();
210 const char* const value_param = test_info.value_param();
211 if (type_param != NULL || value_param != NULL) {
212 printf(", where ");
213 if (type_param != NULL) {
214 printf("TypeParam = %s", type_param);
215 if (value_param != NULL) {
216 printf(" and ");
217 }
218 }
219 if (value_param != NULL) {
220 printf("GetParam() = %s", value_param);
221 }
222 }
223 }
224
225 if (testing::GTEST_FLAG(print_time)) {
226 printf(" (%lld ms)\n", test_info.result()->elapsed_time());
227 } else {
228 printf("\n");
229 }
230 fflush(stdout);
231}
232
233static int64_t NanoTime() {
234 struct timespec t;
235 t.tv_sec = t.tv_nsec = 0;
236 clock_gettime(CLOCK_MONOTONIC, &t);
237 return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
238}
239
240static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
241 std::string command;
242 for (int i = 0; i < argc; ++i) {
243 command += argv[i];
244 command += " ";
245 }
246 command += "--gtest_list_tests";
247 FILE* fp = popen(command.c_str(), "r");
248 if (fp == NULL) {
249 perror("popen");
250 return false;
251 }
252
253 char buf[200];
254 while (fgets(buf, sizeof(buf), fp) != NULL) {
255 char* p = buf;
256
257 while (*p != '\0' && isspace(*p)) {
258 ++p;
259 }
260 if (*p == '\0') continue;
261 char* start = p;
262 while (*p != '\0' && !isspace(*p)) {
263 ++p;
264 }
265 char* end = p;
266 while (*p != '\0' && isspace(*p)) {
267 ++p;
268 }
269 if (*p != '\0') {
270 // This is not we want, gtest must meet with some error when parsing the arguments.
271 fprintf(stderr, "argument error, check with --help\n");
272 return false;
273 }
274 *end = '\0';
275 if (*(end - 1) == '.') {
276 *(end - 1) = '\0';
277 testcase_list.push_back(TestCase(start));
278 } else {
279 testcase_list.back().AppendTest(start);
280 }
281 }
282 int result = pclose(fp);
283 return (result != -1 && WEXITSTATUS(result) == 0);
284}
285
Yabin Cui294d1e22014-12-07 20:43:37 -0800286// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
287// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
288// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800289static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
290 size_t iteration_count) {
291 if (iteration_count > 1) {
292 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800293 }
294 ColoredPrintf(COLOR_GREEN, "[==========] ");
295
Yabin Cuibe837362015-01-02 18:45:37 -0800296 size_t testcase_count = testcase_list.size();
297 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800298 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800299 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800300 }
301
Yabin Cuibe837362015-01-02 18:45:37 -0800302 printf("Running %zu %s from %zu %s.\n",
303 test_count, (test_count == 1) ? "test" : "tests",
304 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800305 fflush(stdout);
306}
307
Yabin Cuibe837362015-01-02 18:45:37 -0800308static void OnTestTerminatedPrint(const TestCase& testcase, size_t test_id, int sig) {
309 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
310 printf("%s terminated by signal: %s\n", testcase.GetTestName(test_id).c_str(),
311 strsignal(sig));
312 fflush(stdout);
313}
314
315static void OnTestTimeoutPrint(const TestCase& testcase, size_t test_id) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800316 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
317 printf("%s (killed by timeout at %lld ms)\n", testcase.GetTestName(test_id).c_str(),
318 testcase.GetTestTime(test_id) / 1000000LL);
319 fflush(stdout);
320}
321
322static void TestcaseTimePrint(const TestCase& testcase) {
323 int64_t testcase_time = 0;
Yabin Cuibe837362015-01-02 18:45:37 -0800324 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800325 testcase_time += testcase.GetTestTime(i);
326 }
Yabin Cuibe837362015-01-02 18:45:37 -0800327 printf("%zu %s from %s (%lld ms total)\n", testcase.TestCount(),
328 (testcase.TestCount() == 1) ? "test" : "tests",
329 testcase.GetName().c_str(),
330 testcase_time / 1000000LL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800331 fflush(stdout);
332}
333
Yabin Cuibe837362015-01-02 18:45:37 -0800334static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui294d1e22014-12-07 20:43:37 -0800335 int64_t elapsed_time) {
336
337 std::vector<std::string> fail_test_name_list;
338 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
339
340 // For tests run exceed warnline but not timeout.
341 std::vector<std::tuple<std::string, int64_t, int>> timewarn_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800342 size_t testcase_count = testcase_list.size();
343 size_t test_count = 0;
344 size_t success_test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800345
346 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800347 test_count += testcase.TestCount();
348 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800349 TestResult result = testcase.GetTestResult(i);
350 if (result == TEST_SUCCESS) {
Yabin Cuibe837362015-01-02 18:45:37 -0800351 ++success_test_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800352 } else if (result == TEST_FAILED) {
353 fail_test_name_list.push_back(testcase.GetTestName(i));
354 } else if (result == TEST_TIMEOUT) {
355 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i),
356 testcase.GetTestTime(i)));
357 }
358 if (result != TEST_TIMEOUT &&
359 testcase.GetTestTime(i) / 1000000 >= GetWarnlineInfo(testcase.GetTestName(i))) {
360 timewarn_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
361 testcase.GetTestTime(i),
362 GetWarnlineInfo(testcase.GetTestName(i))));
363 }
364 }
365 }
366
367 for (auto const& testcase : testcase_list) {
368 TestcaseTimePrint(testcase);
369 }
370
371 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800372 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
373 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800374 if (testing::GTEST_FLAG(print_time)) {
375 printf(" (%lld ms total)", elapsed_time / 1000000LL);
376 }
377 printf("\n");
378 ColoredPrintf(COLOR_GREEN, "[ PASSED ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800379 printf("%zu %s.\n", success_test_count, (success_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800380
381 // Print tests failed.
Yabin Cuibe837362015-01-02 18:45:37 -0800382 size_t fail_test_count = fail_test_name_list.size();
383 if (fail_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800384 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800385 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800386 for (const auto& name : fail_test_name_list) {
387 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
388 printf("%s\n", name.c_str());
389 }
390 }
391
392 // Print tests run timeout.
Yabin Cuibe837362015-01-02 18:45:37 -0800393 size_t timeout_test_count = timeout_test_list.size();
394 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800395 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800396 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800397 for (const auto& timeout_pair : timeout_test_list) {
398 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
399 printf("%s (stopped at %lld ms)\n", timeout_pair.first.c_str(),
400 timeout_pair.second / 1000000LL);
401 }
402 }
403
404 // Print tests run exceed warnline.
Yabin Cuibe837362015-01-02 18:45:37 -0800405 size_t timewarn_test_count = timewarn_test_list.size();
406 if (timewarn_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800407 ColoredPrintf(COLOR_YELLOW, "[ TIMEWARN ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800408 printf("%zu %s, listed below:\n", timewarn_test_count, (timewarn_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800409 for (const auto& timewarn_tuple : timewarn_test_list) {
410 ColoredPrintf(COLOR_YELLOW, "[ TIMEWARN ] ");
411 printf("%s (%lld ms, exceed warnline %d ms)\n", std::get<0>(timewarn_tuple).c_str(),
412 std::get<1>(timewarn_tuple) / 1000000LL,
413 std::get<2>(timewarn_tuple));
414 }
415 }
416
Yabin Cuibe837362015-01-02 18:45:37 -0800417 if (fail_test_count > 0) {
418 printf("\n%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800419 }
Yabin Cuibe837362015-01-02 18:45:37 -0800420 if (timeout_test_count > 0) {
421 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800422 }
Yabin Cuibe837362015-01-02 18:45:37 -0800423 if (timewarn_test_count > 0) {
424 printf("%2zu TIMEWARN %s\n", timewarn_test_count, (timewarn_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800425 }
426 fflush(stdout);
427}
428
429// Forked Child process, run the single test.
430static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
431 char** new_argv = new char*[argc + 1];
432 memcpy(new_argv, argv, sizeof(char*) * argc);
433
434 char* filter_arg = new char [test_name.size() + 20];
435 strcpy(filter_arg, "--gtest_filter=");
436 strcat(filter_arg, test_name.c_str());
437 new_argv[argc] = filter_arg;
438
439 int new_argc = argc + 1;
440 testing::InitGoogleTest(&new_argc, new_argv);
441 int result = RUN_ALL_TESTS();
442 exit(result);
443}
444
445struct ChildProcInfo {
446 pid_t pid;
447 int64_t start_time;
448 int64_t deadline_time;
Yabin Cuibe837362015-01-02 18:45:37 -0800449 size_t testcase_id, test_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800450 bool done_flag;
Yabin Cuibe837362015-01-02 18:45:37 -0800451 bool timeout_flag;
452 int exit_status;
Yabin Cui294d1e22014-12-07 20:43:37 -0800453 ChildProcInfo() : pid(0) {}
454};
455
456static void WaitChildProcs(std::vector<ChildProcInfo>& child_proc_list) {
457 pid_t result;
Yabin Cuibe837362015-01-02 18:45:37 -0800458 int status;
Yabin Cui294d1e22014-12-07 20:43:37 -0800459 bool loop_flag = true;
460
461 while (true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800462 while ((result = waitpid(-1, &status, WNOHANG)) == -1) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800463 if (errno != EINTR) {
464 break;
465 }
466 }
467
468 if (result == -1) {
469 perror("waitpid");
470 exit(1);
471 } else if (result == 0) {
472 // Check child timeout.
473 int64_t current_time = NanoTime();
474 for (size_t i = 0; i < child_proc_list.size(); ++i) {
475 if (child_proc_list[i].deadline_time <= current_time) {
476 child_proc_list[i].done_flag = true;
Yabin Cuibe837362015-01-02 18:45:37 -0800477 child_proc_list[i].timeout_flag = true;
Yabin Cui294d1e22014-12-07 20:43:37 -0800478 loop_flag = false;
479 }
480 }
481 } else {
482 // Check child finish.
483 for (size_t i = 0; i < child_proc_list.size(); ++i) {
484 if (child_proc_list[i].pid == result) {
485 child_proc_list[i].done_flag = true;
Yabin Cuibe837362015-01-02 18:45:37 -0800486 child_proc_list[i].timeout_flag = false;
487 child_proc_list[i].exit_status = status;
Yabin Cui294d1e22014-12-07 20:43:37 -0800488 loop_flag = false;
489 break;
490 }
491 }
492 }
493
494 if (!loop_flag) break;
495 // sleep 1 ms to avoid busy looping.
496 timespec sleep_time;
497 sleep_time.tv_sec = 0;
498 sleep_time.tv_nsec = 1000000;
499 nanosleep(&sleep_time, NULL);
500 }
501}
502
503static TestResult WaitChildProc(pid_t pid) {
504 pid_t result;
505 int exit_status;
506
507 while ((result = waitpid(pid, &exit_status, 0)) == -1) {
508 if (errno != EINTR) {
509 break;
510 }
511 }
512
513 TestResult test_result = TEST_SUCCESS;
514 if (result != pid || WEXITSTATUS(exit_status) != 0) {
515 test_result = TEST_FAILED;
516 }
517 return test_result;
518}
519
520// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
521// makes deadlock to use fork in multi-thread.
522static void RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Yabin Cuibe837362015-01-02 18:45:37 -0800523 size_t iteration_count, size_t job_count) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800524 // Stop default result printer to avoid environment setup/teardown information for each test.
525 testing::UnitTest::GetInstance()->listeners().Release(
526 testing::UnitTest::GetInstance()->listeners().default_result_printer());
527 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
528
Yabin Cuibe837362015-01-02 18:45:37 -0800529 for (size_t iteration = 1; iteration <= iteration_count; ++iteration) {
530 OnTestIterationStartPrint(testcase_list, iteration, iteration_count);
Yabin Cui294d1e22014-12-07 20:43:37 -0800531 int64_t iteration_start_time = NanoTime();
532
Yabin Cuibe837362015-01-02 18:45:37 -0800533 // Run up to job_count tests in parallel, each test in a child process.
534 std::vector<ChildProcInfo> child_proc_list(job_count);
Yabin Cui294d1e22014-12-07 20:43:37 -0800535
Yabin Cuibe837362015-01-02 18:45:37 -0800536 // Next test to run is [next_testcase_id:next_test_id].
537 size_t next_testcase_id = 0;
538 size_t next_test_id = 0;
539
540 // Record how many tests are finished.
541 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
542 size_t finished_testcase_count = 0;
543
544 while (finished_testcase_count < testcase_list.size()) {
545 // Fork up to job_count child processes.
Yabin Cui294d1e22014-12-07 20:43:37 -0800546 for (auto& child_proc : child_proc_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800547 if (child_proc.pid == 0 && next_testcase_id < testcase_list.size()) {
548 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
Yabin Cui294d1e22014-12-07 20:43:37 -0800549 pid_t pid = fork();
550 if (pid == -1) {
551 perror("fork in RunTestInSeparateProc");
552 exit(1);
553 } else if (pid == 0) {
554 // Run child process test, never return.
555 ChildProcessFn(argc, argv, test_name);
556 }
557 // Parent process
558 child_proc.pid = pid;
559 child_proc.start_time = NanoTime();
560 child_proc.deadline_time = child_proc.start_time + GetDeadlineInfo(test_name) * 1000000LL;
Yabin Cuibe837362015-01-02 18:45:37 -0800561 child_proc.testcase_id = next_testcase_id;
562 child_proc.test_id = next_test_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800563 child_proc.done_flag = false;
Yabin Cuibe837362015-01-02 18:45:37 -0800564 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
565 next_test_id = 0;
566 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800567 }
568 }
569 }
570
571 // Wait for any child proc finish or timeout.
572 WaitChildProcs(child_proc_list);
573
574 // Collect result.
575 for (auto& child_proc : child_proc_list) {
576 if (child_proc.pid != 0 && child_proc.done_flag == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800577 size_t testcase_id = child_proc.testcase_id;
578 size_t test_id = child_proc.test_id;
579 TestCase& testcase = testcase_list[testcase_id];
580 testcase.SetTestTime(test_id, NanoTime() - child_proc.start_time);
581
582 if (child_proc.timeout_flag) {
583 // Kill and wait the timeout child process.
Yabin Cui294d1e22014-12-07 20:43:37 -0800584 kill(child_proc.pid, SIGKILL);
585 WaitChildProc(child_proc.pid);
Yabin Cuibe837362015-01-02 18:45:37 -0800586 testcase.SetTestResult(test_id, TEST_TIMEOUT);
Yabin Cui294d1e22014-12-07 20:43:37 -0800587 OnTestTimeoutPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800588
589 } else if (WIFSIGNALED(child_proc.exit_status)) {
590 // Record signal terminated test as failed.
591 testcase.SetTestResult(test_id, TEST_FAILED);
592 OnTestTerminatedPrint(testcase, test_id, WTERMSIG(child_proc.exit_status));
593
594 } else {
595 testcase.SetTestResult(test_id, WEXITSTATUS(child_proc.exit_status) == 0 ?
596 TEST_SUCCESS : TEST_FAILED);
597 // TestResultPrinter::OnTestEnd has already printed result for normal exit.
Yabin Cui294d1e22014-12-07 20:43:37 -0800598 }
Yabin Cuibe837362015-01-02 18:45:37 -0800599
600 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
601 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800602 }
603 child_proc.pid = 0;
604 child_proc.done_flag = false;
605 }
606 }
607 }
608
609 OnTestIterationEndPrint(testcase_list, iteration, NanoTime() - iteration_start_time);
610 }
611}
612
Yabin Cuibe837362015-01-02 18:45:37 -0800613static size_t GetProcessorCount() {
614 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800615}
616
Yabin Cuibe837362015-01-02 18:45:37 -0800617// Pick options not for gtest: There are two parts in argv, one part is handled by PickOptions()
618// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
619// gtest. PickOptions() picks the first part of options and change them into flags and operations,
620// lefting the second part in argv.
621// Arguments:
622// argv is used to pass in all command arguments, and pass out only the part of options for gtest.
623// exit_flag is to indicate whether we need to run gtest workflow after PickOptions.
624// Return false if run error.
625static bool PickOptions(std::vector<char*>& argv, bool* exit_flag) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800626 *exit_flag = false;
Yabin Cuibe837362015-01-02 18:45:37 -0800627 for (size_t i = 1; i < argv.size() - 1; ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800628 if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
629 PrintHelpInfo();
630 return true;
631 }
632 }
633
Yabin Cuibe837362015-01-02 18:45:37 -0800634 // Move --gtest_filter option to last, and add "-bionic_selftest*" to disable self test.
635 std::string gtest_filter_str = "--gtest_filter=-bionic_selftest*";
636 for (size_t i = argv.size() - 2; i >= 1; --i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800637 if (strncmp(argv[i], "--gtest_filter=", sizeof("--gtest_filter=") - 1) == 0) {
Yabin Cuibe837362015-01-02 18:45:37 -0800638 gtest_filter_str = std::string(argv[i]) + ":-bionic_selftest*";
639 argv.erase(argv.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800640 break;
641 }
642 }
Yabin Cuibe837362015-01-02 18:45:37 -0800643 argv.insert(argv.end() - 1, strdup(gtest_filter_str.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -0800644
Yabin Cuibe837362015-01-02 18:45:37 -0800645 // Init default bionic_gtest option.
646 bool isolate_option = true;
647 size_t job_count_option = GetProcessorCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800648
Yabin Cuibe837362015-01-02 18:45:37 -0800649 size_t deadline_option_len = strlen("--deadline=");
650 size_t warnline_option_len = strlen("--warnline=");
651 size_t gtest_color_option_len = strlen("--gtest_color=");
Yabin Cui294d1e22014-12-07 20:43:37 -0800652
Yabin Cuibe837362015-01-02 18:45:37 -0800653 // Parse bionic_gtest specific options in arguments.
654 for (size_t i = 1; i < argv.size() - 1; ++i) {
655 if (strcmp(argv[i], "-j") == 0) {
656 isolate_option = true; // Enable isolation mode when -j is used.
657 int tmp;
658 if (argv[i + 1] != NULL && (tmp = atoi(argv[i + 1])) > 0) {
659 job_count_option = tmp;
660 argv.erase(argv.begin() + i);
661 } else {
662 job_count_option = GetProcessorCount();
663 }
664 argv.erase(argv.begin() + i);
665 --i;
Yabin Cui294d1e22014-12-07 20:43:37 -0800666
Yabin Cuibe837362015-01-02 18:45:37 -0800667 } else if (strcmp(argv[i], "--no-isolate") == 0) {
668 isolate_option = false;
669 argv.erase(argv.begin() + i);
670 --i;
Yabin Cui294d1e22014-12-07 20:43:37 -0800671
672 } else if (strncmp(argv[i], "--deadline=", deadline_option_len) == 0) {
673 global_test_run_deadline_in_ms = atoi(argv[i] + deadline_option_len);
674 if (global_test_run_deadline_in_ms <= 0) {
675 fprintf(stderr, "value for --deadline option should be positive: %s\n",
676 argv[i] + deadline_option_len);
677 exit(1);
678 }
Yabin Cuibe837362015-01-02 18:45:37 -0800679 argv.erase(argv.begin() + i);
680 --i;
Yabin Cui294d1e22014-12-07 20:43:37 -0800681
682 } else if (strncmp(argv[i], "--warnline=", warnline_option_len) == 0) {
683 global_test_run_warnline_in_ms = atoi(argv[i] + warnline_option_len);
684 if (global_test_run_warnline_in_ms <= 0) {
685 fprintf(stderr, "value for --warnline option should be positive: %s\n",
686 argv[i] + warnline_option_len);
687 exit(1);
688 }
Yabin Cuibe837362015-01-02 18:45:37 -0800689 argv.erase(argv.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800690 --i;
Yabin Cuibe837362015-01-02 18:45:37 -0800691
692 } else if (strncmp(argv[i], "--gtest_color=", gtest_color_option_len) == 0) {
693 // If running in isolation mode, main process doesn't call testing::InitGoogleTest(&argc, argv).
694 // So we should parse gtest options for printing by ourselves.
695 testing::GTEST_FLAG(color) = argv[i] + gtest_color_option_len;
696
697 } else if (strcmp(argv[i], "--gtest_print_time=0") == 0) {
698 testing::GTEST_FLAG(print_time) = false;
699
700 } else if (strcmp(argv[i], "--gtest_list_tests") == 0) {
701 // Disable isolation mode in gtest_list_tests option.
702 isolate_option = false;
703
704 } else if (strcmp(argv[i], "--bionic-selftest") == 0) {
705 // This option is to enable "bionic_selftest*" for self test, and not shown in help informantion.
706 // Don't remove this option from argument list.
707 argv[argv.size() - 2] = strdup("--gtest_filter=bionic_selftest*");
Yabin Cui294d1e22014-12-07 20:43:37 -0800708 }
709 }
710
711 // Handle --gtest_repeat=[COUNT] option if we are in isolation mode.
712 // We should check and remove this option to avoid child process running single test for several
713 // iterations.
Yabin Cuibe837362015-01-02 18:45:37 -0800714 size_t gtest_repeat_count = 1;
Yabin Cui294d1e22014-12-07 20:43:37 -0800715 if (isolate_option == true) {
716 int len = sizeof("--gtest_repeat=") - 1;
Yabin Cuibe837362015-01-02 18:45:37 -0800717 for (size_t i = 1; i < argv.size() - 1; ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800718 if (strncmp(argv[i], "--gtest_repeat=", len) == 0) {
Yabin Cuibe837362015-01-02 18:45:37 -0800719 int tmp = atoi(argv[i] + len);
720 if (tmp < 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800721 fprintf(stderr, "error count for option --gtest_repeat=[COUNT]\n");
722 return false;
723 }
Yabin Cuibe837362015-01-02 18:45:37 -0800724 gtest_repeat_count = tmp;
725 argv.erase(argv.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800726 break;
727 }
728 }
729 }
730
Yabin Cuibe837362015-01-02 18:45:37 -0800731 // Add --no-isolate option in argv to suppress subprocess running in isolation mode again.
732 // As DeathTest will try to execve again, this option should always be set.
733 argv.insert(argv.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -0800734
735 // Run tests in isolation mode.
736 if (isolate_option) {
737 *exit_flag = true;
738
739 std::vector<TestCase> testcase_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800740 int argc = static_cast<int>(argv.size()) - 1;
741 if (EnumerateTests(argc, argv.data(), testcase_list) == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800742 return false;
743 }
Yabin Cuibe837362015-01-02 18:45:37 -0800744 RunTestInSeparateProc(argc, argv.data(), testcase_list, gtest_repeat_count, job_count_option);
Yabin Cui294d1e22014-12-07 20:43:37 -0800745 return true;
746 }
747 return true;
748}
749
750int main(int argc, char** argv) {
Yabin Cuibe837362015-01-02 18:45:37 -0800751 std::vector<char*> arg_list;
752 for (int i = 0; i < argc; ++i) {
753 arg_list.push_back(argv[i]);
754 }
755 arg_list.push_back(NULL);
756
Yabin Cui294d1e22014-12-07 20:43:37 -0800757 bool exit_flag;
758 int return_result = 0;
759
Yabin Cuibe837362015-01-02 18:45:37 -0800760 if (PickOptions(arg_list, &exit_flag) == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800761 return_result = 1;
762 } else if (!exit_flag) {
Yabin Cuibe837362015-01-02 18:45:37 -0800763 argc = static_cast<int>(arg_list.size()) - 1;
764 testing::InitGoogleTest(&argc, arg_list.data());
Yabin Cui294d1e22014-12-07 20:43:37 -0800765 return_result = RUN_ALL_TESTS();
766 }
767 return return_result;
768}
769
770//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -0800771// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -0800772
Yabin Cuibe837362015-01-02 18:45:37 -0800773TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800774 ASSERT_EQ(1, 1);
775}
776
Yabin Cuibe837362015-01-02 18:45:37 -0800777TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800778 ASSERT_EQ(0, 1);
779}
780
Yabin Cuibe837362015-01-02 18:45:37 -0800781TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800782 sleep(4);
783}
784
Yabin Cuibe837362015-01-02 18:45:37 -0800785TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800786 while (1) {}
787}
Yabin Cuibe837362015-01-02 18:45:37 -0800788
789TEST(bionic_selftest, test_signal_SEGV_terminated) {
790 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
791 *p = 3;
792}