blob: 86d64660d3ffb8caf0603dcf54188b1d04e0cfb8 [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
Yabin Cuiead08142015-02-04 20:53:56 -080019#include <ctype.h>
Yabin Cui294d1e22014-12-07 20:43:37 -080020#include <errno.h>
Yabin Cui657b1f92015-01-22 19:26:12 -080021#include <fcntl.h>
22#include <inttypes.h>
Yabin Cuiead08142015-02-04 20:53:56 -080023#include <limits.h>
Yabin Cui1d4c7802015-02-02 19:14:05 -080024#include <signal.h>
Yabin Cui294d1e22014-12-07 20:43:37 -080025#include <stdarg.h>
26#include <stdio.h>
27#include <string.h>
28#include <sys/wait.h>
29#include <time.h>
30#include <unistd.h>
31
32#include <string>
33#include <tuple>
34#include <utility>
35#include <vector>
36
Yabin Cui657b1f92015-01-22 19:26:12 -080037#include "BionicDeathTest.h" // For selftest.
38
Yabin Cui294d1e22014-12-07 20:43:37 -080039namespace testing {
40namespace internal {
41
42// Reuse of testing::internal::ColoredPrintf in gtest.
43enum GTestColor {
44 COLOR_DEFAULT,
45 COLOR_RED,
46 COLOR_GREEN,
47 COLOR_YELLOW
48};
49
50void ColoredPrintf(GTestColor color, const char* fmt, ...);
51
Yabin Cuibe837362015-01-02 18:45:37 -080052} // namespace internal
53} // namespace testing
Yabin Cui294d1e22014-12-07 20:43:37 -080054
55using testing::internal::GTestColor;
56using testing::internal::COLOR_DEFAULT;
57using testing::internal::COLOR_RED;
58using testing::internal::COLOR_GREEN;
59using testing::internal::COLOR_YELLOW;
60using testing::internal::ColoredPrintf;
61
Yabin Cui657b1f92015-01-22 19:26:12 -080062constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 60000;
63constexpr int DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -080064
65// The time each test can run before killed for the reason of timeout.
66// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080067static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080068
69// The time each test can run before be warned for too much running time.
70// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080071static int global_test_run_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080072
73// Return deadline duration for a test, in ms.
74static int GetDeadlineInfo(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -080075 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -080076}
77
78// Return warnline duration for a test, in ms.
79static int GetWarnlineInfo(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -080080 return global_test_run_warnline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -080081}
82
Yabin Cuibe837362015-01-02 18:45:37 -080083static void PrintHelpInfo() {
84 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -080085 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -080086 " Run up to JOB_COUNT tests in parallel.\n"
87 " Use isolation mode, Run each test in a separate process.\n"
88 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
89 " --no-isolate\n"
90 " Don't use isolation mode, run all tests in a single process.\n"
91 " --deadline=[TIME_IN_MS]\n"
92 " Run each test in no longer than [TIME_IN_MS] time.\n"
93 " It takes effect only in isolation mode. Deafult deadline is 60000 ms.\n"
94 " --warnline=[TIME_IN_MS]\n"
95 " Test running longer than [TIME_IN_MS] will be warned.\n"
96 " It takes effect only in isolation mode. Default warnline is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -080097 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
98 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -080099 "Default bionic unit test option is -j.\n"
100 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
101 "running tests, or send SIGINT to the parent process to stop testing and\n"
102 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800103 "\n");
104}
105
Yabin Cui294d1e22014-12-07 20:43:37 -0800106enum TestResult {
107 TEST_SUCCESS = 0,
108 TEST_FAILED,
109 TEST_TIMEOUT
110};
111
Yabin Cui657b1f92015-01-22 19:26:12 -0800112class Test {
113 public:
114 Test() {} // For std::vector<Test>.
115 explicit Test(const char* name) : name_(name) {}
116
117 const std::string& GetName() const { return name_; }
118
119 void SetResult(TestResult result) { result_ = result; }
120
121 TestResult GetResult() const { return result_; }
122
123 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
124
125 int64_t GetTestTime() const { return elapsed_time_ns_; }
126
127 void AppendFailureMessage(const std::string& s) { failure_message_ += s; }
128
129 const std::string& GetFailureMessage() const { return failure_message_; }
130
131 private:
132 const std::string name_;
133 TestResult result_;
134 int64_t elapsed_time_ns_;
135 std::string failure_message_;
136};
137
Yabin Cui294d1e22014-12-07 20:43:37 -0800138class TestCase {
139 public:
140 TestCase() {} // For std::vector<TestCase>.
141 explicit TestCase(const char* name) : name_(name) {}
142
143 const std::string& GetName() const { return name_; }
144
Yabin Cui657b1f92015-01-22 19:26:12 -0800145 void AppendTest(const char* test_name) {
146 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800147 }
148
Yabin Cuibe837362015-01-02 18:45:37 -0800149 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800150
Yabin Cuibe837362015-01-02 18:45:37 -0800151 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800152 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800153 return name_ + "." + test_list_[test_id].GetName();
154 }
155
156 Test& GetTest(size_t test_id) {
157 VerifyTestId(test_id);
158 return test_list_[test_id];
159 }
160
161 const Test& GetTest(size_t test_id) const {
162 VerifyTestId(test_id);
163 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800164 }
165
Yabin Cuibe837362015-01-02 18:45:37 -0800166 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800167 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800168 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800169 }
170
Yabin Cuibe837362015-01-02 18:45:37 -0800171 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800172 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800173 return test_list_[test_id].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800174 }
175
Yabin Cui657b1f92015-01-22 19:26:12 -0800176 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800177 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800178 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800179 }
180
Yabin Cuibe837362015-01-02 18:45:37 -0800181 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800182 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800183 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800184 }
185
186 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800187 void VerifyTestId(size_t test_id) const {
188 if(test_id >= test_list_.size()) {
189 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800190 exit(1);
191 }
192 }
193
194 private:
195 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800196 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800197};
198
Yabin Cui657b1f92015-01-22 19:26:12 -0800199// This is the file descriptor used by the child process to write failure message.
200// The parent process will collect the information and dump to stdout / xml file.
201static int child_output_fd;
202
Yabin Cui294d1e22014-12-07 20:43:37 -0800203class TestResultPrinter : public testing::EmptyTestEventListener {
204 public:
205 TestResultPrinter() : pinfo_(NULL) {}
206 virtual void OnTestStart(const testing::TestInfo& test_info) {
207 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
208 }
209 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800210
211 private:
212 const testing::TestInfo* pinfo_;
213};
214
215// Called after an assertion failure.
216void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
217 // If the test part succeeded, we don't need to do anything.
218 if (result.type() == testing::TestPartResult::kSuccess)
219 return;
220
221 // Print failure message from the assertion (e.g. expected this and got that).
222 char buf[1024];
223 snprintf(buf, sizeof(buf), "%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(),
224 result.line_number(),
225 pinfo_->test_case_name(),
226 pinfo_->name(),
227 result.message());
228
Yabin Cui294d1e22014-12-07 20:43:37 -0800229 int towrite = strlen(buf);
230 char* p = buf;
231 while (towrite > 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800232 ssize_t bytes_written = TEMP_FAILURE_RETRY(write(child_output_fd, p, towrite));
233 if (bytes_written == -1) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800234 fprintf(stderr, "failed to write child_output_fd: %s\n", strerror(errno));
235 exit(1);
Yabin Cui294d1e22014-12-07 20:43:37 -0800236 } else {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800237 towrite -= bytes_written;
238 p += bytes_written;
Yabin Cui294d1e22014-12-07 20:43:37 -0800239 }
240 }
241}
242
Yabin Cui294d1e22014-12-07 20:43:37 -0800243static int64_t NanoTime() {
244 struct timespec t;
245 t.tv_sec = t.tv_nsec = 0;
246 clock_gettime(CLOCK_MONOTONIC, &t);
247 return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
248}
249
250static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
251 std::string command;
252 for (int i = 0; i < argc; ++i) {
253 command += argv[i];
254 command += " ";
255 }
256 command += "--gtest_list_tests";
257 FILE* fp = popen(command.c_str(), "r");
258 if (fp == NULL) {
259 perror("popen");
260 return false;
261 }
262
263 char buf[200];
264 while (fgets(buf, sizeof(buf), fp) != NULL) {
265 char* p = buf;
266
267 while (*p != '\0' && isspace(*p)) {
268 ++p;
269 }
270 if (*p == '\0') continue;
271 char* start = p;
272 while (*p != '\0' && !isspace(*p)) {
273 ++p;
274 }
275 char* end = p;
276 while (*p != '\0' && isspace(*p)) {
277 ++p;
278 }
279 if (*p != '\0') {
280 // This is not we want, gtest must meet with some error when parsing the arguments.
281 fprintf(stderr, "argument error, check with --help\n");
282 return false;
283 }
284 *end = '\0';
285 if (*(end - 1) == '.') {
286 *(end - 1) = '\0';
287 testcase_list.push_back(TestCase(start));
288 } else {
289 testcase_list.back().AppendTest(start);
290 }
291 }
292 int result = pclose(fp);
293 return (result != -1 && WEXITSTATUS(result) == 0);
294}
295
Yabin Cui294d1e22014-12-07 20:43:37 -0800296// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
297// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
298// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800299static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
300 size_t iteration_count) {
301 if (iteration_count > 1) {
302 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800303 }
304 ColoredPrintf(COLOR_GREEN, "[==========] ");
305
Yabin Cuibe837362015-01-02 18:45:37 -0800306 size_t testcase_count = testcase_list.size();
307 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800308 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800309 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800310 }
311
Yabin Cuibe837362015-01-02 18:45:37 -0800312 printf("Running %zu %s from %zu %s.\n",
313 test_count, (test_count == 1) ? "test" : "tests",
314 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800315 fflush(stdout);
316}
317
Yabin Cui657b1f92015-01-22 19:26:12 -0800318static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
319 TestResult result = testcase.GetTestResult(test_id);
320 if (result == TEST_SUCCESS) {
321 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
322 } else if (result == TEST_FAILED) {
323 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
324 } else if (result == TEST_TIMEOUT) {
325 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
326 }
Yabin Cuibe837362015-01-02 18:45:37 -0800327
Yabin Cui657b1f92015-01-22 19:26:12 -0800328 printf("%s", testcase.GetTestName(test_id).c_str());
329 if (testing::GTEST_FLAG(print_time)) {
330 printf(" (%" PRId64 " ms)\n", testcase.GetTestTime(test_id) / 1000000);
331 } else {
332 printf("\n");
333 }
334
335 const std::string& failure_message = testcase.GetTest(test_id).GetFailureMessage();
336 printf("%s", failure_message.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800337 fflush(stdout);
338}
339
Yabin Cuibe837362015-01-02 18:45:37 -0800340static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800341 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800342
343 std::vector<std::string> fail_test_name_list;
344 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
345
346 // For tests run exceed warnline but not timeout.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800347 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800348 size_t testcase_count = testcase_list.size();
349 size_t test_count = 0;
350 size_t success_test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800351
352 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800353 test_count += testcase.TestCount();
354 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800355 TestResult result = testcase.GetTestResult(i);
356 if (result == TEST_SUCCESS) {
Yabin Cuibe837362015-01-02 18:45:37 -0800357 ++success_test_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800358 } else if (result == TEST_FAILED) {
359 fail_test_name_list.push_back(testcase.GetTestName(i));
360 } else if (result == TEST_TIMEOUT) {
361 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i),
362 testcase.GetTestTime(i)));
363 }
364 if (result != TEST_TIMEOUT &&
365 testcase.GetTestTime(i) / 1000000 >= GetWarnlineInfo(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800366 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
367 testcase.GetTestTime(i),
368 GetWarnlineInfo(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800369 }
370 }
371 }
372
Yabin Cui294d1e22014-12-07 20:43:37 -0800373 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800374 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
375 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800376 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800377 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800378 }
379 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800380 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800381 printf("%zu %s.\n", success_test_count, (success_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800382
383 // Print tests failed.
Yabin Cuibe837362015-01-02 18:45:37 -0800384 size_t fail_test_count = fail_test_name_list.size();
385 if (fail_test_count > 0) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800386 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800387 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800388 for (const auto& name : fail_test_name_list) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800389 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
Yabin Cui294d1e22014-12-07 20:43:37 -0800390 printf("%s\n", name.c_str());
391 }
392 }
393
394 // Print tests run timeout.
Yabin Cuibe837362015-01-02 18:45:37 -0800395 size_t timeout_test_count = timeout_test_list.size();
396 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800397 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800398 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800399 for (const auto& timeout_pair : timeout_test_list) {
400 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800401 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
402 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800403 }
404 }
405
406 // Print tests run exceed warnline.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800407 size_t slow_test_count = slow_test_list.size();
408 if (slow_test_count > 0) {
409 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
410 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
411 for (const auto& slow_tuple : slow_test_list) {
412 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
413 printf("%s (%" PRId64 " ms, exceed warnline %d ms)\n", std::get<0>(slow_tuple).c_str(),
414 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800415 }
416 }
417
Yabin Cuibe837362015-01-02 18:45:37 -0800418 if (fail_test_count > 0) {
419 printf("\n%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800420 }
Yabin Cuibe837362015-01-02 18:45:37 -0800421 if (timeout_test_count > 0) {
422 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800423 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800424 if (slow_test_count > 0) {
425 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800426 }
427 fflush(stdout);
428}
429
Yabin Cui657b1f92015-01-22 19:26:12 -0800430// Output xml file when --gtest_output is used, write this function as we can't reuse
431// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
432// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
433// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
434void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
435 const std::vector<TestCase>& testcase_list,
436 time_t epoch_iteration_start_time,
437 int64_t elapsed_time_ns) {
438 FILE* fp = fopen(xml_output_filename.c_str(), "w");
439 if (fp == NULL) {
440 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
441 exit(1);
442 }
443
444 size_t total_test_count = 0;
445 size_t total_failed_count = 0;
446 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
447 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
448 for (size_t i = 0; i < testcase_list.size(); ++i) {
449 auto& testcase = testcase_list[i];
450 total_test_count += testcase.TestCount();
451 for (size_t j = 0; j < testcase.TestCount(); ++j) {
452 if (testcase.GetTestResult(j) != TEST_SUCCESS) {
453 ++failed_count_list[i];
454 }
455 elapsed_time_list[i] += testcase.GetTestTime(j);
456 }
457 total_failed_count += failed_count_list[i];
458 }
459
460 const tm* time_struct = localtime(&epoch_iteration_start_time);
461 char timestamp[40];
462 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
463 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
464 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
465
466 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
467 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
468 total_test_count, total_failed_count);
469 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
470 for (size_t i = 0; i < testcase_list.size(); ++i) {
471 auto& testcase = testcase_list[i];
472 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
473 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
474 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
475
476 for (size_t j = 0; j < testcase.TestCount(); ++j) {
477 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
478 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
479 testcase.GetName().c_str());
480 if (testcase.GetTestResult(j) == TEST_SUCCESS) {
481 fputs(" />\n", fp);
482 } else {
483 fputs(">\n", fp);
484 const std::string& failure_message = testcase.GetTest(j).GetFailureMessage();
485 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", failure_message.c_str());
486 fputs(" </failure>\n", fp);
487 fputs(" </testcase>\n", fp);
488 }
489 }
490
491 fputs(" </testsuite>\n", fp);
492 }
493 fputs("</testsuites>\n", fp);
494 fclose(fp);
495}
496
Yabin Cui1d4c7802015-02-02 19:14:05 -0800497struct ChildProcInfo {
498 pid_t pid;
499 int64_t start_time_ns;
500 int64_t end_time_ns;
501 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
502 size_t testcase_id, test_id;
503 bool finished;
504 bool timed_out;
505 int exit_status;
506 int child_read_fd; // File descriptor to read child test failure info.
507};
508
Yabin Cui294d1e22014-12-07 20:43:37 -0800509// Forked Child process, run the single test.
510static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800511 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800512 memcpy(new_argv, argv, sizeof(char*) * argc);
513
514 char* filter_arg = new char [test_name.size() + 20];
515 strcpy(filter_arg, "--gtest_filter=");
516 strcat(filter_arg, test_name.c_str());
517 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800518 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800519
520 int new_argc = argc + 1;
521 testing::InitGoogleTest(&new_argc, new_argv);
522 int result = RUN_ALL_TESTS();
523 exit(result);
524}
525
Yabin Cui1d4c7802015-02-02 19:14:05 -0800526static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
527 sigset_t sigmask, int argc, char** argv) {
528 int pipefd[2];
529 int ret = pipe2(pipefd, O_NONBLOCK);
530 if (ret == -1) {
531 perror("pipe2 in RunTestInSeparateProc");
532 exit(1);
533 }
534 pid_t pid = fork();
535 if (pid == -1) {
536 perror("fork in RunTestInSeparateProc");
537 exit(1);
538 } else if (pid == 0) {
539 // In child process, run a single test.
540 close(pipefd[0]);
541 child_output_fd = pipefd[1];
Yabin Cui294d1e22014-12-07 20:43:37 -0800542
Yabin Cui1d4c7802015-02-02 19:14:05 -0800543 if (sigprocmask(SIG_SETMASK, &sigmask, NULL) == -1) {
544 perror("sigprocmask SIG_SETMASK");
545 exit(1);
546 }
547 ChildProcessFn(argc, argv, test_name);
548 // Unreachable.
549 }
550 // In parent process, initialize child process info.
551 close(pipefd[1]);
552 ChildProcInfo child_proc;
553 child_proc.child_read_fd = pipefd[0];
554 child_proc.pid = pid;
555 child_proc.start_time_ns = NanoTime();
556 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetDeadlineInfo(test_name) * 1000000LL;
557 child_proc.testcase_id = testcase_id;
558 child_proc.test_id = test_id;
559 child_proc.finished = false;
560 return child_proc;
561}
Yabin Cui294d1e22014-12-07 20:43:37 -0800562
Yabin Cui1d4c7802015-02-02 19:14:05 -0800563static void HandleSignals(std::vector<TestCase>& testcase_list,
564 std::vector<ChildProcInfo>& child_proc_list) {
565 sigset_t waiting_mask;
566 sigemptyset(&waiting_mask);
567 sigaddset(&waiting_mask, SIGINT);
568 sigaddset(&waiting_mask, SIGQUIT);
569 timespec timeout;
570 timeout.tv_sec = timeout.tv_nsec = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800571 while (true) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800572 int signo = TEMP_FAILURE_RETRY(sigtimedwait(&waiting_mask, NULL, &timeout));
573 if (signo == -1) {
574 if (errno == EAGAIN) {
575 return; // Timeout, no pending signals.
576 }
577 perror("sigtimedwait");
578 exit(1);
579 } else if (signo == SIGQUIT) {
580 // Print current running tests.
581 printf("List of current running tests:\n");
582 for (auto& child_proc : child_proc_list) {
583 if (child_proc.pid != 0) {
584 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
585 int64_t current_time_ns = NanoTime();
586 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
587 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
588 }
589 }
590 } else if (signo == SIGINT) {
591 // Kill current running tests.
592 for (auto& child_proc : child_proc_list) {
593 if (child_proc.pid != 0) {
594 // Send SIGKILL to ensure the child process can be killed unconditionally.
595 kill(child_proc.pid, SIGKILL);
596 }
597 }
598 // SIGINT kills the parent process as well.
599 exit(1);
600 }
601 }
602}
603
604static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
605 std::vector<ChildProcInfo>& child_proc_list) {
606 for (size_t i = 0; i < child_proc_list.size(); ++i) {
607 if (child_proc_list[i].pid == exit_pid) {
608 child_proc_list[i].finished = true;
609 child_proc_list[i].timed_out = false;
610 child_proc_list[i].exit_status = exit_status;
611 child_proc_list[i].end_time_ns = NanoTime();
612 return true;
613 }
614 }
615 return false;
616}
617
618static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
619 int64_t current_time_ns = NanoTime();
620 size_t timeout_child_count = 0;
621 for (size_t i = 0; i < child_proc_list.size(); ++i) {
622 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
623 child_proc_list[i].finished = true;
624 child_proc_list[i].timed_out = true;
625 child_proc_list[i].end_time_ns = current_time_ns;
626 ++timeout_child_count;
627 }
628 }
629 return timeout_child_count;
630}
631
632static void WaitChildProcs(std::vector<TestCase>& testcase_list,
633 std::vector<ChildProcInfo>& child_proc_list) {
634 size_t finished_child_count = 0;
635 while (true) {
636 int status;
637 pid_t result;
638 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
639 if (CheckChildProcExit(result, status, child_proc_list)) {
640 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800641 }
642 }
643
644 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800645 if (errno == ECHILD) {
646 // This happens when we have no running child processes.
647 return;
648 } else {
649 perror("waitpid");
650 exit(1);
651 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800652 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800653 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800654 }
655
Yabin Cui1d4c7802015-02-02 19:14:05 -0800656 if (finished_child_count > 0) {
657 return;
658 }
659
660 HandleSignals(testcase_list, child_proc_list);
661
Yabin Cui294d1e22014-12-07 20:43:37 -0800662 // sleep 1 ms to avoid busy looping.
663 timespec sleep_time;
664 sleep_time.tv_sec = 0;
665 sleep_time.tv_nsec = 1000000;
666 nanosleep(&sleep_time, NULL);
667 }
668}
669
Yabin Cui1d4c7802015-02-02 19:14:05 -0800670static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800671 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800672 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800673
674 TestResult test_result = TEST_SUCCESS;
675 if (result != pid || WEXITSTATUS(exit_status) != 0) {
676 test_result = TEST_FAILED;
677 }
678 return test_result;
679}
680
Yabin Cui1d4c7802015-02-02 19:14:05 -0800681static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
682 int test_id = child_proc.test_id;
683 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
684 if (child_proc.timed_out) {
685 // The child process marked as timed_out has not exited, and we should kill it manually.
686 kill(child_proc.pid, SIGKILL);
687 WaitForOneChild(child_proc.pid);
688 }
689
690 while (true) {
691 char buf[1024];
692 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
693 if (bytes_read > 0) {
694 buf[bytes_read] = '\0';
695 testcase.GetTest(test_id).AppendFailureMessage(buf);
696 } else if (bytes_read == 0) {
697 break; // Read end.
698 } else {
699 if (errno == EAGAIN) {
700 // No data is available. This rarely happens, only when the child process created other
701 // processes which have not exited so far. But the child process has already exited or
702 // been killed, so the test has finished, and we shouldn't wait further.
703 break;
704 }
705 perror("read child_read_fd in RunTestInSeparateProc");
706 exit(1);
707 }
708 }
709 close(child_proc.child_read_fd);
710
711 if (child_proc.timed_out) {
712 testcase.SetTestResult(test_id, TEST_TIMEOUT);
713 char buf[1024];
714 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
715 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
716 testcase.GetTest(test_id).AppendFailureMessage(buf);
717
718 } else if (WIFSIGNALED(child_proc.exit_status)) {
719 // Record signal terminated test as failed.
720 testcase.SetTestResult(test_id, TEST_FAILED);
721 char buf[1024];
722 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
723 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
724 testcase.GetTest(test_id).AppendFailureMessage(buf);
725
726 } else {
727 testcase.SetTestResult(test_id, WEXITSTATUS(child_proc.exit_status) == 0 ?
728 TEST_SUCCESS : TEST_FAILED);
729 }
730}
731
Yabin Cui294d1e22014-12-07 20:43:37 -0800732// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
733// makes deadlock to use fork in multi-thread.
734static void RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Yabin Cui657b1f92015-01-22 19:26:12 -0800735 size_t iteration_count, size_t job_count,
736 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800737 // Stop default result printer to avoid environment setup/teardown information for each test.
738 testing::UnitTest::GetInstance()->listeners().Release(
739 testing::UnitTest::GetInstance()->listeners().default_result_printer());
740 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
741
Yabin Cui1d4c7802015-02-02 19:14:05 -0800742 // Signals are blocked here as we want to handle them in HandleSignals() later.
743 sigset_t block_mask, orig_mask;
744 sigemptyset(&block_mask);
745 sigaddset(&block_mask, SIGINT);
746 sigaddset(&block_mask, SIGQUIT);
747 if (sigprocmask(SIG_BLOCK, &block_mask, &orig_mask) == -1) {
748 perror("sigprocmask SIG_BLOCK");
749 exit(1);
750 }
751
Yabin Cuibe837362015-01-02 18:45:37 -0800752 for (size_t iteration = 1; iteration <= iteration_count; ++iteration) {
753 OnTestIterationStartPrint(testcase_list, iteration, iteration_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800754 int64_t iteration_start_time_ns = NanoTime();
755 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800756
Yabin Cuibe837362015-01-02 18:45:37 -0800757 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800758 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800759
Yabin Cuibe837362015-01-02 18:45:37 -0800760 // Next test to run is [next_testcase_id:next_test_id].
761 size_t next_testcase_id = 0;
762 size_t next_test_id = 0;
763
764 // Record how many tests are finished.
765 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
766 size_t finished_testcase_count = 0;
767
768 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800769 // run up to job_count child processes.
770 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
771 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
772 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
773 orig_mask, argc, argv);
774 child_proc_list.push_back(child_proc);
775 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
776 next_test_id = 0;
777 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800778 }
779 }
780
781 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800782 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800783
784 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800785 auto it = child_proc_list.begin();
786 while (it != child_proc_list.end()) {
787 auto& child_proc = *it;
788 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800789 size_t testcase_id = child_proc.testcase_id;
790 size_t test_id = child_proc.test_id;
791 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800792
Yabin Cui1d4c7802015-02-02 19:14:05 -0800793 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800794 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800795
796 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
797 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800798 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800799
800 it = child_proc_list.erase(it);
801 } else {
802 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800803 }
804 }
805 }
806
Yabin Cui657b1f92015-01-22 19:26:12 -0800807 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
808 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
809 if (!xml_output_filename.empty()) {
810 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
811 elapsed_time_ns);
812 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800813 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800814
815 // Restore signal mask.
816 if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) == -1) {
817 perror("sigprocmask SIG_SETMASK");
818 exit(1);
819 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800820}
821
Yabin Cuibe837362015-01-02 18:45:37 -0800822static size_t GetProcessorCount() {
823 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800824}
825
Yabin Cuiead08142015-02-04 20:53:56 -0800826static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
827 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
828 // test program via a valid path that contains at least one path separator.
829 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
830 // and execve() doesn't read environment variable PATH, so execve() will not success
831 // until we specify the absolute path or relative path of the test program directly.
832 if (strchr(args[0], '/') == NULL) {
833 char path[PATH_MAX];
834 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
835 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
836 perror("readlink");
837 exit(1);
838 }
839 path[path_len] = '\0';
840 args[0] = strdup(path);
841 }
842}
843
Yabin Cui11c43532015-01-28 14:28:14 -0800844static void AddGtestFilterSynonym(std::vector<char*>& args) {
845 // Support --gtest-filter as a synonym for --gtest_filter.
846 for (size_t i = 1; i < args.size(); ++i) {
847 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
848 args[i][7] = '_';
849 }
850 }
851}
852
Yabin Cui657b1f92015-01-22 19:26:12 -0800853struct IsolationTestOptions {
854 bool isolate;
855 size_t job_count;
856 int test_deadline_ms;
857 int test_warnline_ms;
858 std::string gtest_color;
859 bool gtest_print_time;
860 size_t gtest_repeat;
861 std::string gtest_output;
862};
863
864// 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 -0800865// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -0800866// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
867// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -0800868// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -0800869// args is used to pass in all command arguments, and pass out only the part of options for gtest.
870// options is used to pass out test options in isolation mode.
871// Return false if there is error in arguments.
872static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
873 for (size_t i = 1; i < args.size(); ++i) {
874 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800875 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -0800876 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800877 return true;
878 }
879 }
880
Yabin Cuiead08142015-02-04 20:53:56 -0800881 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -0800882 AddGtestFilterSynonym(args);
883
Yabin Cui657b1f92015-01-22 19:26:12 -0800884 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
885 bool enable_selftest = false;
886 for (size_t i = 1; i < args.size(); ++i) {
887 if (strcmp(args[i], "--bionic-selftest") == 0) {
888 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
889 // Don't remove this option from arguments.
890 enable_selftest = true;
891 }
892 }
893 std::string gtest_filter_str;
894 for (size_t i = args.size() - 1; i >= 1; --i) {
895 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
896 gtest_filter_str = std::string(args[i]);
897 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800898 break;
899 }
900 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800901 if (enable_selftest == true) {
902 args.push_back(strdup("--gtest_filter=bionic_selftest*"));
903 } else {
904 if (gtest_filter_str == "") {
905 gtest_filter_str = "--gtest_filter=-bionic_selftest*";
906 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -0800907 // Find if '-' for NEGATIVE_PATTERNS exists.
908 if (gtest_filter_str.find(":-") != std::string::npos) {
909 gtest_filter_str += ":bionic_selftest*";
910 } else {
911 gtest_filter_str += ":-bionic_selftest*";
912 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800913 }
914 args.push_back(strdup(gtest_filter_str.c_str()));
915 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800916
Yabin Cui657b1f92015-01-22 19:26:12 -0800917 options.isolate = true;
918 // Parse arguments that make us can't run in isolation mode.
919 for (size_t i = 1; i < args.size(); ++i) {
920 if (strcmp(args[i], "--no-isolate") == 0) {
921 options.isolate = false;
922 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
923 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800924 }
925 }
926
Yabin Cui657b1f92015-01-22 19:26:12 -0800927 // Stop parsing if we will not run in isolation mode.
928 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800929 return true;
930 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800931
932 // Init default isolation test options.
933 options.job_count = GetProcessorCount();
934 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
935 options.test_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
936 options.gtest_color = testing::GTEST_FLAG(color);
937 options.gtest_print_time = testing::GTEST_FLAG(print_time);
938 options.gtest_repeat = testing::GTEST_FLAG(repeat);
939 options.gtest_output = testing::GTEST_FLAG(output);
940
941 // Parse arguments speficied for isolation mode.
942 for (size_t i = 1; i < args.size(); ++i) {
943 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
944 char* p = args[i] + strlen("-j");
945 int count = 0;
946 if (*p != '\0') {
947 // Argument like -j5.
948 count = atoi(p);
949 } else if (args.size() > i + 1) {
950 // Arguments like -j 5.
951 count = atoi(args[i + 1]);
952 ++i;
953 }
954 if (count <= 0) {
955 fprintf(stderr, "invalid job count: %d\n", count);
956 return false;
957 }
958 options.job_count = static_cast<size_t>(count);
959 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
960 int time_ms = atoi(args[i] + strlen("--deadline="));
961 if (time_ms <= 0) {
962 fprintf(stderr, "invalid deadline: %d\n", time_ms);
963 return false;
964 }
965 options.test_deadline_ms = time_ms;
966 } else if (strncmp(args[i], "--warnline=", strlen("--warnline=")) == 0) {
967 int time_ms = atoi(args[i] + strlen("--warnline="));
968 if (time_ms <= 0) {
969 fprintf(stderr, "invalid warnline: %d\n", time_ms);
970 return false;
971 }
972 options.test_warnline_ms = time_ms;
973 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
974 options.gtest_color = args[i] + strlen("--gtest_color=");
975 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
976 options.gtest_print_time = false;
977 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
978 int repeat = atoi(args[i] + strlen("--gtest_repeat="));
979 if (repeat < 0) {
980 fprintf(stderr, "invalid gtest_repeat count: %d\n", repeat);
981 return false;
982 }
983 options.gtest_repeat = repeat;
984 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
985 args.erase(args.begin() + i);
986 --i;
987 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
988 std::string output = args[i] + strlen("--gtest_output=");
989 // generate output xml file path according to the strategy in gtest.
990 bool success = true;
991 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
992 output = output.substr(strlen("xml:"));
993 if (output.size() == 0) {
994 success = false;
995 }
996 // Make absolute path.
997 if (success && output[0] != '/') {
998 char* cwd = getcwd(NULL, 0);
999 if (cwd != NULL) {
1000 output = std::string(cwd) + "/" + output;
1001 free(cwd);
1002 } else {
1003 success = false;
1004 }
1005 }
1006 // Add file name if output is a directory.
1007 if (success && output.back() == '/') {
1008 output += "test_details.xml";
1009 }
1010 }
1011 if (success) {
1012 options.gtest_output = output;
1013 } else {
1014 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1015 return false;
1016 }
1017
1018 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1019 args.erase(args.begin() + i);
1020 --i;
1021 }
1022 }
1023
1024 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1025 // As DeathTest will try to call execve(), this argument should always be added.
1026 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001027 return true;
1028}
1029
1030int main(int argc, char** argv) {
Yabin Cuibe837362015-01-02 18:45:37 -08001031 std::vector<char*> arg_list;
1032 for (int i = 0; i < argc; ++i) {
1033 arg_list.push_back(argv[i]);
1034 }
Yabin Cuibe837362015-01-02 18:45:37 -08001035
Yabin Cui657b1f92015-01-22 19:26:12 -08001036 IsolationTestOptions options;
1037 if (PickOptions(arg_list, options) == false) {
1038 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001039 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001040
1041 if (options.isolate == true) {
1042 // Set global variables.
1043 global_test_run_deadline_ms = options.test_deadline_ms;
1044 global_test_run_warnline_ms = options.test_warnline_ms;
1045 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1046 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1047 std::vector<TestCase> testcase_list;
1048
1049 argc = static_cast<int>(arg_list.size());
1050 arg_list.push_back(NULL);
1051 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1052 return 1;
1053 }
1054 RunTestInSeparateProc(argc, arg_list.data(), testcase_list, options.gtest_repeat,
1055 options.job_count, options.gtest_output);
1056 } else {
1057 argc = static_cast<int>(arg_list.size());
1058 arg_list.push_back(NULL);
1059 testing::InitGoogleTest(&argc, arg_list.data());
1060 return RUN_ALL_TESTS();
1061 }
1062 return 0;
Yabin Cui294d1e22014-12-07 20:43:37 -08001063}
1064
1065//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001066// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001067
Yabin Cuibe837362015-01-02 18:45:37 -08001068TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001069 ASSERT_EQ(1, 1);
1070}
1071
Yabin Cuibe837362015-01-02 18:45:37 -08001072TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001073 ASSERT_EQ(0, 1);
1074}
1075
Yabin Cuibe837362015-01-02 18:45:37 -08001076TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001077 sleep(4);
1078}
1079
Yabin Cuibe837362015-01-02 18:45:37 -08001080TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001081 while (1) {}
1082}
Yabin Cuibe837362015-01-02 18:45:37 -08001083
1084TEST(bionic_selftest, test_signal_SEGV_terminated) {
1085 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1086 *p = 3;
1087}
Yabin Cui657b1f92015-01-22 19:26:12 -08001088
1089class bionic_selftest_DeathTest : public BionicDeathTest {};
1090
1091static void deathtest_helper_success() {
1092 ASSERT_EQ(1, 1);
1093 exit(0);
1094}
1095
1096TEST_F(bionic_selftest_DeathTest, success) {
1097 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1098}
1099
1100static void deathtest_helper_fail() {
1101 ASSERT_EQ(1, 0);
1102}
1103
1104TEST_F(bionic_selftest_DeathTest, fail) {
1105 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1106}