blob: 3b9f6b9233d96e81cf0bc752ada6559d4ea8ae81 [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 Cui767fb1c2015-09-01 15:06:39 -0700578#if defined(__APPLE__)
579
580static int pipe2(int pipefd[2], int flags) {
581 int ret = pipe(pipefd);
582 if (ret != -1) {
583 ret = fcntl(pipefd[0], F_SETFL, flags);
584 }
585 if (ret != -1) {
586 ret = fcntl(pipefd[1], F_SETFL, flags);
587 }
588 return ret;
589}
590
591#endif
592
Yabin Cui1d4c7802015-02-02 19:14:05 -0800593static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700594 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800595 int pipefd[2];
596 int ret = pipe2(pipefd, O_NONBLOCK);
597 if (ret == -1) {
598 perror("pipe2 in RunTestInSeparateProc");
599 exit(1);
600 }
601 pid_t pid = fork();
602 if (pid == -1) {
603 perror("fork in RunTestInSeparateProc");
604 exit(1);
605 } else if (pid == 0) {
606 // In child process, run a single test.
607 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800608 close(STDOUT_FILENO);
609 close(STDERR_FILENO);
610 dup2(pipefd[1], STDOUT_FILENO);
611 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800612
Yabin Cui767fb1c2015-09-01 15:06:39 -0700613 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800614 exit(1);
615 }
616 ChildProcessFn(argc, argv, test_name);
617 // Unreachable.
618 }
619 // In parent process, initialize child process info.
620 close(pipefd[1]);
621 ChildProcInfo child_proc;
622 child_proc.child_read_fd = pipefd[0];
623 child_proc.pid = pid;
624 child_proc.start_time_ns = NanoTime();
625 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetDeadlineInfo(test_name) * 1000000LL;
626 child_proc.testcase_id = testcase_id;
627 child_proc.test_id = test_id;
628 child_proc.finished = false;
629 return child_proc;
630}
Yabin Cui294d1e22014-12-07 20:43:37 -0800631
Yabin Cui1d4c7802015-02-02 19:14:05 -0800632static void HandleSignals(std::vector<TestCase>& testcase_list,
633 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700634 if (sigquit_flag) {
635 sigquit_flag = false;
636 // Print current running tests.
637 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700638 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700639 if (child_proc.pid != 0) {
640 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
641 int64_t current_time_ns = NanoTime();
642 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
643 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800644 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800645 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700646 } else if (sigint_flag) {
647 sigint_flag = false;
648 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700649 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700650 if (child_proc.pid != 0) {
651 // Send SIGKILL to ensure the child process can be killed unconditionally.
652 kill(child_proc.pid, SIGKILL);
653 }
654 }
655 // SIGINT kills the parent process as well.
656 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800657 }
658}
659
660static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
661 std::vector<ChildProcInfo>& child_proc_list) {
662 for (size_t i = 0; i < child_proc_list.size(); ++i) {
663 if (child_proc_list[i].pid == exit_pid) {
664 child_proc_list[i].finished = true;
665 child_proc_list[i].timed_out = false;
666 child_proc_list[i].exit_status = exit_status;
667 child_proc_list[i].end_time_ns = NanoTime();
668 return true;
669 }
670 }
671 return false;
672}
673
674static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
675 int64_t current_time_ns = NanoTime();
676 size_t timeout_child_count = 0;
677 for (size_t i = 0; i < child_proc_list.size(); ++i) {
678 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
679 child_proc_list[i].finished = true;
680 child_proc_list[i].timed_out = true;
681 child_proc_list[i].end_time_ns = current_time_ns;
682 ++timeout_child_count;
683 }
684 }
685 return timeout_child_count;
686}
687
688static void WaitChildProcs(std::vector<TestCase>& testcase_list,
689 std::vector<ChildProcInfo>& child_proc_list) {
690 size_t finished_child_count = 0;
691 while (true) {
692 int status;
693 pid_t result;
694 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
695 if (CheckChildProcExit(result, status, child_proc_list)) {
696 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800697 }
698 }
699
700 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800701 if (errno == ECHILD) {
702 // This happens when we have no running child processes.
703 return;
704 } else {
705 perror("waitpid");
706 exit(1);
707 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800708 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800709 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800710 }
711
Yabin Cui1d4c7802015-02-02 19:14:05 -0800712 if (finished_child_count > 0) {
713 return;
714 }
715
716 HandleSignals(testcase_list, child_proc_list);
717
Yabin Cui294d1e22014-12-07 20:43:37 -0800718 // sleep 1 ms to avoid busy looping.
719 timespec sleep_time;
720 sleep_time.tv_sec = 0;
721 sleep_time.tv_nsec = 1000000;
722 nanosleep(&sleep_time, NULL);
723 }
724}
725
Yabin Cui1d4c7802015-02-02 19:14:05 -0800726static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800727 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800728 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800729
730 TestResult test_result = TEST_SUCCESS;
731 if (result != pid || WEXITSTATUS(exit_status) != 0) {
732 test_result = TEST_FAILED;
733 }
734 return test_result;
735}
736
Yabin Cui1d4c7802015-02-02 19:14:05 -0800737static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
738 int test_id = child_proc.test_id;
739 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
740 if (child_proc.timed_out) {
741 // The child process marked as timed_out has not exited, and we should kill it manually.
742 kill(child_proc.pid, SIGKILL);
743 WaitForOneChild(child_proc.pid);
744 }
745
746 while (true) {
747 char buf[1024];
748 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
749 if (bytes_read > 0) {
750 buf[bytes_read] = '\0';
Yabin Cuiea9c9332015-02-24 14:39:19 -0800751 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800752 } else if (bytes_read == 0) {
753 break; // Read end.
754 } else {
755 if (errno == EAGAIN) {
756 // No data is available. This rarely happens, only when the child process created other
757 // processes which have not exited so far. But the child process has already exited or
758 // been killed, so the test has finished, and we shouldn't wait further.
759 break;
760 }
761 perror("read child_read_fd in RunTestInSeparateProc");
762 exit(1);
763 }
764 }
765 close(child_proc.child_read_fd);
766
767 if (child_proc.timed_out) {
768 testcase.SetTestResult(test_id, TEST_TIMEOUT);
769 char buf[1024];
770 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
771 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800772 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800773
774 } else if (WIFSIGNALED(child_proc.exit_status)) {
775 // Record signal terminated test as failed.
776 testcase.SetTestResult(test_id, TEST_FAILED);
777 char buf[1024];
778 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
779 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800780 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800781
782 } else {
783 testcase.SetTestResult(test_id, WEXITSTATUS(child_proc.exit_status) == 0 ?
784 TEST_SUCCESS : TEST_FAILED);
785 }
786}
787
Yabin Cui294d1e22014-12-07 20:43:37 -0800788// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
789// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700790// Returns true if all tests run successfully, otherwise return false.
791static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700792 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800793 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800794 // Stop default result printer to avoid environment setup/teardown information for each test.
795 testing::UnitTest::GetInstance()->listeners().Release(
796 testing::UnitTest::GetInstance()->listeners().default_result_printer());
797 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
798
Yabin Cui767fb1c2015-09-01 15:06:39 -0700799 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800800 exit(1);
801 }
802
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700803 bool all_tests_passed = true;
804
Christopher Ferris119cb552015-04-02 12:02:55 -0700805 for (size_t iteration = 1;
806 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
807 ++iteration) {
Yabin Cuibe837362015-01-02 18:45:37 -0800808 OnTestIterationStartPrint(testcase_list, iteration, iteration_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800809 int64_t iteration_start_time_ns = NanoTime();
810 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800811
Yabin Cuibe837362015-01-02 18:45:37 -0800812 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800813 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800814
Yabin Cuibe837362015-01-02 18:45:37 -0800815 // Next test to run is [next_testcase_id:next_test_id].
816 size_t next_testcase_id = 0;
817 size_t next_test_id = 0;
818
819 // Record how many tests are finished.
820 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
821 size_t finished_testcase_count = 0;
822
823 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800824 // run up to job_count child processes.
825 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
826 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
827 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700828 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800829 child_proc_list.push_back(child_proc);
830 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
831 next_test_id = 0;
832 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800833 }
834 }
835
836 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800837 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800838
839 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800840 auto it = child_proc_list.begin();
841 while (it != child_proc_list.end()) {
842 auto& child_proc = *it;
843 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800844 size_t testcase_id = child_proc.testcase_id;
845 size_t test_id = child_proc.test_id;
846 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800847
Yabin Cui1d4c7802015-02-02 19:14:05 -0800848 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800849 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800850
851 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
852 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800853 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700854 if (testcase.GetTestResult(test_id) != TEST_SUCCESS) {
855 all_tests_passed = false;
856 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800857
858 it = child_proc_list.erase(it);
859 } else {
860 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800861 }
862 }
863 }
864
Yabin Cui657b1f92015-01-22 19:26:12 -0800865 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
866 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
867 if (!xml_output_filename.empty()) {
868 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
869 elapsed_time_ns);
870 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800871 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800872
Yabin Cui767fb1c2015-09-01 15:06:39 -0700873 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800874 exit(1);
875 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700876
877 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800878}
879
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700880static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800881 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800882}
883
Yabin Cuiead08142015-02-04 20:53:56 -0800884static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
885 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
886 // test program via a valid path that contains at least one path separator.
887 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
888 // and execve() doesn't read environment variable PATH, so execve() will not success
889 // until we specify the absolute path or relative path of the test program directly.
890 if (strchr(args[0], '/') == NULL) {
891 char path[PATH_MAX];
892 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
893 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
894 perror("readlink");
895 exit(1);
896 }
897 path[path_len] = '\0';
898 args[0] = strdup(path);
899 }
900}
901
Yabin Cui11c43532015-01-28 14:28:14 -0800902static void AddGtestFilterSynonym(std::vector<char*>& args) {
903 // Support --gtest-filter as a synonym for --gtest_filter.
904 for (size_t i = 1; i < args.size(); ++i) {
905 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
906 args[i][7] = '_';
907 }
908 }
909}
910
Yabin Cui657b1f92015-01-22 19:26:12 -0800911struct IsolationTestOptions {
912 bool isolate;
913 size_t job_count;
914 int test_deadline_ms;
915 int test_warnline_ms;
916 std::string gtest_color;
917 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -0700918 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -0800919 std::string gtest_output;
920};
921
922// 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 -0800923// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -0800924// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
925// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -0800926// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -0800927// args is used to pass in all command arguments, and pass out only the part of options for gtest.
928// options is used to pass out test options in isolation mode.
929// Return false if there is error in arguments.
930static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
931 for (size_t i = 1; i < args.size(); ++i) {
932 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800933 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -0800934 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800935 return true;
936 }
937 }
938
Yabin Cuiead08142015-02-04 20:53:56 -0800939 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -0800940 AddGtestFilterSynonym(args);
941
Yabin Cui657b1f92015-01-22 19:26:12 -0800942 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
943 bool enable_selftest = false;
944 for (size_t i = 1; i < args.size(); ++i) {
945 if (strcmp(args[i], "--bionic-selftest") == 0) {
946 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
947 // Don't remove this option from arguments.
948 enable_selftest = true;
949 }
950 }
951 std::string gtest_filter_str;
952 for (size_t i = args.size() - 1; i >= 1; --i) {
953 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
954 gtest_filter_str = std::string(args[i]);
955 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800956 break;
957 }
958 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800959 if (enable_selftest == true) {
960 args.push_back(strdup("--gtest_filter=bionic_selftest*"));
961 } else {
962 if (gtest_filter_str == "") {
963 gtest_filter_str = "--gtest_filter=-bionic_selftest*";
964 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -0800965 // Find if '-' for NEGATIVE_PATTERNS exists.
966 if (gtest_filter_str.find(":-") != std::string::npos) {
967 gtest_filter_str += ":bionic_selftest*";
968 } else {
969 gtest_filter_str += ":-bionic_selftest*";
970 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800971 }
972 args.push_back(strdup(gtest_filter_str.c_str()));
973 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800974
Yabin Cui657b1f92015-01-22 19:26:12 -0800975 options.isolate = true;
976 // Parse arguments that make us can't run in isolation mode.
977 for (size_t i = 1; i < args.size(); ++i) {
978 if (strcmp(args[i], "--no-isolate") == 0) {
979 options.isolate = false;
980 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
981 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800982 }
983 }
984
Yabin Cui657b1f92015-01-22 19:26:12 -0800985 // Stop parsing if we will not run in isolation mode.
986 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800987 return true;
988 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800989
990 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700991 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -0800992 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
993 options.test_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
994 options.gtest_color = testing::GTEST_FLAG(color);
995 options.gtest_print_time = testing::GTEST_FLAG(print_time);
996 options.gtest_repeat = testing::GTEST_FLAG(repeat);
997 options.gtest_output = testing::GTEST_FLAG(output);
998
999 // Parse arguments speficied for isolation mode.
1000 for (size_t i = 1; i < args.size(); ++i) {
1001 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1002 char* p = args[i] + strlen("-j");
1003 int count = 0;
1004 if (*p != '\0') {
1005 // Argument like -j5.
1006 count = atoi(p);
1007 } else if (args.size() > i + 1) {
1008 // Arguments like -j 5.
1009 count = atoi(args[i + 1]);
1010 ++i;
1011 }
1012 if (count <= 0) {
1013 fprintf(stderr, "invalid job count: %d\n", count);
1014 return false;
1015 }
1016 options.job_count = static_cast<size_t>(count);
1017 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1018 int time_ms = atoi(args[i] + strlen("--deadline="));
1019 if (time_ms <= 0) {
1020 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1021 return false;
1022 }
1023 options.test_deadline_ms = time_ms;
1024 } else if (strncmp(args[i], "--warnline=", strlen("--warnline=")) == 0) {
1025 int time_ms = atoi(args[i] + strlen("--warnline="));
1026 if (time_ms <= 0) {
1027 fprintf(stderr, "invalid warnline: %d\n", time_ms);
1028 return false;
1029 }
1030 options.test_warnline_ms = time_ms;
1031 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1032 options.gtest_color = args[i] + strlen("--gtest_color=");
1033 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1034 options.gtest_print_time = false;
1035 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001036 // If the value of gtest_repeat is < 0, then it indicates the tests
1037 // should be repeated forever.
1038 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001039 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1040 args.erase(args.begin() + i);
1041 --i;
1042 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1043 std::string output = args[i] + strlen("--gtest_output=");
1044 // generate output xml file path according to the strategy in gtest.
1045 bool success = true;
1046 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1047 output = output.substr(strlen("xml:"));
1048 if (output.size() == 0) {
1049 success = false;
1050 }
1051 // Make absolute path.
1052 if (success && output[0] != '/') {
1053 char* cwd = getcwd(NULL, 0);
1054 if (cwd != NULL) {
1055 output = std::string(cwd) + "/" + output;
1056 free(cwd);
1057 } else {
1058 success = false;
1059 }
1060 }
1061 // Add file name if output is a directory.
1062 if (success && output.back() == '/') {
1063 output += "test_details.xml";
1064 }
1065 }
1066 if (success) {
1067 options.gtest_output = output;
1068 } else {
1069 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1070 return false;
1071 }
1072
1073 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1074 args.erase(args.begin() + i);
1075 --i;
1076 }
1077 }
1078
1079 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1080 // As DeathTest will try to call execve(), this argument should always be added.
1081 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001082 return true;
1083}
1084
1085int main(int argc, char** argv) {
Yabin Cuibe837362015-01-02 18:45:37 -08001086 std::vector<char*> arg_list;
1087 for (int i = 0; i < argc; ++i) {
1088 arg_list.push_back(argv[i]);
1089 }
Yabin Cuibe837362015-01-02 18:45:37 -08001090
Yabin Cui657b1f92015-01-22 19:26:12 -08001091 IsolationTestOptions options;
1092 if (PickOptions(arg_list, options) == false) {
1093 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001094 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001095
1096 if (options.isolate == true) {
1097 // Set global variables.
1098 global_test_run_deadline_ms = options.test_deadline_ms;
1099 global_test_run_warnline_ms = options.test_warnline_ms;
1100 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1101 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1102 std::vector<TestCase> testcase_list;
1103
1104 argc = static_cast<int>(arg_list.size());
1105 arg_list.push_back(NULL);
1106 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1107 return 1;
1108 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001109 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1110 options.gtest_repeat, options.job_count, options.gtest_output);
1111 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001112 } else {
1113 argc = static_cast<int>(arg_list.size());
1114 arg_list.push_back(NULL);
1115 testing::InitGoogleTest(&argc, arg_list.data());
1116 return RUN_ALL_TESTS();
1117 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001118}
1119
1120//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001121// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001122
Yabin Cuibe837362015-01-02 18:45:37 -08001123TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001124 ASSERT_EQ(1, 1);
1125}
1126
Yabin Cuibe837362015-01-02 18:45:37 -08001127TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001128 ASSERT_EQ(0, 1);
1129}
1130
Yabin Cuibe837362015-01-02 18:45:37 -08001131TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001132 sleep(4);
1133}
1134
Yabin Cuibe837362015-01-02 18:45:37 -08001135TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001136 while (1) {}
1137}
Yabin Cuibe837362015-01-02 18:45:37 -08001138
1139TEST(bionic_selftest, test_signal_SEGV_terminated) {
1140 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1141 *p = 3;
1142}
Yabin Cui657b1f92015-01-22 19:26:12 -08001143
Yabin Cui767fb1c2015-09-01 15:06:39 -07001144class bionic_selftest_DeathTest : public ::testing::Test {
1145 protected:
1146 virtual void SetUp() {
1147 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1148 }
1149};
Yabin Cui657b1f92015-01-22 19:26:12 -08001150
1151static void deathtest_helper_success() {
1152 ASSERT_EQ(1, 1);
1153 exit(0);
1154}
1155
1156TEST_F(bionic_selftest_DeathTest, success) {
1157 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1158}
1159
1160static void deathtest_helper_fail() {
1161 ASSERT_EQ(1, 0);
1162}
1163
1164TEST_F(bionic_selftest_DeathTest, fail) {
1165 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1166}