blob: 2bbd582903c73f06227b61fa9a27f3a497dabe37 [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);
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800312 posix_spawn_file_actions_addclose(&fa, write_fd);
Yabin Cui294d1e22014-12-07 20:43:37 -0800313
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800314 pid_t pid;
315 int result = posix_spawnp(&pid, argv[0], &fa, nullptr, const_cast<char**>(args.data()), nullptr);
316 posix_spawn_file_actions_destroy(&fa);
317 if (result == -1) {
318 perror("posix_spawn");
319 return false;
320 }
321 write_fd.reset();
322
323 std::string content;
324 if (!android::base::ReadFdToString(read_fd, &content)) {
325 perror("ReadFdToString");
326 return false;
327 }
328
329 for (auto& line : android::base::Split(content, "\n")) {
Yabin Cui5e235c82017-11-16 16:20:28 -0800330 line = android::base::Split(line, "#")[0];
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800331 line = android::base::Trim(line);
332 if (line.empty()) continue;
333 if (android::base::EndsWith(line, ".")) {
334 line.pop_back();
335 testcase_list.push_back(TestCase(line.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -0800336 } else {
Tao Bao99327892018-03-23 00:27:26 -0700337 if (testcase_list.empty()) {
338 // Invalid response from gtest - likely it has been upset by an invalid --gtest_* flag.
339 // Relay the message to user.
340 fprintf(stderr, "%s", content.c_str());
341 return false;
342 }
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800343 testcase_list.back().AppendTest(line.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800344 }
345 }
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800346
347 int status;
Elliott Hughescabc77f2017-11-28 12:55:19 -0800348 if (TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)) != pid) {
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800349 perror("waitpid");
350 return false;
351 }
352 return (WIFEXITED(status) && WEXITSTATUS(status) == 0);
Yabin Cui294d1e22014-12-07 20:43:37 -0800353}
354
Yabin Cui294d1e22014-12-07 20:43:37 -0800355// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
356// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
357// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800358static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
Elliott Hughes48de71e2016-10-28 10:04:44 -0700359 int iteration_count, size_t job_count) {
Christopher Ferris119cb552015-04-02 12:02:55 -0700360 if (iteration_count != 1) {
Yabin Cuibe837362015-01-02 18:45:37 -0800361 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800362 }
363 ColoredPrintf(COLOR_GREEN, "[==========] ");
364
Yabin Cuibe837362015-01-02 18:45:37 -0800365 size_t testcase_count = testcase_list.size();
366 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800367 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800368 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800369 }
370
Elliott Hughes48de71e2016-10-28 10:04:44 -0700371 printf("Running %zu %s from %zu %s (%zu %s).\n",
Yabin Cuibe837362015-01-02 18:45:37 -0800372 test_count, (test_count == 1) ? "test" : "tests",
Elliott Hughes48de71e2016-10-28 10:04:44 -0700373 testcase_count, (testcase_count == 1) ? "test case" : "test cases",
374 job_count, (job_count == 1) ? "job" : "jobs");
Yabin Cui294d1e22014-12-07 20:43:37 -0800375 fflush(stdout);
376}
377
Yabin Cuif6237472015-02-26 19:03:54 -0800378// bionic cts test needs gtest output format.
379#if defined(USING_GTEST_OUTPUT_FORMAT)
380
381static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
382 ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
383 printf("%s\n", testcase.GetTestName(test_id).c_str());
384
385 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
386 printf("%s", test_output.c_str());
387
388 TestResult result = testcase.GetTestResult(test_id);
Elliott Hughes93a89f82017-07-21 18:51:06 -0700389 if (result == TEST_SUCCESS) {
Yabin Cuif6237472015-02-26 19:03:54 -0800390 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
391 } else {
392 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
393 }
394 printf("%s", testcase.GetTestName(test_id).c_str());
395 if (testing::GTEST_FLAG(print_time)) {
396 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
397 }
398 printf("\n");
399 fflush(stdout);
400}
401
402#else // !defined(USING_GTEST_OUTPUT_FORMAT)
403
Yabin Cui657b1f92015-01-22 19:26:12 -0800404static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
405 TestResult result = testcase.GetTestResult(test_id);
406 if (result == TEST_SUCCESS) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700407 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800408 } else if (result == TEST_FAILED) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700409 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800410 } else if (result == TEST_TIMEOUT) {
411 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
412 }
Yabin Cuibe837362015-01-02 18:45:37 -0800413
Yabin Cui657b1f92015-01-22 19:26:12 -0800414 printf("%s", testcase.GetTestName(test_id).c_str());
415 if (testing::GTEST_FLAG(print_time)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800416 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
Yabin Cui657b1f92015-01-22 19:26:12 -0800417 }
Yabin Cuif6237472015-02-26 19:03:54 -0800418 printf("\n");
Yabin Cui657b1f92015-01-22 19:26:12 -0800419
Yabin Cuiea9c9332015-02-24 14:39:19 -0800420 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
421 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800422 fflush(stdout);
423}
424
Yabin Cuif6237472015-02-26 19:03:54 -0800425#endif // !defined(USING_GTEST_OUTPUT_FORMAT)
426
Yabin Cuibe837362015-01-02 18:45:37 -0800427static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800428 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800429
430 std::vector<std::string> fail_test_name_list;
431 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
432
Elliott Hughesa456fae2016-08-31 13:30:14 -0700433 // For tests that were slow but didn't time out.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800434 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800435 size_t testcase_count = testcase_list.size();
436 size_t test_count = 0;
437 size_t success_test_count = 0;
Josh Gao01052222017-01-09 16:43:33 -0800438 size_t expected_failure_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800439
440 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800441 test_count += testcase.TestCount();
442 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800443 TestResult result = testcase.GetTestResult(i);
Josh Gao01052222017-01-09 16:43:33 -0800444 if (result == TEST_TIMEOUT) {
445 timeout_test_list.push_back(
446 std::make_pair(testcase.GetTestName(i), testcase.GetTestTime(i)));
Elliott Hughes93a89f82017-07-21 18:51:06 -0700447 } else if (result == TEST_SUCCESS) {
448 ++success_test_count;
449 if (testcase.GetTestName(i).find(".xfail_") != std::string::npos) ++expected_failure_count;
450 } else if (result == TEST_FAILED) {
Josh Gao01052222017-01-09 16:43:33 -0800451 fail_test_name_list.push_back(testcase.GetTestName(i));
Yabin Cui294d1e22014-12-07 20:43:37 -0800452 }
453 if (result != TEST_TIMEOUT &&
Elliott Hughesa456fae2016-08-31 13:30:14 -0700454 testcase.GetTestTime(i) / 1000000 >= GetSlowThresholdMs(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800455 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
456 testcase.GetTestTime(i),
Elliott Hughesa456fae2016-08-31 13:30:14 -0700457 GetSlowThresholdMs(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800458 }
459 }
460 }
461
Yabin Cui294d1e22014-12-07 20:43:37 -0800462 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800463 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
464 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800465 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800466 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800467 }
468 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800469 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Josh Gao01052222017-01-09 16:43:33 -0800470 printf("%zu %s.", success_test_count, (success_test_count == 1) ? "test" : "tests");
471 if (expected_failure_count > 0) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700472 printf(" (%zu expected failure%s.)", expected_failure_count,
Josh Gao01052222017-01-09 16:43:33 -0800473 (expected_failure_count == 1) ? "" : "s");
474 }
475 printf("\n");
Yabin Cui294d1e22014-12-07 20:43:37 -0800476
Elliott Hughesa456fae2016-08-31 13:30:14 -0700477 // Print tests that timed out.
Yabin Cuibe837362015-01-02 18:45:37 -0800478 size_t timeout_test_count = timeout_test_list.size();
479 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800480 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800481 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800482 for (const auto& timeout_pair : timeout_test_list) {
483 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800484 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
485 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800486 }
487 }
488
Elliott Hughesa456fae2016-08-31 13:30:14 -0700489 // Print tests that were slow.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800490 size_t slow_test_count = slow_test_list.size();
491 if (slow_test_count > 0) {
492 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
493 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
494 for (const auto& slow_tuple : slow_test_list) {
495 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
Elliott Hughesa456fae2016-08-31 13:30:14 -0700496 printf("%s (%" PRId64 " ms, exceeded %d ms)\n", std::get<0>(slow_tuple).c_str(),
Yabin Cui4a82ede2015-01-26 17:19:37 -0800497 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800498 }
499 }
500
Elliott Hughesa456fae2016-08-31 13:30:14 -0700501 // Print tests that failed.
502 size_t fail_test_count = fail_test_name_list.size();
Yabin Cuibe837362015-01-02 18:45:37 -0800503 if (fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700504 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
505 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
506 for (const auto& name : fail_test_name_list) {
507 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
508 printf("%s\n", name.c_str());
509 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800510 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700511
Elliott Hughes93a89f82017-07-21 18:51:06 -0700512 if (timeout_test_count > 0 || slow_test_count > 0 || fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700513 printf("\n");
514 }
515
Yabin Cuibe837362015-01-02 18:45:37 -0800516 if (timeout_test_count > 0) {
517 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800518 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800519 if (slow_test_count > 0) {
520 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800521 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700522 if (fail_test_count > 0) {
523 printf("%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
524 }
Josh Gao01052222017-01-09 16:43:33 -0800525
Yabin Cui294d1e22014-12-07 20:43:37 -0800526 fflush(stdout);
527}
528
Dan Albert09a99642016-01-13 21:48:56 -0800529std::string XmlEscape(const std::string& xml) {
530 std::string escaped;
531 escaped.reserve(xml.size());
532
533 for (auto c : xml) {
534 switch (c) {
535 case '<':
536 escaped.append("&lt;");
537 break;
538 case '>':
539 escaped.append("&gt;");
540 break;
541 case '&':
542 escaped.append("&amp;");
543 break;
544 case '\'':
545 escaped.append("&apos;");
546 break;
547 case '"':
548 escaped.append("&quot;");
549 break;
550 default:
551 escaped.append(1, c);
552 break;
553 }
554 }
555
556 return escaped;
557}
558
Yabin Cui657b1f92015-01-22 19:26:12 -0800559// Output xml file when --gtest_output is used, write this function as we can't reuse
560// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
561// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
562// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
563void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
564 const std::vector<TestCase>& testcase_list,
565 time_t epoch_iteration_start_time,
566 int64_t elapsed_time_ns) {
Elliott Hughes5cec3772018-01-19 15:45:23 -0800567 FILE* fp = fopen(xml_output_filename.c_str(), "we");
Yi Kong32bc0fc2018-08-02 17:31:13 -0700568 if (fp == nullptr) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800569 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
570 exit(1);
571 }
572
573 size_t total_test_count = 0;
574 size_t total_failed_count = 0;
575 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
576 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
577 for (size_t i = 0; i < testcase_list.size(); ++i) {
578 auto& testcase = testcase_list[i];
579 total_test_count += testcase.TestCount();
580 for (size_t j = 0; j < testcase.TestCount(); ++j) {
Josh Gao01052222017-01-09 16:43:33 -0800581 if (!testcase.GetTestSuccess(j)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800582 ++failed_count_list[i];
583 }
584 elapsed_time_list[i] += testcase.GetTestTime(j);
585 }
586 total_failed_count += failed_count_list[i];
587 }
588
589 const tm* time_struct = localtime(&epoch_iteration_start_time);
590 char timestamp[40];
591 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
592 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
593 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
594
595 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
596 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
597 total_test_count, total_failed_count);
598 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
599 for (size_t i = 0; i < testcase_list.size(); ++i) {
600 auto& testcase = testcase_list[i];
601 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
602 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
603 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
604
605 for (size_t j = 0; j < testcase.TestCount(); ++j) {
606 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
607 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
608 testcase.GetName().c_str());
Josh Gao01052222017-01-09 16:43:33 -0800609 if (!testcase.GetTestSuccess(j)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800610 fputs(" />\n", fp);
611 } else {
612 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800613 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
Dan Albert09a99642016-01-13 21:48:56 -0800614 const std::string escaped_test_output = XmlEscape(test_output);
615 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", escaped_test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800616 fputs(" </failure>\n", fp);
617 fputs(" </testcase>\n", fp);
618 }
619 }
620
621 fputs(" </testsuite>\n", fp);
622 }
623 fputs("</testsuites>\n", fp);
624 fclose(fp);
625}
626
Yabin Cui767fb1c2015-09-01 15:06:39 -0700627static bool sigint_flag;
628static bool sigquit_flag;
629
630static void signal_handler(int sig) {
631 if (sig == SIGINT) {
632 sigint_flag = true;
633 } else if (sig == SIGQUIT) {
634 sigquit_flag = true;
635 }
636}
637
638static bool RegisterSignalHandler() {
639 sigint_flag = false;
640 sigquit_flag = false;
641 sig_t ret = signal(SIGINT, signal_handler);
642 if (ret != SIG_ERR) {
643 ret = signal(SIGQUIT, signal_handler);
644 }
645 if (ret == SIG_ERR) {
646 perror("RegisterSignalHandler");
647 return false;
648 }
649 return true;
650}
651
652static bool UnregisterSignalHandler() {
653 sig_t ret = signal(SIGINT, SIG_DFL);
654 if (ret != SIG_ERR) {
655 ret = signal(SIGQUIT, SIG_DFL);
656 }
657 if (ret == SIG_ERR) {
658 perror("UnregisterSignalHandler");
659 return false;
660 }
661 return true;
662}
663
Yabin Cui1d4c7802015-02-02 19:14:05 -0800664struct ChildProcInfo {
665 pid_t pid;
666 int64_t start_time_ns;
667 int64_t end_time_ns;
668 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
669 size_t testcase_id, test_id;
670 bool finished;
671 bool timed_out;
672 int exit_status;
673 int child_read_fd; // File descriptor to read child test failure info.
674};
675
Yabin Cui294d1e22014-12-07 20:43:37 -0800676// Forked Child process, run the single test.
677static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800678 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800679 memcpy(new_argv, argv, sizeof(char*) * argc);
680
681 char* filter_arg = new char [test_name.size() + 20];
682 strcpy(filter_arg, "--gtest_filter=");
683 strcat(filter_arg, test_name.c_str());
684 new_argv[argc] = filter_arg;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700685 new_argv[argc + 1] = nullptr;
Yabin Cui294d1e22014-12-07 20:43:37 -0800686
687 int new_argc = argc + 1;
688 testing::InitGoogleTest(&new_argc, new_argv);
689 int result = RUN_ALL_TESTS();
690 exit(result);
691}
692
Yabin Cui1d4c7802015-02-02 19:14:05 -0800693static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700694 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800695 int pipefd[2];
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800696 if (pipe(pipefd) == -1) {
697 perror("pipe in RunTestInSeparateProc");
698 exit(1);
699 }
700 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
701 perror("fcntl in RunTestInSeparateProc");
Yabin Cui1d4c7802015-02-02 19:14:05 -0800702 exit(1);
703 }
704 pid_t pid = fork();
705 if (pid == -1) {
706 perror("fork in RunTestInSeparateProc");
707 exit(1);
708 } else if (pid == 0) {
709 // In child process, run a single test.
710 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800711 close(STDOUT_FILENO);
712 close(STDERR_FILENO);
713 dup2(pipefd[1], STDOUT_FILENO);
714 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800715
Yabin Cui767fb1c2015-09-01 15:06:39 -0700716 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800717 exit(1);
718 }
719 ChildProcessFn(argc, argv, test_name);
720 // Unreachable.
721 }
722 // In parent process, initialize child process info.
723 close(pipefd[1]);
724 ChildProcInfo child_proc;
725 child_proc.child_read_fd = pipefd[0];
726 child_proc.pid = pid;
727 child_proc.start_time_ns = NanoTime();
Elliott Hughesa456fae2016-08-31 13:30:14 -0700728 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetTimeoutMs(test_name) * 1000000LL;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800729 child_proc.testcase_id = testcase_id;
730 child_proc.test_id = test_id;
731 child_proc.finished = false;
732 return child_proc;
733}
Yabin Cui294d1e22014-12-07 20:43:37 -0800734
Yabin Cui1d4c7802015-02-02 19:14:05 -0800735static void HandleSignals(std::vector<TestCase>& testcase_list,
736 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700737 if (sigquit_flag) {
738 sigquit_flag = false;
739 // Print current running tests.
740 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700741 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700742 if (child_proc.pid != 0) {
743 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
744 int64_t current_time_ns = NanoTime();
745 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
746 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800747 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800748 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700749 } else if (sigint_flag) {
750 sigint_flag = false;
751 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700752 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700753 if (child_proc.pid != 0) {
754 // Send SIGKILL to ensure the child process can be killed unconditionally.
755 kill(child_proc.pid, SIGKILL);
756 }
757 }
758 // SIGINT kills the parent process as well.
759 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800760 }
761}
762
763static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
764 std::vector<ChildProcInfo>& child_proc_list) {
765 for (size_t i = 0; i < child_proc_list.size(); ++i) {
766 if (child_proc_list[i].pid == exit_pid) {
767 child_proc_list[i].finished = true;
768 child_proc_list[i].timed_out = false;
769 child_proc_list[i].exit_status = exit_status;
770 child_proc_list[i].end_time_ns = NanoTime();
771 return true;
772 }
773 }
774 return false;
775}
776
777static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
778 int64_t current_time_ns = NanoTime();
779 size_t timeout_child_count = 0;
780 for (size_t i = 0; i < child_proc_list.size(); ++i) {
781 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
782 child_proc_list[i].finished = true;
783 child_proc_list[i].timed_out = true;
784 child_proc_list[i].end_time_ns = current_time_ns;
785 ++timeout_child_count;
786 }
787 }
788 return timeout_child_count;
789}
790
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800791static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
792 std::vector<ChildProcInfo>& child_proc_list) {
793 for (const auto& child_proc : child_proc_list) {
794 TestCase& testcase = testcase_list[child_proc.testcase_id];
795 int test_id = child_proc.test_id;
796 while (true) {
797 char buf[1024];
798 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
799 if (bytes_read > 0) {
800 buf[bytes_read] = '\0';
801 testcase.GetTest(test_id).AppendTestOutput(buf);
802 } else if (bytes_read == 0) {
803 break; // Read end.
804 } else {
805 if (errno == EAGAIN) {
806 break;
807 }
808 perror("failed to read child_read_fd");
809 exit(1);
810 }
811 }
812 }
813}
814
Yabin Cui1d4c7802015-02-02 19:14:05 -0800815static void WaitChildProcs(std::vector<TestCase>& testcase_list,
816 std::vector<ChildProcInfo>& child_proc_list) {
817 size_t finished_child_count = 0;
818 while (true) {
819 int status;
820 pid_t result;
821 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
822 if (CheckChildProcExit(result, status, child_proc_list)) {
823 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800824 }
825 }
826
827 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800828 if (errno == ECHILD) {
829 // This happens when we have no running child processes.
830 return;
831 } else {
832 perror("waitpid");
833 exit(1);
834 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800835 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800836 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800837 }
838
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800839 ReadChildProcOutput(testcase_list, child_proc_list);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800840 if (finished_child_count > 0) {
841 return;
842 }
843
844 HandleSignals(testcase_list, child_proc_list);
845
Yabin Cui294d1e22014-12-07 20:43:37 -0800846 // sleep 1 ms to avoid busy looping.
847 timespec sleep_time;
848 sleep_time.tv_sec = 0;
849 sleep_time.tv_nsec = 1000000;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700850 nanosleep(&sleep_time, nullptr);
Yabin Cui294d1e22014-12-07 20:43:37 -0800851 }
852}
853
Yabin Cui1d4c7802015-02-02 19:14:05 -0800854static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800855 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800856 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800857
858 TestResult test_result = TEST_SUCCESS;
859 if (result != pid || WEXITSTATUS(exit_status) != 0) {
860 test_result = TEST_FAILED;
861 }
862 return test_result;
863}
864
Yabin Cui1d4c7802015-02-02 19:14:05 -0800865static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
866 int test_id = child_proc.test_id;
867 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
868 if (child_proc.timed_out) {
869 // The child process marked as timed_out has not exited, and we should kill it manually.
870 kill(child_proc.pid, SIGKILL);
871 WaitForOneChild(child_proc.pid);
872 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800873 close(child_proc.child_read_fd);
874
875 if (child_proc.timed_out) {
876 testcase.SetTestResult(test_id, TEST_TIMEOUT);
877 char buf[1024];
878 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
879 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800880 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800881
882 } else if (WIFSIGNALED(child_proc.exit_status)) {
883 // Record signal terminated test as failed.
884 testcase.SetTestResult(test_id, TEST_FAILED);
885 char buf[1024];
886 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
887 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800888 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800889
890 } else {
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800891 int exitcode = WEXITSTATUS(child_proc.exit_status);
892 testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
893 if (exitcode != 0) {
Yabin Cuia32fc862015-12-03 16:28:03 -0800894 char buf[1024];
895 snprintf(buf, sizeof(buf), "%s exited with exitcode %d.\n",
896 testcase.GetTestName(test_id).c_str(), exitcode);
897 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800898 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800899 }
900}
901
Yabin Cui294d1e22014-12-07 20:43:37 -0800902// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
903// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700904// Returns true if all tests run successfully, otherwise return false.
905static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700906 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800907 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800908 // Stop default result printer to avoid environment setup/teardown information for each test.
909 testing::UnitTest::GetInstance()->listeners().Release(
910 testing::UnitTest::GetInstance()->listeners().default_result_printer());
911 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
912
Yabin Cui767fb1c2015-09-01 15:06:39 -0700913 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800914 exit(1);
915 }
916
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700917 bool all_tests_passed = true;
918
Christopher Ferris119cb552015-04-02 12:02:55 -0700919 for (size_t iteration = 1;
920 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
921 ++iteration) {
Elliott Hughes48de71e2016-10-28 10:04:44 -0700922 OnTestIterationStartPrint(testcase_list, iteration, iteration_count, job_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800923 int64_t iteration_start_time_ns = NanoTime();
Yi Kong32bc0fc2018-08-02 17:31:13 -0700924 time_t epoch_iteration_start_time = time(nullptr);
Yabin Cui294d1e22014-12-07 20:43:37 -0800925
Yabin Cuibe837362015-01-02 18:45:37 -0800926 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800927 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800928
Yabin Cuibe837362015-01-02 18:45:37 -0800929 // Next test to run is [next_testcase_id:next_test_id].
930 size_t next_testcase_id = 0;
931 size_t next_test_id = 0;
932
933 // Record how many tests are finished.
934 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
935 size_t finished_testcase_count = 0;
936
937 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800938 // run up to job_count child processes.
939 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
940 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
941 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700942 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800943 child_proc_list.push_back(child_proc);
944 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
945 next_test_id = 0;
946 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800947 }
948 }
949
950 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800951 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800952
953 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800954 auto it = child_proc_list.begin();
955 while (it != child_proc_list.end()) {
956 auto& child_proc = *it;
957 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800958 size_t testcase_id = child_proc.testcase_id;
959 size_t test_id = child_proc.test_id;
960 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800961
Yabin Cui1d4c7802015-02-02 19:14:05 -0800962 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800963 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800964
965 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
966 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800967 }
Josh Gao01052222017-01-09 16:43:33 -0800968 if (!testcase.GetTestSuccess(test_id)) {
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700969 all_tests_passed = false;
970 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800971
972 it = child_proc_list.erase(it);
973 } else {
974 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800975 }
976 }
977 }
978
Yabin Cui657b1f92015-01-22 19:26:12 -0800979 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
980 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
981 if (!xml_output_filename.empty()) {
982 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
983 elapsed_time_ns);
984 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800985 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800986
Yabin Cui767fb1c2015-09-01 15:06:39 -0700987 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800988 exit(1);
989 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700990
991 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800992}
993
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700994static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800995 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800996}
997
Yabin Cuiead08142015-02-04 20:53:56 -0800998static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
999 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
1000 // test program via a valid path that contains at least one path separator.
1001 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
1002 // and execve() doesn't read environment variable PATH, so execve() will not success
1003 // until we specify the absolute path or relative path of the test program directly.
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001004 if (strchr(args[0], '/') == nullptr) {
1005 args[0] = strdup(g_executable_path.c_str());
Yabin Cuiead08142015-02-04 20:53:56 -08001006 }
1007}
1008
Yabin Cui11c43532015-01-28 14:28:14 -08001009static void AddGtestFilterSynonym(std::vector<char*>& args) {
1010 // Support --gtest-filter as a synonym for --gtest_filter.
1011 for (size_t i = 1; i < args.size(); ++i) {
1012 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
1013 args[i][7] = '_';
1014 }
1015 }
1016}
1017
Yabin Cui657b1f92015-01-22 19:26:12 -08001018struct IsolationTestOptions {
1019 bool isolate;
1020 size_t job_count;
1021 int test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001022 int test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001023 std::string gtest_color;
1024 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -07001025 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -08001026 std::string gtest_output;
1027};
1028
1029// 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 -08001030// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -08001031// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
1032// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -08001033// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -08001034// args is used to pass in all command arguments, and pass out only the part of options for gtest.
1035// options is used to pass out test options in isolation mode.
1036// Return false if there is error in arguments.
1037static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
1038 for (size_t i = 1; i < args.size(); ++i) {
1039 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001040 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -08001041 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001042 return true;
1043 }
1044 }
1045
Yabin Cuiead08142015-02-04 20:53:56 -08001046 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -08001047 AddGtestFilterSynonym(args);
1048
Yabin Cui657b1f92015-01-22 19:26:12 -08001049 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
1050 bool enable_selftest = false;
1051 for (size_t i = 1; i < args.size(); ++i) {
1052 if (strcmp(args[i], "--bionic-selftest") == 0) {
1053 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
1054 // Don't remove this option from arguments.
1055 enable_selftest = true;
1056 }
1057 }
1058 std::string gtest_filter_str;
1059 for (size_t i = args.size() - 1; i >= 1; --i) {
1060 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
Yabin Cuic641a952016-12-12 13:32:15 -08001061 gtest_filter_str = args[i] + strlen("--gtest_filter=");
Yabin Cui657b1f92015-01-22 19:26:12 -08001062 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -08001063 break;
1064 }
1065 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001066 if (enable_selftest == true) {
Yabin Cuic641a952016-12-12 13:32:15 -08001067 gtest_filter_str = "bionic_selftest*";
Yabin Cui657b1f92015-01-22 19:26:12 -08001068 } else {
Yabin Cuic641a952016-12-12 13:32:15 -08001069 if (gtest_filter_str.empty()) {
1070 gtest_filter_str = "-bionic_selftest*";
Yabin Cui657b1f92015-01-22 19:26:12 -08001071 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001072 // Find if '-' for NEGATIVE_PATTERNS exists.
wy828b9e12017-05-10 15:21:13 -07001073 if (gtest_filter_str.find('-') != std::string::npos) {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001074 gtest_filter_str += ":bionic_selftest*";
1075 } else {
1076 gtest_filter_str += ":-bionic_selftest*";
1077 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001078 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001079 }
Yabin Cuic641a952016-12-12 13:32:15 -08001080 gtest_filter_str = "--gtest_filter=" + gtest_filter_str;
1081 args.push_back(strdup(gtest_filter_str.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -08001082
Yabin Cui657b1f92015-01-22 19:26:12 -08001083 options.isolate = true;
1084 // Parse arguments that make us can't run in isolation mode.
1085 for (size_t i = 1; i < args.size(); ++i) {
1086 if (strcmp(args[i], "--no-isolate") == 0) {
1087 options.isolate = false;
1088 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
1089 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001090 }
1091 }
1092
Yabin Cui657b1f92015-01-22 19:26:12 -08001093 // Stop parsing if we will not run in isolation mode.
1094 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001095 return true;
1096 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001097
1098 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -07001099 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -08001100 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001101 options.test_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui657b1f92015-01-22 19:26:12 -08001102 options.gtest_color = testing::GTEST_FLAG(color);
1103 options.gtest_print_time = testing::GTEST_FLAG(print_time);
1104 options.gtest_repeat = testing::GTEST_FLAG(repeat);
1105 options.gtest_output = testing::GTEST_FLAG(output);
1106
1107 // Parse arguments speficied for isolation mode.
1108 for (size_t i = 1; i < args.size(); ++i) {
1109 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1110 char* p = args[i] + strlen("-j");
1111 int count = 0;
1112 if (*p != '\0') {
1113 // Argument like -j5.
1114 count = atoi(p);
1115 } else if (args.size() > i + 1) {
1116 // Arguments like -j 5.
1117 count = atoi(args[i + 1]);
1118 ++i;
1119 }
1120 if (count <= 0) {
1121 fprintf(stderr, "invalid job count: %d\n", count);
1122 return false;
1123 }
1124 options.job_count = static_cast<size_t>(count);
1125 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1126 int time_ms = atoi(args[i] + strlen("--deadline="));
1127 if (time_ms <= 0) {
1128 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1129 return false;
1130 }
1131 options.test_deadline_ms = time_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001132 } else if (strncmp(args[i], "--slow-threshold=", strlen("--slow-threshold=")) == 0) {
1133 int time_ms = atoi(args[i] + strlen("--slow-threshold="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001134 if (time_ms <= 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -07001135 fprintf(stderr, "invalid slow test threshold: %d\n", time_ms);
Yabin Cui657b1f92015-01-22 19:26:12 -08001136 return false;
1137 }
Elliott Hughesa456fae2016-08-31 13:30:14 -07001138 options.test_slow_threshold_ms = time_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001139 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1140 options.gtest_color = args[i] + strlen("--gtest_color=");
1141 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1142 options.gtest_print_time = false;
1143 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001144 // If the value of gtest_repeat is < 0, then it indicates the tests
1145 // should be repeated forever.
1146 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001147 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1148 args.erase(args.begin() + i);
1149 --i;
1150 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1151 std::string output = args[i] + strlen("--gtest_output=");
1152 // generate output xml file path according to the strategy in gtest.
1153 bool success = true;
1154 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1155 output = output.substr(strlen("xml:"));
1156 if (output.size() == 0) {
1157 success = false;
1158 }
1159 // Make absolute path.
1160 if (success && output[0] != '/') {
Yi Kong32bc0fc2018-08-02 17:31:13 -07001161 char* cwd = getcwd(nullptr, 0);
1162 if (cwd != nullptr) {
Yabin Cui657b1f92015-01-22 19:26:12 -08001163 output = std::string(cwd) + "/" + output;
1164 free(cwd);
1165 } else {
1166 success = false;
1167 }
1168 }
1169 // Add file name if output is a directory.
1170 if (success && output.back() == '/') {
1171 output += "test_details.xml";
1172 }
1173 }
1174 if (success) {
1175 options.gtest_output = output;
1176 } else {
1177 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1178 return false;
1179 }
1180
1181 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1182 args.erase(args.begin() + i);
1183 --i;
1184 }
1185 }
1186
1187 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1188 // As DeathTest will try to call execve(), this argument should always be added.
1189 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001190 return true;
1191}
1192
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001193static std::string get_proc_self_exe() {
1194 char path[PATH_MAX];
1195 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
1196 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
1197 perror("readlink");
1198 exit(1);
1199 }
1200
1201 return std::string(path, path_len);
1202}
1203
Dimitry Ivanov55437462016-07-20 15:33:07 -07001204int main(int argc, char** argv, char** envp) {
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001205 g_executable_path = get_proc_self_exe();
Dimitry Ivanov55437462016-07-20 15:33:07 -07001206 g_argc = argc;
1207 g_argv = argv;
1208 g_envp = envp;
Elliott Hughes5cec3772018-01-19 15:45:23 -08001209 std::vector<char*> arg_list(argv, argv + argc);
Yabin Cuibe837362015-01-02 18:45:37 -08001210
Yabin Cui657b1f92015-01-22 19:26:12 -08001211 IsolationTestOptions options;
1212 if (PickOptions(arg_list, options) == false) {
1213 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001214 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001215
1216 if (options.isolate == true) {
1217 // Set global variables.
1218 global_test_run_deadline_ms = options.test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001219 global_test_run_slow_threshold_ms = options.test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001220 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1221 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1222 std::vector<TestCase> testcase_list;
1223
1224 argc = static_cast<int>(arg_list.size());
Yi Kong32bc0fc2018-08-02 17:31:13 -07001225 arg_list.push_back(nullptr);
Yabin Cui657b1f92015-01-22 19:26:12 -08001226 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1227 return 1;
1228 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001229 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1230 options.gtest_repeat, options.job_count, options.gtest_output);
1231 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001232 } else {
1233 argc = static_cast<int>(arg_list.size());
Yi Kong32bc0fc2018-08-02 17:31:13 -07001234 arg_list.push_back(nullptr);
Yabin Cui657b1f92015-01-22 19:26:12 -08001235 testing::InitGoogleTest(&argc, arg_list.data());
1236 return RUN_ALL_TESTS();
1237 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001238}
1239
1240//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001241// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001242
Yabin Cuibe837362015-01-02 18:45:37 -08001243TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001244 ASSERT_EQ(1, 1);
1245}
1246
Yabin Cuibe837362015-01-02 18:45:37 -08001247TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001248 ASSERT_EQ(0, 1);
1249}
1250
Yabin Cuibe837362015-01-02 18:45:37 -08001251TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001252 sleep(4);
1253}
1254
Yabin Cuibe837362015-01-02 18:45:37 -08001255TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001256 while (1) {}
1257}
Yabin Cuibe837362015-01-02 18:45:37 -08001258
1259TEST(bionic_selftest, test_signal_SEGV_terminated) {
1260 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1261 *p = 3;
1262}
Yabin Cui657b1f92015-01-22 19:26:12 -08001263
Yabin Cui767fb1c2015-09-01 15:06:39 -07001264class bionic_selftest_DeathTest : public ::testing::Test {
1265 protected:
1266 virtual void SetUp() {
1267 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1268 }
1269};
Yabin Cui657b1f92015-01-22 19:26:12 -08001270
1271static void deathtest_helper_success() {
1272 ASSERT_EQ(1, 1);
1273 exit(0);
1274}
1275
1276TEST_F(bionic_selftest_DeathTest, success) {
1277 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1278}
1279
1280static void deathtest_helper_fail() {
1281 ASSERT_EQ(1, 0);
1282}
1283
1284TEST_F(bionic_selftest_DeathTest, fail) {
1285 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1286}
Yabin Cui5e235c82017-11-16 16:20:28 -08001287
1288class BionicSelfTest : public ::testing::TestWithParam<bool> {
1289};
1290
1291TEST_P(BionicSelfTest, test_success) {
1292 ASSERT_EQ(GetParam(), GetParam());
1293}
1294
1295INSTANTIATE_TEST_CASE_P(bionic_selftest, BionicSelfTest, ::testing::Values(true, false));
1296
1297template <typename T>
1298class bionic_selftest_TestT : public ::testing::Test {
1299};
1300
1301typedef ::testing::Types<char, int> MyTypes;
1302
1303TYPED_TEST_CASE(bionic_selftest_TestT, MyTypes);
1304
1305TYPED_TEST(bionic_selftest_TestT, test_success) {
1306 ASSERT_EQ(true, true);
1307}