blob: b707a4abefba53750c89684b5b0069f305b20a93 [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 Cuid4c9b9d2015-11-16 20:39:58 -080037#include <base/stringprintf.h>
38
Yabin Cui767fb1c2015-09-01 15:06:39 -070039#ifndef TEMP_FAILURE_RETRY
40
41/* Used to retry syscalls that can return EINTR. */
42#define TEMP_FAILURE_RETRY(exp) ({ \
43 __typeof__(exp) _rc; \
44 do { \
45 _rc = (exp); \
46 } while (_rc == -1 && errno == EINTR); \
47 _rc; })
48
49#endif
Yabin Cui657b1f92015-01-22 19:26:12 -080050
Yabin Cui294d1e22014-12-07 20:43:37 -080051namespace testing {
52namespace internal {
53
54// Reuse of testing::internal::ColoredPrintf in gtest.
55enum GTestColor {
56 COLOR_DEFAULT,
57 COLOR_RED,
58 COLOR_GREEN,
59 COLOR_YELLOW
60};
61
62void ColoredPrintf(GTestColor color, const char* fmt, ...);
63
Yabin Cuibe837362015-01-02 18:45:37 -080064} // namespace internal
65} // namespace testing
Yabin Cui294d1e22014-12-07 20:43:37 -080066
67using testing::internal::GTestColor;
68using testing::internal::COLOR_DEFAULT;
69using testing::internal::COLOR_RED;
70using testing::internal::COLOR_GREEN;
71using testing::internal::COLOR_YELLOW;
72using testing::internal::ColoredPrintf;
73
Christopher Ferrisdaaaed12015-09-24 18:45:53 -070074constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 90000;
Yabin Cui657b1f92015-01-22 19:26:12 -080075constexpr int DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -080076
77// The time each test can run before killed for the reason of timeout.
78// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080079static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080080
81// The time each test can run before be warned for too much running time.
82// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080083static int global_test_run_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080084
85// Return deadline duration for a test, in ms.
86static int GetDeadlineInfo(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -080087 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -080088}
89
90// Return warnline duration for a test, in ms.
91static int GetWarnlineInfo(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -080092 return global_test_run_warnline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -080093}
94
Yabin Cuibe837362015-01-02 18:45:37 -080095static void PrintHelpInfo() {
96 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -080097 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -080098 " Run up to JOB_COUNT tests in parallel.\n"
99 " Use isolation mode, Run each test in a separate process.\n"
100 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
101 " --no-isolate\n"
102 " Don't use isolation mode, run all tests in a single process.\n"
103 " --deadline=[TIME_IN_MS]\n"
104 " Run each test in no longer than [TIME_IN_MS] time.\n"
Yabin Cuibc6379d2015-10-06 16:30:14 -0700105 " It takes effect only in isolation mode. Deafult deadline is 90000 ms.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800106 " --warnline=[TIME_IN_MS]\n"
107 " Test running longer than [TIME_IN_MS] will be warned.\n"
108 " It takes effect only in isolation mode. Default warnline is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -0800109 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
110 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -0800111 "Default bionic unit test option is -j.\n"
112 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
113 "running tests, or send SIGINT to the parent process to stop testing and\n"
114 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800115 "\n");
116}
117
Yabin Cui294d1e22014-12-07 20:43:37 -0800118enum TestResult {
119 TEST_SUCCESS = 0,
120 TEST_FAILED,
121 TEST_TIMEOUT
122};
123
Yabin Cui657b1f92015-01-22 19:26:12 -0800124class Test {
125 public:
126 Test() {} // For std::vector<Test>.
127 explicit Test(const char* name) : name_(name) {}
128
129 const std::string& GetName() const { return name_; }
130
131 void SetResult(TestResult result) { result_ = result; }
132
133 TestResult GetResult() const { return result_; }
134
135 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
136
137 int64_t GetTestTime() const { return elapsed_time_ns_; }
138
Yabin Cuiea9c9332015-02-24 14:39:19 -0800139 void AppendTestOutput(const std::string& s) { output_ += s; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800140
Yabin Cuiea9c9332015-02-24 14:39:19 -0800141 const std::string& GetTestOutput() const { return output_; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800142
143 private:
144 const std::string name_;
145 TestResult result_;
146 int64_t elapsed_time_ns_;
Yabin Cuiea9c9332015-02-24 14:39:19 -0800147 std::string output_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800148};
149
Yabin Cui294d1e22014-12-07 20:43:37 -0800150class TestCase {
151 public:
152 TestCase() {} // For std::vector<TestCase>.
153 explicit TestCase(const char* name) : name_(name) {}
154
155 const std::string& GetName() const { return name_; }
156
Yabin Cui657b1f92015-01-22 19:26:12 -0800157 void AppendTest(const char* test_name) {
158 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800159 }
160
Yabin Cuibe837362015-01-02 18:45:37 -0800161 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800162
Yabin Cuibe837362015-01-02 18:45:37 -0800163 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800164 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800165 return name_ + "." + test_list_[test_id].GetName();
166 }
167
168 Test& GetTest(size_t test_id) {
169 VerifyTestId(test_id);
170 return test_list_[test_id];
171 }
172
173 const Test& GetTest(size_t test_id) const {
174 VerifyTestId(test_id);
175 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800176 }
177
Yabin Cuibe837362015-01-02 18:45:37 -0800178 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800179 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800180 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800181 }
182
Yabin Cuibe837362015-01-02 18:45:37 -0800183 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800184 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800185 return test_list_[test_id].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800186 }
187
Yabin Cui657b1f92015-01-22 19:26:12 -0800188 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800189 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800190 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800191 }
192
Yabin Cuibe837362015-01-02 18:45:37 -0800193 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800194 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800195 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800196 }
197
198 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800199 void VerifyTestId(size_t test_id) const {
200 if(test_id >= test_list_.size()) {
201 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800202 exit(1);
203 }
204 }
205
206 private:
207 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800208 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800209};
210
Yabin Cui294d1e22014-12-07 20:43:37 -0800211class TestResultPrinter : public testing::EmptyTestEventListener {
212 public:
213 TestResultPrinter() : pinfo_(NULL) {}
214 virtual void OnTestStart(const testing::TestInfo& test_info) {
215 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
216 }
217 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800218
219 private:
220 const testing::TestInfo* pinfo_;
221};
222
223// Called after an assertion failure.
224void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
225 // If the test part succeeded, we don't need to do anything.
226 if (result.type() == testing::TestPartResult::kSuccess)
227 return;
228
229 // Print failure message from the assertion (e.g. expected this and got that).
Yabin Cuiea9c9332015-02-24 14:39:19 -0800230 printf("%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), result.line_number(),
231 pinfo_->test_case_name(), pinfo_->name(), result.message());
232 fflush(stdout);
Yabin Cui294d1e22014-12-07 20:43:37 -0800233}
234
Yabin Cui294d1e22014-12-07 20:43:37 -0800235static int64_t NanoTime() {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700236 std::chrono::nanoseconds duration(std::chrono::steady_clock::now().time_since_epoch());
237 return static_cast<int64_t>(duration.count());
Yabin Cui294d1e22014-12-07 20:43:37 -0800238}
239
240static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
241 std::string command;
242 for (int i = 0; i < argc; ++i) {
243 command += argv[i];
244 command += " ";
245 }
246 command += "--gtest_list_tests";
247 FILE* fp = popen(command.c_str(), "r");
248 if (fp == NULL) {
249 perror("popen");
250 return false;
251 }
252
253 char buf[200];
254 while (fgets(buf, sizeof(buf), fp) != NULL) {
255 char* p = buf;
256
257 while (*p != '\0' && isspace(*p)) {
258 ++p;
259 }
260 if (*p == '\0') continue;
261 char* start = p;
262 while (*p != '\0' && !isspace(*p)) {
263 ++p;
264 }
265 char* end = p;
266 while (*p != '\0' && isspace(*p)) {
267 ++p;
268 }
Yabin Cuibf830ad2015-08-10 12:12:39 -0700269 if (*p != '\0' && *p != '#') {
Yabin Cui294d1e22014-12-07 20:43:37 -0800270 // This is not we want, gtest must meet with some error when parsing the arguments.
271 fprintf(stderr, "argument error, check with --help\n");
272 return false;
273 }
274 *end = '\0';
275 if (*(end - 1) == '.') {
276 *(end - 1) = '\0';
277 testcase_list.push_back(TestCase(start));
278 } else {
279 testcase_list.back().AppendTest(start);
280 }
281 }
282 int result = pclose(fp);
283 return (result != -1 && WEXITSTATUS(result) == 0);
284}
285
Yabin Cui294d1e22014-12-07 20:43:37 -0800286// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
287// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
288// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800289static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
Christopher Ferris119cb552015-04-02 12:02:55 -0700290 int iteration_count) {
291 if (iteration_count != 1) {
Yabin Cuibe837362015-01-02 18:45:37 -0800292 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800293 }
294 ColoredPrintf(COLOR_GREEN, "[==========] ");
295
Yabin Cuibe837362015-01-02 18:45:37 -0800296 size_t testcase_count = testcase_list.size();
297 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800298 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800299 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800300 }
301
Yabin Cuibe837362015-01-02 18:45:37 -0800302 printf("Running %zu %s from %zu %s.\n",
303 test_count, (test_count == 1) ? "test" : "tests",
304 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800305 fflush(stdout);
306}
307
Yabin Cuif6237472015-02-26 19:03:54 -0800308// bionic cts test needs gtest output format.
309#if defined(USING_GTEST_OUTPUT_FORMAT)
310
311static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
312 ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
313 printf("%s\n", testcase.GetTestName(test_id).c_str());
314
315 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
316 printf("%s", test_output.c_str());
317
318 TestResult result = testcase.GetTestResult(test_id);
319 if (result == TEST_SUCCESS) {
320 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
321 } else {
322 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
323 }
324 printf("%s", testcase.GetTestName(test_id).c_str());
325 if (testing::GTEST_FLAG(print_time)) {
326 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
327 }
328 printf("\n");
329 fflush(stdout);
330}
331
332#else // !defined(USING_GTEST_OUTPUT_FORMAT)
333
Yabin Cui657b1f92015-01-22 19:26:12 -0800334static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
335 TestResult result = testcase.GetTestResult(test_id);
336 if (result == TEST_SUCCESS) {
337 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
338 } else if (result == TEST_FAILED) {
339 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
340 } else if (result == TEST_TIMEOUT) {
341 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
342 }
Yabin Cuibe837362015-01-02 18:45:37 -0800343
Yabin Cui657b1f92015-01-22 19:26:12 -0800344 printf("%s", testcase.GetTestName(test_id).c_str());
345 if (testing::GTEST_FLAG(print_time)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800346 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
Yabin Cui657b1f92015-01-22 19:26:12 -0800347 }
Yabin Cuif6237472015-02-26 19:03:54 -0800348 printf("\n");
Yabin Cui657b1f92015-01-22 19:26:12 -0800349
Yabin Cuiea9c9332015-02-24 14:39:19 -0800350 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
351 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800352 fflush(stdout);
353}
354
Yabin Cuif6237472015-02-26 19:03:54 -0800355#endif // !defined(USING_GTEST_OUTPUT_FORMAT)
356
Yabin Cuibe837362015-01-02 18:45:37 -0800357static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800358 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800359
360 std::vector<std::string> fail_test_name_list;
361 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
362
363 // For tests run exceed warnline but not timeout.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800364 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800365 size_t testcase_count = testcase_list.size();
366 size_t test_count = 0;
367 size_t success_test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800368
369 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800370 test_count += testcase.TestCount();
371 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800372 TestResult result = testcase.GetTestResult(i);
373 if (result == TEST_SUCCESS) {
Yabin Cuibe837362015-01-02 18:45:37 -0800374 ++success_test_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800375 } else if (result == TEST_FAILED) {
376 fail_test_name_list.push_back(testcase.GetTestName(i));
377 } else if (result == TEST_TIMEOUT) {
378 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i),
379 testcase.GetTestTime(i)));
380 }
381 if (result != TEST_TIMEOUT &&
382 testcase.GetTestTime(i) / 1000000 >= GetWarnlineInfo(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800383 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
384 testcase.GetTestTime(i),
385 GetWarnlineInfo(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800386 }
387 }
388 }
389
Yabin Cui294d1e22014-12-07 20:43:37 -0800390 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800391 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
392 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800393 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800394 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800395 }
396 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800397 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800398 printf("%zu %s.\n", success_test_count, (success_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800399
400 // Print tests failed.
Yabin Cuibe837362015-01-02 18:45:37 -0800401 size_t fail_test_count = fail_test_name_list.size();
402 if (fail_test_count > 0) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800403 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800404 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800405 for (const auto& name : fail_test_name_list) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800406 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
Yabin Cui294d1e22014-12-07 20:43:37 -0800407 printf("%s\n", name.c_str());
408 }
409 }
410
411 // Print tests run timeout.
Yabin Cuibe837362015-01-02 18:45:37 -0800412 size_t timeout_test_count = timeout_test_list.size();
413 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800414 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800415 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800416 for (const auto& timeout_pair : timeout_test_list) {
417 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800418 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
419 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800420 }
421 }
422
423 // Print tests run exceed warnline.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800424 size_t slow_test_count = slow_test_list.size();
425 if (slow_test_count > 0) {
426 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
427 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
428 for (const auto& slow_tuple : slow_test_list) {
429 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
430 printf("%s (%" PRId64 " ms, exceed warnline %d ms)\n", std::get<0>(slow_tuple).c_str(),
431 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800432 }
433 }
434
Yabin Cuibe837362015-01-02 18:45:37 -0800435 if (fail_test_count > 0) {
436 printf("\n%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800437 }
Yabin Cuibe837362015-01-02 18:45:37 -0800438 if (timeout_test_count > 0) {
439 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800440 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800441 if (slow_test_count > 0) {
442 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800443 }
444 fflush(stdout);
445}
446
Yabin Cui657b1f92015-01-22 19:26:12 -0800447// Output xml file when --gtest_output is used, write this function as we can't reuse
448// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
449// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
450// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
451void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
452 const std::vector<TestCase>& testcase_list,
453 time_t epoch_iteration_start_time,
454 int64_t elapsed_time_ns) {
455 FILE* fp = fopen(xml_output_filename.c_str(), "w");
456 if (fp == NULL) {
457 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
458 exit(1);
459 }
460
461 size_t total_test_count = 0;
462 size_t total_failed_count = 0;
463 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
464 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
465 for (size_t i = 0; i < testcase_list.size(); ++i) {
466 auto& testcase = testcase_list[i];
467 total_test_count += testcase.TestCount();
468 for (size_t j = 0; j < testcase.TestCount(); ++j) {
469 if (testcase.GetTestResult(j) != TEST_SUCCESS) {
470 ++failed_count_list[i];
471 }
472 elapsed_time_list[i] += testcase.GetTestTime(j);
473 }
474 total_failed_count += failed_count_list[i];
475 }
476
477 const tm* time_struct = localtime(&epoch_iteration_start_time);
478 char timestamp[40];
479 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
480 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
481 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
482
483 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
484 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
485 total_test_count, total_failed_count);
486 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
487 for (size_t i = 0; i < testcase_list.size(); ++i) {
488 auto& testcase = testcase_list[i];
489 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
490 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
491 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
492
493 for (size_t j = 0; j < testcase.TestCount(); ++j) {
494 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
495 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
496 testcase.GetName().c_str());
497 if (testcase.GetTestResult(j) == TEST_SUCCESS) {
498 fputs(" />\n", fp);
499 } else {
500 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800501 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
502 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800503 fputs(" </failure>\n", fp);
504 fputs(" </testcase>\n", fp);
505 }
506 }
507
508 fputs(" </testsuite>\n", fp);
509 }
510 fputs("</testsuites>\n", fp);
511 fclose(fp);
512}
513
Yabin Cui767fb1c2015-09-01 15:06:39 -0700514static bool sigint_flag;
515static bool sigquit_flag;
516
517static void signal_handler(int sig) {
518 if (sig == SIGINT) {
519 sigint_flag = true;
520 } else if (sig == SIGQUIT) {
521 sigquit_flag = true;
522 }
523}
524
525static bool RegisterSignalHandler() {
526 sigint_flag = false;
527 sigquit_flag = false;
528 sig_t ret = signal(SIGINT, signal_handler);
529 if (ret != SIG_ERR) {
530 ret = signal(SIGQUIT, signal_handler);
531 }
532 if (ret == SIG_ERR) {
533 perror("RegisterSignalHandler");
534 return false;
535 }
536 return true;
537}
538
539static bool UnregisterSignalHandler() {
540 sig_t ret = signal(SIGINT, SIG_DFL);
541 if (ret != SIG_ERR) {
542 ret = signal(SIGQUIT, SIG_DFL);
543 }
544 if (ret == SIG_ERR) {
545 perror("UnregisterSignalHandler");
546 return false;
547 }
548 return true;
549}
550
Yabin Cui1d4c7802015-02-02 19:14:05 -0800551struct ChildProcInfo {
552 pid_t pid;
553 int64_t start_time_ns;
554 int64_t end_time_ns;
555 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
556 size_t testcase_id, test_id;
557 bool finished;
558 bool timed_out;
559 int exit_status;
560 int child_read_fd; // File descriptor to read child test failure info.
561};
562
Yabin Cui294d1e22014-12-07 20:43:37 -0800563// Forked Child process, run the single test.
564static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800565 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800566 memcpy(new_argv, argv, sizeof(char*) * argc);
567
568 char* filter_arg = new char [test_name.size() + 20];
569 strcpy(filter_arg, "--gtest_filter=");
570 strcat(filter_arg, test_name.c_str());
571 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800572 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800573
574 int new_argc = argc + 1;
575 testing::InitGoogleTest(&new_argc, new_argv);
576 int result = RUN_ALL_TESTS();
577 exit(result);
578}
579
Yabin Cui1d4c7802015-02-02 19:14:05 -0800580static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700581 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800582 int pipefd[2];
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800583 if (pipe(pipefd) == -1) {
584 perror("pipe in RunTestInSeparateProc");
585 exit(1);
586 }
587 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
588 perror("fcntl in RunTestInSeparateProc");
Yabin Cui1d4c7802015-02-02 19:14:05 -0800589 exit(1);
590 }
591 pid_t pid = fork();
592 if (pid == -1) {
593 perror("fork in RunTestInSeparateProc");
594 exit(1);
595 } else if (pid == 0) {
596 // In child process, run a single test.
597 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800598 close(STDOUT_FILENO);
599 close(STDERR_FILENO);
600 dup2(pipefd[1], STDOUT_FILENO);
601 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800602
Yabin Cui767fb1c2015-09-01 15:06:39 -0700603 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800604 exit(1);
605 }
606 ChildProcessFn(argc, argv, test_name);
607 // Unreachable.
608 }
609 // In parent process, initialize child process info.
610 close(pipefd[1]);
611 ChildProcInfo child_proc;
612 child_proc.child_read_fd = pipefd[0];
613 child_proc.pid = pid;
614 child_proc.start_time_ns = NanoTime();
615 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetDeadlineInfo(test_name) * 1000000LL;
616 child_proc.testcase_id = testcase_id;
617 child_proc.test_id = test_id;
618 child_proc.finished = false;
619 return child_proc;
620}
Yabin Cui294d1e22014-12-07 20:43:37 -0800621
Yabin Cui1d4c7802015-02-02 19:14:05 -0800622static void HandleSignals(std::vector<TestCase>& testcase_list,
623 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700624 if (sigquit_flag) {
625 sigquit_flag = false;
626 // Print current running tests.
627 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700628 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700629 if (child_proc.pid != 0) {
630 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
631 int64_t current_time_ns = NanoTime();
632 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
633 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800634 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800635 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700636 } else if (sigint_flag) {
637 sigint_flag = false;
638 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700639 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700640 if (child_proc.pid != 0) {
641 // Send SIGKILL to ensure the child process can be killed unconditionally.
642 kill(child_proc.pid, SIGKILL);
643 }
644 }
645 // SIGINT kills the parent process as well.
646 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800647 }
648}
649
650static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
651 std::vector<ChildProcInfo>& child_proc_list) {
652 for (size_t i = 0; i < child_proc_list.size(); ++i) {
653 if (child_proc_list[i].pid == exit_pid) {
654 child_proc_list[i].finished = true;
655 child_proc_list[i].timed_out = false;
656 child_proc_list[i].exit_status = exit_status;
657 child_proc_list[i].end_time_ns = NanoTime();
658 return true;
659 }
660 }
661 return false;
662}
663
664static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
665 int64_t current_time_ns = NanoTime();
666 size_t timeout_child_count = 0;
667 for (size_t i = 0; i < child_proc_list.size(); ++i) {
668 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
669 child_proc_list[i].finished = true;
670 child_proc_list[i].timed_out = true;
671 child_proc_list[i].end_time_ns = current_time_ns;
672 ++timeout_child_count;
673 }
674 }
675 return timeout_child_count;
676}
677
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800678static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
679 std::vector<ChildProcInfo>& child_proc_list) {
680 for (const auto& child_proc : child_proc_list) {
681 TestCase& testcase = testcase_list[child_proc.testcase_id];
682 int test_id = child_proc.test_id;
683 while (true) {
684 char buf[1024];
685 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
686 if (bytes_read > 0) {
687 buf[bytes_read] = '\0';
688 testcase.GetTest(test_id).AppendTestOutput(buf);
689 } else if (bytes_read == 0) {
690 break; // Read end.
691 } else {
692 if (errno == EAGAIN) {
693 break;
694 }
695 perror("failed to read child_read_fd");
696 exit(1);
697 }
698 }
699 }
700}
701
Yabin Cui1d4c7802015-02-02 19:14:05 -0800702static void WaitChildProcs(std::vector<TestCase>& testcase_list,
703 std::vector<ChildProcInfo>& child_proc_list) {
704 size_t finished_child_count = 0;
705 while (true) {
706 int status;
707 pid_t result;
708 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
709 if (CheckChildProcExit(result, status, child_proc_list)) {
710 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800711 }
712 }
713
714 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800715 if (errno == ECHILD) {
716 // This happens when we have no running child processes.
717 return;
718 } else {
719 perror("waitpid");
720 exit(1);
721 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800722 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800723 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800724 }
725
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800726 ReadChildProcOutput(testcase_list, child_proc_list);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800727 if (finished_child_count > 0) {
728 return;
729 }
730
731 HandleSignals(testcase_list, child_proc_list);
732
Yabin Cui294d1e22014-12-07 20:43:37 -0800733 // sleep 1 ms to avoid busy looping.
734 timespec sleep_time;
735 sleep_time.tv_sec = 0;
736 sleep_time.tv_nsec = 1000000;
737 nanosleep(&sleep_time, NULL);
738 }
739}
740
Yabin Cui1d4c7802015-02-02 19:14:05 -0800741static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800742 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800743 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800744
745 TestResult test_result = TEST_SUCCESS;
746 if (result != pid || WEXITSTATUS(exit_status) != 0) {
747 test_result = TEST_FAILED;
748 }
749 return test_result;
750}
751
Yabin Cui1d4c7802015-02-02 19:14:05 -0800752static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
753 int test_id = child_proc.test_id;
754 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
755 if (child_proc.timed_out) {
756 // The child process marked as timed_out has not exited, and we should kill it manually.
757 kill(child_proc.pid, SIGKILL);
758 WaitForOneChild(child_proc.pid);
759 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800760 close(child_proc.child_read_fd);
761
762 if (child_proc.timed_out) {
763 testcase.SetTestResult(test_id, TEST_TIMEOUT);
764 char buf[1024];
765 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
766 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800767 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800768
769 } else if (WIFSIGNALED(child_proc.exit_status)) {
770 // Record signal terminated test as failed.
771 testcase.SetTestResult(test_id, TEST_FAILED);
772 char buf[1024];
773 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
774 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800775 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800776
777 } else {
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800778 int exitcode = WEXITSTATUS(child_proc.exit_status);
779 testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
780 if (exitcode != 0) {
781 std::string s = android::base::StringPrintf("%s exited with exitcode %d.\n",
782 testcase.GetTestName(test_id).c_str(),
783 exitcode);
784 testcase.GetTest(test_id).AppendTestOutput(s);
785 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800786 }
787}
788
Yabin Cui294d1e22014-12-07 20:43:37 -0800789// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
790// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700791// Returns true if all tests run successfully, otherwise return false.
792static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700793 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800794 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800795 // Stop default result printer to avoid environment setup/teardown information for each test.
796 testing::UnitTest::GetInstance()->listeners().Release(
797 testing::UnitTest::GetInstance()->listeners().default_result_printer());
798 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
799
Yabin Cui767fb1c2015-09-01 15:06:39 -0700800 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800801 exit(1);
802 }
803
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700804 bool all_tests_passed = true;
805
Christopher Ferris119cb552015-04-02 12:02:55 -0700806 for (size_t iteration = 1;
807 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
808 ++iteration) {
Yabin Cuibe837362015-01-02 18:45:37 -0800809 OnTestIterationStartPrint(testcase_list, iteration, iteration_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800810 int64_t iteration_start_time_ns = NanoTime();
811 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800812
Yabin Cuibe837362015-01-02 18:45:37 -0800813 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800814 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800815
Yabin Cuibe837362015-01-02 18:45:37 -0800816 // Next test to run is [next_testcase_id:next_test_id].
817 size_t next_testcase_id = 0;
818 size_t next_test_id = 0;
819
820 // Record how many tests are finished.
821 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
822 size_t finished_testcase_count = 0;
823
824 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800825 // run up to job_count child processes.
826 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
827 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
828 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700829 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800830 child_proc_list.push_back(child_proc);
831 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
832 next_test_id = 0;
833 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800834 }
835 }
836
837 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800838 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800839
840 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800841 auto it = child_proc_list.begin();
842 while (it != child_proc_list.end()) {
843 auto& child_proc = *it;
844 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800845 size_t testcase_id = child_proc.testcase_id;
846 size_t test_id = child_proc.test_id;
847 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800848
Yabin Cui1d4c7802015-02-02 19:14:05 -0800849 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800850 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800851
852 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
853 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800854 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700855 if (testcase.GetTestResult(test_id) != TEST_SUCCESS) {
856 all_tests_passed = false;
857 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800858
859 it = child_proc_list.erase(it);
860 } else {
861 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800862 }
863 }
864 }
865
Yabin Cui657b1f92015-01-22 19:26:12 -0800866 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
867 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
868 if (!xml_output_filename.empty()) {
869 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
870 elapsed_time_ns);
871 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800872 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800873
Yabin Cui767fb1c2015-09-01 15:06:39 -0700874 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800875 exit(1);
876 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700877
878 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800879}
880
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700881static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800882 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800883}
884
Yabin Cuiead08142015-02-04 20:53:56 -0800885static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
886 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
887 // test program via a valid path that contains at least one path separator.
888 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
889 // and execve() doesn't read environment variable PATH, so execve() will not success
890 // until we specify the absolute path or relative path of the test program directly.
891 if (strchr(args[0], '/') == NULL) {
892 char path[PATH_MAX];
893 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
894 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
895 perror("readlink");
896 exit(1);
897 }
898 path[path_len] = '\0';
899 args[0] = strdup(path);
900 }
901}
902
Yabin Cui11c43532015-01-28 14:28:14 -0800903static void AddGtestFilterSynonym(std::vector<char*>& args) {
904 // Support --gtest-filter as a synonym for --gtest_filter.
905 for (size_t i = 1; i < args.size(); ++i) {
906 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
907 args[i][7] = '_';
908 }
909 }
910}
911
Yabin Cui657b1f92015-01-22 19:26:12 -0800912struct IsolationTestOptions {
913 bool isolate;
914 size_t job_count;
915 int test_deadline_ms;
916 int test_warnline_ms;
917 std::string gtest_color;
918 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -0700919 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -0800920 std::string gtest_output;
921};
922
923// 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 -0800924// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -0800925// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
926// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -0800927// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -0800928// args is used to pass in all command arguments, and pass out only the part of options for gtest.
929// options is used to pass out test options in isolation mode.
930// Return false if there is error in arguments.
931static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
932 for (size_t i = 1; i < args.size(); ++i) {
933 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800934 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -0800935 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800936 return true;
937 }
938 }
939
Yabin Cuiead08142015-02-04 20:53:56 -0800940 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -0800941 AddGtestFilterSynonym(args);
942
Yabin Cui657b1f92015-01-22 19:26:12 -0800943 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
944 bool enable_selftest = false;
945 for (size_t i = 1; i < args.size(); ++i) {
946 if (strcmp(args[i], "--bionic-selftest") == 0) {
947 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
948 // Don't remove this option from arguments.
949 enable_selftest = true;
950 }
951 }
952 std::string gtest_filter_str;
953 for (size_t i = args.size() - 1; i >= 1; --i) {
954 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
955 gtest_filter_str = std::string(args[i]);
956 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800957 break;
958 }
959 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800960 if (enable_selftest == true) {
961 args.push_back(strdup("--gtest_filter=bionic_selftest*"));
962 } else {
963 if (gtest_filter_str == "") {
964 gtest_filter_str = "--gtest_filter=-bionic_selftest*";
965 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -0800966 // Find if '-' for NEGATIVE_PATTERNS exists.
967 if (gtest_filter_str.find(":-") != std::string::npos) {
968 gtest_filter_str += ":bionic_selftest*";
969 } else {
970 gtest_filter_str += ":-bionic_selftest*";
971 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800972 }
973 args.push_back(strdup(gtest_filter_str.c_str()));
974 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800975
Yabin Cui657b1f92015-01-22 19:26:12 -0800976 options.isolate = true;
977 // Parse arguments that make us can't run in isolation mode.
978 for (size_t i = 1; i < args.size(); ++i) {
979 if (strcmp(args[i], "--no-isolate") == 0) {
980 options.isolate = false;
981 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
982 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800983 }
984 }
985
Yabin Cui657b1f92015-01-22 19:26:12 -0800986 // Stop parsing if we will not run in isolation mode.
987 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800988 return true;
989 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800990
991 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700992 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -0800993 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
994 options.test_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
995 options.gtest_color = testing::GTEST_FLAG(color);
996 options.gtest_print_time = testing::GTEST_FLAG(print_time);
997 options.gtest_repeat = testing::GTEST_FLAG(repeat);
998 options.gtest_output = testing::GTEST_FLAG(output);
999
1000 // Parse arguments speficied for isolation mode.
1001 for (size_t i = 1; i < args.size(); ++i) {
1002 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1003 char* p = args[i] + strlen("-j");
1004 int count = 0;
1005 if (*p != '\0') {
1006 // Argument like -j5.
1007 count = atoi(p);
1008 } else if (args.size() > i + 1) {
1009 // Arguments like -j 5.
1010 count = atoi(args[i + 1]);
1011 ++i;
1012 }
1013 if (count <= 0) {
1014 fprintf(stderr, "invalid job count: %d\n", count);
1015 return false;
1016 }
1017 options.job_count = static_cast<size_t>(count);
1018 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1019 int time_ms = atoi(args[i] + strlen("--deadline="));
1020 if (time_ms <= 0) {
1021 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1022 return false;
1023 }
1024 options.test_deadline_ms = time_ms;
1025 } else if (strncmp(args[i], "--warnline=", strlen("--warnline=")) == 0) {
1026 int time_ms = atoi(args[i] + strlen("--warnline="));
1027 if (time_ms <= 0) {
1028 fprintf(stderr, "invalid warnline: %d\n", time_ms);
1029 return false;
1030 }
1031 options.test_warnline_ms = time_ms;
1032 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1033 options.gtest_color = args[i] + strlen("--gtest_color=");
1034 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1035 options.gtest_print_time = false;
1036 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001037 // If the value of gtest_repeat is < 0, then it indicates the tests
1038 // should be repeated forever.
1039 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001040 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1041 args.erase(args.begin() + i);
1042 --i;
1043 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1044 std::string output = args[i] + strlen("--gtest_output=");
1045 // generate output xml file path according to the strategy in gtest.
1046 bool success = true;
1047 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1048 output = output.substr(strlen("xml:"));
1049 if (output.size() == 0) {
1050 success = false;
1051 }
1052 // Make absolute path.
1053 if (success && output[0] != '/') {
1054 char* cwd = getcwd(NULL, 0);
1055 if (cwd != NULL) {
1056 output = std::string(cwd) + "/" + output;
1057 free(cwd);
1058 } else {
1059 success = false;
1060 }
1061 }
1062 // Add file name if output is a directory.
1063 if (success && output.back() == '/') {
1064 output += "test_details.xml";
1065 }
1066 }
1067 if (success) {
1068 options.gtest_output = output;
1069 } else {
1070 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1071 return false;
1072 }
1073
1074 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1075 args.erase(args.begin() + i);
1076 --i;
1077 }
1078 }
1079
1080 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1081 // As DeathTest will try to call execve(), this argument should always be added.
1082 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001083 return true;
1084}
1085
1086int main(int argc, char** argv) {
Yabin Cuibe837362015-01-02 18:45:37 -08001087 std::vector<char*> arg_list;
1088 for (int i = 0; i < argc; ++i) {
1089 arg_list.push_back(argv[i]);
1090 }
Yabin Cuibe837362015-01-02 18:45:37 -08001091
Yabin Cui657b1f92015-01-22 19:26:12 -08001092 IsolationTestOptions options;
1093 if (PickOptions(arg_list, options) == false) {
1094 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001095 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001096
1097 if (options.isolate == true) {
1098 // Set global variables.
1099 global_test_run_deadline_ms = options.test_deadline_ms;
1100 global_test_run_warnline_ms = options.test_warnline_ms;
1101 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1102 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1103 std::vector<TestCase> testcase_list;
1104
1105 argc = static_cast<int>(arg_list.size());
1106 arg_list.push_back(NULL);
1107 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1108 return 1;
1109 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001110 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1111 options.gtest_repeat, options.job_count, options.gtest_output);
1112 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001113 } else {
1114 argc = static_cast<int>(arg_list.size());
1115 arg_list.push_back(NULL);
1116 testing::InitGoogleTest(&argc, arg_list.data());
1117 return RUN_ALL_TESTS();
1118 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001119}
1120
1121//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001122// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001123
Yabin Cuibe837362015-01-02 18:45:37 -08001124TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001125 ASSERT_EQ(1, 1);
1126}
1127
Yabin Cuibe837362015-01-02 18:45:37 -08001128TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001129 ASSERT_EQ(0, 1);
1130}
1131
Yabin Cuibe837362015-01-02 18:45:37 -08001132TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001133 sleep(4);
1134}
1135
Yabin Cuibe837362015-01-02 18:45:37 -08001136TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001137 while (1) {}
1138}
Yabin Cuibe837362015-01-02 18:45:37 -08001139
1140TEST(bionic_selftest, test_signal_SEGV_terminated) {
1141 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1142 *p = 3;
1143}
Yabin Cui657b1f92015-01-22 19:26:12 -08001144
Yabin Cui767fb1c2015-09-01 15:06:39 -07001145class bionic_selftest_DeathTest : public ::testing::Test {
1146 protected:
1147 virtual void SetUp() {
1148 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1149 }
1150};
Yabin Cui657b1f92015-01-22 19:26:12 -08001151
1152static void deathtest_helper_success() {
1153 ASSERT_EQ(1, 1);
1154 exit(0);
1155}
1156
1157TEST_F(bionic_selftest_DeathTest, success) {
1158 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1159}
1160
1161static void deathtest_helper_fail() {
1162 ASSERT_EQ(1, 0);
1163}
1164
1165TEST_F(bionic_selftest_DeathTest, fail) {
1166 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1167}