blob: f2b7edd2af90c5da4a1a0f31e616015fe2a3e554 [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
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -070049static std::string g_executable_path;
Dimitry Ivanov55437462016-07-20 15:33:07 -070050static int g_argc;
51static char** g_argv;
52static char** g_envp;
Dimitry Ivanovd17a3772016-03-01 13:11:28 -080053
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -070054const std::string& get_executable_path() {
55 return g_executable_path;
Dimitry Ivanovd17a3772016-03-01 13:11:28 -080056}
57
Dimitry Ivanova36e59b2016-09-01 11:37:39 -070058bool get_realpath(const std::string& path, std::string* real_path) {
59 char realpath_buf[PATH_MAX];
60 if (realpath(path.c_str(), realpath_buf) != realpath_buf) {
61 return false;
62 }
63
64 *real_path = realpath_buf;
65 return true;
66}
67
Dimitry Ivanov55437462016-07-20 15:33:07 -070068int get_argc() {
69 return g_argc;
70}
71
72char** get_argv() {
73 return g_argv;
74}
75
76char** get_envp() {
77 return g_envp;
78}
79
Yabin Cui294d1e22014-12-07 20:43:37 -080080namespace testing {
81namespace internal {
82
83// Reuse of testing::internal::ColoredPrintf in gtest.
84enum GTestColor {
85 COLOR_DEFAULT,
86 COLOR_RED,
87 COLOR_GREEN,
88 COLOR_YELLOW
89};
90
91void ColoredPrintf(GTestColor color, const char* fmt, ...);
92
Yabin Cuibe837362015-01-02 18:45:37 -080093} // namespace internal
94} // namespace testing
Yabin Cui294d1e22014-12-07 20:43:37 -080095
96using testing::internal::GTestColor;
97using testing::internal::COLOR_DEFAULT;
98using testing::internal::COLOR_RED;
99using testing::internal::COLOR_GREEN;
100using testing::internal::COLOR_YELLOW;
101using testing::internal::ColoredPrintf;
102
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700103constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 90000;
Elliott Hughesa456fae2016-08-31 13:30:14 -0700104constexpr int DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -0800105
106// The time each test can run before killed for the reason of timeout.
107// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -0800108static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800109
110// The time each test can run before be warned for too much running time.
111// It takes effect only with --isolate option.
Elliott Hughesa456fae2016-08-31 13:30:14 -0700112static int global_test_run_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800113
Elliott Hughesa456fae2016-08-31 13:30:14 -0700114// Return timeout duration for a test, in ms.
115static int GetTimeoutMs(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800116 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800117}
118
Elliott Hughesa456fae2016-08-31 13:30:14 -0700119// Return threshold for calling a test slow, in ms.
120static int GetSlowThresholdMs(const std::string& /*test_name*/) {
121 return global_test_run_slow_threshold_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800122}
123
Yabin Cuibe837362015-01-02 18:45:37 -0800124static void PrintHelpInfo() {
125 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -0800126 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800127 " Run up to JOB_COUNT tests in parallel.\n"
128 " Use isolation mode, Run each test in a separate process.\n"
129 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
130 " --no-isolate\n"
131 " Don't use isolation mode, run all tests in a single process.\n"
132 " --deadline=[TIME_IN_MS]\n"
133 " Run each test in no longer than [TIME_IN_MS] time.\n"
Elliott Hughesa456fae2016-08-31 13:30:14 -0700134 " Only valid in isolation mode. Default deadline is 90000 ms.\n"
135 " --slow-threshold=[TIME_IN_MS]\n"
136 " Test running longer than [TIME_IN_MS] will be called slow.\n"
137 " Only valid in isolation mode. Default slow threshold is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -0800138 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
139 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -0800140 "Default bionic unit test option is -j.\n"
141 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
142 "running tests, or send SIGINT to the parent process to stop testing and\n"
143 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800144 "\n");
145}
146
Yabin Cui294d1e22014-12-07 20:43:37 -0800147enum TestResult {
148 TEST_SUCCESS = 0,
149 TEST_FAILED,
150 TEST_TIMEOUT
151};
152
Yabin Cui657b1f92015-01-22 19:26:12 -0800153class Test {
154 public:
155 Test() {} // For std::vector<Test>.
156 explicit Test(const char* name) : name_(name) {}
157
158 const std::string& GetName() const { return name_; }
159
160 void SetResult(TestResult result) { result_ = result; }
161
162 TestResult GetResult() const { return result_; }
163
164 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
165
166 int64_t GetTestTime() const { return elapsed_time_ns_; }
167
Yabin Cuiea9c9332015-02-24 14:39:19 -0800168 void AppendTestOutput(const std::string& s) { output_ += s; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800169
Yabin Cuiea9c9332015-02-24 14:39:19 -0800170 const std::string& GetTestOutput() const { return output_; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800171
172 private:
173 const std::string name_;
174 TestResult result_;
175 int64_t elapsed_time_ns_;
Yabin Cuiea9c9332015-02-24 14:39:19 -0800176 std::string output_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800177};
178
Yabin Cui294d1e22014-12-07 20:43:37 -0800179class TestCase {
180 public:
181 TestCase() {} // For std::vector<TestCase>.
182 explicit TestCase(const char* name) : name_(name) {}
183
184 const std::string& GetName() const { return name_; }
185
Yabin Cui657b1f92015-01-22 19:26:12 -0800186 void AppendTest(const char* test_name) {
187 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800188 }
189
Yabin Cuibe837362015-01-02 18:45:37 -0800190 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800191
Yabin Cuibe837362015-01-02 18:45:37 -0800192 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800193 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800194 return name_ + "." + test_list_[test_id].GetName();
195 }
196
197 Test& GetTest(size_t test_id) {
198 VerifyTestId(test_id);
199 return test_list_[test_id];
200 }
201
202 const Test& GetTest(size_t test_id) const {
203 VerifyTestId(test_id);
204 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800205 }
206
Yabin Cuibe837362015-01-02 18:45:37 -0800207 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800208 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800209 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800210 }
211
Yabin Cuibe837362015-01-02 18:45:37 -0800212 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800213 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800214 return test_list_[test_id].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800215 }
216
Yabin Cui657b1f92015-01-22 19:26:12 -0800217 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800218 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800219 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800220 }
221
Yabin Cuibe837362015-01-02 18:45:37 -0800222 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800223 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800224 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800225 }
226
227 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800228 void VerifyTestId(size_t test_id) const {
229 if(test_id >= test_list_.size()) {
230 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800231 exit(1);
232 }
233 }
234
235 private:
236 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800237 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800238};
239
Yabin Cui294d1e22014-12-07 20:43:37 -0800240class TestResultPrinter : public testing::EmptyTestEventListener {
241 public:
242 TestResultPrinter() : pinfo_(NULL) {}
243 virtual void OnTestStart(const testing::TestInfo& test_info) {
244 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
245 }
246 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800247
248 private:
249 const testing::TestInfo* pinfo_;
250};
251
252// Called after an assertion failure.
253void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
254 // If the test part succeeded, we don't need to do anything.
255 if (result.type() == testing::TestPartResult::kSuccess)
256 return;
257
258 // Print failure message from the assertion (e.g. expected this and got that).
Yabin Cuiea9c9332015-02-24 14:39:19 -0800259 printf("%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), result.line_number(),
260 pinfo_->test_case_name(), pinfo_->name(), result.message());
261 fflush(stdout);
Yabin Cui294d1e22014-12-07 20:43:37 -0800262}
263
Yabin Cui294d1e22014-12-07 20:43:37 -0800264static int64_t NanoTime() {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700265 std::chrono::nanoseconds duration(std::chrono::steady_clock::now().time_since_epoch());
266 return static_cast<int64_t>(duration.count());
Yabin Cui294d1e22014-12-07 20:43:37 -0800267}
268
269static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
270 std::string command;
271 for (int i = 0; i < argc; ++i) {
272 command += argv[i];
273 command += " ";
274 }
275 command += "--gtest_list_tests";
276 FILE* fp = popen(command.c_str(), "r");
277 if (fp == NULL) {
278 perror("popen");
279 return false;
280 }
281
282 char buf[200];
283 while (fgets(buf, sizeof(buf), fp) != NULL) {
284 char* p = buf;
285
286 while (*p != '\0' && isspace(*p)) {
287 ++p;
288 }
289 if (*p == '\0') continue;
290 char* start = p;
291 while (*p != '\0' && !isspace(*p)) {
292 ++p;
293 }
294 char* end = p;
295 while (*p != '\0' && isspace(*p)) {
296 ++p;
297 }
Yabin Cuibf830ad2015-08-10 12:12:39 -0700298 if (*p != '\0' && *p != '#') {
Yabin Cui294d1e22014-12-07 20:43:37 -0800299 // This is not we want, gtest must meet with some error when parsing the arguments.
300 fprintf(stderr, "argument error, check with --help\n");
301 return false;
302 }
303 *end = '\0';
304 if (*(end - 1) == '.') {
305 *(end - 1) = '\0';
306 testcase_list.push_back(TestCase(start));
307 } else {
308 testcase_list.back().AppendTest(start);
309 }
310 }
311 int result = pclose(fp);
312 return (result != -1 && WEXITSTATUS(result) == 0);
313}
314
Yabin Cui294d1e22014-12-07 20:43:37 -0800315// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
316// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
317// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800318static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
Christopher Ferris119cb552015-04-02 12:02:55 -0700319 int iteration_count) {
320 if (iteration_count != 1) {
Yabin Cuibe837362015-01-02 18:45:37 -0800321 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800322 }
323 ColoredPrintf(COLOR_GREEN, "[==========] ");
324
Yabin Cuibe837362015-01-02 18:45:37 -0800325 size_t testcase_count = testcase_list.size();
326 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800327 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800328 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800329 }
330
Yabin Cuibe837362015-01-02 18:45:37 -0800331 printf("Running %zu %s from %zu %s.\n",
332 test_count, (test_count == 1) ? "test" : "tests",
333 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800334 fflush(stdout);
335}
336
Yabin Cuif6237472015-02-26 19:03:54 -0800337// bionic cts test needs gtest output format.
338#if defined(USING_GTEST_OUTPUT_FORMAT)
339
340static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
341 ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
342 printf("%s\n", testcase.GetTestName(test_id).c_str());
343
344 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
345 printf("%s", test_output.c_str());
346
347 TestResult result = testcase.GetTestResult(test_id);
348 if (result == TEST_SUCCESS) {
349 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
350 } else {
351 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
352 }
353 printf("%s", testcase.GetTestName(test_id).c_str());
354 if (testing::GTEST_FLAG(print_time)) {
355 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
356 }
357 printf("\n");
358 fflush(stdout);
359}
360
361#else // !defined(USING_GTEST_OUTPUT_FORMAT)
362
Yabin Cui657b1f92015-01-22 19:26:12 -0800363static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
364 TestResult result = testcase.GetTestResult(test_id);
365 if (result == TEST_SUCCESS) {
366 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
367 } else if (result == TEST_FAILED) {
368 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
369 } else if (result == TEST_TIMEOUT) {
370 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
371 }
Yabin Cuibe837362015-01-02 18:45:37 -0800372
Yabin Cui657b1f92015-01-22 19:26:12 -0800373 printf("%s", testcase.GetTestName(test_id).c_str());
374 if (testing::GTEST_FLAG(print_time)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800375 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
Yabin Cui657b1f92015-01-22 19:26:12 -0800376 }
Yabin Cuif6237472015-02-26 19:03:54 -0800377 printf("\n");
Yabin Cui657b1f92015-01-22 19:26:12 -0800378
Yabin Cuiea9c9332015-02-24 14:39:19 -0800379 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
380 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800381 fflush(stdout);
382}
383
Yabin Cuif6237472015-02-26 19:03:54 -0800384#endif // !defined(USING_GTEST_OUTPUT_FORMAT)
385
Yabin Cuibe837362015-01-02 18:45:37 -0800386static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800387 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800388
389 std::vector<std::string> fail_test_name_list;
390 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
391
Elliott Hughesa456fae2016-08-31 13:30:14 -0700392 // For tests that were slow but didn't time out.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800393 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800394 size_t testcase_count = testcase_list.size();
395 size_t test_count = 0;
396 size_t success_test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800397
398 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800399 test_count += testcase.TestCount();
400 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800401 TestResult result = testcase.GetTestResult(i);
402 if (result == TEST_SUCCESS) {
Yabin Cuibe837362015-01-02 18:45:37 -0800403 ++success_test_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800404 } else if (result == TEST_FAILED) {
405 fail_test_name_list.push_back(testcase.GetTestName(i));
406 } else if (result == TEST_TIMEOUT) {
407 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i),
408 testcase.GetTestTime(i)));
409 }
410 if (result != TEST_TIMEOUT &&
Elliott Hughesa456fae2016-08-31 13:30:14 -0700411 testcase.GetTestTime(i) / 1000000 >= GetSlowThresholdMs(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800412 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
413 testcase.GetTestTime(i),
Elliott Hughesa456fae2016-08-31 13:30:14 -0700414 GetSlowThresholdMs(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800415 }
416 }
417 }
418
Yabin Cui294d1e22014-12-07 20:43:37 -0800419 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800420 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
421 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800422 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800423 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800424 }
425 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800426 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800427 printf("%zu %s.\n", success_test_count, (success_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800428
Elliott Hughesa456fae2016-08-31 13:30:14 -0700429 // Print tests that timed out.
Yabin Cuibe837362015-01-02 18:45:37 -0800430 size_t timeout_test_count = timeout_test_list.size();
431 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800432 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800433 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800434 for (const auto& timeout_pair : timeout_test_list) {
435 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800436 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
437 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800438 }
439 }
440
Elliott Hughesa456fae2016-08-31 13:30:14 -0700441 // Print tests that were slow.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800442 size_t slow_test_count = slow_test_list.size();
443 if (slow_test_count > 0) {
444 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
445 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
446 for (const auto& slow_tuple : slow_test_list) {
447 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
Elliott Hughesa456fae2016-08-31 13:30:14 -0700448 printf("%s (%" PRId64 " ms, exceeded %d ms)\n", std::get<0>(slow_tuple).c_str(),
Yabin Cui4a82ede2015-01-26 17:19:37 -0800449 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800450 }
451 }
452
Elliott Hughesa456fae2016-08-31 13:30:14 -0700453 // Print tests that failed.
454 size_t fail_test_count = fail_test_name_list.size();
Yabin Cuibe837362015-01-02 18:45:37 -0800455 if (fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700456 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
457 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
458 for (const auto& name : fail_test_name_list) {
459 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
460 printf("%s\n", name.c_str());
461 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800462 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700463
464 if (timeout_test_count > 0 || slow_test_count > 0 || fail_test_count > 0) {
465 printf("\n");
466 }
467
Yabin Cuibe837362015-01-02 18:45:37 -0800468 if (timeout_test_count > 0) {
469 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800470 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800471 if (slow_test_count > 0) {
472 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800473 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700474 if (fail_test_count > 0) {
475 printf("%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
476 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800477 fflush(stdout);
478}
479
Dan Albert09a99642016-01-13 21:48:56 -0800480std::string XmlEscape(const std::string& xml) {
481 std::string escaped;
482 escaped.reserve(xml.size());
483
484 for (auto c : xml) {
485 switch (c) {
486 case '<':
487 escaped.append("&lt;");
488 break;
489 case '>':
490 escaped.append("&gt;");
491 break;
492 case '&':
493 escaped.append("&amp;");
494 break;
495 case '\'':
496 escaped.append("&apos;");
497 break;
498 case '"':
499 escaped.append("&quot;");
500 break;
501 default:
502 escaped.append(1, c);
503 break;
504 }
505 }
506
507 return escaped;
508}
509
Yabin Cui657b1f92015-01-22 19:26:12 -0800510// Output xml file when --gtest_output is used, write this function as we can't reuse
511// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
512// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
513// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
514void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
515 const std::vector<TestCase>& testcase_list,
516 time_t epoch_iteration_start_time,
517 int64_t elapsed_time_ns) {
518 FILE* fp = fopen(xml_output_filename.c_str(), "w");
519 if (fp == NULL) {
520 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
521 exit(1);
522 }
523
524 size_t total_test_count = 0;
525 size_t total_failed_count = 0;
526 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
527 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
528 for (size_t i = 0; i < testcase_list.size(); ++i) {
529 auto& testcase = testcase_list[i];
530 total_test_count += testcase.TestCount();
531 for (size_t j = 0; j < testcase.TestCount(); ++j) {
532 if (testcase.GetTestResult(j) != TEST_SUCCESS) {
533 ++failed_count_list[i];
534 }
535 elapsed_time_list[i] += testcase.GetTestTime(j);
536 }
537 total_failed_count += failed_count_list[i];
538 }
539
540 const tm* time_struct = localtime(&epoch_iteration_start_time);
541 char timestamp[40];
542 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
543 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
544 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
545
546 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
547 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
548 total_test_count, total_failed_count);
549 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
550 for (size_t i = 0; i < testcase_list.size(); ++i) {
551 auto& testcase = testcase_list[i];
552 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
553 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
554 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
555
556 for (size_t j = 0; j < testcase.TestCount(); ++j) {
557 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
558 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
559 testcase.GetName().c_str());
560 if (testcase.GetTestResult(j) == TEST_SUCCESS) {
561 fputs(" />\n", fp);
562 } else {
563 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800564 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
Dan Albert09a99642016-01-13 21:48:56 -0800565 const std::string escaped_test_output = XmlEscape(test_output);
566 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", escaped_test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800567 fputs(" </failure>\n", fp);
568 fputs(" </testcase>\n", fp);
569 }
570 }
571
572 fputs(" </testsuite>\n", fp);
573 }
574 fputs("</testsuites>\n", fp);
575 fclose(fp);
576}
577
Yabin Cui767fb1c2015-09-01 15:06:39 -0700578static bool sigint_flag;
579static bool sigquit_flag;
580
581static void signal_handler(int sig) {
582 if (sig == SIGINT) {
583 sigint_flag = true;
584 } else if (sig == SIGQUIT) {
585 sigquit_flag = true;
586 }
587}
588
589static bool RegisterSignalHandler() {
590 sigint_flag = false;
591 sigquit_flag = false;
592 sig_t ret = signal(SIGINT, signal_handler);
593 if (ret != SIG_ERR) {
594 ret = signal(SIGQUIT, signal_handler);
595 }
596 if (ret == SIG_ERR) {
597 perror("RegisterSignalHandler");
598 return false;
599 }
600 return true;
601}
602
603static bool UnregisterSignalHandler() {
604 sig_t ret = signal(SIGINT, SIG_DFL);
605 if (ret != SIG_ERR) {
606 ret = signal(SIGQUIT, SIG_DFL);
607 }
608 if (ret == SIG_ERR) {
609 perror("UnregisterSignalHandler");
610 return false;
611 }
612 return true;
613}
614
Yabin Cui1d4c7802015-02-02 19:14:05 -0800615struct ChildProcInfo {
616 pid_t pid;
617 int64_t start_time_ns;
618 int64_t end_time_ns;
619 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
620 size_t testcase_id, test_id;
621 bool finished;
622 bool timed_out;
623 int exit_status;
624 int child_read_fd; // File descriptor to read child test failure info.
625};
626
Yabin Cui294d1e22014-12-07 20:43:37 -0800627// Forked Child process, run the single test.
628static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800629 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800630 memcpy(new_argv, argv, sizeof(char*) * argc);
631
632 char* filter_arg = new char [test_name.size() + 20];
633 strcpy(filter_arg, "--gtest_filter=");
634 strcat(filter_arg, test_name.c_str());
635 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800636 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800637
638 int new_argc = argc + 1;
639 testing::InitGoogleTest(&new_argc, new_argv);
640 int result = RUN_ALL_TESTS();
641 exit(result);
642}
643
Yabin Cui1d4c7802015-02-02 19:14:05 -0800644static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700645 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800646 int pipefd[2];
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800647 if (pipe(pipefd) == -1) {
648 perror("pipe in RunTestInSeparateProc");
649 exit(1);
650 }
651 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
652 perror("fcntl in RunTestInSeparateProc");
Yabin Cui1d4c7802015-02-02 19:14:05 -0800653 exit(1);
654 }
655 pid_t pid = fork();
656 if (pid == -1) {
657 perror("fork in RunTestInSeparateProc");
658 exit(1);
659 } else if (pid == 0) {
660 // In child process, run a single test.
661 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800662 close(STDOUT_FILENO);
663 close(STDERR_FILENO);
664 dup2(pipefd[1], STDOUT_FILENO);
665 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800666
Yabin Cui767fb1c2015-09-01 15:06:39 -0700667 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800668 exit(1);
669 }
670 ChildProcessFn(argc, argv, test_name);
671 // Unreachable.
672 }
673 // In parent process, initialize child process info.
674 close(pipefd[1]);
675 ChildProcInfo child_proc;
676 child_proc.child_read_fd = pipefd[0];
677 child_proc.pid = pid;
678 child_proc.start_time_ns = NanoTime();
Elliott Hughesa456fae2016-08-31 13:30:14 -0700679 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetTimeoutMs(test_name) * 1000000LL;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800680 child_proc.testcase_id = testcase_id;
681 child_proc.test_id = test_id;
682 child_proc.finished = false;
683 return child_proc;
684}
Yabin Cui294d1e22014-12-07 20:43:37 -0800685
Yabin Cui1d4c7802015-02-02 19:14:05 -0800686static void HandleSignals(std::vector<TestCase>& testcase_list,
687 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700688 if (sigquit_flag) {
689 sigquit_flag = false;
690 // Print current running tests.
691 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700692 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700693 if (child_proc.pid != 0) {
694 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
695 int64_t current_time_ns = NanoTime();
696 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
697 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800698 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800699 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700700 } else if (sigint_flag) {
701 sigint_flag = false;
702 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700703 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700704 if (child_proc.pid != 0) {
705 // Send SIGKILL to ensure the child process can be killed unconditionally.
706 kill(child_proc.pid, SIGKILL);
707 }
708 }
709 // SIGINT kills the parent process as well.
710 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800711 }
712}
713
714static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
715 std::vector<ChildProcInfo>& child_proc_list) {
716 for (size_t i = 0; i < child_proc_list.size(); ++i) {
717 if (child_proc_list[i].pid == exit_pid) {
718 child_proc_list[i].finished = true;
719 child_proc_list[i].timed_out = false;
720 child_proc_list[i].exit_status = exit_status;
721 child_proc_list[i].end_time_ns = NanoTime();
722 return true;
723 }
724 }
725 return false;
726}
727
728static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
729 int64_t current_time_ns = NanoTime();
730 size_t timeout_child_count = 0;
731 for (size_t i = 0; i < child_proc_list.size(); ++i) {
732 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
733 child_proc_list[i].finished = true;
734 child_proc_list[i].timed_out = true;
735 child_proc_list[i].end_time_ns = current_time_ns;
736 ++timeout_child_count;
737 }
738 }
739 return timeout_child_count;
740}
741
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800742static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
743 std::vector<ChildProcInfo>& child_proc_list) {
744 for (const auto& child_proc : child_proc_list) {
745 TestCase& testcase = testcase_list[child_proc.testcase_id];
746 int test_id = child_proc.test_id;
747 while (true) {
748 char buf[1024];
749 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
750 if (bytes_read > 0) {
751 buf[bytes_read] = '\0';
752 testcase.GetTest(test_id).AppendTestOutput(buf);
753 } else if (bytes_read == 0) {
754 break; // Read end.
755 } else {
756 if (errno == EAGAIN) {
757 break;
758 }
759 perror("failed to read child_read_fd");
760 exit(1);
761 }
762 }
763 }
764}
765
Yabin Cui1d4c7802015-02-02 19:14:05 -0800766static void WaitChildProcs(std::vector<TestCase>& testcase_list,
767 std::vector<ChildProcInfo>& child_proc_list) {
768 size_t finished_child_count = 0;
769 while (true) {
770 int status;
771 pid_t result;
772 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
773 if (CheckChildProcExit(result, status, child_proc_list)) {
774 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800775 }
776 }
777
778 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800779 if (errno == ECHILD) {
780 // This happens when we have no running child processes.
781 return;
782 } else {
783 perror("waitpid");
784 exit(1);
785 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800786 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800787 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800788 }
789
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800790 ReadChildProcOutput(testcase_list, child_proc_list);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800791 if (finished_child_count > 0) {
792 return;
793 }
794
795 HandleSignals(testcase_list, child_proc_list);
796
Yabin Cui294d1e22014-12-07 20:43:37 -0800797 // sleep 1 ms to avoid busy looping.
798 timespec sleep_time;
799 sleep_time.tv_sec = 0;
800 sleep_time.tv_nsec = 1000000;
801 nanosleep(&sleep_time, NULL);
802 }
803}
804
Yabin Cui1d4c7802015-02-02 19:14:05 -0800805static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800806 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800807 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800808
809 TestResult test_result = TEST_SUCCESS;
810 if (result != pid || WEXITSTATUS(exit_status) != 0) {
811 test_result = TEST_FAILED;
812 }
813 return test_result;
814}
815
Yabin Cui1d4c7802015-02-02 19:14:05 -0800816static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
817 int test_id = child_proc.test_id;
818 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
819 if (child_proc.timed_out) {
820 // The child process marked as timed_out has not exited, and we should kill it manually.
821 kill(child_proc.pid, SIGKILL);
822 WaitForOneChild(child_proc.pid);
823 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800824 close(child_proc.child_read_fd);
825
826 if (child_proc.timed_out) {
827 testcase.SetTestResult(test_id, TEST_TIMEOUT);
828 char buf[1024];
829 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
830 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800831 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800832
833 } else if (WIFSIGNALED(child_proc.exit_status)) {
834 // Record signal terminated test as failed.
835 testcase.SetTestResult(test_id, TEST_FAILED);
836 char buf[1024];
837 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
838 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800839 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800840
841 } else {
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800842 int exitcode = WEXITSTATUS(child_proc.exit_status);
843 testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
844 if (exitcode != 0) {
Yabin Cuia32fc862015-12-03 16:28:03 -0800845 char buf[1024];
846 snprintf(buf, sizeof(buf), "%s exited with exitcode %d.\n",
847 testcase.GetTestName(test_id).c_str(), exitcode);
848 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800849 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800850 }
851}
852
Yabin Cui294d1e22014-12-07 20:43:37 -0800853// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
854// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700855// Returns true if all tests run successfully, otherwise return false.
856static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700857 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800858 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800859 // Stop default result printer to avoid environment setup/teardown information for each test.
860 testing::UnitTest::GetInstance()->listeners().Release(
861 testing::UnitTest::GetInstance()->listeners().default_result_printer());
862 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
863
Yabin Cui767fb1c2015-09-01 15:06:39 -0700864 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800865 exit(1);
866 }
867
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700868 bool all_tests_passed = true;
869
Christopher Ferris119cb552015-04-02 12:02:55 -0700870 for (size_t iteration = 1;
871 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
872 ++iteration) {
Yabin Cuibe837362015-01-02 18:45:37 -0800873 OnTestIterationStartPrint(testcase_list, iteration, iteration_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800874 int64_t iteration_start_time_ns = NanoTime();
875 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800876
Yabin Cuibe837362015-01-02 18:45:37 -0800877 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800878 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800879
Yabin Cuibe837362015-01-02 18:45:37 -0800880 // Next test to run is [next_testcase_id:next_test_id].
881 size_t next_testcase_id = 0;
882 size_t next_test_id = 0;
883
884 // Record how many tests are finished.
885 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
886 size_t finished_testcase_count = 0;
887
888 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800889 // run up to job_count child processes.
890 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
891 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
892 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700893 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800894 child_proc_list.push_back(child_proc);
895 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
896 next_test_id = 0;
897 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800898 }
899 }
900
901 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800902 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800903
904 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800905 auto it = child_proc_list.begin();
906 while (it != child_proc_list.end()) {
907 auto& child_proc = *it;
908 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800909 size_t testcase_id = child_proc.testcase_id;
910 size_t test_id = child_proc.test_id;
911 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800912
Yabin Cui1d4c7802015-02-02 19:14:05 -0800913 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800914 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800915
916 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
917 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800918 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700919 if (testcase.GetTestResult(test_id) != TEST_SUCCESS) {
920 all_tests_passed = false;
921 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800922
923 it = child_proc_list.erase(it);
924 } else {
925 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800926 }
927 }
928 }
929
Yabin Cui657b1f92015-01-22 19:26:12 -0800930 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
931 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
932 if (!xml_output_filename.empty()) {
933 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
934 elapsed_time_ns);
935 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800936 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800937
Yabin Cui767fb1c2015-09-01 15:06:39 -0700938 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800939 exit(1);
940 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700941
942 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800943}
944
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700945static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800946 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800947}
948
Yabin Cuiead08142015-02-04 20:53:56 -0800949static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
950 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
951 // test program via a valid path that contains at least one path separator.
952 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
953 // and execve() doesn't read environment variable PATH, so execve() will not success
954 // until we specify the absolute path or relative path of the test program directly.
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -0700955 if (strchr(args[0], '/') == nullptr) {
956 args[0] = strdup(g_executable_path.c_str());
Yabin Cuiead08142015-02-04 20:53:56 -0800957 }
958}
959
Yabin Cui11c43532015-01-28 14:28:14 -0800960static void AddGtestFilterSynonym(std::vector<char*>& args) {
961 // Support --gtest-filter as a synonym for --gtest_filter.
962 for (size_t i = 1; i < args.size(); ++i) {
963 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
964 args[i][7] = '_';
965 }
966 }
967}
968
Yabin Cui657b1f92015-01-22 19:26:12 -0800969struct IsolationTestOptions {
970 bool isolate;
971 size_t job_count;
972 int test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -0700973 int test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -0800974 std::string gtest_color;
975 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -0700976 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -0800977 std::string gtest_output;
978};
979
980// 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 -0800981// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -0800982// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
983// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -0800984// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -0800985// args is used to pass in all command arguments, and pass out only the part of options for gtest.
986// options is used to pass out test options in isolation mode.
987// Return false if there is error in arguments.
988static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
989 for (size_t i = 1; i < args.size(); ++i) {
990 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800991 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -0800992 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800993 return true;
994 }
995 }
996
Yabin Cuiead08142015-02-04 20:53:56 -0800997 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -0800998 AddGtestFilterSynonym(args);
999
Yabin Cui657b1f92015-01-22 19:26:12 -08001000 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
1001 bool enable_selftest = false;
1002 for (size_t i = 1; i < args.size(); ++i) {
1003 if (strcmp(args[i], "--bionic-selftest") == 0) {
1004 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
1005 // Don't remove this option from arguments.
1006 enable_selftest = true;
1007 }
1008 }
1009 std::string gtest_filter_str;
1010 for (size_t i = args.size() - 1; i >= 1; --i) {
1011 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
1012 gtest_filter_str = std::string(args[i]);
1013 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -08001014 break;
1015 }
1016 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001017 if (enable_selftest == true) {
1018 args.push_back(strdup("--gtest_filter=bionic_selftest*"));
1019 } else {
1020 if (gtest_filter_str == "") {
1021 gtest_filter_str = "--gtest_filter=-bionic_selftest*";
1022 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001023 // Find if '-' for NEGATIVE_PATTERNS exists.
1024 if (gtest_filter_str.find(":-") != std::string::npos) {
1025 gtest_filter_str += ":bionic_selftest*";
1026 } else {
1027 gtest_filter_str += ":-bionic_selftest*";
1028 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001029 }
1030 args.push_back(strdup(gtest_filter_str.c_str()));
1031 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001032
Yabin Cui657b1f92015-01-22 19:26:12 -08001033 options.isolate = true;
1034 // Parse arguments that make us can't run in isolation mode.
1035 for (size_t i = 1; i < args.size(); ++i) {
1036 if (strcmp(args[i], "--no-isolate") == 0) {
1037 options.isolate = false;
1038 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
1039 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001040 }
1041 }
1042
Yabin Cui657b1f92015-01-22 19:26:12 -08001043 // Stop parsing if we will not run in isolation mode.
1044 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001045 return true;
1046 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001047
1048 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -07001049 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -08001050 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001051 options.test_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui657b1f92015-01-22 19:26:12 -08001052 options.gtest_color = testing::GTEST_FLAG(color);
1053 options.gtest_print_time = testing::GTEST_FLAG(print_time);
1054 options.gtest_repeat = testing::GTEST_FLAG(repeat);
1055 options.gtest_output = testing::GTEST_FLAG(output);
1056
1057 // Parse arguments speficied for isolation mode.
1058 for (size_t i = 1; i < args.size(); ++i) {
1059 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1060 char* p = args[i] + strlen("-j");
1061 int count = 0;
1062 if (*p != '\0') {
1063 // Argument like -j5.
1064 count = atoi(p);
1065 } else if (args.size() > i + 1) {
1066 // Arguments like -j 5.
1067 count = atoi(args[i + 1]);
1068 ++i;
1069 }
1070 if (count <= 0) {
1071 fprintf(stderr, "invalid job count: %d\n", count);
1072 return false;
1073 }
1074 options.job_count = static_cast<size_t>(count);
1075 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1076 int time_ms = atoi(args[i] + strlen("--deadline="));
1077 if (time_ms <= 0) {
1078 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1079 return false;
1080 }
1081 options.test_deadline_ms = time_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001082 } else if (strncmp(args[i], "--slow-threshold=", strlen("--slow-threshold=")) == 0) {
1083 int time_ms = atoi(args[i] + strlen("--slow-threshold="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001084 if (time_ms <= 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -07001085 fprintf(stderr, "invalid slow test threshold: %d\n", time_ms);
Yabin Cui657b1f92015-01-22 19:26:12 -08001086 return false;
1087 }
Elliott Hughesa456fae2016-08-31 13:30:14 -07001088 options.test_slow_threshold_ms = time_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001089 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1090 options.gtest_color = args[i] + strlen("--gtest_color=");
1091 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1092 options.gtest_print_time = false;
1093 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001094 // If the value of gtest_repeat is < 0, then it indicates the tests
1095 // should be repeated forever.
1096 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001097 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1098 args.erase(args.begin() + i);
1099 --i;
1100 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1101 std::string output = args[i] + strlen("--gtest_output=");
1102 // generate output xml file path according to the strategy in gtest.
1103 bool success = true;
1104 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1105 output = output.substr(strlen("xml:"));
1106 if (output.size() == 0) {
1107 success = false;
1108 }
1109 // Make absolute path.
1110 if (success && output[0] != '/') {
1111 char* cwd = getcwd(NULL, 0);
1112 if (cwd != NULL) {
1113 output = std::string(cwd) + "/" + output;
1114 free(cwd);
1115 } else {
1116 success = false;
1117 }
1118 }
1119 // Add file name if output is a directory.
1120 if (success && output.back() == '/') {
1121 output += "test_details.xml";
1122 }
1123 }
1124 if (success) {
1125 options.gtest_output = output;
1126 } else {
1127 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1128 return false;
1129 }
1130
1131 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1132 args.erase(args.begin() + i);
1133 --i;
1134 }
1135 }
1136
1137 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1138 // As DeathTest will try to call execve(), this argument should always be added.
1139 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001140 return true;
1141}
1142
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001143static std::string get_proc_self_exe() {
1144 char path[PATH_MAX];
1145 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
1146 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
1147 perror("readlink");
1148 exit(1);
1149 }
1150
1151 return std::string(path, path_len);
1152}
1153
Dimitry Ivanov55437462016-07-20 15:33:07 -07001154int main(int argc, char** argv, char** envp) {
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001155 g_executable_path = get_proc_self_exe();
Dimitry Ivanov55437462016-07-20 15:33:07 -07001156 g_argc = argc;
1157 g_argv = argv;
1158 g_envp = envp;
Yabin Cuibe837362015-01-02 18:45:37 -08001159 std::vector<char*> arg_list;
1160 for (int i = 0; i < argc; ++i) {
1161 arg_list.push_back(argv[i]);
1162 }
Yabin Cuibe837362015-01-02 18:45:37 -08001163
Yabin Cui657b1f92015-01-22 19:26:12 -08001164 IsolationTestOptions options;
1165 if (PickOptions(arg_list, options) == false) {
1166 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001167 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001168
1169 if (options.isolate == true) {
1170 // Set global variables.
1171 global_test_run_deadline_ms = options.test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001172 global_test_run_slow_threshold_ms = options.test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001173 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1174 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1175 std::vector<TestCase> testcase_list;
1176
1177 argc = static_cast<int>(arg_list.size());
1178 arg_list.push_back(NULL);
1179 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1180 return 1;
1181 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001182 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1183 options.gtest_repeat, options.job_count, options.gtest_output);
1184 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001185 } else {
1186 argc = static_cast<int>(arg_list.size());
1187 arg_list.push_back(NULL);
1188 testing::InitGoogleTest(&argc, arg_list.data());
1189 return RUN_ALL_TESTS();
1190 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001191}
1192
1193//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001194// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001195
Yabin Cuibe837362015-01-02 18:45:37 -08001196TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001197 ASSERT_EQ(1, 1);
1198}
1199
Yabin Cuibe837362015-01-02 18:45:37 -08001200TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001201 ASSERT_EQ(0, 1);
1202}
1203
Yabin Cuibe837362015-01-02 18:45:37 -08001204TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001205 sleep(4);
1206}
1207
Yabin Cuibe837362015-01-02 18:45:37 -08001208TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001209 while (1) {}
1210}
Yabin Cuibe837362015-01-02 18:45:37 -08001211
1212TEST(bionic_selftest, test_signal_SEGV_terminated) {
1213 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1214 *p = 3;
1215}
Yabin Cui657b1f92015-01-22 19:26:12 -08001216
Yabin Cui767fb1c2015-09-01 15:06:39 -07001217class bionic_selftest_DeathTest : public ::testing::Test {
1218 protected:
1219 virtual void SetUp() {
1220 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1221 }
1222};
Yabin Cui657b1f92015-01-22 19:26:12 -08001223
1224static void deathtest_helper_success() {
1225 ASSERT_EQ(1, 1);
1226 exit(0);
1227}
1228
1229TEST_F(bionic_selftest_DeathTest, success) {
1230 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1231}
1232
1233static void deathtest_helper_fail() {
1234 ASSERT_EQ(1, 0);
1235}
1236
1237TEST_F(bionic_selftest_DeathTest, fail) {
1238 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1239}