blob: a662c73ac41f9a036529f2eb188a534b699e1373 [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>
Yabin Cui294d1e22014-12-07 20:43:37 -080029#include <unistd.h>
30
Yabin Cui767fb1c2015-09-01 15:06:39 -070031#include <chrono>
Yabin Cui294d1e22014-12-07 20:43:37 -080032#include <string>
33#include <tuple>
34#include <utility>
35#include <vector>
36
Yabin Cui767fb1c2015-09-01 15:06:39 -070037#ifndef TEMP_FAILURE_RETRY
38
39/* Used to retry syscalls that can return EINTR. */
40#define TEMP_FAILURE_RETRY(exp) ({ \
41 __typeof__(exp) _rc; \
42 do { \
43 _rc = (exp); \
44 } while (_rc == -1 && errno == EINTR); \
45 _rc; })
46
47#endif
Yabin Cui657b1f92015-01-22 19:26:12 -080048
Yabin Cui294d1e22014-12-07 20:43:37 -080049namespace testing {
50namespace internal {
51
52// Reuse of testing::internal::ColoredPrintf in gtest.
53enum GTestColor {
54 COLOR_DEFAULT,
55 COLOR_RED,
56 COLOR_GREEN,
57 COLOR_YELLOW
58};
59
60void ColoredPrintf(GTestColor color, const char* fmt, ...);
61
Yabin Cuibe837362015-01-02 18:45:37 -080062} // namespace internal
63} // namespace testing
Yabin Cui294d1e22014-12-07 20:43:37 -080064
65using testing::internal::GTestColor;
66using testing::internal::COLOR_DEFAULT;
67using testing::internal::COLOR_RED;
68using testing::internal::COLOR_GREEN;
69using testing::internal::COLOR_YELLOW;
70using testing::internal::ColoredPrintf;
71
Christopher Ferrisdaaaed12015-09-24 18:45:53 -070072constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 90000;
Yabin Cui657b1f92015-01-22 19:26:12 -080073constexpr int DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -080074
75// The time each test can run before killed for the reason of timeout.
76// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080077static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080078
79// The time each test can run before be warned for too much running time.
80// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080081static int global_test_run_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080082
83// Return deadline duration for a test, in ms.
84static int GetDeadlineInfo(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -080085 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -080086}
87
88// Return warnline duration for a test, in ms.
89static int GetWarnlineInfo(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -080090 return global_test_run_warnline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -080091}
92
Yabin Cuibe837362015-01-02 18:45:37 -080093static void PrintHelpInfo() {
94 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -080095 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -080096 " Run up to JOB_COUNT tests in parallel.\n"
97 " Use isolation mode, Run each test in a separate process.\n"
98 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
99 " --no-isolate\n"
100 " Don't use isolation mode, run all tests in a single process.\n"
101 " --deadline=[TIME_IN_MS]\n"
102 " Run each test in no longer than [TIME_IN_MS] time.\n"
Yabin Cuibc6379d2015-10-06 16:30:14 -0700103 " It takes effect only in isolation mode. Deafult deadline is 90000 ms.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800104 " --warnline=[TIME_IN_MS]\n"
105 " Test running longer than [TIME_IN_MS] will be warned.\n"
106 " It takes effect only in isolation mode. Default warnline is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -0800107 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
108 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -0800109 "Default bionic unit test option is -j.\n"
110 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
111 "running tests, or send SIGINT to the parent process to stop testing and\n"
112 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800113 "\n");
114}
115
Yabin Cui294d1e22014-12-07 20:43:37 -0800116enum TestResult {
117 TEST_SUCCESS = 0,
118 TEST_FAILED,
119 TEST_TIMEOUT
120};
121
Yabin Cui657b1f92015-01-22 19:26:12 -0800122class Test {
123 public:
124 Test() {} // For std::vector<Test>.
125 explicit Test(const char* name) : name_(name) {}
126
127 const std::string& GetName() const { return name_; }
128
129 void SetResult(TestResult result) { result_ = result; }
130
131 TestResult GetResult() const { return result_; }
132
133 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
134
135 int64_t GetTestTime() const { return elapsed_time_ns_; }
136
Yabin Cuiea9c9332015-02-24 14:39:19 -0800137 void AppendTestOutput(const std::string& s) { output_ += s; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800138
Yabin Cuiea9c9332015-02-24 14:39:19 -0800139 const std::string& GetTestOutput() const { return output_; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800140
141 private:
142 const std::string name_;
143 TestResult result_;
144 int64_t elapsed_time_ns_;
Yabin Cuiea9c9332015-02-24 14:39:19 -0800145 std::string output_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800146};
147
Yabin Cui294d1e22014-12-07 20:43:37 -0800148class TestCase {
149 public:
150 TestCase() {} // For std::vector<TestCase>.
151 explicit TestCase(const char* name) : name_(name) {}
152
153 const std::string& GetName() const { return name_; }
154
Yabin Cui657b1f92015-01-22 19:26:12 -0800155 void AppendTest(const char* test_name) {
156 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800157 }
158
Yabin Cuibe837362015-01-02 18:45:37 -0800159 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800160
Yabin Cuibe837362015-01-02 18:45:37 -0800161 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800162 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800163 return name_ + "." + test_list_[test_id].GetName();
164 }
165
166 Test& GetTest(size_t test_id) {
167 VerifyTestId(test_id);
168 return test_list_[test_id];
169 }
170
171 const Test& GetTest(size_t test_id) const {
172 VerifyTestId(test_id);
173 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800174 }
175
Yabin Cuibe837362015-01-02 18:45:37 -0800176 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800177 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800178 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800179 }
180
Yabin Cuibe837362015-01-02 18:45:37 -0800181 TestResult GetTestResult(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].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800184 }
185
Yabin Cui657b1f92015-01-22 19:26:12 -0800186 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800187 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800188 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800189 }
190
Yabin Cuibe837362015-01-02 18:45:37 -0800191 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800192 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800193 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800194 }
195
196 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800197 void VerifyTestId(size_t test_id) const {
198 if(test_id >= test_list_.size()) {
199 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800200 exit(1);
201 }
202 }
203
204 private:
205 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800206 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800207};
208
Yabin Cui294d1e22014-12-07 20:43:37 -0800209class TestResultPrinter : public testing::EmptyTestEventListener {
210 public:
211 TestResultPrinter() : pinfo_(NULL) {}
212 virtual void OnTestStart(const testing::TestInfo& test_info) {
213 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
214 }
215 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800216
217 private:
218 const testing::TestInfo* pinfo_;
219};
220
221// Called after an assertion failure.
222void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
223 // If the test part succeeded, we don't need to do anything.
224 if (result.type() == testing::TestPartResult::kSuccess)
225 return;
226
227 // Print failure message from the assertion (e.g. expected this and got that).
Yabin Cuiea9c9332015-02-24 14:39:19 -0800228 printf("%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), result.line_number(),
229 pinfo_->test_case_name(), pinfo_->name(), result.message());
230 fflush(stdout);
Yabin Cui294d1e22014-12-07 20:43:37 -0800231}
232
Yabin Cui294d1e22014-12-07 20:43:37 -0800233static int64_t NanoTime() {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700234 std::chrono::nanoseconds duration(std::chrono::steady_clock::now().time_since_epoch());
235 return static_cast<int64_t>(duration.count());
Yabin Cui294d1e22014-12-07 20:43:37 -0800236}
237
238static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
239 std::string command;
240 for (int i = 0; i < argc; ++i) {
241 command += argv[i];
242 command += " ";
243 }
244 command += "--gtest_list_tests";
245 FILE* fp = popen(command.c_str(), "r");
246 if (fp == NULL) {
247 perror("popen");
248 return false;
249 }
250
251 char buf[200];
252 while (fgets(buf, sizeof(buf), fp) != NULL) {
253 char* p = buf;
254
255 while (*p != '\0' && isspace(*p)) {
256 ++p;
257 }
258 if (*p == '\0') continue;
259 char* start = p;
260 while (*p != '\0' && !isspace(*p)) {
261 ++p;
262 }
263 char* end = p;
264 while (*p != '\0' && isspace(*p)) {
265 ++p;
266 }
Yabin Cuibf830ad2015-08-10 12:12:39 -0700267 if (*p != '\0' && *p != '#') {
Yabin Cui294d1e22014-12-07 20:43:37 -0800268 // This is not we want, gtest must meet with some error when parsing the arguments.
269 fprintf(stderr, "argument error, check with --help\n");
270 return false;
271 }
272 *end = '\0';
273 if (*(end - 1) == '.') {
274 *(end - 1) = '\0';
275 testcase_list.push_back(TestCase(start));
276 } else {
277 testcase_list.back().AppendTest(start);
278 }
279 }
280 int result = pclose(fp);
281 return (result != -1 && WEXITSTATUS(result) == 0);
282}
283
Yabin Cui294d1e22014-12-07 20:43:37 -0800284// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
285// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
286// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800287static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
Christopher Ferris119cb552015-04-02 12:02:55 -0700288 int iteration_count) {
289 if (iteration_count != 1) {
Yabin Cuibe837362015-01-02 18:45:37 -0800290 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800291 }
292 ColoredPrintf(COLOR_GREEN, "[==========] ");
293
Yabin Cuibe837362015-01-02 18:45:37 -0800294 size_t testcase_count = testcase_list.size();
295 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800296 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800297 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800298 }
299
Yabin Cuibe837362015-01-02 18:45:37 -0800300 printf("Running %zu %s from %zu %s.\n",
301 test_count, (test_count == 1) ? "test" : "tests",
302 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800303 fflush(stdout);
304}
305
Yabin Cuif6237472015-02-26 19:03:54 -0800306// bionic cts test needs gtest output format.
307#if defined(USING_GTEST_OUTPUT_FORMAT)
308
309static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
310 ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
311 printf("%s\n", testcase.GetTestName(test_id).c_str());
312
313 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
314 printf("%s", test_output.c_str());
315
316 TestResult result = testcase.GetTestResult(test_id);
317 if (result == TEST_SUCCESS) {
318 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
319 } else {
320 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
321 }
322 printf("%s", testcase.GetTestName(test_id).c_str());
323 if (testing::GTEST_FLAG(print_time)) {
324 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
325 }
326 printf("\n");
327 fflush(stdout);
328}
329
330#else // !defined(USING_GTEST_OUTPUT_FORMAT)
331
Yabin Cui657b1f92015-01-22 19:26:12 -0800332static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
333 TestResult result = testcase.GetTestResult(test_id);
334 if (result == TEST_SUCCESS) {
335 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
336 } else if (result == TEST_FAILED) {
337 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
338 } else if (result == TEST_TIMEOUT) {
339 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
340 }
Yabin Cuibe837362015-01-02 18:45:37 -0800341
Yabin Cui657b1f92015-01-22 19:26:12 -0800342 printf("%s", testcase.GetTestName(test_id).c_str());
343 if (testing::GTEST_FLAG(print_time)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800344 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
Yabin Cui657b1f92015-01-22 19:26:12 -0800345 }
Yabin Cuif6237472015-02-26 19:03:54 -0800346 printf("\n");
Yabin Cui657b1f92015-01-22 19:26:12 -0800347
Yabin Cuiea9c9332015-02-24 14:39:19 -0800348 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
349 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800350 fflush(stdout);
351}
352
Yabin Cuif6237472015-02-26 19:03:54 -0800353#endif // !defined(USING_GTEST_OUTPUT_FORMAT)
354
Yabin Cuibe837362015-01-02 18:45:37 -0800355static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800356 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800357
358 std::vector<std::string> fail_test_name_list;
359 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
360
361 // For tests run exceed warnline but not timeout.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800362 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800363 size_t testcase_count = testcase_list.size();
364 size_t test_count = 0;
365 size_t success_test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800366
367 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800368 test_count += testcase.TestCount();
369 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800370 TestResult result = testcase.GetTestResult(i);
371 if (result == TEST_SUCCESS) {
Yabin Cuibe837362015-01-02 18:45:37 -0800372 ++success_test_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800373 } else if (result == TEST_FAILED) {
374 fail_test_name_list.push_back(testcase.GetTestName(i));
375 } else if (result == TEST_TIMEOUT) {
376 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i),
377 testcase.GetTestTime(i)));
378 }
379 if (result != TEST_TIMEOUT &&
380 testcase.GetTestTime(i) / 1000000 >= GetWarnlineInfo(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800381 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
382 testcase.GetTestTime(i),
383 GetWarnlineInfo(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800384 }
385 }
386 }
387
Yabin Cui294d1e22014-12-07 20:43:37 -0800388 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800389 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
390 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800391 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800392 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800393 }
394 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800395 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800396 printf("%zu %s.\n", success_test_count, (success_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800397
398 // Print tests failed.
Yabin Cuibe837362015-01-02 18:45:37 -0800399 size_t fail_test_count = fail_test_name_list.size();
400 if (fail_test_count > 0) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800401 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800402 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800403 for (const auto& name : fail_test_name_list) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800404 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
Yabin Cui294d1e22014-12-07 20:43:37 -0800405 printf("%s\n", name.c_str());
406 }
407 }
408
409 // Print tests run timeout.
Yabin Cuibe837362015-01-02 18:45:37 -0800410 size_t timeout_test_count = timeout_test_list.size();
411 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800412 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800413 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800414 for (const auto& timeout_pair : timeout_test_list) {
415 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800416 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
417 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800418 }
419 }
420
421 // Print tests run exceed warnline.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800422 size_t slow_test_count = slow_test_list.size();
423 if (slow_test_count > 0) {
424 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
425 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
426 for (const auto& slow_tuple : slow_test_list) {
427 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
428 printf("%s (%" PRId64 " ms, exceed warnline %d ms)\n", std::get<0>(slow_tuple).c_str(),
429 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800430 }
431 }
432
Yabin Cuibe837362015-01-02 18:45:37 -0800433 if (fail_test_count > 0) {
434 printf("\n%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800435 }
Yabin Cuibe837362015-01-02 18:45:37 -0800436 if (timeout_test_count > 0) {
437 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800438 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800439 if (slow_test_count > 0) {
440 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800441 }
442 fflush(stdout);
443}
444
Yabin Cui657b1f92015-01-22 19:26:12 -0800445// Output xml file when --gtest_output is used, write this function as we can't reuse
446// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
447// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
448// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
449void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
450 const std::vector<TestCase>& testcase_list,
451 time_t epoch_iteration_start_time,
452 int64_t elapsed_time_ns) {
453 FILE* fp = fopen(xml_output_filename.c_str(), "w");
454 if (fp == NULL) {
455 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
456 exit(1);
457 }
458
459 size_t total_test_count = 0;
460 size_t total_failed_count = 0;
461 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
462 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
463 for (size_t i = 0; i < testcase_list.size(); ++i) {
464 auto& testcase = testcase_list[i];
465 total_test_count += testcase.TestCount();
466 for (size_t j = 0; j < testcase.TestCount(); ++j) {
467 if (testcase.GetTestResult(j) != TEST_SUCCESS) {
468 ++failed_count_list[i];
469 }
470 elapsed_time_list[i] += testcase.GetTestTime(j);
471 }
472 total_failed_count += failed_count_list[i];
473 }
474
475 const tm* time_struct = localtime(&epoch_iteration_start_time);
476 char timestamp[40];
477 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
478 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
479 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
480
481 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
482 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
483 total_test_count, total_failed_count);
484 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
485 for (size_t i = 0; i < testcase_list.size(); ++i) {
486 auto& testcase = testcase_list[i];
487 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
488 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
489 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
490
491 for (size_t j = 0; j < testcase.TestCount(); ++j) {
492 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
493 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
494 testcase.GetName().c_str());
495 if (testcase.GetTestResult(j) == TEST_SUCCESS) {
496 fputs(" />\n", fp);
497 } else {
498 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800499 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
500 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800501 fputs(" </failure>\n", fp);
502 fputs(" </testcase>\n", fp);
503 }
504 }
505
506 fputs(" </testsuite>\n", fp);
507 }
508 fputs("</testsuites>\n", fp);
509 fclose(fp);
510}
511
Yabin Cui767fb1c2015-09-01 15:06:39 -0700512static bool sigint_flag;
513static bool sigquit_flag;
514
515static void signal_handler(int sig) {
516 if (sig == SIGINT) {
517 sigint_flag = true;
518 } else if (sig == SIGQUIT) {
519 sigquit_flag = true;
520 }
521}
522
523static bool RegisterSignalHandler() {
524 sigint_flag = false;
525 sigquit_flag = false;
526 sig_t ret = signal(SIGINT, signal_handler);
527 if (ret != SIG_ERR) {
528 ret = signal(SIGQUIT, signal_handler);
529 }
530 if (ret == SIG_ERR) {
531 perror("RegisterSignalHandler");
532 return false;
533 }
534 return true;
535}
536
537static bool UnregisterSignalHandler() {
538 sig_t ret = signal(SIGINT, SIG_DFL);
539 if (ret != SIG_ERR) {
540 ret = signal(SIGQUIT, SIG_DFL);
541 }
542 if (ret == SIG_ERR) {
543 perror("UnregisterSignalHandler");
544 return false;
545 }
546 return true;
547}
548
Yabin Cui1d4c7802015-02-02 19:14:05 -0800549struct ChildProcInfo {
550 pid_t pid;
551 int64_t start_time_ns;
552 int64_t end_time_ns;
553 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
554 size_t testcase_id, test_id;
555 bool finished;
556 bool timed_out;
557 int exit_status;
558 int child_read_fd; // File descriptor to read child test failure info.
559};
560
Yabin Cui294d1e22014-12-07 20:43:37 -0800561// Forked Child process, run the single test.
562static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800563 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800564 memcpy(new_argv, argv, sizeof(char*) * argc);
565
566 char* filter_arg = new char [test_name.size() + 20];
567 strcpy(filter_arg, "--gtest_filter=");
568 strcat(filter_arg, test_name.c_str());
569 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800570 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800571
572 int new_argc = argc + 1;
573 testing::InitGoogleTest(&new_argc, new_argv);
574 int result = RUN_ALL_TESTS();
575 exit(result);
576}
577
Yabin Cui1d4c7802015-02-02 19:14:05 -0800578static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700579 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800580 int pipefd[2];
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800581 if (pipe(pipefd) == -1) {
582 perror("pipe in RunTestInSeparateProc");
583 exit(1);
584 }
585 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
586 perror("fcntl in RunTestInSeparateProc");
Yabin Cui1d4c7802015-02-02 19:14:05 -0800587 exit(1);
588 }
589 pid_t pid = fork();
590 if (pid == -1) {
591 perror("fork in RunTestInSeparateProc");
592 exit(1);
593 } else if (pid == 0) {
594 // In child process, run a single test.
595 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800596 close(STDOUT_FILENO);
597 close(STDERR_FILENO);
598 dup2(pipefd[1], STDOUT_FILENO);
599 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800600
Yabin Cui767fb1c2015-09-01 15:06:39 -0700601 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800602 exit(1);
603 }
604 ChildProcessFn(argc, argv, test_name);
605 // Unreachable.
606 }
607 // In parent process, initialize child process info.
608 close(pipefd[1]);
609 ChildProcInfo child_proc;
610 child_proc.child_read_fd = pipefd[0];
611 child_proc.pid = pid;
612 child_proc.start_time_ns = NanoTime();
613 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetDeadlineInfo(test_name) * 1000000LL;
614 child_proc.testcase_id = testcase_id;
615 child_proc.test_id = test_id;
616 child_proc.finished = false;
617 return child_proc;
618}
Yabin Cui294d1e22014-12-07 20:43:37 -0800619
Yabin Cui1d4c7802015-02-02 19:14:05 -0800620static void HandleSignals(std::vector<TestCase>& testcase_list,
621 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700622 if (sigquit_flag) {
623 sigquit_flag = false;
624 // Print current running tests.
625 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700626 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700627 if (child_proc.pid != 0) {
628 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
629 int64_t current_time_ns = NanoTime();
630 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
631 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800632 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800633 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700634 } else if (sigint_flag) {
635 sigint_flag = false;
636 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700637 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700638 if (child_proc.pid != 0) {
639 // Send SIGKILL to ensure the child process can be killed unconditionally.
640 kill(child_proc.pid, SIGKILL);
641 }
642 }
643 // SIGINT kills the parent process as well.
644 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800645 }
646}
647
648static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
649 std::vector<ChildProcInfo>& child_proc_list) {
650 for (size_t i = 0; i < child_proc_list.size(); ++i) {
651 if (child_proc_list[i].pid == exit_pid) {
652 child_proc_list[i].finished = true;
653 child_proc_list[i].timed_out = false;
654 child_proc_list[i].exit_status = exit_status;
655 child_proc_list[i].end_time_ns = NanoTime();
656 return true;
657 }
658 }
659 return false;
660}
661
662static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
663 int64_t current_time_ns = NanoTime();
664 size_t timeout_child_count = 0;
665 for (size_t i = 0; i < child_proc_list.size(); ++i) {
666 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
667 child_proc_list[i].finished = true;
668 child_proc_list[i].timed_out = true;
669 child_proc_list[i].end_time_ns = current_time_ns;
670 ++timeout_child_count;
671 }
672 }
673 return timeout_child_count;
674}
675
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800676static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
677 std::vector<ChildProcInfo>& child_proc_list) {
678 for (const auto& child_proc : child_proc_list) {
679 TestCase& testcase = testcase_list[child_proc.testcase_id];
680 int test_id = child_proc.test_id;
681 while (true) {
682 char buf[1024];
683 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
684 if (bytes_read > 0) {
685 buf[bytes_read] = '\0';
686 testcase.GetTest(test_id).AppendTestOutput(buf);
687 } else if (bytes_read == 0) {
688 break; // Read end.
689 } else {
690 if (errno == EAGAIN) {
691 break;
692 }
693 perror("failed to read child_read_fd");
694 exit(1);
695 }
696 }
697 }
698}
699
Yabin Cui1d4c7802015-02-02 19:14:05 -0800700static void WaitChildProcs(std::vector<TestCase>& testcase_list,
701 std::vector<ChildProcInfo>& child_proc_list) {
702 size_t finished_child_count = 0;
703 while (true) {
704 int status;
705 pid_t result;
706 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
707 if (CheckChildProcExit(result, status, child_proc_list)) {
708 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800709 }
710 }
711
712 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800713 if (errno == ECHILD) {
714 // This happens when we have no running child processes.
715 return;
716 } else {
717 perror("waitpid");
718 exit(1);
719 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800720 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800721 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800722 }
723
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800724 ReadChildProcOutput(testcase_list, child_proc_list);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800725 if (finished_child_count > 0) {
726 return;
727 }
728
729 HandleSignals(testcase_list, child_proc_list);
730
Yabin Cui294d1e22014-12-07 20:43:37 -0800731 // sleep 1 ms to avoid busy looping.
732 timespec sleep_time;
733 sleep_time.tv_sec = 0;
734 sleep_time.tv_nsec = 1000000;
735 nanosleep(&sleep_time, NULL);
736 }
737}
738
Yabin Cui1d4c7802015-02-02 19:14:05 -0800739static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800740 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800741 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800742
743 TestResult test_result = TEST_SUCCESS;
744 if (result != pid || WEXITSTATUS(exit_status) != 0) {
745 test_result = TEST_FAILED;
746 }
747 return test_result;
748}
749
Yabin Cui1d4c7802015-02-02 19:14:05 -0800750static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
751 int test_id = child_proc.test_id;
752 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
753 if (child_proc.timed_out) {
754 // The child process marked as timed_out has not exited, and we should kill it manually.
755 kill(child_proc.pid, SIGKILL);
756 WaitForOneChild(child_proc.pid);
757 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800758 close(child_proc.child_read_fd);
759
760 if (child_proc.timed_out) {
761 testcase.SetTestResult(test_id, TEST_TIMEOUT);
762 char buf[1024];
763 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
764 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800765 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800766
767 } else if (WIFSIGNALED(child_proc.exit_status)) {
768 // Record signal terminated test as failed.
769 testcase.SetTestResult(test_id, TEST_FAILED);
770 char buf[1024];
771 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
772 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800773 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800774
775 } else {
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800776 int exitcode = WEXITSTATUS(child_proc.exit_status);
777 testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
778 if (exitcode != 0) {
Yabin Cuia32fc862015-12-03 16:28:03 -0800779 char buf[1024];
780 snprintf(buf, sizeof(buf), "%s exited with exitcode %d.\n",
781 testcase.GetTestName(test_id).c_str(), exitcode);
782 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800783 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800784 }
785}
786
Yabin Cui294d1e22014-12-07 20:43:37 -0800787// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
788// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700789// Returns true if all tests run successfully, otherwise return false.
790static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700791 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800792 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800793 // Stop default result printer to avoid environment setup/teardown information for each test.
794 testing::UnitTest::GetInstance()->listeners().Release(
795 testing::UnitTest::GetInstance()->listeners().default_result_printer());
796 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
797
Yabin Cui767fb1c2015-09-01 15:06:39 -0700798 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800799 exit(1);
800 }
801
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700802 bool all_tests_passed = true;
803
Christopher Ferris119cb552015-04-02 12:02:55 -0700804 for (size_t iteration = 1;
805 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
806 ++iteration) {
Yabin Cuibe837362015-01-02 18:45:37 -0800807 OnTestIterationStartPrint(testcase_list, iteration, iteration_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800808 int64_t iteration_start_time_ns = NanoTime();
809 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800810
Yabin Cuibe837362015-01-02 18:45:37 -0800811 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800812 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800813
Yabin Cuibe837362015-01-02 18:45:37 -0800814 // Next test to run is [next_testcase_id:next_test_id].
815 size_t next_testcase_id = 0;
816 size_t next_test_id = 0;
817
818 // Record how many tests are finished.
819 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
820 size_t finished_testcase_count = 0;
821
822 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800823 // run up to job_count child processes.
824 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
825 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
826 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700827 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800828 child_proc_list.push_back(child_proc);
829 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
830 next_test_id = 0;
831 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800832 }
833 }
834
835 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800836 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800837
838 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800839 auto it = child_proc_list.begin();
840 while (it != child_proc_list.end()) {
841 auto& child_proc = *it;
842 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800843 size_t testcase_id = child_proc.testcase_id;
844 size_t test_id = child_proc.test_id;
845 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800846
Yabin Cui1d4c7802015-02-02 19:14:05 -0800847 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800848 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800849
850 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
851 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800852 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700853 if (testcase.GetTestResult(test_id) != TEST_SUCCESS) {
854 all_tests_passed = false;
855 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800856
857 it = child_proc_list.erase(it);
858 } else {
859 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800860 }
861 }
862 }
863
Yabin Cui657b1f92015-01-22 19:26:12 -0800864 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
865 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
866 if (!xml_output_filename.empty()) {
867 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
868 elapsed_time_ns);
869 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800870 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800871
Yabin Cui767fb1c2015-09-01 15:06:39 -0700872 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800873 exit(1);
874 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700875
876 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800877}
878
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700879static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800880 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800881}
882
Yabin Cuiead08142015-02-04 20:53:56 -0800883static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
884 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
885 // test program via a valid path that contains at least one path separator.
886 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
887 // and execve() doesn't read environment variable PATH, so execve() will not success
888 // until we specify the absolute path or relative path of the test program directly.
889 if (strchr(args[0], '/') == NULL) {
890 char path[PATH_MAX];
891 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
892 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
893 perror("readlink");
894 exit(1);
895 }
896 path[path_len] = '\0';
897 args[0] = strdup(path);
898 }
899}
900
Yabin Cui11c43532015-01-28 14:28:14 -0800901static void AddGtestFilterSynonym(std::vector<char*>& args) {
902 // Support --gtest-filter as a synonym for --gtest_filter.
903 for (size_t i = 1; i < args.size(); ++i) {
904 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
905 args[i][7] = '_';
906 }
907 }
908}
909
Yabin Cui657b1f92015-01-22 19:26:12 -0800910struct IsolationTestOptions {
911 bool isolate;
912 size_t job_count;
913 int test_deadline_ms;
914 int test_warnline_ms;
915 std::string gtest_color;
916 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -0700917 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -0800918 std::string gtest_output;
919};
920
921// 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 -0800922// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -0800923// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
924// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -0800925// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -0800926// args is used to pass in all command arguments, and pass out only the part of options for gtest.
927// options is used to pass out test options in isolation mode.
928// Return false if there is error in arguments.
929static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
930 for (size_t i = 1; i < args.size(); ++i) {
931 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800932 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -0800933 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800934 return true;
935 }
936 }
937
Yabin Cuiead08142015-02-04 20:53:56 -0800938 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -0800939 AddGtestFilterSynonym(args);
940
Yabin Cui657b1f92015-01-22 19:26:12 -0800941 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
942 bool enable_selftest = false;
943 for (size_t i = 1; i < args.size(); ++i) {
944 if (strcmp(args[i], "--bionic-selftest") == 0) {
945 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
946 // Don't remove this option from arguments.
947 enable_selftest = true;
948 }
949 }
950 std::string gtest_filter_str;
951 for (size_t i = args.size() - 1; i >= 1; --i) {
952 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
953 gtest_filter_str = std::string(args[i]);
954 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800955 break;
956 }
957 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800958 if (enable_selftest == true) {
959 args.push_back(strdup("--gtest_filter=bionic_selftest*"));
960 } else {
961 if (gtest_filter_str == "") {
962 gtest_filter_str = "--gtest_filter=-bionic_selftest*";
963 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -0800964 // Find if '-' for NEGATIVE_PATTERNS exists.
965 if (gtest_filter_str.find(":-") != std::string::npos) {
966 gtest_filter_str += ":bionic_selftest*";
967 } else {
968 gtest_filter_str += ":-bionic_selftest*";
969 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800970 }
971 args.push_back(strdup(gtest_filter_str.c_str()));
972 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800973
Yabin Cui657b1f92015-01-22 19:26:12 -0800974 options.isolate = true;
975 // Parse arguments that make us can't run in isolation mode.
976 for (size_t i = 1; i < args.size(); ++i) {
977 if (strcmp(args[i], "--no-isolate") == 0) {
978 options.isolate = false;
979 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
980 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800981 }
982 }
983
Yabin Cui657b1f92015-01-22 19:26:12 -0800984 // Stop parsing if we will not run in isolation mode.
985 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800986 return true;
987 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800988
989 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700990 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -0800991 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
992 options.test_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
993 options.gtest_color = testing::GTEST_FLAG(color);
994 options.gtest_print_time = testing::GTEST_FLAG(print_time);
995 options.gtest_repeat = testing::GTEST_FLAG(repeat);
996 options.gtest_output = testing::GTEST_FLAG(output);
997
998 // Parse arguments speficied for isolation mode.
999 for (size_t i = 1; i < args.size(); ++i) {
1000 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1001 char* p = args[i] + strlen("-j");
1002 int count = 0;
1003 if (*p != '\0') {
1004 // Argument like -j5.
1005 count = atoi(p);
1006 } else if (args.size() > i + 1) {
1007 // Arguments like -j 5.
1008 count = atoi(args[i + 1]);
1009 ++i;
1010 }
1011 if (count <= 0) {
1012 fprintf(stderr, "invalid job count: %d\n", count);
1013 return false;
1014 }
1015 options.job_count = static_cast<size_t>(count);
1016 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1017 int time_ms = atoi(args[i] + strlen("--deadline="));
1018 if (time_ms <= 0) {
1019 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1020 return false;
1021 }
1022 options.test_deadline_ms = time_ms;
1023 } else if (strncmp(args[i], "--warnline=", strlen("--warnline=")) == 0) {
1024 int time_ms = atoi(args[i] + strlen("--warnline="));
1025 if (time_ms <= 0) {
1026 fprintf(stderr, "invalid warnline: %d\n", time_ms);
1027 return false;
1028 }
1029 options.test_warnline_ms = time_ms;
1030 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1031 options.gtest_color = args[i] + strlen("--gtest_color=");
1032 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1033 options.gtest_print_time = false;
1034 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001035 // If the value of gtest_repeat is < 0, then it indicates the tests
1036 // should be repeated forever.
1037 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001038 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1039 args.erase(args.begin() + i);
1040 --i;
1041 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1042 std::string output = args[i] + strlen("--gtest_output=");
1043 // generate output xml file path according to the strategy in gtest.
1044 bool success = true;
1045 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1046 output = output.substr(strlen("xml:"));
1047 if (output.size() == 0) {
1048 success = false;
1049 }
1050 // Make absolute path.
1051 if (success && output[0] != '/') {
1052 char* cwd = getcwd(NULL, 0);
1053 if (cwd != NULL) {
1054 output = std::string(cwd) + "/" + output;
1055 free(cwd);
1056 } else {
1057 success = false;
1058 }
1059 }
1060 // Add file name if output is a directory.
1061 if (success && output.back() == '/') {
1062 output += "test_details.xml";
1063 }
1064 }
1065 if (success) {
1066 options.gtest_output = output;
1067 } else {
1068 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1069 return false;
1070 }
1071
1072 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1073 args.erase(args.begin() + i);
1074 --i;
1075 }
1076 }
1077
1078 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1079 // As DeathTest will try to call execve(), this argument should always be added.
1080 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001081 return true;
1082}
1083
1084int main(int argc, char** argv) {
Yabin Cuibe837362015-01-02 18:45:37 -08001085 std::vector<char*> arg_list;
1086 for (int i = 0; i < argc; ++i) {
1087 arg_list.push_back(argv[i]);
1088 }
Yabin Cuibe837362015-01-02 18:45:37 -08001089
Yabin Cui657b1f92015-01-22 19:26:12 -08001090 IsolationTestOptions options;
1091 if (PickOptions(arg_list, options) == false) {
1092 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001093 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001094
1095 if (options.isolate == true) {
1096 // Set global variables.
1097 global_test_run_deadline_ms = options.test_deadline_ms;
1098 global_test_run_warnline_ms = options.test_warnline_ms;
1099 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1100 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1101 std::vector<TestCase> testcase_list;
1102
1103 argc = static_cast<int>(arg_list.size());
1104 arg_list.push_back(NULL);
1105 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1106 return 1;
1107 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001108 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1109 options.gtest_repeat, options.job_count, options.gtest_output);
1110 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001111 } else {
1112 argc = static_cast<int>(arg_list.size());
1113 arg_list.push_back(NULL);
1114 testing::InitGoogleTest(&argc, arg_list.data());
1115 return RUN_ALL_TESTS();
1116 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001117}
1118
1119//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001120// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001121
Yabin Cuibe837362015-01-02 18:45:37 -08001122TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001123 ASSERT_EQ(1, 1);
1124}
1125
Yabin Cuibe837362015-01-02 18:45:37 -08001126TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001127 ASSERT_EQ(0, 1);
1128}
1129
Yabin Cuibe837362015-01-02 18:45:37 -08001130TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001131 sleep(4);
1132}
1133
Yabin Cuibe837362015-01-02 18:45:37 -08001134TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001135 while (1) {}
1136}
Yabin Cuibe837362015-01-02 18:45:37 -08001137
1138TEST(bionic_selftest, test_signal_SEGV_terminated) {
1139 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1140 *p = 3;
1141}
Yabin Cui657b1f92015-01-22 19:26:12 -08001142
Yabin Cui767fb1c2015-09-01 15:06:39 -07001143class bionic_selftest_DeathTest : public ::testing::Test {
1144 protected:
1145 virtual void SetUp() {
1146 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1147 }
1148};
Yabin Cui657b1f92015-01-22 19:26:12 -08001149
1150static void deathtest_helper_success() {
1151 ASSERT_EQ(1, 1);
1152 exit(0);
1153}
1154
1155TEST_F(bionic_selftest_DeathTest, success) {
1156 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1157}
1158
1159static void deathtest_helper_fail() {
1160 ASSERT_EQ(1, 0);
1161}
1162
1163TEST_F(bionic_selftest_DeathTest, fail) {
1164 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1165}