blob: dd3ff9ed6664a2d5e6eaa815ebe46fa2e91073a7 [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>
Yabin Cui657b1f92015-01-22 19:26:12 -080020#include <fcntl.h>
21#include <inttypes.h>
Yabin Cui1d4c7802015-02-02 19:14:05 -080022#include <signal.h>
Yabin Cui294d1e22014-12-07 20:43:37 -080023#include <stdarg.h>
24#include <stdio.h>
25#include <string.h>
26#include <sys/wait.h>
27#include <time.h>
28#include <unistd.h>
29
30#include <string>
31#include <tuple>
32#include <utility>
33#include <vector>
34
Yabin Cui657b1f92015-01-22 19:26:12 -080035#include "BionicDeathTest.h" // For selftest.
36
Yabin Cui294d1e22014-12-07 20:43:37 -080037namespace testing {
38namespace internal {
39
40// Reuse of testing::internal::ColoredPrintf in gtest.
41enum GTestColor {
42 COLOR_DEFAULT,
43 COLOR_RED,
44 COLOR_GREEN,
45 COLOR_YELLOW
46};
47
48void ColoredPrintf(GTestColor color, const char* fmt, ...);
49
Yabin Cuibe837362015-01-02 18:45:37 -080050} // namespace internal
51} // namespace testing
Yabin Cui294d1e22014-12-07 20:43:37 -080052
53using testing::internal::GTestColor;
54using testing::internal::COLOR_DEFAULT;
55using testing::internal::COLOR_RED;
56using testing::internal::COLOR_GREEN;
57using testing::internal::COLOR_YELLOW;
58using testing::internal::ColoredPrintf;
59
Yabin Cui657b1f92015-01-22 19:26:12 -080060constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 60000;
61constexpr int DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -080062
63// The time each test can run before killed for the reason of timeout.
64// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080065static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080066
67// The time each test can run before be warned for too much running time.
68// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080069static int global_test_run_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080070
71// Return deadline duration for a test, in ms.
72static int GetDeadlineInfo(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -080073 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -080074}
75
76// Return warnline duration for a test, in ms.
77static int GetWarnlineInfo(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -080078 return global_test_run_warnline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -080079}
80
Yabin Cuibe837362015-01-02 18:45:37 -080081static void PrintHelpInfo() {
82 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -080083 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -080084 " Run up to JOB_COUNT tests in parallel.\n"
85 " Use isolation mode, Run each test in a separate process.\n"
86 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
87 " --no-isolate\n"
88 " Don't use isolation mode, run all tests in a single process.\n"
89 " --deadline=[TIME_IN_MS]\n"
90 " Run each test in no longer than [TIME_IN_MS] time.\n"
91 " It takes effect only in isolation mode. Deafult deadline is 60000 ms.\n"
92 " --warnline=[TIME_IN_MS]\n"
93 " Test running longer than [TIME_IN_MS] will be warned.\n"
94 " It takes effect only in isolation mode. Default warnline is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -080095 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
96 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -080097 "Default bionic unit test option is -j.\n"
98 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
99 "running tests, or send SIGINT to the parent process to stop testing and\n"
100 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800101 "\n");
102}
103
Yabin Cui294d1e22014-12-07 20:43:37 -0800104enum TestResult {
105 TEST_SUCCESS = 0,
106 TEST_FAILED,
107 TEST_TIMEOUT
108};
109
Yabin Cui657b1f92015-01-22 19:26:12 -0800110class Test {
111 public:
112 Test() {} // For std::vector<Test>.
113 explicit Test(const char* name) : name_(name) {}
114
115 const std::string& GetName() const { return name_; }
116
117 void SetResult(TestResult result) { result_ = result; }
118
119 TestResult GetResult() const { return result_; }
120
121 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
122
123 int64_t GetTestTime() const { return elapsed_time_ns_; }
124
125 void AppendFailureMessage(const std::string& s) { failure_message_ += s; }
126
127 const std::string& GetFailureMessage() const { return failure_message_; }
128
129 private:
130 const std::string name_;
131 TestResult result_;
132 int64_t elapsed_time_ns_;
133 std::string failure_message_;
134};
135
Yabin Cui294d1e22014-12-07 20:43:37 -0800136class TestCase {
137 public:
138 TestCase() {} // For std::vector<TestCase>.
139 explicit TestCase(const char* name) : name_(name) {}
140
141 const std::string& GetName() const { return name_; }
142
Yabin Cui657b1f92015-01-22 19:26:12 -0800143 void AppendTest(const char* test_name) {
144 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800145 }
146
Yabin Cuibe837362015-01-02 18:45:37 -0800147 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800148
Yabin Cuibe837362015-01-02 18:45:37 -0800149 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800150 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800151 return name_ + "." + test_list_[test_id].GetName();
152 }
153
154 Test& GetTest(size_t test_id) {
155 VerifyTestId(test_id);
156 return test_list_[test_id];
157 }
158
159 const Test& GetTest(size_t test_id) const {
160 VerifyTestId(test_id);
161 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800162 }
163
Yabin Cuibe837362015-01-02 18:45:37 -0800164 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800165 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800166 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800167 }
168
Yabin Cuibe837362015-01-02 18:45:37 -0800169 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800170 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800171 return test_list_[test_id].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800172 }
173
Yabin Cui657b1f92015-01-22 19:26:12 -0800174 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800175 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800176 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800177 }
178
Yabin Cuibe837362015-01-02 18:45:37 -0800179 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800180 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800181 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800182 }
183
184 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800185 void VerifyTestId(size_t test_id) const {
186 if(test_id >= test_list_.size()) {
187 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800188 exit(1);
189 }
190 }
191
192 private:
193 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800194 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800195};
196
Yabin Cui657b1f92015-01-22 19:26:12 -0800197// This is the file descriptor used by the child process to write failure message.
198// The parent process will collect the information and dump to stdout / xml file.
199static int child_output_fd;
200
Yabin Cui294d1e22014-12-07 20:43:37 -0800201class TestResultPrinter : public testing::EmptyTestEventListener {
202 public:
203 TestResultPrinter() : pinfo_(NULL) {}
204 virtual void OnTestStart(const testing::TestInfo& test_info) {
205 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
206 }
207 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800208
209 private:
210 const testing::TestInfo* pinfo_;
211};
212
213// Called after an assertion failure.
214void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
215 // If the test part succeeded, we don't need to do anything.
216 if (result.type() == testing::TestPartResult::kSuccess)
217 return;
218
219 // Print failure message from the assertion (e.g. expected this and got that).
220 char buf[1024];
221 snprintf(buf, sizeof(buf), "%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(),
222 result.line_number(),
223 pinfo_->test_case_name(),
224 pinfo_->name(),
225 result.message());
226
Yabin Cui294d1e22014-12-07 20:43:37 -0800227 int towrite = strlen(buf);
228 char* p = buf;
229 while (towrite > 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800230 ssize_t bytes_written = TEMP_FAILURE_RETRY(write(child_output_fd, p, towrite));
231 if (bytes_written == -1) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800232 fprintf(stderr, "failed to write child_output_fd: %s\n", strerror(errno));
233 exit(1);
Yabin Cui294d1e22014-12-07 20:43:37 -0800234 } else {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800235 towrite -= bytes_written;
236 p += bytes_written;
Yabin Cui294d1e22014-12-07 20:43:37 -0800237 }
238 }
239}
240
Yabin Cui294d1e22014-12-07 20:43:37 -0800241static int64_t NanoTime() {
242 struct timespec t;
243 t.tv_sec = t.tv_nsec = 0;
244 clock_gettime(CLOCK_MONOTONIC, &t);
245 return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
246}
247
248static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
249 std::string command;
250 for (int i = 0; i < argc; ++i) {
251 command += argv[i];
252 command += " ";
253 }
254 command += "--gtest_list_tests";
255 FILE* fp = popen(command.c_str(), "r");
256 if (fp == NULL) {
257 perror("popen");
258 return false;
259 }
260
261 char buf[200];
262 while (fgets(buf, sizeof(buf), fp) != NULL) {
263 char* p = buf;
264
265 while (*p != '\0' && isspace(*p)) {
266 ++p;
267 }
268 if (*p == '\0') continue;
269 char* start = p;
270 while (*p != '\0' && !isspace(*p)) {
271 ++p;
272 }
273 char* end = p;
274 while (*p != '\0' && isspace(*p)) {
275 ++p;
276 }
277 if (*p != '\0') {
278 // This is not we want, gtest must meet with some error when parsing the arguments.
279 fprintf(stderr, "argument error, check with --help\n");
280 return false;
281 }
282 *end = '\0';
283 if (*(end - 1) == '.') {
284 *(end - 1) = '\0';
285 testcase_list.push_back(TestCase(start));
286 } else {
287 testcase_list.back().AppendTest(start);
288 }
289 }
290 int result = pclose(fp);
291 return (result != -1 && WEXITSTATUS(result) == 0);
292}
293
Yabin Cui294d1e22014-12-07 20:43:37 -0800294// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
295// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
296// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800297static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
298 size_t iteration_count) {
299 if (iteration_count > 1) {
300 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800301 }
302 ColoredPrintf(COLOR_GREEN, "[==========] ");
303
Yabin Cuibe837362015-01-02 18:45:37 -0800304 size_t testcase_count = testcase_list.size();
305 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800306 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800307 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800308 }
309
Yabin Cuibe837362015-01-02 18:45:37 -0800310 printf("Running %zu %s from %zu %s.\n",
311 test_count, (test_count == 1) ? "test" : "tests",
312 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800313 fflush(stdout);
314}
315
Yabin Cui657b1f92015-01-22 19:26:12 -0800316static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
317 TestResult result = testcase.GetTestResult(test_id);
318 if (result == TEST_SUCCESS) {
319 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
320 } else if (result == TEST_FAILED) {
321 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
322 } else if (result == TEST_TIMEOUT) {
323 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
324 }
Yabin Cuibe837362015-01-02 18:45:37 -0800325
Yabin Cui657b1f92015-01-22 19:26:12 -0800326 printf("%s", testcase.GetTestName(test_id).c_str());
327 if (testing::GTEST_FLAG(print_time)) {
328 printf(" (%" PRId64 " ms)\n", testcase.GetTestTime(test_id) / 1000000);
329 } else {
330 printf("\n");
331 }
332
333 const std::string& failure_message = testcase.GetTest(test_id).GetFailureMessage();
334 printf("%s", failure_message.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800335 fflush(stdout);
336}
337
Yabin Cuibe837362015-01-02 18:45:37 -0800338static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800339 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800340
341 std::vector<std::string> fail_test_name_list;
342 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
343
344 // For tests run exceed warnline but not timeout.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800345 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800346 size_t testcase_count = testcase_list.size();
347 size_t test_count = 0;
348 size_t success_test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800349
350 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800351 test_count += testcase.TestCount();
352 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800353 TestResult result = testcase.GetTestResult(i);
354 if (result == TEST_SUCCESS) {
Yabin Cuibe837362015-01-02 18:45:37 -0800355 ++success_test_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800356 } else if (result == TEST_FAILED) {
357 fail_test_name_list.push_back(testcase.GetTestName(i));
358 } else if (result == TEST_TIMEOUT) {
359 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i),
360 testcase.GetTestTime(i)));
361 }
362 if (result != TEST_TIMEOUT &&
363 testcase.GetTestTime(i) / 1000000 >= GetWarnlineInfo(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800364 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
365 testcase.GetTestTime(i),
366 GetWarnlineInfo(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800367 }
368 }
369 }
370
Yabin Cui294d1e22014-12-07 20:43:37 -0800371 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)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800375 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800376 }
377 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800378 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
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 Cui4a82ede2015-01-26 17:19:37 -0800384 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
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) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800387 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
Yabin Cui294d1e22014-12-07 20:43:37 -0800388 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 ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800399 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
400 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800401 }
402 }
403
404 // Print tests run exceed warnline.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800405 size_t slow_test_count = slow_test_list.size();
406 if (slow_test_count > 0) {
407 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
408 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
409 for (const auto& slow_tuple : slow_test_list) {
410 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
411 printf("%s (%" PRId64 " ms, exceed warnline %d ms)\n", std::get<0>(slow_tuple).c_str(),
412 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800413 }
414 }
415
Yabin Cuibe837362015-01-02 18:45:37 -0800416 if (fail_test_count > 0) {
417 printf("\n%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800418 }
Yabin Cuibe837362015-01-02 18:45:37 -0800419 if (timeout_test_count > 0) {
420 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800421 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800422 if (slow_test_count > 0) {
423 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800424 }
425 fflush(stdout);
426}
427
Yabin Cui657b1f92015-01-22 19:26:12 -0800428// Output xml file when --gtest_output is used, write this function as we can't reuse
429// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
430// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
431// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
432void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
433 const std::vector<TestCase>& testcase_list,
434 time_t epoch_iteration_start_time,
435 int64_t elapsed_time_ns) {
436 FILE* fp = fopen(xml_output_filename.c_str(), "w");
437 if (fp == NULL) {
438 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
439 exit(1);
440 }
441
442 size_t total_test_count = 0;
443 size_t total_failed_count = 0;
444 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
445 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
446 for (size_t i = 0; i < testcase_list.size(); ++i) {
447 auto& testcase = testcase_list[i];
448 total_test_count += testcase.TestCount();
449 for (size_t j = 0; j < testcase.TestCount(); ++j) {
450 if (testcase.GetTestResult(j) != TEST_SUCCESS) {
451 ++failed_count_list[i];
452 }
453 elapsed_time_list[i] += testcase.GetTestTime(j);
454 }
455 total_failed_count += failed_count_list[i];
456 }
457
458 const tm* time_struct = localtime(&epoch_iteration_start_time);
459 char timestamp[40];
460 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
461 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
462 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
463
464 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
465 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
466 total_test_count, total_failed_count);
467 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
468 for (size_t i = 0; i < testcase_list.size(); ++i) {
469 auto& testcase = testcase_list[i];
470 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
471 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
472 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
473
474 for (size_t j = 0; j < testcase.TestCount(); ++j) {
475 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
476 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
477 testcase.GetName().c_str());
478 if (testcase.GetTestResult(j) == TEST_SUCCESS) {
479 fputs(" />\n", fp);
480 } else {
481 fputs(">\n", fp);
482 const std::string& failure_message = testcase.GetTest(j).GetFailureMessage();
483 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", failure_message.c_str());
484 fputs(" </failure>\n", fp);
485 fputs(" </testcase>\n", fp);
486 }
487 }
488
489 fputs(" </testsuite>\n", fp);
490 }
491 fputs("</testsuites>\n", fp);
492 fclose(fp);
493}
494
Yabin Cui1d4c7802015-02-02 19:14:05 -0800495struct ChildProcInfo {
496 pid_t pid;
497 int64_t start_time_ns;
498 int64_t end_time_ns;
499 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
500 size_t testcase_id, test_id;
501 bool finished;
502 bool timed_out;
503 int exit_status;
504 int child_read_fd; // File descriptor to read child test failure info.
505};
506
Yabin Cui294d1e22014-12-07 20:43:37 -0800507// Forked Child process, run the single test.
508static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800509 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800510 memcpy(new_argv, argv, sizeof(char*) * argc);
511
512 char* filter_arg = new char [test_name.size() + 20];
513 strcpy(filter_arg, "--gtest_filter=");
514 strcat(filter_arg, test_name.c_str());
515 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800516 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800517
518 int new_argc = argc + 1;
519 testing::InitGoogleTest(&new_argc, new_argv);
520 int result = RUN_ALL_TESTS();
521 exit(result);
522}
523
Yabin Cui1d4c7802015-02-02 19:14:05 -0800524static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
525 sigset_t sigmask, int argc, char** argv) {
526 int pipefd[2];
527 int ret = pipe2(pipefd, O_NONBLOCK);
528 if (ret == -1) {
529 perror("pipe2 in RunTestInSeparateProc");
530 exit(1);
531 }
532 pid_t pid = fork();
533 if (pid == -1) {
534 perror("fork in RunTestInSeparateProc");
535 exit(1);
536 } else if (pid == 0) {
537 // In child process, run a single test.
538 close(pipefd[0]);
539 child_output_fd = pipefd[1];
Yabin Cui294d1e22014-12-07 20:43:37 -0800540
Yabin Cui1d4c7802015-02-02 19:14:05 -0800541 if (sigprocmask(SIG_SETMASK, &sigmask, NULL) == -1) {
542 perror("sigprocmask SIG_SETMASK");
543 exit(1);
544 }
545 ChildProcessFn(argc, argv, test_name);
546 // Unreachable.
547 }
548 // In parent process, initialize child process info.
549 close(pipefd[1]);
550 ChildProcInfo child_proc;
551 child_proc.child_read_fd = pipefd[0];
552 child_proc.pid = pid;
553 child_proc.start_time_ns = NanoTime();
554 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetDeadlineInfo(test_name) * 1000000LL;
555 child_proc.testcase_id = testcase_id;
556 child_proc.test_id = test_id;
557 child_proc.finished = false;
558 return child_proc;
559}
Yabin Cui294d1e22014-12-07 20:43:37 -0800560
Yabin Cui1d4c7802015-02-02 19:14:05 -0800561static void HandleSignals(std::vector<TestCase>& testcase_list,
562 std::vector<ChildProcInfo>& child_proc_list) {
563 sigset_t waiting_mask;
564 sigemptyset(&waiting_mask);
565 sigaddset(&waiting_mask, SIGINT);
566 sigaddset(&waiting_mask, SIGQUIT);
567 timespec timeout;
568 timeout.tv_sec = timeout.tv_nsec = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800569 while (true) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800570 int signo = TEMP_FAILURE_RETRY(sigtimedwait(&waiting_mask, NULL, &timeout));
571 if (signo == -1) {
572 if (errno == EAGAIN) {
573 return; // Timeout, no pending signals.
574 }
575 perror("sigtimedwait");
576 exit(1);
577 } else if (signo == SIGQUIT) {
578 // Print current running tests.
579 printf("List of current running tests:\n");
580 for (auto& child_proc : child_proc_list) {
581 if (child_proc.pid != 0) {
582 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
583 int64_t current_time_ns = NanoTime();
584 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
585 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
586 }
587 }
588 } else if (signo == SIGINT) {
589 // Kill current running tests.
590 for (auto& child_proc : child_proc_list) {
591 if (child_proc.pid != 0) {
592 // Send SIGKILL to ensure the child process can be killed unconditionally.
593 kill(child_proc.pid, SIGKILL);
594 }
595 }
596 // SIGINT kills the parent process as well.
597 exit(1);
598 }
599 }
600}
601
602static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
603 std::vector<ChildProcInfo>& child_proc_list) {
604 for (size_t i = 0; i < child_proc_list.size(); ++i) {
605 if (child_proc_list[i].pid == exit_pid) {
606 child_proc_list[i].finished = true;
607 child_proc_list[i].timed_out = false;
608 child_proc_list[i].exit_status = exit_status;
609 child_proc_list[i].end_time_ns = NanoTime();
610 return true;
611 }
612 }
613 return false;
614}
615
616static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
617 int64_t current_time_ns = NanoTime();
618 size_t timeout_child_count = 0;
619 for (size_t i = 0; i < child_proc_list.size(); ++i) {
620 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
621 child_proc_list[i].finished = true;
622 child_proc_list[i].timed_out = true;
623 child_proc_list[i].end_time_ns = current_time_ns;
624 ++timeout_child_count;
625 }
626 }
627 return timeout_child_count;
628}
629
630static void WaitChildProcs(std::vector<TestCase>& testcase_list,
631 std::vector<ChildProcInfo>& child_proc_list) {
632 size_t finished_child_count = 0;
633 while (true) {
634 int status;
635 pid_t result;
636 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
637 if (CheckChildProcExit(result, status, child_proc_list)) {
638 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800639 }
640 }
641
642 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800643 if (errno == ECHILD) {
644 // This happens when we have no running child processes.
645 return;
646 } else {
647 perror("waitpid");
648 exit(1);
649 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800650 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800651 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800652 }
653
Yabin Cui1d4c7802015-02-02 19:14:05 -0800654 if (finished_child_count > 0) {
655 return;
656 }
657
658 HandleSignals(testcase_list, child_proc_list);
659
Yabin Cui294d1e22014-12-07 20:43:37 -0800660 // sleep 1 ms to avoid busy looping.
661 timespec sleep_time;
662 sleep_time.tv_sec = 0;
663 sleep_time.tv_nsec = 1000000;
664 nanosleep(&sleep_time, NULL);
665 }
666}
667
Yabin Cui1d4c7802015-02-02 19:14:05 -0800668static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800669 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800670 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800671
672 TestResult test_result = TEST_SUCCESS;
673 if (result != pid || WEXITSTATUS(exit_status) != 0) {
674 test_result = TEST_FAILED;
675 }
676 return test_result;
677}
678
Yabin Cui1d4c7802015-02-02 19:14:05 -0800679static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
680 int test_id = child_proc.test_id;
681 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
682 if (child_proc.timed_out) {
683 // The child process marked as timed_out has not exited, and we should kill it manually.
684 kill(child_proc.pid, SIGKILL);
685 WaitForOneChild(child_proc.pid);
686 }
687
688 while (true) {
689 char buf[1024];
690 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
691 if (bytes_read > 0) {
692 buf[bytes_read] = '\0';
693 testcase.GetTest(test_id).AppendFailureMessage(buf);
694 } else if (bytes_read == 0) {
695 break; // Read end.
696 } else {
697 if (errno == EAGAIN) {
698 // No data is available. This rarely happens, only when the child process created other
699 // processes which have not exited so far. But the child process has already exited or
700 // been killed, so the test has finished, and we shouldn't wait further.
701 break;
702 }
703 perror("read child_read_fd in RunTestInSeparateProc");
704 exit(1);
705 }
706 }
707 close(child_proc.child_read_fd);
708
709 if (child_proc.timed_out) {
710 testcase.SetTestResult(test_id, TEST_TIMEOUT);
711 char buf[1024];
712 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
713 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
714 testcase.GetTest(test_id).AppendFailureMessage(buf);
715
716 } else if (WIFSIGNALED(child_proc.exit_status)) {
717 // Record signal terminated test as failed.
718 testcase.SetTestResult(test_id, TEST_FAILED);
719 char buf[1024];
720 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
721 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
722 testcase.GetTest(test_id).AppendFailureMessage(buf);
723
724 } else {
725 testcase.SetTestResult(test_id, WEXITSTATUS(child_proc.exit_status) == 0 ?
726 TEST_SUCCESS : TEST_FAILED);
727 }
728}
729
Yabin Cui294d1e22014-12-07 20:43:37 -0800730// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
731// makes deadlock to use fork in multi-thread.
732static void RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Yabin Cui657b1f92015-01-22 19:26:12 -0800733 size_t iteration_count, size_t job_count,
734 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800735 // Stop default result printer to avoid environment setup/teardown information for each test.
736 testing::UnitTest::GetInstance()->listeners().Release(
737 testing::UnitTest::GetInstance()->listeners().default_result_printer());
738 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
739
Yabin Cui1d4c7802015-02-02 19:14:05 -0800740 // Signals are blocked here as we want to handle them in HandleSignals() later.
741 sigset_t block_mask, orig_mask;
742 sigemptyset(&block_mask);
743 sigaddset(&block_mask, SIGINT);
744 sigaddset(&block_mask, SIGQUIT);
745 if (sigprocmask(SIG_BLOCK, &block_mask, &orig_mask) == -1) {
746 perror("sigprocmask SIG_BLOCK");
747 exit(1);
748 }
749
Yabin Cuibe837362015-01-02 18:45:37 -0800750 for (size_t iteration = 1; iteration <= iteration_count; ++iteration) {
751 OnTestIterationStartPrint(testcase_list, iteration, iteration_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800752 int64_t iteration_start_time_ns = NanoTime();
753 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800754
Yabin Cuibe837362015-01-02 18:45:37 -0800755 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800756 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800757
Yabin Cuibe837362015-01-02 18:45:37 -0800758 // Next test to run is [next_testcase_id:next_test_id].
759 size_t next_testcase_id = 0;
760 size_t next_test_id = 0;
761
762 // Record how many tests are finished.
763 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
764 size_t finished_testcase_count = 0;
765
766 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800767 // run up to job_count child processes.
768 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
769 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
770 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
771 orig_mask, argc, argv);
772 child_proc_list.push_back(child_proc);
773 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
774 next_test_id = 0;
775 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800776 }
777 }
778
779 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800780 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800781
782 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800783 auto it = child_proc_list.begin();
784 while (it != child_proc_list.end()) {
785 auto& child_proc = *it;
786 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800787 size_t testcase_id = child_proc.testcase_id;
788 size_t test_id = child_proc.test_id;
789 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800790
Yabin Cui1d4c7802015-02-02 19:14:05 -0800791 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800792 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800793
794 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
795 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800796 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800797
798 it = child_proc_list.erase(it);
799 } else {
800 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800801 }
802 }
803 }
804
Yabin Cui657b1f92015-01-22 19:26:12 -0800805 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
806 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
807 if (!xml_output_filename.empty()) {
808 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
809 elapsed_time_ns);
810 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800811 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800812
813 // Restore signal mask.
814 if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) == -1) {
815 perror("sigprocmask SIG_SETMASK");
816 exit(1);
817 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800818}
819
Yabin Cuibe837362015-01-02 18:45:37 -0800820static size_t GetProcessorCount() {
821 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800822}
823
Yabin Cui11c43532015-01-28 14:28:14 -0800824static void AddGtestFilterSynonym(std::vector<char*>& args) {
825 // Support --gtest-filter as a synonym for --gtest_filter.
826 for (size_t i = 1; i < args.size(); ++i) {
827 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
828 args[i][7] = '_';
829 }
830 }
831}
832
Yabin Cui657b1f92015-01-22 19:26:12 -0800833struct IsolationTestOptions {
834 bool isolate;
835 size_t job_count;
836 int test_deadline_ms;
837 int test_warnline_ms;
838 std::string gtest_color;
839 bool gtest_print_time;
840 size_t gtest_repeat;
841 std::string gtest_output;
842};
843
844// Pick options not for gtest: There are two parts in args, one part is used in isolation test mode
Yabin Cuibe837362015-01-02 18:45:37 -0800845// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -0800846// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
847// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -0800848// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -0800849// args is used to pass in all command arguments, and pass out only the part of options for gtest.
850// options is used to pass out test options in isolation mode.
851// Return false if there is error in arguments.
852static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
853 for (size_t i = 1; i < args.size(); ++i) {
854 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800855 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -0800856 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800857 return true;
858 }
859 }
860
Yabin Cui11c43532015-01-28 14:28:14 -0800861 AddGtestFilterSynonym(args);
862
Yabin Cui657b1f92015-01-22 19:26:12 -0800863 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
864 bool enable_selftest = false;
865 for (size_t i = 1; i < args.size(); ++i) {
866 if (strcmp(args[i], "--bionic-selftest") == 0) {
867 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
868 // Don't remove this option from arguments.
869 enable_selftest = true;
870 }
871 }
872 std::string gtest_filter_str;
873 for (size_t i = args.size() - 1; i >= 1; --i) {
874 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
875 gtest_filter_str = std::string(args[i]);
876 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800877 break;
878 }
879 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800880 if (enable_selftest == true) {
881 args.push_back(strdup("--gtest_filter=bionic_selftest*"));
882 } else {
883 if (gtest_filter_str == "") {
884 gtest_filter_str = "--gtest_filter=-bionic_selftest*";
885 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -0800886 // Find if '-' for NEGATIVE_PATTERNS exists.
887 if (gtest_filter_str.find(":-") != std::string::npos) {
888 gtest_filter_str += ":bionic_selftest*";
889 } else {
890 gtest_filter_str += ":-bionic_selftest*";
891 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800892 }
893 args.push_back(strdup(gtest_filter_str.c_str()));
894 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800895
Yabin Cui657b1f92015-01-22 19:26:12 -0800896 options.isolate = true;
897 // Parse arguments that make us can't run in isolation mode.
898 for (size_t i = 1; i < args.size(); ++i) {
899 if (strcmp(args[i], "--no-isolate") == 0) {
900 options.isolate = false;
901 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
902 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800903 }
904 }
905
Yabin Cui657b1f92015-01-22 19:26:12 -0800906 // Stop parsing if we will not run in isolation mode.
907 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800908 return true;
909 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800910
911 // Init default isolation test options.
912 options.job_count = GetProcessorCount();
913 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
914 options.test_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
915 options.gtest_color = testing::GTEST_FLAG(color);
916 options.gtest_print_time = testing::GTEST_FLAG(print_time);
917 options.gtest_repeat = testing::GTEST_FLAG(repeat);
918 options.gtest_output = testing::GTEST_FLAG(output);
919
920 // Parse arguments speficied for isolation mode.
921 for (size_t i = 1; i < args.size(); ++i) {
922 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
923 char* p = args[i] + strlen("-j");
924 int count = 0;
925 if (*p != '\0') {
926 // Argument like -j5.
927 count = atoi(p);
928 } else if (args.size() > i + 1) {
929 // Arguments like -j 5.
930 count = atoi(args[i + 1]);
931 ++i;
932 }
933 if (count <= 0) {
934 fprintf(stderr, "invalid job count: %d\n", count);
935 return false;
936 }
937 options.job_count = static_cast<size_t>(count);
938 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
939 int time_ms = atoi(args[i] + strlen("--deadline="));
940 if (time_ms <= 0) {
941 fprintf(stderr, "invalid deadline: %d\n", time_ms);
942 return false;
943 }
944 options.test_deadline_ms = time_ms;
945 } else if (strncmp(args[i], "--warnline=", strlen("--warnline=")) == 0) {
946 int time_ms = atoi(args[i] + strlen("--warnline="));
947 if (time_ms <= 0) {
948 fprintf(stderr, "invalid warnline: %d\n", time_ms);
949 return false;
950 }
951 options.test_warnline_ms = time_ms;
952 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
953 options.gtest_color = args[i] + strlen("--gtest_color=");
954 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
955 options.gtest_print_time = false;
956 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
957 int repeat = atoi(args[i] + strlen("--gtest_repeat="));
958 if (repeat < 0) {
959 fprintf(stderr, "invalid gtest_repeat count: %d\n", repeat);
960 return false;
961 }
962 options.gtest_repeat = repeat;
963 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
964 args.erase(args.begin() + i);
965 --i;
966 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
967 std::string output = args[i] + strlen("--gtest_output=");
968 // generate output xml file path according to the strategy in gtest.
969 bool success = true;
970 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
971 output = output.substr(strlen("xml:"));
972 if (output.size() == 0) {
973 success = false;
974 }
975 // Make absolute path.
976 if (success && output[0] != '/') {
977 char* cwd = getcwd(NULL, 0);
978 if (cwd != NULL) {
979 output = std::string(cwd) + "/" + output;
980 free(cwd);
981 } else {
982 success = false;
983 }
984 }
985 // Add file name if output is a directory.
986 if (success && output.back() == '/') {
987 output += "test_details.xml";
988 }
989 }
990 if (success) {
991 options.gtest_output = output;
992 } else {
993 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
994 return false;
995 }
996
997 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
998 args.erase(args.begin() + i);
999 --i;
1000 }
1001 }
1002
1003 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1004 // As DeathTest will try to call execve(), this argument should always be added.
1005 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001006 return true;
1007}
1008
1009int main(int argc, char** argv) {
Yabin Cuibe837362015-01-02 18:45:37 -08001010 std::vector<char*> arg_list;
1011 for (int i = 0; i < argc; ++i) {
1012 arg_list.push_back(argv[i]);
1013 }
Yabin Cuibe837362015-01-02 18:45:37 -08001014
Yabin Cui657b1f92015-01-22 19:26:12 -08001015 IsolationTestOptions options;
1016 if (PickOptions(arg_list, options) == false) {
1017 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001018 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001019
1020 if (options.isolate == true) {
1021 // Set global variables.
1022 global_test_run_deadline_ms = options.test_deadline_ms;
1023 global_test_run_warnline_ms = options.test_warnline_ms;
1024 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1025 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1026 std::vector<TestCase> testcase_list;
1027
1028 argc = static_cast<int>(arg_list.size());
1029 arg_list.push_back(NULL);
1030 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1031 return 1;
1032 }
1033 RunTestInSeparateProc(argc, arg_list.data(), testcase_list, options.gtest_repeat,
1034 options.job_count, options.gtest_output);
1035 } else {
1036 argc = static_cast<int>(arg_list.size());
1037 arg_list.push_back(NULL);
1038 testing::InitGoogleTest(&argc, arg_list.data());
1039 return RUN_ALL_TESTS();
1040 }
1041 return 0;
Yabin Cui294d1e22014-12-07 20:43:37 -08001042}
1043
1044//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001045// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001046
Yabin Cuibe837362015-01-02 18:45:37 -08001047TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001048 ASSERT_EQ(1, 1);
1049}
1050
Yabin Cuibe837362015-01-02 18:45:37 -08001051TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001052 ASSERT_EQ(0, 1);
1053}
1054
Yabin Cuibe837362015-01-02 18:45:37 -08001055TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001056 sleep(4);
1057}
1058
Yabin Cuibe837362015-01-02 18:45:37 -08001059TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001060 while (1) {}
1061}
Yabin Cuibe837362015-01-02 18:45:37 -08001062
1063TEST(bionic_selftest, test_signal_SEGV_terminated) {
1064 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1065 *p = 3;
1066}
Yabin Cui657b1f92015-01-22 19:26:12 -08001067
1068class bionic_selftest_DeathTest : public BionicDeathTest {};
1069
1070static void deathtest_helper_success() {
1071 ASSERT_EQ(1, 1);
1072 exit(0);
1073}
1074
1075TEST_F(bionic_selftest_DeathTest, success) {
1076 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1077}
1078
1079static void deathtest_helper_fail() {
1080 ASSERT_EQ(1, 0);
1081}
1082
1083TEST_F(bionic_selftest_DeathTest, fail) {
1084 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1085}