blob: 227b6d192d44553c77d982c55757b1dbd8ec1c2e [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>
Dimitry Ivanovd0b5c3a2016-11-25 12:23:11 -080023#include <libgen.h>
Yabin Cuiead08142015-02-04 20:53:56 -080024#include <limits.h>
Yabin Cui1d4c7802015-02-02 19:14:05 -080025#include <signal.h>
Yabin Cui294d1e22014-12-07 20:43:37 -080026#include <stdarg.h>
27#include <stdio.h>
28#include <string.h>
29#include <sys/wait.h>
Yabin Cui294d1e22014-12-07 20:43:37 -080030#include <unistd.h>
31
Yabin Cui767fb1c2015-09-01 15:06:39 -070032#include <chrono>
Yabin Cui294d1e22014-12-07 20:43:37 -080033#include <string>
34#include <tuple>
35#include <utility>
36#include <vector>
37
Yabin Cui767fb1c2015-09-01 15:06:39 -070038#ifndef TEMP_FAILURE_RETRY
39
40/* Used to retry syscalls that can return EINTR. */
41#define TEMP_FAILURE_RETRY(exp) ({ \
42 __typeof__(exp) _rc; \
43 do { \
44 _rc = (exp); \
45 } while (_rc == -1 && errno == EINTR); \
46 _rc; })
47
48#endif
Yabin Cui657b1f92015-01-22 19:26:12 -080049
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -070050static std::string g_executable_path;
Dimitry Ivanov55437462016-07-20 15:33:07 -070051static int g_argc;
52static char** g_argv;
53static char** g_envp;
Dimitry Ivanovd17a3772016-03-01 13:11:28 -080054
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -070055const std::string& get_executable_path() {
56 return g_executable_path;
Dimitry Ivanovd17a3772016-03-01 13:11:28 -080057}
58
Dimitry Ivanov55437462016-07-20 15:33:07 -070059int get_argc() {
60 return g_argc;
61}
62
63char** get_argv() {
64 return g_argv;
65}
66
67char** get_envp() {
68 return g_envp;
69}
70
Yabin Cui294d1e22014-12-07 20:43:37 -080071namespace testing {
72namespace internal {
73
74// Reuse of testing::internal::ColoredPrintf in gtest.
75enum GTestColor {
76 COLOR_DEFAULT,
77 COLOR_RED,
78 COLOR_GREEN,
79 COLOR_YELLOW
80};
81
82void ColoredPrintf(GTestColor color, const char* fmt, ...);
83
Yabin Cuibe837362015-01-02 18:45:37 -080084} // namespace internal
85} // namespace testing
Yabin Cui294d1e22014-12-07 20:43:37 -080086
87using testing::internal::GTestColor;
88using testing::internal::COLOR_DEFAULT;
89using testing::internal::COLOR_RED;
90using testing::internal::COLOR_GREEN;
91using testing::internal::COLOR_YELLOW;
92using testing::internal::ColoredPrintf;
93
Christopher Ferrisdaaaed12015-09-24 18:45:53 -070094constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 90000;
Elliott Hughesa456fae2016-08-31 13:30:14 -070095constexpr int DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -080096
97// The time each test can run before killed for the reason of timeout.
98// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080099static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800100
101// The time each test can run before be warned for too much running time.
102// It takes effect only with --isolate option.
Elliott Hughesa456fae2016-08-31 13:30:14 -0700103static int global_test_run_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800104
Elliott Hughesa456fae2016-08-31 13:30:14 -0700105// Return timeout duration for a test, in ms.
106static int GetTimeoutMs(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800107 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800108}
109
Elliott Hughesa456fae2016-08-31 13:30:14 -0700110// Return threshold for calling a test slow, in ms.
111static int GetSlowThresholdMs(const std::string& /*test_name*/) {
112 return global_test_run_slow_threshold_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800113}
114
Yabin Cuibe837362015-01-02 18:45:37 -0800115static void PrintHelpInfo() {
116 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -0800117 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800118 " Run up to JOB_COUNT tests in parallel.\n"
119 " Use isolation mode, Run each test in a separate process.\n"
120 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
121 " --no-isolate\n"
122 " Don't use isolation mode, run all tests in a single process.\n"
123 " --deadline=[TIME_IN_MS]\n"
124 " Run each test in no longer than [TIME_IN_MS] time.\n"
Elliott Hughesa456fae2016-08-31 13:30:14 -0700125 " Only valid in isolation mode. Default deadline is 90000 ms.\n"
126 " --slow-threshold=[TIME_IN_MS]\n"
127 " Test running longer than [TIME_IN_MS] will be called slow.\n"
128 " Only valid in isolation mode. Default slow threshold is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -0800129 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
130 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -0800131 "Default bionic unit test option is -j.\n"
132 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
133 "running tests, or send SIGINT to the parent process to stop testing and\n"
134 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800135 "\n");
136}
137
Yabin Cui294d1e22014-12-07 20:43:37 -0800138enum TestResult {
139 TEST_SUCCESS = 0,
140 TEST_FAILED,
141 TEST_TIMEOUT
142};
143
Yabin Cui657b1f92015-01-22 19:26:12 -0800144class Test {
145 public:
146 Test() {} // For std::vector<Test>.
147 explicit Test(const char* name) : name_(name) {}
148
149 const std::string& GetName() const { return name_; }
150
151 void SetResult(TestResult result) { result_ = result; }
152
153 TestResult GetResult() const { return result_; }
Josh Gao01052222017-01-09 16:43:33 -0800154 TestResult GetExpectedResult() const {
Josh Gao7d15dc32017-03-13 17:10:46 -0700155 return GetName().find("xfail") == 0 ? TEST_FAILED : TEST_SUCCESS;
Josh Gao01052222017-01-09 16:43:33 -0800156 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800157
158 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
159
160 int64_t GetTestTime() const { return elapsed_time_ns_; }
161
Yabin Cuiea9c9332015-02-24 14:39:19 -0800162 void AppendTestOutput(const std::string& s) { output_ += s; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800163
Yabin Cuiea9c9332015-02-24 14:39:19 -0800164 const std::string& GetTestOutput() const { return output_; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800165
166 private:
167 const std::string name_;
168 TestResult result_;
169 int64_t elapsed_time_ns_;
Yabin Cuiea9c9332015-02-24 14:39:19 -0800170 std::string output_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800171};
172
Yabin Cui294d1e22014-12-07 20:43:37 -0800173class TestCase {
174 public:
175 TestCase() {} // For std::vector<TestCase>.
176 explicit TestCase(const char* name) : name_(name) {}
177
178 const std::string& GetName() const { return name_; }
179
Yabin Cui657b1f92015-01-22 19:26:12 -0800180 void AppendTest(const char* test_name) {
181 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800182 }
183
Yabin Cuibe837362015-01-02 18:45:37 -0800184 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800185
Yabin Cuibe837362015-01-02 18:45:37 -0800186 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800187 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800188 return name_ + "." + test_list_[test_id].GetName();
189 }
190
191 Test& GetTest(size_t test_id) {
192 VerifyTestId(test_id);
193 return test_list_[test_id];
194 }
195
196 const Test& GetTest(size_t test_id) const {
197 VerifyTestId(test_id);
198 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800199 }
200
Yabin Cuibe837362015-01-02 18:45:37 -0800201 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800202 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800203 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800204 }
205
Yabin Cuibe837362015-01-02 18:45:37 -0800206 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800207 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800208 return test_list_[test_id].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800209 }
210
Josh Gao01052222017-01-09 16:43:33 -0800211 TestResult GetExpectedTestResult(size_t test_id) const {
212 VerifyTestId(test_id);
213 return test_list_[test_id].GetExpectedResult();
214 }
215
216 bool GetTestSuccess(size_t test_id) const {
217 return GetTestResult(test_id) == GetExpectedTestResult(test_id);
218 }
219
Yabin Cui657b1f92015-01-22 19:26:12 -0800220 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800221 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800222 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800223 }
224
Yabin Cuibe837362015-01-02 18:45:37 -0800225 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800226 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800227 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800228 }
229
230 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800231 void VerifyTestId(size_t test_id) const {
232 if(test_id >= test_list_.size()) {
233 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800234 exit(1);
235 }
236 }
237
238 private:
239 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800240 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800241};
242
Yabin Cui294d1e22014-12-07 20:43:37 -0800243class TestResultPrinter : public testing::EmptyTestEventListener {
244 public:
245 TestResultPrinter() : pinfo_(NULL) {}
246 virtual void OnTestStart(const testing::TestInfo& test_info) {
247 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
248 }
249 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800250
251 private:
252 const testing::TestInfo* pinfo_;
253};
254
255// Called after an assertion failure.
256void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
257 // If the test part succeeded, we don't need to do anything.
258 if (result.type() == testing::TestPartResult::kSuccess)
259 return;
260
261 // Print failure message from the assertion (e.g. expected this and got that).
Yabin Cuiea9c9332015-02-24 14:39:19 -0800262 printf("%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), result.line_number(),
263 pinfo_->test_case_name(), pinfo_->name(), result.message());
264 fflush(stdout);
Yabin Cui294d1e22014-12-07 20:43:37 -0800265}
266
Yabin Cui294d1e22014-12-07 20:43:37 -0800267static int64_t NanoTime() {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700268 std::chrono::nanoseconds duration(std::chrono::steady_clock::now().time_since_epoch());
269 return static_cast<int64_t>(duration.count());
Yabin Cui294d1e22014-12-07 20:43:37 -0800270}
271
272static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
273 std::string command;
274 for (int i = 0; i < argc; ++i) {
275 command += argv[i];
276 command += " ";
277 }
278 command += "--gtest_list_tests";
279 FILE* fp = popen(command.c_str(), "r");
280 if (fp == NULL) {
281 perror("popen");
282 return false;
283 }
284
285 char buf[200];
286 while (fgets(buf, sizeof(buf), fp) != NULL) {
287 char* p = buf;
288
289 while (*p != '\0' && isspace(*p)) {
290 ++p;
291 }
292 if (*p == '\0') continue;
293 char* start = p;
294 while (*p != '\0' && !isspace(*p)) {
295 ++p;
296 }
297 char* end = p;
298 while (*p != '\0' && isspace(*p)) {
299 ++p;
300 }
Yabin Cuibf830ad2015-08-10 12:12:39 -0700301 if (*p != '\0' && *p != '#') {
Yabin Cui294d1e22014-12-07 20:43:37 -0800302 // This is not we want, gtest must meet with some error when parsing the arguments.
303 fprintf(stderr, "argument error, check with --help\n");
304 return false;
305 }
306 *end = '\0';
307 if (*(end - 1) == '.') {
308 *(end - 1) = '\0';
309 testcase_list.push_back(TestCase(start));
310 } else {
311 testcase_list.back().AppendTest(start);
312 }
313 }
314 int result = pclose(fp);
315 return (result != -1 && WEXITSTATUS(result) == 0);
316}
317
Yabin Cui294d1e22014-12-07 20:43:37 -0800318// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
319// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
320// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800321static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
Elliott Hughes48de71e2016-10-28 10:04:44 -0700322 int iteration_count, size_t job_count) {
Christopher Ferris119cb552015-04-02 12:02:55 -0700323 if (iteration_count != 1) {
Yabin Cuibe837362015-01-02 18:45:37 -0800324 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800325 }
326 ColoredPrintf(COLOR_GREEN, "[==========] ");
327
Yabin Cuibe837362015-01-02 18:45:37 -0800328 size_t testcase_count = testcase_list.size();
329 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800330 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800331 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800332 }
333
Elliott Hughes48de71e2016-10-28 10:04:44 -0700334 printf("Running %zu %s from %zu %s (%zu %s).\n",
Yabin Cuibe837362015-01-02 18:45:37 -0800335 test_count, (test_count == 1) ? "test" : "tests",
Elliott Hughes48de71e2016-10-28 10:04:44 -0700336 testcase_count, (testcase_count == 1) ? "test case" : "test cases",
337 job_count, (job_count == 1) ? "job" : "jobs");
Yabin Cui294d1e22014-12-07 20:43:37 -0800338 fflush(stdout);
339}
340
Yabin Cuif6237472015-02-26 19:03:54 -0800341// bionic cts test needs gtest output format.
342#if defined(USING_GTEST_OUTPUT_FORMAT)
343
344static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
345 ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
346 printf("%s\n", testcase.GetTestName(test_id).c_str());
347
348 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
349 printf("%s", test_output.c_str());
350
351 TestResult result = testcase.GetTestResult(test_id);
Josh Gao01052222017-01-09 16:43:33 -0800352 if (result == testcase.GetExpectedTestResult(test_id)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800353 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
354 } else {
355 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
356 }
357 printf("%s", testcase.GetTestName(test_id).c_str());
358 if (testing::GTEST_FLAG(print_time)) {
359 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
360 }
361 printf("\n");
362 fflush(stdout);
363}
364
365#else // !defined(USING_GTEST_OUTPUT_FORMAT)
366
Yabin Cui657b1f92015-01-22 19:26:12 -0800367static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
368 TestResult result = testcase.GetTestResult(test_id);
Josh Gao01052222017-01-09 16:43:33 -0800369 TestResult expected = testcase.GetExpectedTestResult(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800370 if (result == TEST_SUCCESS) {
Josh Gao01052222017-01-09 16:43:33 -0800371 if (expected == TEST_SUCCESS) {
372 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
373 } else if (expected == TEST_FAILED) {
374 ColoredPrintf(COLOR_RED, "[ XPASS ] ");
375 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800376 } else if (result == TEST_FAILED) {
Josh Gao01052222017-01-09 16:43:33 -0800377 if (expected == TEST_SUCCESS) {
378 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
379 } else if (expected == TEST_FAILED) {
380 ColoredPrintf(COLOR_YELLOW, "[ XFAIL ] ");
381 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800382 } else if (result == TEST_TIMEOUT) {
383 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
384 }
Yabin Cuibe837362015-01-02 18:45:37 -0800385
Yabin Cui657b1f92015-01-22 19:26:12 -0800386 printf("%s", testcase.GetTestName(test_id).c_str());
387 if (testing::GTEST_FLAG(print_time)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800388 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
Yabin Cui657b1f92015-01-22 19:26:12 -0800389 }
Yabin Cuif6237472015-02-26 19:03:54 -0800390 printf("\n");
Yabin Cui657b1f92015-01-22 19:26:12 -0800391
Yabin Cuiea9c9332015-02-24 14:39:19 -0800392 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
393 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800394 fflush(stdout);
395}
396
Yabin Cuif6237472015-02-26 19:03:54 -0800397#endif // !defined(USING_GTEST_OUTPUT_FORMAT)
398
Yabin Cuibe837362015-01-02 18:45:37 -0800399static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800400 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800401
402 std::vector<std::string> fail_test_name_list;
Josh Gao01052222017-01-09 16:43:33 -0800403 std::vector<std::string> xpass_test_name_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800404 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
405
Elliott Hughesa456fae2016-08-31 13:30:14 -0700406 // For tests that were slow but didn't time out.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800407 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800408 size_t testcase_count = testcase_list.size();
409 size_t test_count = 0;
410 size_t success_test_count = 0;
Josh Gao01052222017-01-09 16:43:33 -0800411 size_t expected_failure_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800412
413 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800414 test_count += testcase.TestCount();
415 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800416 TestResult result = testcase.GetTestResult(i);
Josh Gao01052222017-01-09 16:43:33 -0800417 TestResult expected = testcase.GetExpectedTestResult(i);
418 if (result == TEST_TIMEOUT) {
419 timeout_test_list.push_back(
420 std::make_pair(testcase.GetTestName(i), testcase.GetTestTime(i)));
421 } else if (result == expected) {
422 if (result == TEST_SUCCESS) {
423 ++success_test_count;
424 } else {
425 ++expected_failure_count;
426 }
427 } else {
428 if (result == TEST_FAILED) {
429 fail_test_name_list.push_back(testcase.GetTestName(i));
430 } else {
431 xpass_test_name_list.push_back(testcase.GetTestName(i));
432 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800433 }
434 if (result != TEST_TIMEOUT &&
Elliott Hughesa456fae2016-08-31 13:30:14 -0700435 testcase.GetTestTime(i) / 1000000 >= GetSlowThresholdMs(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800436 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
437 testcase.GetTestTime(i),
Elliott Hughesa456fae2016-08-31 13:30:14 -0700438 GetSlowThresholdMs(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800439 }
440 }
441 }
442
Yabin Cui294d1e22014-12-07 20:43:37 -0800443 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800444 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
445 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800446 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800447 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800448 }
449 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800450 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Josh Gao01052222017-01-09 16:43:33 -0800451 printf("%zu %s.", success_test_count, (success_test_count == 1) ? "test" : "tests");
452 if (expected_failure_count > 0) {
453 printf(" (%zu expected failure%s)", expected_failure_count,
454 (expected_failure_count == 1) ? "" : "s");
455 }
456 printf("\n");
Yabin Cui294d1e22014-12-07 20:43:37 -0800457
Elliott Hughesa456fae2016-08-31 13:30:14 -0700458 // Print tests that timed out.
Yabin Cuibe837362015-01-02 18:45:37 -0800459 size_t timeout_test_count = timeout_test_list.size();
460 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800461 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800462 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800463 for (const auto& timeout_pair : timeout_test_list) {
464 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800465 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
466 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800467 }
468 }
469
Elliott Hughesa456fae2016-08-31 13:30:14 -0700470 // Print tests that were slow.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800471 size_t slow_test_count = slow_test_list.size();
472 if (slow_test_count > 0) {
473 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
474 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
475 for (const auto& slow_tuple : slow_test_list) {
476 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
Elliott Hughesa456fae2016-08-31 13:30:14 -0700477 printf("%s (%" PRId64 " ms, exceeded %d ms)\n", std::get<0>(slow_tuple).c_str(),
Yabin Cui4a82ede2015-01-26 17:19:37 -0800478 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800479 }
480 }
481
Elliott Hughesa456fae2016-08-31 13:30:14 -0700482 // Print tests that failed.
483 size_t fail_test_count = fail_test_name_list.size();
Yabin Cuibe837362015-01-02 18:45:37 -0800484 if (fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700485 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
486 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
487 for (const auto& name : fail_test_name_list) {
488 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
489 printf("%s\n", name.c_str());
490 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800491 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700492
Josh Gao01052222017-01-09 16:43:33 -0800493 // Print tests that should have failed.
494 size_t xpass_test_count = xpass_test_name_list.size();
495 if (xpass_test_count > 0) {
496 ColoredPrintf(COLOR_RED, "[ XPASS ] ");
497 printf("%zu %s, listed below:\n", xpass_test_count, (xpass_test_count == 1) ? "test" : "tests");
498 for (const auto& name : xpass_test_name_list) {
499 ColoredPrintf(COLOR_RED, "[ XPASS ] ");
500 printf("%s\n", name.c_str());
501 }
502 }
503
504 if (timeout_test_count > 0 || slow_test_count > 0 || fail_test_count > 0 || xpass_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700505 printf("\n");
506 }
507
Yabin Cuibe837362015-01-02 18:45:37 -0800508 if (timeout_test_count > 0) {
509 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800510 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800511 if (slow_test_count > 0) {
512 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800513 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700514 if (fail_test_count > 0) {
515 printf("%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
516 }
Josh Gao01052222017-01-09 16:43:33 -0800517 if (xpass_test_count > 0) {
518 printf("%2zu SHOULD HAVE FAILED %s\n", xpass_test_count, (xpass_test_count == 1) ? "TEST" : "TESTS");
519 }
520
Yabin Cui294d1e22014-12-07 20:43:37 -0800521 fflush(stdout);
522}
523
Dan Albert09a99642016-01-13 21:48:56 -0800524std::string XmlEscape(const std::string& xml) {
525 std::string escaped;
526 escaped.reserve(xml.size());
527
528 for (auto c : xml) {
529 switch (c) {
530 case '<':
531 escaped.append("&lt;");
532 break;
533 case '>':
534 escaped.append("&gt;");
535 break;
536 case '&':
537 escaped.append("&amp;");
538 break;
539 case '\'':
540 escaped.append("&apos;");
541 break;
542 case '"':
543 escaped.append("&quot;");
544 break;
545 default:
546 escaped.append(1, c);
547 break;
548 }
549 }
550
551 return escaped;
552}
553
Yabin Cui657b1f92015-01-22 19:26:12 -0800554// Output xml file when --gtest_output is used, write this function as we can't reuse
555// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
556// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
557// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
558void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
559 const std::vector<TestCase>& testcase_list,
560 time_t epoch_iteration_start_time,
561 int64_t elapsed_time_ns) {
562 FILE* fp = fopen(xml_output_filename.c_str(), "w");
563 if (fp == NULL) {
564 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
565 exit(1);
566 }
567
568 size_t total_test_count = 0;
569 size_t total_failed_count = 0;
570 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
571 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
572 for (size_t i = 0; i < testcase_list.size(); ++i) {
573 auto& testcase = testcase_list[i];
574 total_test_count += testcase.TestCount();
575 for (size_t j = 0; j < testcase.TestCount(); ++j) {
Josh Gao01052222017-01-09 16:43:33 -0800576 if (!testcase.GetTestSuccess(j)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800577 ++failed_count_list[i];
578 }
579 elapsed_time_list[i] += testcase.GetTestTime(j);
580 }
581 total_failed_count += failed_count_list[i];
582 }
583
584 const tm* time_struct = localtime(&epoch_iteration_start_time);
585 char timestamp[40];
586 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
587 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
588 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
589
590 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
591 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
592 total_test_count, total_failed_count);
593 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
594 for (size_t i = 0; i < testcase_list.size(); ++i) {
595 auto& testcase = testcase_list[i];
596 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
597 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
598 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
599
600 for (size_t j = 0; j < testcase.TestCount(); ++j) {
601 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
602 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
603 testcase.GetName().c_str());
Josh Gao01052222017-01-09 16:43:33 -0800604 if (!testcase.GetTestSuccess(j)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800605 fputs(" />\n", fp);
606 } else {
607 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800608 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
Dan Albert09a99642016-01-13 21:48:56 -0800609 const std::string escaped_test_output = XmlEscape(test_output);
610 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", escaped_test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800611 fputs(" </failure>\n", fp);
612 fputs(" </testcase>\n", fp);
613 }
614 }
615
616 fputs(" </testsuite>\n", fp);
617 }
618 fputs("</testsuites>\n", fp);
619 fclose(fp);
620}
621
Yabin Cui767fb1c2015-09-01 15:06:39 -0700622static bool sigint_flag;
623static bool sigquit_flag;
624
625static void signal_handler(int sig) {
626 if (sig == SIGINT) {
627 sigint_flag = true;
628 } else if (sig == SIGQUIT) {
629 sigquit_flag = true;
630 }
631}
632
633static bool RegisterSignalHandler() {
634 sigint_flag = false;
635 sigquit_flag = false;
636 sig_t ret = signal(SIGINT, signal_handler);
637 if (ret != SIG_ERR) {
638 ret = signal(SIGQUIT, signal_handler);
639 }
640 if (ret == SIG_ERR) {
641 perror("RegisterSignalHandler");
642 return false;
643 }
644 return true;
645}
646
647static bool UnregisterSignalHandler() {
648 sig_t ret = signal(SIGINT, SIG_DFL);
649 if (ret != SIG_ERR) {
650 ret = signal(SIGQUIT, SIG_DFL);
651 }
652 if (ret == SIG_ERR) {
653 perror("UnregisterSignalHandler");
654 return false;
655 }
656 return true;
657}
658
Yabin Cui1d4c7802015-02-02 19:14:05 -0800659struct ChildProcInfo {
660 pid_t pid;
661 int64_t start_time_ns;
662 int64_t end_time_ns;
663 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
664 size_t testcase_id, test_id;
665 bool finished;
666 bool timed_out;
667 int exit_status;
668 int child_read_fd; // File descriptor to read child test failure info.
669};
670
Yabin Cui294d1e22014-12-07 20:43:37 -0800671// Forked Child process, run the single test.
672static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800673 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800674 memcpy(new_argv, argv, sizeof(char*) * argc);
675
676 char* filter_arg = new char [test_name.size() + 20];
677 strcpy(filter_arg, "--gtest_filter=");
678 strcat(filter_arg, test_name.c_str());
679 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800680 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800681
682 int new_argc = argc + 1;
683 testing::InitGoogleTest(&new_argc, new_argv);
684 int result = RUN_ALL_TESTS();
685 exit(result);
686}
687
Yabin Cui1d4c7802015-02-02 19:14:05 -0800688static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700689 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800690 int pipefd[2];
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800691 if (pipe(pipefd) == -1) {
692 perror("pipe in RunTestInSeparateProc");
693 exit(1);
694 }
695 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
696 perror("fcntl in RunTestInSeparateProc");
Yabin Cui1d4c7802015-02-02 19:14:05 -0800697 exit(1);
698 }
699 pid_t pid = fork();
700 if (pid == -1) {
701 perror("fork in RunTestInSeparateProc");
702 exit(1);
703 } else if (pid == 0) {
704 // In child process, run a single test.
705 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800706 close(STDOUT_FILENO);
707 close(STDERR_FILENO);
708 dup2(pipefd[1], STDOUT_FILENO);
709 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800710
Yabin Cui767fb1c2015-09-01 15:06:39 -0700711 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800712 exit(1);
713 }
714 ChildProcessFn(argc, argv, test_name);
715 // Unreachable.
716 }
717 // In parent process, initialize child process info.
718 close(pipefd[1]);
719 ChildProcInfo child_proc;
720 child_proc.child_read_fd = pipefd[0];
721 child_proc.pid = pid;
722 child_proc.start_time_ns = NanoTime();
Elliott Hughesa456fae2016-08-31 13:30:14 -0700723 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetTimeoutMs(test_name) * 1000000LL;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800724 child_proc.testcase_id = testcase_id;
725 child_proc.test_id = test_id;
726 child_proc.finished = false;
727 return child_proc;
728}
Yabin Cui294d1e22014-12-07 20:43:37 -0800729
Yabin Cui1d4c7802015-02-02 19:14:05 -0800730static void HandleSignals(std::vector<TestCase>& testcase_list,
731 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700732 if (sigquit_flag) {
733 sigquit_flag = false;
734 // Print current running tests.
735 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700736 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700737 if (child_proc.pid != 0) {
738 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
739 int64_t current_time_ns = NanoTime();
740 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
741 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800742 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800743 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700744 } else if (sigint_flag) {
745 sigint_flag = false;
746 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700747 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700748 if (child_proc.pid != 0) {
749 // Send SIGKILL to ensure the child process can be killed unconditionally.
750 kill(child_proc.pid, SIGKILL);
751 }
752 }
753 // SIGINT kills the parent process as well.
754 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800755 }
756}
757
758static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
759 std::vector<ChildProcInfo>& child_proc_list) {
760 for (size_t i = 0; i < child_proc_list.size(); ++i) {
761 if (child_proc_list[i].pid == exit_pid) {
762 child_proc_list[i].finished = true;
763 child_proc_list[i].timed_out = false;
764 child_proc_list[i].exit_status = exit_status;
765 child_proc_list[i].end_time_ns = NanoTime();
766 return true;
767 }
768 }
769 return false;
770}
771
772static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
773 int64_t current_time_ns = NanoTime();
774 size_t timeout_child_count = 0;
775 for (size_t i = 0; i < child_proc_list.size(); ++i) {
776 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
777 child_proc_list[i].finished = true;
778 child_proc_list[i].timed_out = true;
779 child_proc_list[i].end_time_ns = current_time_ns;
780 ++timeout_child_count;
781 }
782 }
783 return timeout_child_count;
784}
785
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800786static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
787 std::vector<ChildProcInfo>& child_proc_list) {
788 for (const auto& child_proc : child_proc_list) {
789 TestCase& testcase = testcase_list[child_proc.testcase_id];
790 int test_id = child_proc.test_id;
791 while (true) {
792 char buf[1024];
793 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
794 if (bytes_read > 0) {
795 buf[bytes_read] = '\0';
796 testcase.GetTest(test_id).AppendTestOutput(buf);
797 } else if (bytes_read == 0) {
798 break; // Read end.
799 } else {
800 if (errno == EAGAIN) {
801 break;
802 }
803 perror("failed to read child_read_fd");
804 exit(1);
805 }
806 }
807 }
808}
809
Yabin Cui1d4c7802015-02-02 19:14:05 -0800810static void WaitChildProcs(std::vector<TestCase>& testcase_list,
811 std::vector<ChildProcInfo>& child_proc_list) {
812 size_t finished_child_count = 0;
813 while (true) {
814 int status;
815 pid_t result;
816 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
817 if (CheckChildProcExit(result, status, child_proc_list)) {
818 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800819 }
820 }
821
822 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800823 if (errno == ECHILD) {
824 // This happens when we have no running child processes.
825 return;
826 } else {
827 perror("waitpid");
828 exit(1);
829 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800830 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800831 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800832 }
833
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800834 ReadChildProcOutput(testcase_list, child_proc_list);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800835 if (finished_child_count > 0) {
836 return;
837 }
838
839 HandleSignals(testcase_list, child_proc_list);
840
Yabin Cui294d1e22014-12-07 20:43:37 -0800841 // sleep 1 ms to avoid busy looping.
842 timespec sleep_time;
843 sleep_time.tv_sec = 0;
844 sleep_time.tv_nsec = 1000000;
845 nanosleep(&sleep_time, NULL);
846 }
847}
848
Yabin Cui1d4c7802015-02-02 19:14:05 -0800849static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800850 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800851 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800852
853 TestResult test_result = TEST_SUCCESS;
854 if (result != pid || WEXITSTATUS(exit_status) != 0) {
855 test_result = TEST_FAILED;
856 }
857 return test_result;
858}
859
Yabin Cui1d4c7802015-02-02 19:14:05 -0800860static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
861 int test_id = child_proc.test_id;
862 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
863 if (child_proc.timed_out) {
864 // The child process marked as timed_out has not exited, and we should kill it manually.
865 kill(child_proc.pid, SIGKILL);
866 WaitForOneChild(child_proc.pid);
867 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800868 close(child_proc.child_read_fd);
869
870 if (child_proc.timed_out) {
871 testcase.SetTestResult(test_id, TEST_TIMEOUT);
872 char buf[1024];
873 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
874 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800875 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800876
877 } else if (WIFSIGNALED(child_proc.exit_status)) {
878 // Record signal terminated test as failed.
879 testcase.SetTestResult(test_id, TEST_FAILED);
880 char buf[1024];
881 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
882 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800883 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800884
885 } else {
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800886 int exitcode = WEXITSTATUS(child_proc.exit_status);
887 testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
888 if (exitcode != 0) {
Yabin Cuia32fc862015-12-03 16:28:03 -0800889 char buf[1024];
890 snprintf(buf, sizeof(buf), "%s exited with exitcode %d.\n",
891 testcase.GetTestName(test_id).c_str(), exitcode);
892 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800893 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800894 }
895}
896
Yabin Cui294d1e22014-12-07 20:43:37 -0800897// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
898// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700899// Returns true if all tests run successfully, otherwise return false.
900static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700901 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800902 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800903 // Stop default result printer to avoid environment setup/teardown information for each test.
904 testing::UnitTest::GetInstance()->listeners().Release(
905 testing::UnitTest::GetInstance()->listeners().default_result_printer());
906 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
907
Yabin Cui767fb1c2015-09-01 15:06:39 -0700908 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800909 exit(1);
910 }
911
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700912 bool all_tests_passed = true;
913
Christopher Ferris119cb552015-04-02 12:02:55 -0700914 for (size_t iteration = 1;
915 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
916 ++iteration) {
Elliott Hughes48de71e2016-10-28 10:04:44 -0700917 OnTestIterationStartPrint(testcase_list, iteration, iteration_count, job_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800918 int64_t iteration_start_time_ns = NanoTime();
919 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800920
Yabin Cuibe837362015-01-02 18:45:37 -0800921 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800922 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800923
Yabin Cuibe837362015-01-02 18:45:37 -0800924 // Next test to run is [next_testcase_id:next_test_id].
925 size_t next_testcase_id = 0;
926 size_t next_test_id = 0;
927
928 // Record how many tests are finished.
929 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
930 size_t finished_testcase_count = 0;
931
932 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800933 // run up to job_count child processes.
934 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
935 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
936 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700937 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800938 child_proc_list.push_back(child_proc);
939 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
940 next_test_id = 0;
941 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800942 }
943 }
944
945 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800946 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800947
948 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800949 auto it = child_proc_list.begin();
950 while (it != child_proc_list.end()) {
951 auto& child_proc = *it;
952 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800953 size_t testcase_id = child_proc.testcase_id;
954 size_t test_id = child_proc.test_id;
955 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800956
Yabin Cui1d4c7802015-02-02 19:14:05 -0800957 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800958 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800959
960 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
961 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800962 }
Josh Gao01052222017-01-09 16:43:33 -0800963 if (!testcase.GetTestSuccess(test_id)) {
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700964 all_tests_passed = false;
965 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800966
967 it = child_proc_list.erase(it);
968 } else {
969 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800970 }
971 }
972 }
973
Yabin Cui657b1f92015-01-22 19:26:12 -0800974 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
975 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
976 if (!xml_output_filename.empty()) {
977 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
978 elapsed_time_ns);
979 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800980 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800981
Yabin Cui767fb1c2015-09-01 15:06:39 -0700982 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800983 exit(1);
984 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700985
986 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800987}
988
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700989static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800990 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800991}
992
Yabin Cuiead08142015-02-04 20:53:56 -0800993static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
994 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
995 // test program via a valid path that contains at least one path separator.
996 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
997 // and execve() doesn't read environment variable PATH, so execve() will not success
998 // until we specify the absolute path or relative path of the test program directly.
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -0700999 if (strchr(args[0], '/') == nullptr) {
1000 args[0] = strdup(g_executable_path.c_str());
Yabin Cuiead08142015-02-04 20:53:56 -08001001 }
1002}
1003
Yabin Cui11c43532015-01-28 14:28:14 -08001004static void AddGtestFilterSynonym(std::vector<char*>& args) {
1005 // Support --gtest-filter as a synonym for --gtest_filter.
1006 for (size_t i = 1; i < args.size(); ++i) {
1007 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
1008 args[i][7] = '_';
1009 }
1010 }
1011}
1012
Yabin Cui657b1f92015-01-22 19:26:12 -08001013struct IsolationTestOptions {
1014 bool isolate;
1015 size_t job_count;
1016 int test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001017 int test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001018 std::string gtest_color;
1019 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -07001020 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -08001021 std::string gtest_output;
1022};
1023
1024// 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 -08001025// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -08001026// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
1027// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -08001028// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -08001029// args is used to pass in all command arguments, and pass out only the part of options for gtest.
1030// options is used to pass out test options in isolation mode.
1031// Return false if there is error in arguments.
1032static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
1033 for (size_t i = 1; i < args.size(); ++i) {
1034 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001035 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -08001036 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001037 return true;
1038 }
1039 }
1040
Yabin Cuiead08142015-02-04 20:53:56 -08001041 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -08001042 AddGtestFilterSynonym(args);
1043
Yabin Cui657b1f92015-01-22 19:26:12 -08001044 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
1045 bool enable_selftest = false;
1046 for (size_t i = 1; i < args.size(); ++i) {
1047 if (strcmp(args[i], "--bionic-selftest") == 0) {
1048 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
1049 // Don't remove this option from arguments.
1050 enable_selftest = true;
1051 }
1052 }
1053 std::string gtest_filter_str;
1054 for (size_t i = args.size() - 1; i >= 1; --i) {
1055 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
Yabin Cuic641a952016-12-12 13:32:15 -08001056 gtest_filter_str = args[i] + strlen("--gtest_filter=");
Yabin Cui657b1f92015-01-22 19:26:12 -08001057 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -08001058 break;
1059 }
1060 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001061 if (enable_selftest == true) {
Yabin Cuic641a952016-12-12 13:32:15 -08001062 gtest_filter_str = "bionic_selftest*";
Yabin Cui657b1f92015-01-22 19:26:12 -08001063 } else {
Yabin Cuic641a952016-12-12 13:32:15 -08001064 if (gtest_filter_str.empty()) {
1065 gtest_filter_str = "-bionic_selftest*";
Yabin Cui657b1f92015-01-22 19:26:12 -08001066 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001067 // Find if '-' for NEGATIVE_PATTERNS exists.
wy828b9e12017-05-10 15:21:13 -07001068 if (gtest_filter_str.find('-') != std::string::npos) {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001069 gtest_filter_str += ":bionic_selftest*";
1070 } else {
1071 gtest_filter_str += ":-bionic_selftest*";
1072 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001073 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001074 }
Yabin Cuic641a952016-12-12 13:32:15 -08001075 gtest_filter_str = "--gtest_filter=" + gtest_filter_str;
1076 args.push_back(strdup(gtest_filter_str.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -08001077
Yabin Cui657b1f92015-01-22 19:26:12 -08001078 options.isolate = true;
1079 // Parse arguments that make us can't run in isolation mode.
1080 for (size_t i = 1; i < args.size(); ++i) {
1081 if (strcmp(args[i], "--no-isolate") == 0) {
1082 options.isolate = false;
1083 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
1084 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001085 }
1086 }
1087
Yabin Cui657b1f92015-01-22 19:26:12 -08001088 // Stop parsing if we will not run in isolation mode.
1089 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001090 return true;
1091 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001092
1093 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -07001094 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -08001095 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001096 options.test_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui657b1f92015-01-22 19:26:12 -08001097 options.gtest_color = testing::GTEST_FLAG(color);
1098 options.gtest_print_time = testing::GTEST_FLAG(print_time);
1099 options.gtest_repeat = testing::GTEST_FLAG(repeat);
1100 options.gtest_output = testing::GTEST_FLAG(output);
1101
1102 // Parse arguments speficied for isolation mode.
1103 for (size_t i = 1; i < args.size(); ++i) {
1104 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1105 char* p = args[i] + strlen("-j");
1106 int count = 0;
1107 if (*p != '\0') {
1108 // Argument like -j5.
1109 count = atoi(p);
1110 } else if (args.size() > i + 1) {
1111 // Arguments like -j 5.
1112 count = atoi(args[i + 1]);
1113 ++i;
1114 }
1115 if (count <= 0) {
1116 fprintf(stderr, "invalid job count: %d\n", count);
1117 return false;
1118 }
1119 options.job_count = static_cast<size_t>(count);
1120 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1121 int time_ms = atoi(args[i] + strlen("--deadline="));
1122 if (time_ms <= 0) {
1123 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1124 return false;
1125 }
1126 options.test_deadline_ms = time_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001127 } else if (strncmp(args[i], "--slow-threshold=", strlen("--slow-threshold=")) == 0) {
1128 int time_ms = atoi(args[i] + strlen("--slow-threshold="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001129 if (time_ms <= 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -07001130 fprintf(stderr, "invalid slow test threshold: %d\n", time_ms);
Yabin Cui657b1f92015-01-22 19:26:12 -08001131 return false;
1132 }
Elliott Hughesa456fae2016-08-31 13:30:14 -07001133 options.test_slow_threshold_ms = time_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001134 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1135 options.gtest_color = args[i] + strlen("--gtest_color=");
1136 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1137 options.gtest_print_time = false;
1138 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001139 // If the value of gtest_repeat is < 0, then it indicates the tests
1140 // should be repeated forever.
1141 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001142 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1143 args.erase(args.begin() + i);
1144 --i;
1145 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1146 std::string output = args[i] + strlen("--gtest_output=");
1147 // generate output xml file path according to the strategy in gtest.
1148 bool success = true;
1149 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1150 output = output.substr(strlen("xml:"));
1151 if (output.size() == 0) {
1152 success = false;
1153 }
1154 // Make absolute path.
1155 if (success && output[0] != '/') {
1156 char* cwd = getcwd(NULL, 0);
1157 if (cwd != NULL) {
1158 output = std::string(cwd) + "/" + output;
1159 free(cwd);
1160 } else {
1161 success = false;
1162 }
1163 }
1164 // Add file name if output is a directory.
1165 if (success && output.back() == '/') {
1166 output += "test_details.xml";
1167 }
1168 }
1169 if (success) {
1170 options.gtest_output = output;
1171 } else {
1172 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1173 return false;
1174 }
1175
1176 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1177 args.erase(args.begin() + i);
1178 --i;
1179 }
1180 }
1181
1182 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1183 // As DeathTest will try to call execve(), this argument should always be added.
1184 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001185 return true;
1186}
1187
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001188static std::string get_proc_self_exe() {
1189 char path[PATH_MAX];
1190 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
1191 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
1192 perror("readlink");
1193 exit(1);
1194 }
1195
1196 return std::string(path, path_len);
1197}
1198
Dimitry Ivanov55437462016-07-20 15:33:07 -07001199int main(int argc, char** argv, char** envp) {
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001200 g_executable_path = get_proc_self_exe();
Dimitry Ivanov55437462016-07-20 15:33:07 -07001201 g_argc = argc;
1202 g_argv = argv;
1203 g_envp = envp;
Yabin Cuibe837362015-01-02 18:45:37 -08001204 std::vector<char*> arg_list;
1205 for (int i = 0; i < argc; ++i) {
1206 arg_list.push_back(argv[i]);
1207 }
Yabin Cuibe837362015-01-02 18:45:37 -08001208
Yabin Cui657b1f92015-01-22 19:26:12 -08001209 IsolationTestOptions options;
1210 if (PickOptions(arg_list, options) == false) {
1211 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001212 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001213
1214 if (options.isolate == true) {
1215 // Set global variables.
1216 global_test_run_deadline_ms = options.test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001217 global_test_run_slow_threshold_ms = options.test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001218 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1219 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1220 std::vector<TestCase> testcase_list;
1221
1222 argc = static_cast<int>(arg_list.size());
1223 arg_list.push_back(NULL);
1224 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1225 return 1;
1226 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001227 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1228 options.gtest_repeat, options.job_count, options.gtest_output);
1229 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001230 } else {
1231 argc = static_cast<int>(arg_list.size());
1232 arg_list.push_back(NULL);
1233 testing::InitGoogleTest(&argc, arg_list.data());
1234 return RUN_ALL_TESTS();
1235 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001236}
1237
1238//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001239// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001240
Yabin Cuibe837362015-01-02 18:45:37 -08001241TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001242 ASSERT_EQ(1, 1);
1243}
1244
Yabin Cuibe837362015-01-02 18:45:37 -08001245TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001246 ASSERT_EQ(0, 1);
1247}
1248
Yabin Cuibe837362015-01-02 18:45:37 -08001249TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001250 sleep(4);
1251}
1252
Yabin Cuibe837362015-01-02 18:45:37 -08001253TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001254 while (1) {}
1255}
Yabin Cuibe837362015-01-02 18:45:37 -08001256
1257TEST(bionic_selftest, test_signal_SEGV_terminated) {
1258 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1259 *p = 3;
1260}
Yabin Cui657b1f92015-01-22 19:26:12 -08001261
Yabin Cui767fb1c2015-09-01 15:06:39 -07001262class bionic_selftest_DeathTest : public ::testing::Test {
1263 protected:
1264 virtual void SetUp() {
1265 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1266 }
1267};
Yabin Cui657b1f92015-01-22 19:26:12 -08001268
1269static void deathtest_helper_success() {
1270 ASSERT_EQ(1, 1);
1271 exit(0);
1272}
1273
1274TEST_F(bionic_selftest_DeathTest, success) {
1275 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1276}
1277
1278static void deathtest_helper_fail() {
1279 ASSERT_EQ(1, 0);
1280}
1281
1282TEST_F(bionic_selftest_DeathTest, fail) {
1283 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1284}