blob: 99cd4eebbb37193a4c029908cfc4560ab53e4302 [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
Yabin Cuibe837362015-01-02 18:45:37 -0800322static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui294d1e22014-12-07 20:43:37 -0800323 int64_t elapsed_time) {
324
325 std::vector<std::string> fail_test_name_list;
326 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
327
328 // For tests run exceed warnline but not timeout.
329 std::vector<std::tuple<std::string, int64_t, int>> timewarn_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800330 size_t testcase_count = testcase_list.size();
331 size_t test_count = 0;
332 size_t success_test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800333
334 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800335 test_count += testcase.TestCount();
336 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800337 TestResult result = testcase.GetTestResult(i);
338 if (result == TEST_SUCCESS) {
Yabin Cuibe837362015-01-02 18:45:37 -0800339 ++success_test_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800340 } else if (result == TEST_FAILED) {
341 fail_test_name_list.push_back(testcase.GetTestName(i));
342 } else if (result == TEST_TIMEOUT) {
343 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i),
344 testcase.GetTestTime(i)));
345 }
346 if (result != TEST_TIMEOUT &&
347 testcase.GetTestTime(i) / 1000000 >= GetWarnlineInfo(testcase.GetTestName(i))) {
348 timewarn_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
349 testcase.GetTestTime(i),
350 GetWarnlineInfo(testcase.GetTestName(i))));
351 }
352 }
353 }
354
Yabin Cui294d1e22014-12-07 20:43:37 -0800355 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800356 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
357 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800358 if (testing::GTEST_FLAG(print_time)) {
359 printf(" (%lld ms total)", elapsed_time / 1000000LL);
360 }
361 printf("\n");
362 ColoredPrintf(COLOR_GREEN, "[ PASSED ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800363 printf("%zu %s.\n", success_test_count, (success_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800364
365 // Print tests failed.
Yabin Cuibe837362015-01-02 18:45:37 -0800366 size_t fail_test_count = fail_test_name_list.size();
367 if (fail_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800368 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800369 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800370 for (const auto& name : fail_test_name_list) {
371 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
372 printf("%s\n", name.c_str());
373 }
374 }
375
376 // Print tests run timeout.
Yabin Cuibe837362015-01-02 18:45:37 -0800377 size_t timeout_test_count = timeout_test_list.size();
378 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800379 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800380 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800381 for (const auto& timeout_pair : timeout_test_list) {
382 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
383 printf("%s (stopped at %lld ms)\n", timeout_pair.first.c_str(),
384 timeout_pair.second / 1000000LL);
385 }
386 }
387
388 // Print tests run exceed warnline.
Yabin Cuibe837362015-01-02 18:45:37 -0800389 size_t timewarn_test_count = timewarn_test_list.size();
390 if (timewarn_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800391 ColoredPrintf(COLOR_YELLOW, "[ TIMEWARN ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800392 printf("%zu %s, listed below:\n", timewarn_test_count, (timewarn_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800393 for (const auto& timewarn_tuple : timewarn_test_list) {
394 ColoredPrintf(COLOR_YELLOW, "[ TIMEWARN ] ");
395 printf("%s (%lld ms, exceed warnline %d ms)\n", std::get<0>(timewarn_tuple).c_str(),
396 std::get<1>(timewarn_tuple) / 1000000LL,
397 std::get<2>(timewarn_tuple));
398 }
399 }
400
Yabin Cuibe837362015-01-02 18:45:37 -0800401 if (fail_test_count > 0) {
402 printf("\n%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800403 }
Yabin Cuibe837362015-01-02 18:45:37 -0800404 if (timeout_test_count > 0) {
405 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800406 }
Yabin Cuibe837362015-01-02 18:45:37 -0800407 if (timewarn_test_count > 0) {
408 printf("%2zu TIMEWARN %s\n", timewarn_test_count, (timewarn_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800409 }
410 fflush(stdout);
411}
412
413// Forked Child process, run the single test.
414static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
415 char** new_argv = new char*[argc + 1];
416 memcpy(new_argv, argv, sizeof(char*) * argc);
417
418 char* filter_arg = new char [test_name.size() + 20];
419 strcpy(filter_arg, "--gtest_filter=");
420 strcat(filter_arg, test_name.c_str());
421 new_argv[argc] = filter_arg;
422
423 int new_argc = argc + 1;
424 testing::InitGoogleTest(&new_argc, new_argv);
425 int result = RUN_ALL_TESTS();
426 exit(result);
427}
428
429struct ChildProcInfo {
430 pid_t pid;
431 int64_t start_time;
432 int64_t deadline_time;
Yabin Cuibe837362015-01-02 18:45:37 -0800433 size_t testcase_id, test_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800434 bool done_flag;
Yabin Cuibe837362015-01-02 18:45:37 -0800435 bool timeout_flag;
436 int exit_status;
Yabin Cui294d1e22014-12-07 20:43:37 -0800437 ChildProcInfo() : pid(0) {}
438};
439
440static void WaitChildProcs(std::vector<ChildProcInfo>& child_proc_list) {
441 pid_t result;
Yabin Cuibe837362015-01-02 18:45:37 -0800442 int status;
Yabin Cui294d1e22014-12-07 20:43:37 -0800443 bool loop_flag = true;
444
445 while (true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800446 while ((result = waitpid(-1, &status, WNOHANG)) == -1) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800447 if (errno != EINTR) {
448 break;
449 }
450 }
451
452 if (result == -1) {
453 perror("waitpid");
454 exit(1);
455 } else if (result == 0) {
456 // Check child timeout.
457 int64_t current_time = NanoTime();
458 for (size_t i = 0; i < child_proc_list.size(); ++i) {
459 if (child_proc_list[i].deadline_time <= current_time) {
460 child_proc_list[i].done_flag = true;
Yabin Cuibe837362015-01-02 18:45:37 -0800461 child_proc_list[i].timeout_flag = true;
Yabin Cui294d1e22014-12-07 20:43:37 -0800462 loop_flag = false;
463 }
464 }
465 } else {
466 // Check child finish.
467 for (size_t i = 0; i < child_proc_list.size(); ++i) {
468 if (child_proc_list[i].pid == result) {
469 child_proc_list[i].done_flag = true;
Yabin Cuibe837362015-01-02 18:45:37 -0800470 child_proc_list[i].timeout_flag = false;
471 child_proc_list[i].exit_status = status;
Yabin Cui294d1e22014-12-07 20:43:37 -0800472 loop_flag = false;
473 break;
474 }
475 }
476 }
477
478 if (!loop_flag) break;
479 // sleep 1 ms to avoid busy looping.
480 timespec sleep_time;
481 sleep_time.tv_sec = 0;
482 sleep_time.tv_nsec = 1000000;
483 nanosleep(&sleep_time, NULL);
484 }
485}
486
487static TestResult WaitChildProc(pid_t pid) {
488 pid_t result;
489 int exit_status;
490
491 while ((result = waitpid(pid, &exit_status, 0)) == -1) {
492 if (errno != EINTR) {
493 break;
494 }
495 }
496
497 TestResult test_result = TEST_SUCCESS;
498 if (result != pid || WEXITSTATUS(exit_status) != 0) {
499 test_result = TEST_FAILED;
500 }
501 return test_result;
502}
503
504// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
505// makes deadlock to use fork in multi-thread.
506static void RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Yabin Cuibe837362015-01-02 18:45:37 -0800507 size_t iteration_count, size_t job_count) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800508 // Stop default result printer to avoid environment setup/teardown information for each test.
509 testing::UnitTest::GetInstance()->listeners().Release(
510 testing::UnitTest::GetInstance()->listeners().default_result_printer());
511 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
512
Yabin Cuibe837362015-01-02 18:45:37 -0800513 for (size_t iteration = 1; iteration <= iteration_count; ++iteration) {
514 OnTestIterationStartPrint(testcase_list, iteration, iteration_count);
Yabin Cui294d1e22014-12-07 20:43:37 -0800515 int64_t iteration_start_time = NanoTime();
516
Yabin Cuibe837362015-01-02 18:45:37 -0800517 // Run up to job_count tests in parallel, each test in a child process.
518 std::vector<ChildProcInfo> child_proc_list(job_count);
Yabin Cui294d1e22014-12-07 20:43:37 -0800519
Yabin Cuibe837362015-01-02 18:45:37 -0800520 // Next test to run is [next_testcase_id:next_test_id].
521 size_t next_testcase_id = 0;
522 size_t next_test_id = 0;
523
524 // Record how many tests are finished.
525 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
526 size_t finished_testcase_count = 0;
527
528 while (finished_testcase_count < testcase_list.size()) {
529 // Fork up to job_count child processes.
Yabin Cui294d1e22014-12-07 20:43:37 -0800530 for (auto& child_proc : child_proc_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800531 if (child_proc.pid == 0 && next_testcase_id < testcase_list.size()) {
532 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
Yabin Cui294d1e22014-12-07 20:43:37 -0800533 pid_t pid = fork();
534 if (pid == -1) {
535 perror("fork in RunTestInSeparateProc");
536 exit(1);
537 } else if (pid == 0) {
538 // Run child process test, never return.
539 ChildProcessFn(argc, argv, test_name);
540 }
541 // Parent process
542 child_proc.pid = pid;
543 child_proc.start_time = NanoTime();
544 child_proc.deadline_time = child_proc.start_time + GetDeadlineInfo(test_name) * 1000000LL;
Yabin Cuibe837362015-01-02 18:45:37 -0800545 child_proc.testcase_id = next_testcase_id;
546 child_proc.test_id = next_test_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800547 child_proc.done_flag = false;
Yabin Cuibe837362015-01-02 18:45:37 -0800548 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
549 next_test_id = 0;
550 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800551 }
552 }
553 }
554
555 // Wait for any child proc finish or timeout.
556 WaitChildProcs(child_proc_list);
557
558 // Collect result.
559 for (auto& child_proc : child_proc_list) {
560 if (child_proc.pid != 0 && child_proc.done_flag == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800561 size_t testcase_id = child_proc.testcase_id;
562 size_t test_id = child_proc.test_id;
563 TestCase& testcase = testcase_list[testcase_id];
564 testcase.SetTestTime(test_id, NanoTime() - child_proc.start_time);
565
566 if (child_proc.timeout_flag) {
567 // Kill and wait the timeout child process.
Yabin Cui294d1e22014-12-07 20:43:37 -0800568 kill(child_proc.pid, SIGKILL);
569 WaitChildProc(child_proc.pid);
Yabin Cuibe837362015-01-02 18:45:37 -0800570 testcase.SetTestResult(test_id, TEST_TIMEOUT);
Yabin Cui294d1e22014-12-07 20:43:37 -0800571 OnTestTimeoutPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800572
573 } else if (WIFSIGNALED(child_proc.exit_status)) {
574 // Record signal terminated test as failed.
575 testcase.SetTestResult(test_id, TEST_FAILED);
576 OnTestTerminatedPrint(testcase, test_id, WTERMSIG(child_proc.exit_status));
577
578 } else {
579 testcase.SetTestResult(test_id, WEXITSTATUS(child_proc.exit_status) == 0 ?
580 TEST_SUCCESS : TEST_FAILED);
581 // TestResultPrinter::OnTestEnd has already printed result for normal exit.
Yabin Cui294d1e22014-12-07 20:43:37 -0800582 }
Yabin Cuibe837362015-01-02 18:45:37 -0800583
584 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
585 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800586 }
587 child_proc.pid = 0;
588 child_proc.done_flag = false;
589 }
590 }
591 }
592
593 OnTestIterationEndPrint(testcase_list, iteration, NanoTime() - iteration_start_time);
594 }
595}
596
Yabin Cuibe837362015-01-02 18:45:37 -0800597static size_t GetProcessorCount() {
598 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800599}
600
Yabin Cuibe837362015-01-02 18:45:37 -0800601// Pick options not for gtest: There are two parts in argv, one part is handled by PickOptions()
602// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
603// gtest. PickOptions() picks the first part of options and change them into flags and operations,
604// lefting the second part in argv.
605// Arguments:
606// argv is used to pass in all command arguments, and pass out only the part of options for gtest.
607// exit_flag is to indicate whether we need to run gtest workflow after PickOptions.
608// Return false if run error.
609static bool PickOptions(std::vector<char*>& argv, bool* exit_flag) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800610 *exit_flag = false;
Yabin Cuibe837362015-01-02 18:45:37 -0800611 for (size_t i = 1; i < argv.size() - 1; ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800612 if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
613 PrintHelpInfo();
614 return true;
615 }
616 }
617
Yabin Cuibe837362015-01-02 18:45:37 -0800618 // Move --gtest_filter option to last, and add "-bionic_selftest*" to disable self test.
619 std::string gtest_filter_str = "--gtest_filter=-bionic_selftest*";
620 for (size_t i = argv.size() - 2; i >= 1; --i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800621 if (strncmp(argv[i], "--gtest_filter=", sizeof("--gtest_filter=") - 1) == 0) {
Yabin Cuibe837362015-01-02 18:45:37 -0800622 gtest_filter_str = std::string(argv[i]) + ":-bionic_selftest*";
623 argv.erase(argv.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800624 break;
625 }
626 }
Yabin Cuibe837362015-01-02 18:45:37 -0800627 argv.insert(argv.end() - 1, strdup(gtest_filter_str.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -0800628
Yabin Cuibe837362015-01-02 18:45:37 -0800629 // Init default bionic_gtest option.
630 bool isolate_option = true;
631 size_t job_count_option = GetProcessorCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800632
Yabin Cuibe837362015-01-02 18:45:37 -0800633 size_t deadline_option_len = strlen("--deadline=");
634 size_t warnline_option_len = strlen("--warnline=");
635 size_t gtest_color_option_len = strlen("--gtest_color=");
Yabin Cui294d1e22014-12-07 20:43:37 -0800636
Yabin Cuibe837362015-01-02 18:45:37 -0800637 // Parse bionic_gtest specific options in arguments.
638 for (size_t i = 1; i < argv.size() - 1; ++i) {
639 if (strcmp(argv[i], "-j") == 0) {
640 isolate_option = true; // Enable isolation mode when -j is used.
641 int tmp;
642 if (argv[i + 1] != NULL && (tmp = atoi(argv[i + 1])) > 0) {
643 job_count_option = tmp;
644 argv.erase(argv.begin() + i);
645 } else {
646 job_count_option = GetProcessorCount();
647 }
648 argv.erase(argv.begin() + i);
649 --i;
Yabin Cui294d1e22014-12-07 20:43:37 -0800650
Yabin Cuibe837362015-01-02 18:45:37 -0800651 } else if (strcmp(argv[i], "--no-isolate") == 0) {
652 isolate_option = false;
653 argv.erase(argv.begin() + i);
654 --i;
Yabin Cui294d1e22014-12-07 20:43:37 -0800655
656 } else if (strncmp(argv[i], "--deadline=", deadline_option_len) == 0) {
657 global_test_run_deadline_in_ms = atoi(argv[i] + deadline_option_len);
658 if (global_test_run_deadline_in_ms <= 0) {
659 fprintf(stderr, "value for --deadline option should be positive: %s\n",
660 argv[i] + deadline_option_len);
661 exit(1);
662 }
Yabin Cuibe837362015-01-02 18:45:37 -0800663 argv.erase(argv.begin() + i);
664 --i;
Yabin Cui294d1e22014-12-07 20:43:37 -0800665
666 } else if (strncmp(argv[i], "--warnline=", warnline_option_len) == 0) {
667 global_test_run_warnline_in_ms = atoi(argv[i] + warnline_option_len);
668 if (global_test_run_warnline_in_ms <= 0) {
669 fprintf(stderr, "value for --warnline option should be positive: %s\n",
670 argv[i] + warnline_option_len);
671 exit(1);
672 }
Yabin Cuibe837362015-01-02 18:45:37 -0800673 argv.erase(argv.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800674 --i;
Yabin Cuibe837362015-01-02 18:45:37 -0800675
676 } else if (strncmp(argv[i], "--gtest_color=", gtest_color_option_len) == 0) {
677 // If running in isolation mode, main process doesn't call testing::InitGoogleTest(&argc, argv).
678 // So we should parse gtest options for printing by ourselves.
679 testing::GTEST_FLAG(color) = argv[i] + gtest_color_option_len;
680
681 } else if (strcmp(argv[i], "--gtest_print_time=0") == 0) {
682 testing::GTEST_FLAG(print_time) = false;
683
684 } else if (strcmp(argv[i], "--gtest_list_tests") == 0) {
685 // Disable isolation mode in gtest_list_tests option.
686 isolate_option = false;
687
688 } else if (strcmp(argv[i], "--bionic-selftest") == 0) {
689 // This option is to enable "bionic_selftest*" for self test, and not shown in help informantion.
690 // Don't remove this option from argument list.
691 argv[argv.size() - 2] = strdup("--gtest_filter=bionic_selftest*");
Yabin Cui294d1e22014-12-07 20:43:37 -0800692 }
693 }
694
695 // Handle --gtest_repeat=[COUNT] option if we are in isolation mode.
696 // We should check and remove this option to avoid child process running single test for several
697 // iterations.
Yabin Cuibe837362015-01-02 18:45:37 -0800698 size_t gtest_repeat_count = 1;
Yabin Cui294d1e22014-12-07 20:43:37 -0800699 if (isolate_option == true) {
700 int len = sizeof("--gtest_repeat=") - 1;
Yabin Cuibe837362015-01-02 18:45:37 -0800701 for (size_t i = 1; i < argv.size() - 1; ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800702 if (strncmp(argv[i], "--gtest_repeat=", len) == 0) {
Yabin Cuibe837362015-01-02 18:45:37 -0800703 int tmp = atoi(argv[i] + len);
704 if (tmp < 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800705 fprintf(stderr, "error count for option --gtest_repeat=[COUNT]\n");
706 return false;
707 }
Yabin Cuibe837362015-01-02 18:45:37 -0800708 gtest_repeat_count = tmp;
709 argv.erase(argv.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800710 break;
711 }
712 }
713 }
714
Yabin Cuibe837362015-01-02 18:45:37 -0800715 // Add --no-isolate option in argv to suppress subprocess running in isolation mode again.
716 // As DeathTest will try to execve again, this option should always be set.
717 argv.insert(argv.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -0800718
719 // Run tests in isolation mode.
720 if (isolate_option) {
721 *exit_flag = true;
722
723 std::vector<TestCase> testcase_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800724 int argc = static_cast<int>(argv.size()) - 1;
725 if (EnumerateTests(argc, argv.data(), testcase_list) == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800726 return false;
727 }
Yabin Cuibe837362015-01-02 18:45:37 -0800728 RunTestInSeparateProc(argc, argv.data(), testcase_list, gtest_repeat_count, job_count_option);
Yabin Cui294d1e22014-12-07 20:43:37 -0800729 return true;
730 }
731 return true;
732}
733
734int main(int argc, char** argv) {
Yabin Cuibe837362015-01-02 18:45:37 -0800735 std::vector<char*> arg_list;
736 for (int i = 0; i < argc; ++i) {
737 arg_list.push_back(argv[i]);
738 }
739 arg_list.push_back(NULL);
740
Yabin Cui294d1e22014-12-07 20:43:37 -0800741 bool exit_flag;
742 int return_result = 0;
743
Yabin Cuibe837362015-01-02 18:45:37 -0800744 if (PickOptions(arg_list, &exit_flag) == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800745 return_result = 1;
746 } else if (!exit_flag) {
Yabin Cuibe837362015-01-02 18:45:37 -0800747 argc = static_cast<int>(arg_list.size()) - 1;
748 testing::InitGoogleTest(&argc, arg_list.data());
Yabin Cui294d1e22014-12-07 20:43:37 -0800749 return_result = RUN_ALL_TESTS();
750 }
751 return return_result;
752}
753
754//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -0800755// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -0800756
Yabin Cuibe837362015-01-02 18:45:37 -0800757TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800758 ASSERT_EQ(1, 1);
759}
760
Yabin Cuibe837362015-01-02 18:45:37 -0800761TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800762 ASSERT_EQ(0, 1);
763}
764
Yabin Cuibe837362015-01-02 18:45:37 -0800765TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800766 sleep(4);
767}
768
Yabin Cuibe837362015-01-02 18:45:37 -0800769TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800770 while (1) {}
771}
Yabin Cuibe837362015-01-02 18:45:37 -0800772
773TEST(bionic_selftest, test_signal_SEGV_terminated) {
774 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
775 *p = 3;
776}