blob: aacf9ae84a74df51a4c8a06b82add10d505052be [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,
Elliott Hughes48de71e2016-10-28 10:04:44 -0700319 int iteration_count, size_t job_count) {
Christopher Ferris119cb552015-04-02 12:02:55 -0700320 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
Elliott Hughes48de71e2016-10-28 10:04:44 -0700331 printf("Running %zu %s from %zu %s (%zu %s).\n",
Yabin Cuibe837362015-01-02 18:45:37 -0800332 test_count, (test_count == 1) ? "test" : "tests",
Elliott Hughes48de71e2016-10-28 10:04:44 -0700333 testcase_count, (testcase_count == 1) ? "test case" : "test cases",
334 job_count, (job_count == 1) ? "job" : "jobs");
Yabin Cui294d1e22014-12-07 20:43:37 -0800335 fflush(stdout);
336}
337
Yabin Cuif6237472015-02-26 19:03:54 -0800338// bionic cts test needs gtest output format.
339#if defined(USING_GTEST_OUTPUT_FORMAT)
340
341static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
342 ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
343 printf("%s\n", testcase.GetTestName(test_id).c_str());
344
345 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
346 printf("%s", test_output.c_str());
347
348 TestResult result = testcase.GetTestResult(test_id);
349 if (result == TEST_SUCCESS) {
350 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
351 } else {
352 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
353 }
354 printf("%s", testcase.GetTestName(test_id).c_str());
355 if (testing::GTEST_FLAG(print_time)) {
356 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
357 }
358 printf("\n");
359 fflush(stdout);
360}
361
362#else // !defined(USING_GTEST_OUTPUT_FORMAT)
363
Yabin Cui657b1f92015-01-22 19:26:12 -0800364static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
365 TestResult result = testcase.GetTestResult(test_id);
366 if (result == TEST_SUCCESS) {
367 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
368 } else if (result == TEST_FAILED) {
369 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
370 } else if (result == TEST_TIMEOUT) {
371 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
372 }
Yabin Cuibe837362015-01-02 18:45:37 -0800373
Yabin Cui657b1f92015-01-22 19:26:12 -0800374 printf("%s", testcase.GetTestName(test_id).c_str());
375 if (testing::GTEST_FLAG(print_time)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800376 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
Yabin Cui657b1f92015-01-22 19:26:12 -0800377 }
Yabin Cuif6237472015-02-26 19:03:54 -0800378 printf("\n");
Yabin Cui657b1f92015-01-22 19:26:12 -0800379
Yabin Cuiea9c9332015-02-24 14:39:19 -0800380 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
381 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800382 fflush(stdout);
383}
384
Yabin Cuif6237472015-02-26 19:03:54 -0800385#endif // !defined(USING_GTEST_OUTPUT_FORMAT)
386
Yabin Cuibe837362015-01-02 18:45:37 -0800387static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800388 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800389
390 std::vector<std::string> fail_test_name_list;
391 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
392
Elliott Hughesa456fae2016-08-31 13:30:14 -0700393 // For tests that were slow but didn't time out.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800394 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800395 size_t testcase_count = testcase_list.size();
396 size_t test_count = 0;
397 size_t success_test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800398
399 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800400 test_count += testcase.TestCount();
401 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800402 TestResult result = testcase.GetTestResult(i);
403 if (result == TEST_SUCCESS) {
Yabin Cuibe837362015-01-02 18:45:37 -0800404 ++success_test_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800405 } else if (result == TEST_FAILED) {
406 fail_test_name_list.push_back(testcase.GetTestName(i));
407 } else if (result == TEST_TIMEOUT) {
408 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i),
409 testcase.GetTestTime(i)));
410 }
411 if (result != TEST_TIMEOUT &&
Elliott Hughesa456fae2016-08-31 13:30:14 -0700412 testcase.GetTestTime(i) / 1000000 >= GetSlowThresholdMs(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800413 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
414 testcase.GetTestTime(i),
Elliott Hughesa456fae2016-08-31 13:30:14 -0700415 GetSlowThresholdMs(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800416 }
417 }
418 }
419
Yabin Cui294d1e22014-12-07 20:43:37 -0800420 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800421 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
422 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800423 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800424 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800425 }
426 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800427 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800428 printf("%zu %s.\n", success_test_count, (success_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800429
Elliott Hughesa456fae2016-08-31 13:30:14 -0700430 // Print tests that timed out.
Yabin Cuibe837362015-01-02 18:45:37 -0800431 size_t timeout_test_count = timeout_test_list.size();
432 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800433 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800434 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800435 for (const auto& timeout_pair : timeout_test_list) {
436 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800437 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
438 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800439 }
440 }
441
Elliott Hughesa456fae2016-08-31 13:30:14 -0700442 // Print tests that were slow.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800443 size_t slow_test_count = slow_test_list.size();
444 if (slow_test_count > 0) {
445 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
446 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
447 for (const auto& slow_tuple : slow_test_list) {
448 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
Elliott Hughesa456fae2016-08-31 13:30:14 -0700449 printf("%s (%" PRId64 " ms, exceeded %d ms)\n", std::get<0>(slow_tuple).c_str(),
Yabin Cui4a82ede2015-01-26 17:19:37 -0800450 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800451 }
452 }
453
Elliott Hughesa456fae2016-08-31 13:30:14 -0700454 // Print tests that failed.
455 size_t fail_test_count = fail_test_name_list.size();
Yabin Cuibe837362015-01-02 18:45:37 -0800456 if (fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700457 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
458 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
459 for (const auto& name : fail_test_name_list) {
460 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
461 printf("%s\n", name.c_str());
462 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800463 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700464
465 if (timeout_test_count > 0 || slow_test_count > 0 || fail_test_count > 0) {
466 printf("\n");
467 }
468
Yabin Cuibe837362015-01-02 18:45:37 -0800469 if (timeout_test_count > 0) {
470 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800471 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800472 if (slow_test_count > 0) {
473 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800474 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700475 if (fail_test_count > 0) {
476 printf("%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
477 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800478 fflush(stdout);
479}
480
Dan Albert09a99642016-01-13 21:48:56 -0800481std::string XmlEscape(const std::string& xml) {
482 std::string escaped;
483 escaped.reserve(xml.size());
484
485 for (auto c : xml) {
486 switch (c) {
487 case '<':
488 escaped.append("&lt;");
489 break;
490 case '>':
491 escaped.append("&gt;");
492 break;
493 case '&':
494 escaped.append("&amp;");
495 break;
496 case '\'':
497 escaped.append("&apos;");
498 break;
499 case '"':
500 escaped.append("&quot;");
501 break;
502 default:
503 escaped.append(1, c);
504 break;
505 }
506 }
507
508 return escaped;
509}
510
Yabin Cui657b1f92015-01-22 19:26:12 -0800511// Output xml file when --gtest_output is used, write this function as we can't reuse
512// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
513// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
514// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
515void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
516 const std::vector<TestCase>& testcase_list,
517 time_t epoch_iteration_start_time,
518 int64_t elapsed_time_ns) {
519 FILE* fp = fopen(xml_output_filename.c_str(), "w");
520 if (fp == NULL) {
521 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
522 exit(1);
523 }
524
525 size_t total_test_count = 0;
526 size_t total_failed_count = 0;
527 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
528 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
529 for (size_t i = 0; i < testcase_list.size(); ++i) {
530 auto& testcase = testcase_list[i];
531 total_test_count += testcase.TestCount();
532 for (size_t j = 0; j < testcase.TestCount(); ++j) {
533 if (testcase.GetTestResult(j) != TEST_SUCCESS) {
534 ++failed_count_list[i];
535 }
536 elapsed_time_list[i] += testcase.GetTestTime(j);
537 }
538 total_failed_count += failed_count_list[i];
539 }
540
541 const tm* time_struct = localtime(&epoch_iteration_start_time);
542 char timestamp[40];
543 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
544 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
545 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
546
547 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
548 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
549 total_test_count, total_failed_count);
550 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
551 for (size_t i = 0; i < testcase_list.size(); ++i) {
552 auto& testcase = testcase_list[i];
553 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
554 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
555 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
556
557 for (size_t j = 0; j < testcase.TestCount(); ++j) {
558 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
559 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
560 testcase.GetName().c_str());
561 if (testcase.GetTestResult(j) == TEST_SUCCESS) {
562 fputs(" />\n", fp);
563 } else {
564 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800565 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
Dan Albert09a99642016-01-13 21:48:56 -0800566 const std::string escaped_test_output = XmlEscape(test_output);
567 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", escaped_test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800568 fputs(" </failure>\n", fp);
569 fputs(" </testcase>\n", fp);
570 }
571 }
572
573 fputs(" </testsuite>\n", fp);
574 }
575 fputs("</testsuites>\n", fp);
576 fclose(fp);
577}
578
Yabin Cui767fb1c2015-09-01 15:06:39 -0700579static bool sigint_flag;
580static bool sigquit_flag;
581
582static void signal_handler(int sig) {
583 if (sig == SIGINT) {
584 sigint_flag = true;
585 } else if (sig == SIGQUIT) {
586 sigquit_flag = true;
587 }
588}
589
590static bool RegisterSignalHandler() {
591 sigint_flag = false;
592 sigquit_flag = false;
593 sig_t ret = signal(SIGINT, signal_handler);
594 if (ret != SIG_ERR) {
595 ret = signal(SIGQUIT, signal_handler);
596 }
597 if (ret == SIG_ERR) {
598 perror("RegisterSignalHandler");
599 return false;
600 }
601 return true;
602}
603
604static bool UnregisterSignalHandler() {
605 sig_t ret = signal(SIGINT, SIG_DFL);
606 if (ret != SIG_ERR) {
607 ret = signal(SIGQUIT, SIG_DFL);
608 }
609 if (ret == SIG_ERR) {
610 perror("UnregisterSignalHandler");
611 return false;
612 }
613 return true;
614}
615
Yabin Cui1d4c7802015-02-02 19:14:05 -0800616struct ChildProcInfo {
617 pid_t pid;
618 int64_t start_time_ns;
619 int64_t end_time_ns;
620 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
621 size_t testcase_id, test_id;
622 bool finished;
623 bool timed_out;
624 int exit_status;
625 int child_read_fd; // File descriptor to read child test failure info.
626};
627
Yabin Cui294d1e22014-12-07 20:43:37 -0800628// Forked Child process, run the single test.
629static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800630 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800631 memcpy(new_argv, argv, sizeof(char*) * argc);
632
633 char* filter_arg = new char [test_name.size() + 20];
634 strcpy(filter_arg, "--gtest_filter=");
635 strcat(filter_arg, test_name.c_str());
636 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800637 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800638
639 int new_argc = argc + 1;
640 testing::InitGoogleTest(&new_argc, new_argv);
641 int result = RUN_ALL_TESTS();
642 exit(result);
643}
644
Yabin Cui1d4c7802015-02-02 19:14:05 -0800645static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700646 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800647 int pipefd[2];
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800648 if (pipe(pipefd) == -1) {
649 perror("pipe in RunTestInSeparateProc");
650 exit(1);
651 }
652 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
653 perror("fcntl in RunTestInSeparateProc");
Yabin Cui1d4c7802015-02-02 19:14:05 -0800654 exit(1);
655 }
656 pid_t pid = fork();
657 if (pid == -1) {
658 perror("fork in RunTestInSeparateProc");
659 exit(1);
660 } else if (pid == 0) {
661 // In child process, run a single test.
662 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800663 close(STDOUT_FILENO);
664 close(STDERR_FILENO);
665 dup2(pipefd[1], STDOUT_FILENO);
666 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800667
Yabin Cui767fb1c2015-09-01 15:06:39 -0700668 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800669 exit(1);
670 }
671 ChildProcessFn(argc, argv, test_name);
672 // Unreachable.
673 }
674 // In parent process, initialize child process info.
675 close(pipefd[1]);
676 ChildProcInfo child_proc;
677 child_proc.child_read_fd = pipefd[0];
678 child_proc.pid = pid;
679 child_proc.start_time_ns = NanoTime();
Elliott Hughesa456fae2016-08-31 13:30:14 -0700680 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetTimeoutMs(test_name) * 1000000LL;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800681 child_proc.testcase_id = testcase_id;
682 child_proc.test_id = test_id;
683 child_proc.finished = false;
684 return child_proc;
685}
Yabin Cui294d1e22014-12-07 20:43:37 -0800686
Yabin Cui1d4c7802015-02-02 19:14:05 -0800687static void HandleSignals(std::vector<TestCase>& testcase_list,
688 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700689 if (sigquit_flag) {
690 sigquit_flag = false;
691 // Print current running tests.
692 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700693 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700694 if (child_proc.pid != 0) {
695 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
696 int64_t current_time_ns = NanoTime();
697 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
698 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800699 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800700 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700701 } else if (sigint_flag) {
702 sigint_flag = false;
703 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700704 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700705 if (child_proc.pid != 0) {
706 // Send SIGKILL to ensure the child process can be killed unconditionally.
707 kill(child_proc.pid, SIGKILL);
708 }
709 }
710 // SIGINT kills the parent process as well.
711 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800712 }
713}
714
715static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
716 std::vector<ChildProcInfo>& child_proc_list) {
717 for (size_t i = 0; i < child_proc_list.size(); ++i) {
718 if (child_proc_list[i].pid == exit_pid) {
719 child_proc_list[i].finished = true;
720 child_proc_list[i].timed_out = false;
721 child_proc_list[i].exit_status = exit_status;
722 child_proc_list[i].end_time_ns = NanoTime();
723 return true;
724 }
725 }
726 return false;
727}
728
729static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
730 int64_t current_time_ns = NanoTime();
731 size_t timeout_child_count = 0;
732 for (size_t i = 0; i < child_proc_list.size(); ++i) {
733 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
734 child_proc_list[i].finished = true;
735 child_proc_list[i].timed_out = true;
736 child_proc_list[i].end_time_ns = current_time_ns;
737 ++timeout_child_count;
738 }
739 }
740 return timeout_child_count;
741}
742
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800743static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
744 std::vector<ChildProcInfo>& child_proc_list) {
745 for (const auto& child_proc : child_proc_list) {
746 TestCase& testcase = testcase_list[child_proc.testcase_id];
747 int test_id = child_proc.test_id;
748 while (true) {
749 char buf[1024];
750 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
751 if (bytes_read > 0) {
752 buf[bytes_read] = '\0';
753 testcase.GetTest(test_id).AppendTestOutput(buf);
754 } else if (bytes_read == 0) {
755 break; // Read end.
756 } else {
757 if (errno == EAGAIN) {
758 break;
759 }
760 perror("failed to read child_read_fd");
761 exit(1);
762 }
763 }
764 }
765}
766
Yabin Cui1d4c7802015-02-02 19:14:05 -0800767static void WaitChildProcs(std::vector<TestCase>& testcase_list,
768 std::vector<ChildProcInfo>& child_proc_list) {
769 size_t finished_child_count = 0;
770 while (true) {
771 int status;
772 pid_t result;
773 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
774 if (CheckChildProcExit(result, status, child_proc_list)) {
775 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800776 }
777 }
778
779 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800780 if (errno == ECHILD) {
781 // This happens when we have no running child processes.
782 return;
783 } else {
784 perror("waitpid");
785 exit(1);
786 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800787 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800788 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800789 }
790
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800791 ReadChildProcOutput(testcase_list, child_proc_list);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800792 if (finished_child_count > 0) {
793 return;
794 }
795
796 HandleSignals(testcase_list, child_proc_list);
797
Yabin Cui294d1e22014-12-07 20:43:37 -0800798 // sleep 1 ms to avoid busy looping.
799 timespec sleep_time;
800 sleep_time.tv_sec = 0;
801 sleep_time.tv_nsec = 1000000;
802 nanosleep(&sleep_time, NULL);
803 }
804}
805
Yabin Cui1d4c7802015-02-02 19:14:05 -0800806static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800807 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800808 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800809
810 TestResult test_result = TEST_SUCCESS;
811 if (result != pid || WEXITSTATUS(exit_status) != 0) {
812 test_result = TEST_FAILED;
813 }
814 return test_result;
815}
816
Yabin Cui1d4c7802015-02-02 19:14:05 -0800817static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
818 int test_id = child_proc.test_id;
819 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
820 if (child_proc.timed_out) {
821 // The child process marked as timed_out has not exited, and we should kill it manually.
822 kill(child_proc.pid, SIGKILL);
823 WaitForOneChild(child_proc.pid);
824 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800825 close(child_proc.child_read_fd);
826
827 if (child_proc.timed_out) {
828 testcase.SetTestResult(test_id, TEST_TIMEOUT);
829 char buf[1024];
830 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
831 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800832 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800833
834 } else if (WIFSIGNALED(child_proc.exit_status)) {
835 // Record signal terminated test as failed.
836 testcase.SetTestResult(test_id, TEST_FAILED);
837 char buf[1024];
838 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
839 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800840 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800841
842 } else {
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800843 int exitcode = WEXITSTATUS(child_proc.exit_status);
844 testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
845 if (exitcode != 0) {
Yabin Cuia32fc862015-12-03 16:28:03 -0800846 char buf[1024];
847 snprintf(buf, sizeof(buf), "%s exited with exitcode %d.\n",
848 testcase.GetTestName(test_id).c_str(), exitcode);
849 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800850 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800851 }
852}
853
Yabin Cui294d1e22014-12-07 20:43:37 -0800854// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
855// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700856// Returns true if all tests run successfully, otherwise return false.
857static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700858 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800859 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800860 // Stop default result printer to avoid environment setup/teardown information for each test.
861 testing::UnitTest::GetInstance()->listeners().Release(
862 testing::UnitTest::GetInstance()->listeners().default_result_printer());
863 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
864
Yabin Cui767fb1c2015-09-01 15:06:39 -0700865 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800866 exit(1);
867 }
868
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700869 bool all_tests_passed = true;
870
Christopher Ferris119cb552015-04-02 12:02:55 -0700871 for (size_t iteration = 1;
872 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
873 ++iteration) {
Elliott Hughes48de71e2016-10-28 10:04:44 -0700874 OnTestIterationStartPrint(testcase_list, iteration, iteration_count, job_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800875 int64_t iteration_start_time_ns = NanoTime();
876 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800877
Yabin Cuibe837362015-01-02 18:45:37 -0800878 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800879 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800880
Yabin Cuibe837362015-01-02 18:45:37 -0800881 // Next test to run is [next_testcase_id:next_test_id].
882 size_t next_testcase_id = 0;
883 size_t next_test_id = 0;
884
885 // Record how many tests are finished.
886 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
887 size_t finished_testcase_count = 0;
888
889 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800890 // run up to job_count child processes.
891 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
892 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
893 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700894 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800895 child_proc_list.push_back(child_proc);
896 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
897 next_test_id = 0;
898 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800899 }
900 }
901
902 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800903 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800904
905 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800906 auto it = child_proc_list.begin();
907 while (it != child_proc_list.end()) {
908 auto& child_proc = *it;
909 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800910 size_t testcase_id = child_proc.testcase_id;
911 size_t test_id = child_proc.test_id;
912 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800913
Yabin Cui1d4c7802015-02-02 19:14:05 -0800914 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800915 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800916
917 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
918 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800919 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700920 if (testcase.GetTestResult(test_id) != TEST_SUCCESS) {
921 all_tests_passed = false;
922 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800923
924 it = child_proc_list.erase(it);
925 } else {
926 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800927 }
928 }
929 }
930
Yabin Cui657b1f92015-01-22 19:26:12 -0800931 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
932 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
933 if (!xml_output_filename.empty()) {
934 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
935 elapsed_time_ns);
936 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800937 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800938
Yabin Cui767fb1c2015-09-01 15:06:39 -0700939 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800940 exit(1);
941 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700942
943 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800944}
945
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700946static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800947 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800948}
949
Yabin Cuiead08142015-02-04 20:53:56 -0800950static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
951 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
952 // test program via a valid path that contains at least one path separator.
953 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
954 // and execve() doesn't read environment variable PATH, so execve() will not success
955 // until we specify the absolute path or relative path of the test program directly.
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -0700956 if (strchr(args[0], '/') == nullptr) {
957 args[0] = strdup(g_executable_path.c_str());
Yabin Cuiead08142015-02-04 20:53:56 -0800958 }
959}
960
Yabin Cui11c43532015-01-28 14:28:14 -0800961static void AddGtestFilterSynonym(std::vector<char*>& args) {
962 // Support --gtest-filter as a synonym for --gtest_filter.
963 for (size_t i = 1; i < args.size(); ++i) {
964 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
965 args[i][7] = '_';
966 }
967 }
968}
969
Yabin Cui657b1f92015-01-22 19:26:12 -0800970struct IsolationTestOptions {
971 bool isolate;
972 size_t job_count;
973 int test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -0700974 int test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -0800975 std::string gtest_color;
976 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -0700977 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -0800978 std::string gtest_output;
979};
980
981// 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 -0800982// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -0800983// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
984// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -0800985// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -0800986// args is used to pass in all command arguments, and pass out only the part of options for gtest.
987// options is used to pass out test options in isolation mode.
988// Return false if there is error in arguments.
989static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
990 for (size_t i = 1; i < args.size(); ++i) {
991 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800992 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -0800993 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800994 return true;
995 }
996 }
997
Yabin Cuiead08142015-02-04 20:53:56 -0800998 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -0800999 AddGtestFilterSynonym(args);
1000
Yabin Cui657b1f92015-01-22 19:26:12 -08001001 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
1002 bool enable_selftest = false;
1003 for (size_t i = 1; i < args.size(); ++i) {
1004 if (strcmp(args[i], "--bionic-selftest") == 0) {
1005 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
1006 // Don't remove this option from arguments.
1007 enable_selftest = true;
1008 }
1009 }
1010 std::string gtest_filter_str;
1011 for (size_t i = args.size() - 1; i >= 1; --i) {
1012 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
1013 gtest_filter_str = std::string(args[i]);
1014 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -08001015 break;
1016 }
1017 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001018 if (enable_selftest == true) {
1019 args.push_back(strdup("--gtest_filter=bionic_selftest*"));
1020 } else {
1021 if (gtest_filter_str == "") {
1022 gtest_filter_str = "--gtest_filter=-bionic_selftest*";
1023 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001024 // Find if '-' for NEGATIVE_PATTERNS exists.
1025 if (gtest_filter_str.find(":-") != std::string::npos) {
1026 gtest_filter_str += ":bionic_selftest*";
1027 } else {
1028 gtest_filter_str += ":-bionic_selftest*";
1029 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001030 }
1031 args.push_back(strdup(gtest_filter_str.c_str()));
1032 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001033
Yabin Cui657b1f92015-01-22 19:26:12 -08001034 options.isolate = true;
1035 // Parse arguments that make us can't run in isolation mode.
1036 for (size_t i = 1; i < args.size(); ++i) {
1037 if (strcmp(args[i], "--no-isolate") == 0) {
1038 options.isolate = false;
1039 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
1040 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001041 }
1042 }
1043
Yabin Cui657b1f92015-01-22 19:26:12 -08001044 // Stop parsing if we will not run in isolation mode.
1045 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001046 return true;
1047 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001048
1049 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -07001050 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -08001051 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001052 options.test_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui657b1f92015-01-22 19:26:12 -08001053 options.gtest_color = testing::GTEST_FLAG(color);
1054 options.gtest_print_time = testing::GTEST_FLAG(print_time);
1055 options.gtest_repeat = testing::GTEST_FLAG(repeat);
1056 options.gtest_output = testing::GTEST_FLAG(output);
1057
1058 // Parse arguments speficied for isolation mode.
1059 for (size_t i = 1; i < args.size(); ++i) {
1060 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1061 char* p = args[i] + strlen("-j");
1062 int count = 0;
1063 if (*p != '\0') {
1064 // Argument like -j5.
1065 count = atoi(p);
1066 } else if (args.size() > i + 1) {
1067 // Arguments like -j 5.
1068 count = atoi(args[i + 1]);
1069 ++i;
1070 }
1071 if (count <= 0) {
1072 fprintf(stderr, "invalid job count: %d\n", count);
1073 return false;
1074 }
1075 options.job_count = static_cast<size_t>(count);
1076 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1077 int time_ms = atoi(args[i] + strlen("--deadline="));
1078 if (time_ms <= 0) {
1079 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1080 return false;
1081 }
1082 options.test_deadline_ms = time_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001083 } else if (strncmp(args[i], "--slow-threshold=", strlen("--slow-threshold=")) == 0) {
1084 int time_ms = atoi(args[i] + strlen("--slow-threshold="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001085 if (time_ms <= 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -07001086 fprintf(stderr, "invalid slow test threshold: %d\n", time_ms);
Yabin Cui657b1f92015-01-22 19:26:12 -08001087 return false;
1088 }
Elliott Hughesa456fae2016-08-31 13:30:14 -07001089 options.test_slow_threshold_ms = time_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001090 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1091 options.gtest_color = args[i] + strlen("--gtest_color=");
1092 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1093 options.gtest_print_time = false;
1094 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001095 // If the value of gtest_repeat is < 0, then it indicates the tests
1096 // should be repeated forever.
1097 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001098 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1099 args.erase(args.begin() + i);
1100 --i;
1101 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1102 std::string output = args[i] + strlen("--gtest_output=");
1103 // generate output xml file path according to the strategy in gtest.
1104 bool success = true;
1105 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1106 output = output.substr(strlen("xml:"));
1107 if (output.size() == 0) {
1108 success = false;
1109 }
1110 // Make absolute path.
1111 if (success && output[0] != '/') {
1112 char* cwd = getcwd(NULL, 0);
1113 if (cwd != NULL) {
1114 output = std::string(cwd) + "/" + output;
1115 free(cwd);
1116 } else {
1117 success = false;
1118 }
1119 }
1120 // Add file name if output is a directory.
1121 if (success && output.back() == '/') {
1122 output += "test_details.xml";
1123 }
1124 }
1125 if (success) {
1126 options.gtest_output = output;
1127 } else {
1128 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1129 return false;
1130 }
1131
1132 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1133 args.erase(args.begin() + i);
1134 --i;
1135 }
1136 }
1137
1138 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1139 // As DeathTest will try to call execve(), this argument should always be added.
1140 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001141 return true;
1142}
1143
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001144static std::string get_proc_self_exe() {
1145 char path[PATH_MAX];
1146 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
1147 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
1148 perror("readlink");
1149 exit(1);
1150 }
1151
1152 return std::string(path, path_len);
1153}
1154
Dimitry Ivanov55437462016-07-20 15:33:07 -07001155int main(int argc, char** argv, char** envp) {
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001156 g_executable_path = get_proc_self_exe();
Dimitry Ivanov55437462016-07-20 15:33:07 -07001157 g_argc = argc;
1158 g_argv = argv;
1159 g_envp = envp;
Yabin Cuibe837362015-01-02 18:45:37 -08001160 std::vector<char*> arg_list;
1161 for (int i = 0; i < argc; ++i) {
1162 arg_list.push_back(argv[i]);
1163 }
Yabin Cuibe837362015-01-02 18:45:37 -08001164
Yabin Cui657b1f92015-01-22 19:26:12 -08001165 IsolationTestOptions options;
1166 if (PickOptions(arg_list, options) == false) {
1167 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001168 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001169
1170 if (options.isolate == true) {
1171 // Set global variables.
1172 global_test_run_deadline_ms = options.test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001173 global_test_run_slow_threshold_ms = options.test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001174 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1175 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1176 std::vector<TestCase> testcase_list;
1177
1178 argc = static_cast<int>(arg_list.size());
1179 arg_list.push_back(NULL);
1180 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1181 return 1;
1182 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001183 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1184 options.gtest_repeat, options.job_count, options.gtest_output);
1185 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001186 } else {
1187 argc = static_cast<int>(arg_list.size());
1188 arg_list.push_back(NULL);
1189 testing::InitGoogleTest(&argc, arg_list.data());
1190 return RUN_ALL_TESTS();
1191 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001192}
1193
1194//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001195// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001196
Yabin Cuibe837362015-01-02 18:45:37 -08001197TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001198 ASSERT_EQ(1, 1);
1199}
1200
Yabin Cuibe837362015-01-02 18:45:37 -08001201TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001202 ASSERT_EQ(0, 1);
1203}
1204
Yabin Cuibe837362015-01-02 18:45:37 -08001205TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001206 sleep(4);
1207}
1208
Yabin Cuibe837362015-01-02 18:45:37 -08001209TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001210 while (1) {}
1211}
Yabin Cuibe837362015-01-02 18:45:37 -08001212
1213TEST(bionic_selftest, test_signal_SEGV_terminated) {
1214 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1215 *p = 3;
1216}
Yabin Cui657b1f92015-01-22 19:26:12 -08001217
Yabin Cui767fb1c2015-09-01 15:06:39 -07001218class bionic_selftest_DeathTest : public ::testing::Test {
1219 protected:
1220 virtual void SetUp() {
1221 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1222 }
1223};
Yabin Cui657b1f92015-01-22 19:26:12 -08001224
1225static void deathtest_helper_success() {
1226 ASSERT_EQ(1, 1);
1227 exit(0);
1228}
1229
1230TEST_F(bionic_selftest_DeathTest, success) {
1231 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1232}
1233
1234static void deathtest_helper_fail() {
1235 ASSERT_EQ(1, 0);
1236}
1237
1238TEST_F(bionic_selftest_DeathTest, fail) {
1239 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1240}