blob: ba29825f86739f3bd539a9b0623930e6226888a0 [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>
Elliott Hughes10ba4bd2017-11-14 13:11:41 -080026#include <spawn.h>
Yabin Cui294d1e22014-12-07 20:43:37 -080027#include <stdarg.h>
28#include <stdio.h>
29#include <string.h>
30#include <sys/wait.h>
Yabin Cui294d1e22014-12-07 20:43:37 -080031#include <unistd.h>
32
Yabin Cui767fb1c2015-09-01 15:06:39 -070033#include <chrono>
Yabin Cui294d1e22014-12-07 20:43:37 -080034#include <string>
35#include <tuple>
36#include <utility>
37#include <vector>
38
Elliott Hughes10ba4bd2017-11-14 13:11:41 -080039#include <android-base/file.h>
40#include <android-base/strings.h>
41#include <android-base/unique_fd.h>
42
Yabin Cui767fb1c2015-09-01 15:06:39 -070043#ifndef TEMP_FAILURE_RETRY
44
45/* Used to retry syscalls that can return EINTR. */
46#define TEMP_FAILURE_RETRY(exp) ({ \
47 __typeof__(exp) _rc; \
48 do { \
49 _rc = (exp); \
50 } while (_rc == -1 && errno == EINTR); \
51 _rc; })
52
53#endif
Yabin Cui657b1f92015-01-22 19:26:12 -080054
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -070055static std::string g_executable_path;
Dimitry Ivanov55437462016-07-20 15:33:07 -070056static int g_argc;
57static char** g_argv;
58static char** g_envp;
Dimitry Ivanovd17a3772016-03-01 13:11:28 -080059
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -070060const std::string& get_executable_path() {
61 return g_executable_path;
Dimitry Ivanovd17a3772016-03-01 13:11:28 -080062}
63
Dimitry Ivanov55437462016-07-20 15:33:07 -070064int get_argc() {
65 return g_argc;
66}
67
68char** get_argv() {
69 return g_argv;
70}
71
72char** get_envp() {
73 return g_envp;
74}
75
Haibo Huang83b63792018-07-10 14:09:05 -070076static constexpr const char* COLOR_RESET = "\033[m";
77static constexpr const char* COLOR_RED = "\033[0;31m";
78static constexpr const char* COLOR_GREEN = "\033[0;32m";
79static constexpr const char* COLOR_YELLOW = "\033[0;33m";
Yabin Cui294d1e22014-12-07 20:43:37 -080080
Haibo Huangc1ef5eb2018-07-16 09:41:53 -070081static bool ShouldUseColor() {
Haibo Huangc1ef5eb2018-07-16 09:41:53 -070082 const auto& gtest_color = ::testing::GTEST_FLAG(color);
83 if (gtest_color == "yes" || gtest_color == "true" || gtest_color == "t") {
84 return true;
85 }
86 if (gtest_color != "auto") {
87 return false;
88 }
89
Tao Baoafacaab2018-07-17 18:22:14 -070090 bool stdout_is_tty = isatty(STDOUT_FILENO) != 0;
91 if (!stdout_is_tty) {
92 return false;
93 }
94
Haibo Huangc1ef5eb2018-07-16 09:41:53 -070095 const char* const term = getenv("COLORTERM");
96 return term != nullptr && term[0] != 0;
97}
98
99static void ColoredPrintf(const char* const color, const char* fmt, ...) {
100 static const bool use_color = ShouldUseColor();
101
102 va_list args;
103 va_start(args, fmt);
104
105 if (!use_color) {
106 vprintf(fmt, args);
107 } else {
Haibo Huang83b63792018-07-10 14:09:05 -0700108 printf("%s", color);
109 vprintf(fmt, args);
110 printf("%s", COLOR_RESET);
Haibo Huangc1ef5eb2018-07-16 09:41:53 -0700111 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800112
Haibo Huangc1ef5eb2018-07-16 09:41:53 -0700113 va_end(args);
Haibo Huang83b63792018-07-10 14:09:05 -0700114}
Yabin Cui294d1e22014-12-07 20:43:37 -0800115
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700116constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 90000;
Elliott Hughesa456fae2016-08-31 13:30:14 -0700117constexpr int DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -0800118
119// The time each test can run before killed for the reason of timeout.
120// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -0800121static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800122
123// The time each test can run before be warned for too much running time.
124// It takes effect only with --isolate option.
Elliott Hughesa456fae2016-08-31 13:30:14 -0700125static int global_test_run_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800126
Elliott Hughesa456fae2016-08-31 13:30:14 -0700127// Return timeout duration for a test, in ms.
128static int GetTimeoutMs(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800129 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800130}
131
Elliott Hughesa456fae2016-08-31 13:30:14 -0700132// Return threshold for calling a test slow, in ms.
133static int GetSlowThresholdMs(const std::string& /*test_name*/) {
134 return global_test_run_slow_threshold_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800135}
136
Yabin Cuibe837362015-01-02 18:45:37 -0800137static void PrintHelpInfo() {
138 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -0800139 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800140 " Run up to JOB_COUNT tests in parallel.\n"
141 " Use isolation mode, Run each test in a separate process.\n"
142 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
143 " --no-isolate\n"
144 " Don't use isolation mode, run all tests in a single process.\n"
145 " --deadline=[TIME_IN_MS]\n"
146 " Run each test in no longer than [TIME_IN_MS] time.\n"
Elliott Hughesa456fae2016-08-31 13:30:14 -0700147 " Only valid in isolation mode. Default deadline is 90000 ms.\n"
148 " --slow-threshold=[TIME_IN_MS]\n"
149 " Test running longer than [TIME_IN_MS] will be called slow.\n"
150 " Only valid in isolation mode. Default slow threshold is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -0800151 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
152 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -0800153 "Default bionic unit test option is -j.\n"
154 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
155 "running tests, or send SIGINT to the parent process to stop testing and\n"
156 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800157 "\n");
158}
159
Yabin Cui294d1e22014-12-07 20:43:37 -0800160enum TestResult {
161 TEST_SUCCESS = 0,
162 TEST_FAILED,
163 TEST_TIMEOUT
164};
165
Yabin Cui657b1f92015-01-22 19:26:12 -0800166class Test {
167 public:
168 Test() {} // For std::vector<Test>.
169 explicit Test(const char* name) : name_(name) {}
170
171 const std::string& GetName() const { return name_; }
172
Elliott Hughes93a89f82017-07-21 18:51:06 -0700173 void SetResult(TestResult result) {
174 // Native xfails are inherently likely to actually be relying on undefined
175 // behavior/uninitialized memory, and thus likely to pass from time to time
176 // on CTS. Avoid that unpleasantness by just rewriting all xfail failures
177 // as successes. You'll still see the actual failure details.
178 if (GetName().find("xfail") == 0) result = TEST_SUCCESS;
179 result_ = result;
180 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800181
182 TestResult GetResult() const { return result_; }
183
184 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
185
186 int64_t GetTestTime() const { return elapsed_time_ns_; }
187
Yabin Cuiea9c9332015-02-24 14:39:19 -0800188 void AppendTestOutput(const std::string& s) { output_ += s; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800189
Yabin Cuiea9c9332015-02-24 14:39:19 -0800190 const std::string& GetTestOutput() const { return output_; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800191
192 private:
193 const std::string name_;
194 TestResult result_;
195 int64_t elapsed_time_ns_;
Yabin Cuiea9c9332015-02-24 14:39:19 -0800196 std::string output_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800197};
198
Yabin Cui294d1e22014-12-07 20:43:37 -0800199class TestCase {
200 public:
201 TestCase() {} // For std::vector<TestCase>.
202 explicit TestCase(const char* name) : name_(name) {}
203
204 const std::string& GetName() const { return name_; }
205
Yabin Cui657b1f92015-01-22 19:26:12 -0800206 void AppendTest(const char* test_name) {
207 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800208 }
209
Yabin Cuibe837362015-01-02 18:45:37 -0800210 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800211
Yabin Cuibe837362015-01-02 18:45:37 -0800212 std::string GetTestName(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 name_ + "." + test_list_[test_id].GetName();
215 }
216
217 Test& GetTest(size_t test_id) {
218 VerifyTestId(test_id);
219 return test_list_[test_id];
220 }
221
222 const Test& GetTest(size_t test_id) const {
223 VerifyTestId(test_id);
224 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800225 }
226
Yabin Cuibe837362015-01-02 18:45:37 -0800227 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800228 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800229 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800230 }
231
Yabin Cuibe837362015-01-02 18:45:37 -0800232 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800233 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800234 return test_list_[test_id].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800235 }
236
Josh Gao01052222017-01-09 16:43:33 -0800237 bool GetTestSuccess(size_t test_id) const {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700238 return GetTestResult(test_id) == TEST_SUCCESS;
Josh Gao01052222017-01-09 16:43:33 -0800239 }
240
Yabin Cui657b1f92015-01-22 19:26:12 -0800241 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800242 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800243 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800244 }
245
Yabin Cuibe837362015-01-02 18:45:37 -0800246 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800247 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800248 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800249 }
250
251 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800252 void VerifyTestId(size_t test_id) const {
253 if(test_id >= test_list_.size()) {
254 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800255 exit(1);
256 }
257 }
258
259 private:
260 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800261 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800262};
263
Yabin Cui294d1e22014-12-07 20:43:37 -0800264class TestResultPrinter : public testing::EmptyTestEventListener {
265 public:
Yi Kong32bc0fc2018-08-02 17:31:13 -0700266 TestResultPrinter() : pinfo_(nullptr) {}
Yabin Cui294d1e22014-12-07 20:43:37 -0800267 virtual void OnTestStart(const testing::TestInfo& test_info) {
268 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
269 }
270 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800271
272 private:
273 const testing::TestInfo* pinfo_;
274};
275
276// Called after an assertion failure.
277void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
278 // If the test part succeeded, we don't need to do anything.
279 if (result.type() == testing::TestPartResult::kSuccess)
280 return;
281
282 // Print failure message from the assertion (e.g. expected this and got that).
Yabin Cuiea9c9332015-02-24 14:39:19 -0800283 printf("%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), result.line_number(),
284 pinfo_->test_case_name(), pinfo_->name(), result.message());
285 fflush(stdout);
Yabin Cui294d1e22014-12-07 20:43:37 -0800286}
287
Yabin Cui294d1e22014-12-07 20:43:37 -0800288static int64_t NanoTime() {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700289 std::chrono::nanoseconds duration(std::chrono::steady_clock::now().time_since_epoch());
290 return static_cast<int64_t>(duration.count());
Yabin Cui294d1e22014-12-07 20:43:37 -0800291}
292
293static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
Elliott Hughes5cec3772018-01-19 15:45:23 -0800294 std::vector<const char*> args(argv, argv + argc);
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800295 args.push_back("--gtest_list_tests");
296 args.push_back(nullptr);
297
298 // We use posix_spawn(3) rather than the simpler popen(3) because we don't want an intervening
299 // surprise shell invocation making quoting interesting for --gtest_filter (http://b/68949647).
300
301 android::base::unique_fd read_fd;
302 android::base::unique_fd write_fd;
303 if (!android::base::Pipe(&read_fd, &write_fd)) {
304 perror("pipe");
Yabin Cui294d1e22014-12-07 20:43:37 -0800305 return false;
306 }
307
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800308 posix_spawn_file_actions_t fa;
309 posix_spawn_file_actions_init(&fa);
310 posix_spawn_file_actions_addclose(&fa, read_fd);
311 posix_spawn_file_actions_adddup2(&fa, write_fd, 1);
312 posix_spawn_file_actions_adddup2(&fa, write_fd, 2);
313 posix_spawn_file_actions_addclose(&fa, write_fd);
Yabin Cui294d1e22014-12-07 20:43:37 -0800314
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800315 pid_t pid;
316 int result = posix_spawnp(&pid, argv[0], &fa, nullptr, const_cast<char**>(args.data()), nullptr);
317 posix_spawn_file_actions_destroy(&fa);
318 if (result == -1) {
319 perror("posix_spawn");
320 return false;
321 }
322 write_fd.reset();
323
324 std::string content;
325 if (!android::base::ReadFdToString(read_fd, &content)) {
326 perror("ReadFdToString");
327 return false;
328 }
329
330 for (auto& line : android::base::Split(content, "\n")) {
Yabin Cui5e235c82017-11-16 16:20:28 -0800331 line = android::base::Split(line, "#")[0];
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800332 line = android::base::Trim(line);
333 if (line.empty()) continue;
334 if (android::base::EndsWith(line, ".")) {
335 line.pop_back();
336 testcase_list.push_back(TestCase(line.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -0800337 } else {
Tao Bao99327892018-03-23 00:27:26 -0700338 if (testcase_list.empty()) {
339 // Invalid response from gtest - likely it has been upset by an invalid --gtest_* flag.
340 // Relay the message to user.
341 fprintf(stderr, "%s", content.c_str());
342 return false;
343 }
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800344 testcase_list.back().AppendTest(line.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800345 }
346 }
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800347
348 int status;
Elliott Hughescabc77f2017-11-28 12:55:19 -0800349 if (TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)) != pid) {
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800350 perror("waitpid");
351 return false;
352 }
353 return (WIFEXITED(status) && WEXITSTATUS(status) == 0);
Yabin Cui294d1e22014-12-07 20:43:37 -0800354}
355
Yabin Cui294d1e22014-12-07 20:43:37 -0800356// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
357// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
358// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800359static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
Elliott Hughes48de71e2016-10-28 10:04:44 -0700360 int iteration_count, size_t job_count) {
Christopher Ferris119cb552015-04-02 12:02:55 -0700361 if (iteration_count != 1) {
Yabin Cuibe837362015-01-02 18:45:37 -0800362 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800363 }
364 ColoredPrintf(COLOR_GREEN, "[==========] ");
365
Yabin Cuibe837362015-01-02 18:45:37 -0800366 size_t testcase_count = testcase_list.size();
367 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800368 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800369 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800370 }
371
Elliott Hughes48de71e2016-10-28 10:04:44 -0700372 printf("Running %zu %s from %zu %s (%zu %s).\n",
Yabin Cuibe837362015-01-02 18:45:37 -0800373 test_count, (test_count == 1) ? "test" : "tests",
Elliott Hughes48de71e2016-10-28 10:04:44 -0700374 testcase_count, (testcase_count == 1) ? "test case" : "test cases",
375 job_count, (job_count == 1) ? "job" : "jobs");
Yabin Cui294d1e22014-12-07 20:43:37 -0800376 fflush(stdout);
377}
378
Yabin Cuif6237472015-02-26 19:03:54 -0800379// bionic cts test needs gtest output format.
380#if defined(USING_GTEST_OUTPUT_FORMAT)
381
382static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
383 ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
384 printf("%s\n", testcase.GetTestName(test_id).c_str());
385
386 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
387 printf("%s", test_output.c_str());
388
389 TestResult result = testcase.GetTestResult(test_id);
Elliott Hughes93a89f82017-07-21 18:51:06 -0700390 if (result == TEST_SUCCESS) {
Yabin Cuif6237472015-02-26 19:03:54 -0800391 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
392 } else {
393 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
394 }
395 printf("%s", testcase.GetTestName(test_id).c_str());
396 if (testing::GTEST_FLAG(print_time)) {
397 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
398 }
399 printf("\n");
400 fflush(stdout);
401}
402
403#else // !defined(USING_GTEST_OUTPUT_FORMAT)
404
Yabin Cui657b1f92015-01-22 19:26:12 -0800405static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
406 TestResult result = testcase.GetTestResult(test_id);
407 if (result == TEST_SUCCESS) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700408 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800409 } else if (result == TEST_FAILED) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700410 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800411 } else if (result == TEST_TIMEOUT) {
412 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
413 }
Yabin Cuibe837362015-01-02 18:45:37 -0800414
Yabin Cui657b1f92015-01-22 19:26:12 -0800415 printf("%s", testcase.GetTestName(test_id).c_str());
416 if (testing::GTEST_FLAG(print_time)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800417 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
Yabin Cui657b1f92015-01-22 19:26:12 -0800418 }
Yabin Cuif6237472015-02-26 19:03:54 -0800419 printf("\n");
Yabin Cui657b1f92015-01-22 19:26:12 -0800420
Yabin Cuiea9c9332015-02-24 14:39:19 -0800421 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
422 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800423 fflush(stdout);
424}
425
Yabin Cuif6237472015-02-26 19:03:54 -0800426#endif // !defined(USING_GTEST_OUTPUT_FORMAT)
427
Yabin Cuibe837362015-01-02 18:45:37 -0800428static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800429 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800430
431 std::vector<std::string> fail_test_name_list;
432 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
433
Elliott Hughesa456fae2016-08-31 13:30:14 -0700434 // For tests that were slow but didn't time out.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800435 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800436 size_t testcase_count = testcase_list.size();
437 size_t test_count = 0;
438 size_t success_test_count = 0;
Josh Gao01052222017-01-09 16:43:33 -0800439 size_t expected_failure_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800440
441 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800442 test_count += testcase.TestCount();
443 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800444 TestResult result = testcase.GetTestResult(i);
Josh Gao01052222017-01-09 16:43:33 -0800445 if (result == TEST_TIMEOUT) {
446 timeout_test_list.push_back(
447 std::make_pair(testcase.GetTestName(i), testcase.GetTestTime(i)));
Elliott Hughes93a89f82017-07-21 18:51:06 -0700448 } else if (result == TEST_SUCCESS) {
449 ++success_test_count;
450 if (testcase.GetTestName(i).find(".xfail_") != std::string::npos) ++expected_failure_count;
451 } else if (result == TEST_FAILED) {
Josh Gao01052222017-01-09 16:43:33 -0800452 fail_test_name_list.push_back(testcase.GetTestName(i));
Yabin Cui294d1e22014-12-07 20:43:37 -0800453 }
454 if (result != TEST_TIMEOUT &&
Elliott Hughesa456fae2016-08-31 13:30:14 -0700455 testcase.GetTestTime(i) / 1000000 >= GetSlowThresholdMs(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800456 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
457 testcase.GetTestTime(i),
Elliott Hughesa456fae2016-08-31 13:30:14 -0700458 GetSlowThresholdMs(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800459 }
460 }
461 }
462
Yabin Cui294d1e22014-12-07 20:43:37 -0800463 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800464 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
465 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800466 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800467 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800468 }
469 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800470 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Josh Gao01052222017-01-09 16:43:33 -0800471 printf("%zu %s.", success_test_count, (success_test_count == 1) ? "test" : "tests");
472 if (expected_failure_count > 0) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700473 printf(" (%zu expected failure%s.)", expected_failure_count,
Josh Gao01052222017-01-09 16:43:33 -0800474 (expected_failure_count == 1) ? "" : "s");
475 }
476 printf("\n");
Yabin Cui294d1e22014-12-07 20:43:37 -0800477
Elliott Hughesa456fae2016-08-31 13:30:14 -0700478 // Print tests that timed out.
Yabin Cuibe837362015-01-02 18:45:37 -0800479 size_t timeout_test_count = timeout_test_list.size();
480 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800481 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800482 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800483 for (const auto& timeout_pair : timeout_test_list) {
484 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800485 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
486 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800487 }
488 }
489
Elliott Hughesa456fae2016-08-31 13:30:14 -0700490 // Print tests that were slow.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800491 size_t slow_test_count = slow_test_list.size();
492 if (slow_test_count > 0) {
493 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
494 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
495 for (const auto& slow_tuple : slow_test_list) {
496 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
Elliott Hughesa456fae2016-08-31 13:30:14 -0700497 printf("%s (%" PRId64 " ms, exceeded %d ms)\n", std::get<0>(slow_tuple).c_str(),
Yabin Cui4a82ede2015-01-26 17:19:37 -0800498 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800499 }
500 }
501
Elliott Hughesa456fae2016-08-31 13:30:14 -0700502 // Print tests that failed.
503 size_t fail_test_count = fail_test_name_list.size();
Yabin Cuibe837362015-01-02 18:45:37 -0800504 if (fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700505 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
506 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
507 for (const auto& name : fail_test_name_list) {
508 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
509 printf("%s\n", name.c_str());
510 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800511 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700512
Elliott Hughes93a89f82017-07-21 18:51:06 -0700513 if (timeout_test_count > 0 || slow_test_count > 0 || fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700514 printf("\n");
515 }
516
Yabin Cuibe837362015-01-02 18:45:37 -0800517 if (timeout_test_count > 0) {
518 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800519 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800520 if (slow_test_count > 0) {
521 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800522 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700523 if (fail_test_count > 0) {
524 printf("%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
525 }
Josh Gao01052222017-01-09 16:43:33 -0800526
Yabin Cui294d1e22014-12-07 20:43:37 -0800527 fflush(stdout);
528}
529
Dan Albert09a99642016-01-13 21:48:56 -0800530std::string XmlEscape(const std::string& xml) {
531 std::string escaped;
532 escaped.reserve(xml.size());
533
534 for (auto c : xml) {
535 switch (c) {
536 case '<':
537 escaped.append("&lt;");
538 break;
539 case '>':
540 escaped.append("&gt;");
541 break;
542 case '&':
543 escaped.append("&amp;");
544 break;
545 case '\'':
546 escaped.append("&apos;");
547 break;
548 case '"':
549 escaped.append("&quot;");
550 break;
551 default:
552 escaped.append(1, c);
553 break;
554 }
555 }
556
557 return escaped;
558}
559
Yabin Cui657b1f92015-01-22 19:26:12 -0800560// Output xml file when --gtest_output is used, write this function as we can't reuse
561// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
562// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
563// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
564void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
565 const std::vector<TestCase>& testcase_list,
566 time_t epoch_iteration_start_time,
567 int64_t elapsed_time_ns) {
Elliott Hughes5cec3772018-01-19 15:45:23 -0800568 FILE* fp = fopen(xml_output_filename.c_str(), "we");
Yi Kong32bc0fc2018-08-02 17:31:13 -0700569 if (fp == nullptr) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800570 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
571 exit(1);
572 }
573
574 size_t total_test_count = 0;
575 size_t total_failed_count = 0;
576 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
577 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
578 for (size_t i = 0; i < testcase_list.size(); ++i) {
579 auto& testcase = testcase_list[i];
580 total_test_count += testcase.TestCount();
581 for (size_t j = 0; j < testcase.TestCount(); ++j) {
Josh Gao01052222017-01-09 16:43:33 -0800582 if (!testcase.GetTestSuccess(j)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800583 ++failed_count_list[i];
584 }
585 elapsed_time_list[i] += testcase.GetTestTime(j);
586 }
587 total_failed_count += failed_count_list[i];
588 }
589
590 const tm* time_struct = localtime(&epoch_iteration_start_time);
591 char timestamp[40];
592 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
593 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
594 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
595
596 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
597 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
598 total_test_count, total_failed_count);
599 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
600 for (size_t i = 0; i < testcase_list.size(); ++i) {
601 auto& testcase = testcase_list[i];
602 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
603 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
604 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
605
606 for (size_t j = 0; j < testcase.TestCount(); ++j) {
607 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
608 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
609 testcase.GetName().c_str());
Josh Gao01052222017-01-09 16:43:33 -0800610 if (!testcase.GetTestSuccess(j)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800611 fputs(" />\n", fp);
612 } else {
613 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800614 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
Dan Albert09a99642016-01-13 21:48:56 -0800615 const std::string escaped_test_output = XmlEscape(test_output);
616 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", escaped_test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800617 fputs(" </failure>\n", fp);
618 fputs(" </testcase>\n", fp);
619 }
620 }
621
622 fputs(" </testsuite>\n", fp);
623 }
624 fputs("</testsuites>\n", fp);
625 fclose(fp);
626}
627
Yabin Cui767fb1c2015-09-01 15:06:39 -0700628static bool sigint_flag;
629static bool sigquit_flag;
630
631static void signal_handler(int sig) {
632 if (sig == SIGINT) {
633 sigint_flag = true;
634 } else if (sig == SIGQUIT) {
635 sigquit_flag = true;
636 }
637}
638
639static bool RegisterSignalHandler() {
640 sigint_flag = false;
641 sigquit_flag = false;
642 sig_t ret = signal(SIGINT, signal_handler);
643 if (ret != SIG_ERR) {
644 ret = signal(SIGQUIT, signal_handler);
645 }
646 if (ret == SIG_ERR) {
647 perror("RegisterSignalHandler");
648 return false;
649 }
650 return true;
651}
652
653static bool UnregisterSignalHandler() {
654 sig_t ret = signal(SIGINT, SIG_DFL);
655 if (ret != SIG_ERR) {
656 ret = signal(SIGQUIT, SIG_DFL);
657 }
658 if (ret == SIG_ERR) {
659 perror("UnregisterSignalHandler");
660 return false;
661 }
662 return true;
663}
664
Yabin Cui1d4c7802015-02-02 19:14:05 -0800665struct ChildProcInfo {
666 pid_t pid;
667 int64_t start_time_ns;
668 int64_t end_time_ns;
669 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
670 size_t testcase_id, test_id;
671 bool finished;
672 bool timed_out;
673 int exit_status;
674 int child_read_fd; // File descriptor to read child test failure info.
675};
676
Yabin Cui294d1e22014-12-07 20:43:37 -0800677// Forked Child process, run the single test.
678static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800679 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800680 memcpy(new_argv, argv, sizeof(char*) * argc);
681
682 char* filter_arg = new char [test_name.size() + 20];
683 strcpy(filter_arg, "--gtest_filter=");
684 strcat(filter_arg, test_name.c_str());
685 new_argv[argc] = filter_arg;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700686 new_argv[argc + 1] = nullptr;
Yabin Cui294d1e22014-12-07 20:43:37 -0800687
688 int new_argc = argc + 1;
689 testing::InitGoogleTest(&new_argc, new_argv);
690 int result = RUN_ALL_TESTS();
691 exit(result);
692}
693
Yabin Cui1d4c7802015-02-02 19:14:05 -0800694static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700695 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800696 int pipefd[2];
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800697 if (pipe(pipefd) == -1) {
698 perror("pipe in RunTestInSeparateProc");
699 exit(1);
700 }
701 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
702 perror("fcntl in RunTestInSeparateProc");
Yabin Cui1d4c7802015-02-02 19:14:05 -0800703 exit(1);
704 }
705 pid_t pid = fork();
706 if (pid == -1) {
707 perror("fork in RunTestInSeparateProc");
708 exit(1);
709 } else if (pid == 0) {
710 // In child process, run a single test.
711 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800712 close(STDOUT_FILENO);
713 close(STDERR_FILENO);
714 dup2(pipefd[1], STDOUT_FILENO);
715 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800716
Yabin Cui767fb1c2015-09-01 15:06:39 -0700717 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800718 exit(1);
719 }
720 ChildProcessFn(argc, argv, test_name);
721 // Unreachable.
722 }
723 // In parent process, initialize child process info.
724 close(pipefd[1]);
725 ChildProcInfo child_proc;
726 child_proc.child_read_fd = pipefd[0];
727 child_proc.pid = pid;
728 child_proc.start_time_ns = NanoTime();
Elliott Hughesa456fae2016-08-31 13:30:14 -0700729 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetTimeoutMs(test_name) * 1000000LL;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800730 child_proc.testcase_id = testcase_id;
731 child_proc.test_id = test_id;
732 child_proc.finished = false;
733 return child_proc;
734}
Yabin Cui294d1e22014-12-07 20:43:37 -0800735
Yabin Cui1d4c7802015-02-02 19:14:05 -0800736static void HandleSignals(std::vector<TestCase>& testcase_list,
737 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700738 if (sigquit_flag) {
739 sigquit_flag = false;
740 // Print current running tests.
741 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700742 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700743 if (child_proc.pid != 0) {
744 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
745 int64_t current_time_ns = NanoTime();
746 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
747 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800748 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800749 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700750 } else if (sigint_flag) {
751 sigint_flag = false;
752 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700753 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700754 if (child_proc.pid != 0) {
755 // Send SIGKILL to ensure the child process can be killed unconditionally.
756 kill(child_proc.pid, SIGKILL);
757 }
758 }
759 // SIGINT kills the parent process as well.
760 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800761 }
762}
763
764static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
765 std::vector<ChildProcInfo>& child_proc_list) {
766 for (size_t i = 0; i < child_proc_list.size(); ++i) {
767 if (child_proc_list[i].pid == exit_pid) {
768 child_proc_list[i].finished = true;
769 child_proc_list[i].timed_out = false;
770 child_proc_list[i].exit_status = exit_status;
771 child_proc_list[i].end_time_ns = NanoTime();
772 return true;
773 }
774 }
775 return false;
776}
777
778static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
779 int64_t current_time_ns = NanoTime();
780 size_t timeout_child_count = 0;
781 for (size_t i = 0; i < child_proc_list.size(); ++i) {
782 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
783 child_proc_list[i].finished = true;
784 child_proc_list[i].timed_out = true;
785 child_proc_list[i].end_time_ns = current_time_ns;
786 ++timeout_child_count;
787 }
788 }
789 return timeout_child_count;
790}
791
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800792static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
793 std::vector<ChildProcInfo>& child_proc_list) {
794 for (const auto& child_proc : child_proc_list) {
795 TestCase& testcase = testcase_list[child_proc.testcase_id];
796 int test_id = child_proc.test_id;
797 while (true) {
798 char buf[1024];
799 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
800 if (bytes_read > 0) {
801 buf[bytes_read] = '\0';
802 testcase.GetTest(test_id).AppendTestOutput(buf);
803 } else if (bytes_read == 0) {
804 break; // Read end.
805 } else {
806 if (errno == EAGAIN) {
807 break;
808 }
809 perror("failed to read child_read_fd");
810 exit(1);
811 }
812 }
813 }
814}
815
Yabin Cui1d4c7802015-02-02 19:14:05 -0800816static void WaitChildProcs(std::vector<TestCase>& testcase_list,
817 std::vector<ChildProcInfo>& child_proc_list) {
818 size_t finished_child_count = 0;
819 while (true) {
820 int status;
821 pid_t result;
822 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
823 if (CheckChildProcExit(result, status, child_proc_list)) {
824 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800825 }
826 }
827
828 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800829 if (errno == ECHILD) {
830 // This happens when we have no running child processes.
831 return;
832 } else {
833 perror("waitpid");
834 exit(1);
835 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800836 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800837 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800838 }
839
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800840 ReadChildProcOutput(testcase_list, child_proc_list);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800841 if (finished_child_count > 0) {
842 return;
843 }
844
845 HandleSignals(testcase_list, child_proc_list);
846
Yabin Cui294d1e22014-12-07 20:43:37 -0800847 // sleep 1 ms to avoid busy looping.
848 timespec sleep_time;
849 sleep_time.tv_sec = 0;
850 sleep_time.tv_nsec = 1000000;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700851 nanosleep(&sleep_time, nullptr);
Yabin Cui294d1e22014-12-07 20:43:37 -0800852 }
853}
854
Yabin Cui1d4c7802015-02-02 19:14:05 -0800855static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800856 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800857 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800858
859 TestResult test_result = TEST_SUCCESS;
860 if (result != pid || WEXITSTATUS(exit_status) != 0) {
861 test_result = TEST_FAILED;
862 }
863 return test_result;
864}
865
Yabin Cui1d4c7802015-02-02 19:14:05 -0800866static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
867 int test_id = child_proc.test_id;
868 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
869 if (child_proc.timed_out) {
870 // The child process marked as timed_out has not exited, and we should kill it manually.
871 kill(child_proc.pid, SIGKILL);
872 WaitForOneChild(child_proc.pid);
873 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800874 close(child_proc.child_read_fd);
875
876 if (child_proc.timed_out) {
877 testcase.SetTestResult(test_id, TEST_TIMEOUT);
878 char buf[1024];
879 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
880 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800881 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800882
883 } else if (WIFSIGNALED(child_proc.exit_status)) {
884 // Record signal terminated test as failed.
885 testcase.SetTestResult(test_id, TEST_FAILED);
886 char buf[1024];
887 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
888 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800889 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800890
891 } else {
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800892 int exitcode = WEXITSTATUS(child_proc.exit_status);
893 testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
894 if (exitcode != 0) {
Yabin Cuia32fc862015-12-03 16:28:03 -0800895 char buf[1024];
896 snprintf(buf, sizeof(buf), "%s exited with exitcode %d.\n",
897 testcase.GetTestName(test_id).c_str(), exitcode);
898 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800899 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800900 }
901}
902
Yabin Cui294d1e22014-12-07 20:43:37 -0800903// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
904// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700905// Returns true if all tests run successfully, otherwise return false.
906static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700907 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800908 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800909 // Stop default result printer to avoid environment setup/teardown information for each test.
910 testing::UnitTest::GetInstance()->listeners().Release(
911 testing::UnitTest::GetInstance()->listeners().default_result_printer());
912 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
913
Yabin Cui767fb1c2015-09-01 15:06:39 -0700914 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800915 exit(1);
916 }
917
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700918 bool all_tests_passed = true;
919
Christopher Ferris119cb552015-04-02 12:02:55 -0700920 for (size_t iteration = 1;
921 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
922 ++iteration) {
Elliott Hughes48de71e2016-10-28 10:04:44 -0700923 OnTestIterationStartPrint(testcase_list, iteration, iteration_count, job_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800924 int64_t iteration_start_time_ns = NanoTime();
Yi Kong32bc0fc2018-08-02 17:31:13 -0700925 time_t epoch_iteration_start_time = time(nullptr);
Yabin Cui294d1e22014-12-07 20:43:37 -0800926
Yabin Cuibe837362015-01-02 18:45:37 -0800927 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800928 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800929
Yabin Cuibe837362015-01-02 18:45:37 -0800930 // Next test to run is [next_testcase_id:next_test_id].
931 size_t next_testcase_id = 0;
932 size_t next_test_id = 0;
933
934 // Record how many tests are finished.
935 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
936 size_t finished_testcase_count = 0;
937
938 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800939 // run up to job_count child processes.
940 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
941 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
942 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700943 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800944 child_proc_list.push_back(child_proc);
945 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
946 next_test_id = 0;
947 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800948 }
949 }
950
951 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800952 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800953
954 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800955 auto it = child_proc_list.begin();
956 while (it != child_proc_list.end()) {
957 auto& child_proc = *it;
958 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800959 size_t testcase_id = child_proc.testcase_id;
960 size_t test_id = child_proc.test_id;
961 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800962
Yabin Cui1d4c7802015-02-02 19:14:05 -0800963 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800964 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800965
966 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
967 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800968 }
Josh Gao01052222017-01-09 16:43:33 -0800969 if (!testcase.GetTestSuccess(test_id)) {
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700970 all_tests_passed = false;
971 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800972
973 it = child_proc_list.erase(it);
974 } else {
975 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800976 }
977 }
978 }
979
Yabin Cui657b1f92015-01-22 19:26:12 -0800980 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
981 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
982 if (!xml_output_filename.empty()) {
983 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
984 elapsed_time_ns);
985 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800986 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800987
Yabin Cui767fb1c2015-09-01 15:06:39 -0700988 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800989 exit(1);
990 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700991
992 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800993}
994
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700995static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800996 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800997}
998
Yabin Cuiead08142015-02-04 20:53:56 -0800999static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
1000 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
1001 // test program via a valid path that contains at least one path separator.
1002 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
1003 // and execve() doesn't read environment variable PATH, so execve() will not success
1004 // until we specify the absolute path or relative path of the test program directly.
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001005 if (strchr(args[0], '/') == nullptr) {
1006 args[0] = strdup(g_executable_path.c_str());
Yabin Cuiead08142015-02-04 20:53:56 -08001007 }
1008}
1009
Yabin Cui11c43532015-01-28 14:28:14 -08001010static void AddGtestFilterSynonym(std::vector<char*>& args) {
1011 // Support --gtest-filter as a synonym for --gtest_filter.
1012 for (size_t i = 1; i < args.size(); ++i) {
1013 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
1014 args[i][7] = '_';
1015 }
1016 }
1017}
1018
Yabin Cui657b1f92015-01-22 19:26:12 -08001019struct IsolationTestOptions {
1020 bool isolate;
1021 size_t job_count;
1022 int test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001023 int test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001024 std::string gtest_color;
1025 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -07001026 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -08001027 std::string gtest_output;
1028};
1029
1030// 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 -08001031// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -08001032// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
1033// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -08001034// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -08001035// args is used to pass in all command arguments, and pass out only the part of options for gtest.
1036// options is used to pass out test options in isolation mode.
1037// Return false if there is error in arguments.
1038static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
1039 for (size_t i = 1; i < args.size(); ++i) {
1040 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001041 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -08001042 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001043 return true;
1044 }
1045 }
1046
Yabin Cuiead08142015-02-04 20:53:56 -08001047 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -08001048 AddGtestFilterSynonym(args);
1049
Yabin Cui657b1f92015-01-22 19:26:12 -08001050 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
1051 bool enable_selftest = false;
1052 for (size_t i = 1; i < args.size(); ++i) {
1053 if (strcmp(args[i], "--bionic-selftest") == 0) {
1054 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
1055 // Don't remove this option from arguments.
1056 enable_selftest = true;
1057 }
1058 }
1059 std::string gtest_filter_str;
1060 for (size_t i = args.size() - 1; i >= 1; --i) {
1061 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
Yabin Cuic641a952016-12-12 13:32:15 -08001062 gtest_filter_str = args[i] + strlen("--gtest_filter=");
Yabin Cui657b1f92015-01-22 19:26:12 -08001063 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -08001064 break;
1065 }
1066 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001067 if (enable_selftest == true) {
Yabin Cuic641a952016-12-12 13:32:15 -08001068 gtest_filter_str = "bionic_selftest*";
Yabin Cui657b1f92015-01-22 19:26:12 -08001069 } else {
Yabin Cuic641a952016-12-12 13:32:15 -08001070 if (gtest_filter_str.empty()) {
1071 gtest_filter_str = "-bionic_selftest*";
Yabin Cui657b1f92015-01-22 19:26:12 -08001072 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001073 // Find if '-' for NEGATIVE_PATTERNS exists.
wy828b9e12017-05-10 15:21:13 -07001074 if (gtest_filter_str.find('-') != std::string::npos) {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001075 gtest_filter_str += ":bionic_selftest*";
1076 } else {
1077 gtest_filter_str += ":-bionic_selftest*";
1078 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001079 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001080 }
Yabin Cuic641a952016-12-12 13:32:15 -08001081 gtest_filter_str = "--gtest_filter=" + gtest_filter_str;
1082 args.push_back(strdup(gtest_filter_str.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -08001083
Yabin Cui657b1f92015-01-22 19:26:12 -08001084 options.isolate = true;
1085 // Parse arguments that make us can't run in isolation mode.
1086 for (size_t i = 1; i < args.size(); ++i) {
1087 if (strcmp(args[i], "--no-isolate") == 0) {
1088 options.isolate = false;
1089 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
1090 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001091 }
1092 }
1093
Yabin Cui657b1f92015-01-22 19:26:12 -08001094 // Stop parsing if we will not run in isolation mode.
1095 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001096 return true;
1097 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001098
1099 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -07001100 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -08001101 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001102 options.test_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui657b1f92015-01-22 19:26:12 -08001103 options.gtest_color = testing::GTEST_FLAG(color);
1104 options.gtest_print_time = testing::GTEST_FLAG(print_time);
1105 options.gtest_repeat = testing::GTEST_FLAG(repeat);
1106 options.gtest_output = testing::GTEST_FLAG(output);
1107
1108 // Parse arguments speficied for isolation mode.
1109 for (size_t i = 1; i < args.size(); ++i) {
1110 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1111 char* p = args[i] + strlen("-j");
1112 int count = 0;
1113 if (*p != '\0') {
1114 // Argument like -j5.
1115 count = atoi(p);
1116 } else if (args.size() > i + 1) {
1117 // Arguments like -j 5.
1118 count = atoi(args[i + 1]);
1119 ++i;
1120 }
1121 if (count <= 0) {
1122 fprintf(stderr, "invalid job count: %d\n", count);
1123 return false;
1124 }
1125 options.job_count = static_cast<size_t>(count);
1126 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1127 int time_ms = atoi(args[i] + strlen("--deadline="));
1128 if (time_ms <= 0) {
1129 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1130 return false;
1131 }
1132 options.test_deadline_ms = time_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001133 } else if (strncmp(args[i], "--slow-threshold=", strlen("--slow-threshold=")) == 0) {
1134 int time_ms = atoi(args[i] + strlen("--slow-threshold="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001135 if (time_ms <= 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -07001136 fprintf(stderr, "invalid slow test threshold: %d\n", time_ms);
Yabin Cui657b1f92015-01-22 19:26:12 -08001137 return false;
1138 }
Elliott Hughesa456fae2016-08-31 13:30:14 -07001139 options.test_slow_threshold_ms = time_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001140 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1141 options.gtest_color = args[i] + strlen("--gtest_color=");
1142 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1143 options.gtest_print_time = false;
1144 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001145 // If the value of gtest_repeat is < 0, then it indicates the tests
1146 // should be repeated forever.
1147 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001148 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1149 args.erase(args.begin() + i);
1150 --i;
1151 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1152 std::string output = args[i] + strlen("--gtest_output=");
1153 // generate output xml file path according to the strategy in gtest.
1154 bool success = true;
1155 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1156 output = output.substr(strlen("xml:"));
1157 if (output.size() == 0) {
1158 success = false;
1159 }
1160 // Make absolute path.
1161 if (success && output[0] != '/') {
Yi Kong32bc0fc2018-08-02 17:31:13 -07001162 char* cwd = getcwd(nullptr, 0);
1163 if (cwd != nullptr) {
Yabin Cui657b1f92015-01-22 19:26:12 -08001164 output = std::string(cwd) + "/" + output;
1165 free(cwd);
1166 } else {
1167 success = false;
1168 }
1169 }
1170 // Add file name if output is a directory.
1171 if (success && output.back() == '/') {
1172 output += "test_details.xml";
1173 }
1174 }
1175 if (success) {
1176 options.gtest_output = output;
1177 } else {
1178 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1179 return false;
1180 }
1181
1182 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1183 args.erase(args.begin() + i);
1184 --i;
1185 }
1186 }
1187
1188 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1189 // As DeathTest will try to call execve(), this argument should always be added.
1190 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001191 return true;
1192}
1193
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001194static std::string get_proc_self_exe() {
1195 char path[PATH_MAX];
1196 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
1197 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
1198 perror("readlink");
1199 exit(1);
1200 }
1201
1202 return std::string(path, path_len);
1203}
1204
Dimitry Ivanov55437462016-07-20 15:33:07 -07001205int main(int argc, char** argv, char** envp) {
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001206 g_executable_path = get_proc_self_exe();
Dimitry Ivanov55437462016-07-20 15:33:07 -07001207 g_argc = argc;
1208 g_argv = argv;
1209 g_envp = envp;
Elliott Hughes5cec3772018-01-19 15:45:23 -08001210 std::vector<char*> arg_list(argv, argv + argc);
Yabin Cuibe837362015-01-02 18:45:37 -08001211
Yabin Cui657b1f92015-01-22 19:26:12 -08001212 IsolationTestOptions options;
1213 if (PickOptions(arg_list, options) == false) {
1214 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001215 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001216
1217 if (options.isolate == true) {
1218 // Set global variables.
1219 global_test_run_deadline_ms = options.test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001220 global_test_run_slow_threshold_ms = options.test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001221 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1222 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1223 std::vector<TestCase> testcase_list;
1224
1225 argc = static_cast<int>(arg_list.size());
Yi Kong32bc0fc2018-08-02 17:31:13 -07001226 arg_list.push_back(nullptr);
Yabin Cui657b1f92015-01-22 19:26:12 -08001227 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1228 return 1;
1229 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001230 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1231 options.gtest_repeat, options.job_count, options.gtest_output);
1232 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001233 } else {
1234 argc = static_cast<int>(arg_list.size());
Yi Kong32bc0fc2018-08-02 17:31:13 -07001235 arg_list.push_back(nullptr);
Yabin Cui657b1f92015-01-22 19:26:12 -08001236 testing::InitGoogleTest(&argc, arg_list.data());
1237 return RUN_ALL_TESTS();
1238 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001239}
1240
1241//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001242// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001243
Yabin Cuibe837362015-01-02 18:45:37 -08001244TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001245 ASSERT_EQ(1, 1);
1246}
1247
Yabin Cuibe837362015-01-02 18:45:37 -08001248TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001249 ASSERT_EQ(0, 1);
1250}
1251
Yabin Cuibe837362015-01-02 18:45:37 -08001252TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001253 sleep(4);
1254}
1255
Yabin Cuibe837362015-01-02 18:45:37 -08001256TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001257 while (1) {}
1258}
Yabin Cuibe837362015-01-02 18:45:37 -08001259
1260TEST(bionic_selftest, test_signal_SEGV_terminated) {
1261 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1262 *p = 3;
1263}
Yabin Cui657b1f92015-01-22 19:26:12 -08001264
Yabin Cui767fb1c2015-09-01 15:06:39 -07001265class bionic_selftest_DeathTest : public ::testing::Test {
1266 protected:
1267 virtual void SetUp() {
1268 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1269 }
1270};
Yabin Cui657b1f92015-01-22 19:26:12 -08001271
1272static void deathtest_helper_success() {
1273 ASSERT_EQ(1, 1);
1274 exit(0);
1275}
1276
1277TEST_F(bionic_selftest_DeathTest, success) {
1278 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1279}
1280
1281static void deathtest_helper_fail() {
1282 ASSERT_EQ(1, 0);
1283}
1284
1285TEST_F(bionic_selftest_DeathTest, fail) {
1286 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1287}
Yabin Cui5e235c82017-11-16 16:20:28 -08001288
1289class BionicSelfTest : public ::testing::TestWithParam<bool> {
1290};
1291
1292TEST_P(BionicSelfTest, test_success) {
1293 ASSERT_EQ(GetParam(), GetParam());
1294}
1295
1296INSTANTIATE_TEST_CASE_P(bionic_selftest, BionicSelfTest, ::testing::Values(true, false));
1297
1298template <typename T>
1299class bionic_selftest_TestT : public ::testing::Test {
1300};
1301
1302typedef ::testing::Types<char, int> MyTypes;
1303
1304TYPED_TEST_CASE(bionic_selftest_TestT, MyTypes);
1305
1306TYPED_TEST(bionic_selftest_TestT, test_success) {
1307 ASSERT_EQ(true, true);
1308}