blob: 1ee8b53f4c306f5ef6ec1d3c61f7f6fd63a84f6a [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 Huang83b63792018-07-10 14:09:05 -070081static void ColoredPrintf(const char* const color, const char* fmt, ...) {
82 va_list args;
83 va_start(args, fmt);
Yabin Cui294d1e22014-12-07 20:43:37 -080084
Haibo Huang83b63792018-07-10 14:09:05 -070085 printf("%s", color);
86 vprintf(fmt, args);
87 printf("%s", COLOR_RESET);
Yabin Cui294d1e22014-12-07 20:43:37 -080088
Haibo Huang83b63792018-07-10 14:09:05 -070089 va_end(args);
90}
Yabin Cui294d1e22014-12-07 20:43:37 -080091
Christopher Ferrisdaaaed12015-09-24 18:45:53 -070092constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 90000;
Elliott Hughesa456fae2016-08-31 13:30:14 -070093constexpr int DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -080094
95// The time each test can run before killed for the reason of timeout.
96// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080097static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080098
99// The time each test can run before be warned for too much running time.
100// It takes effect only with --isolate option.
Elliott Hughesa456fae2016-08-31 13:30:14 -0700101static int global_test_run_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800102
Elliott Hughesa456fae2016-08-31 13:30:14 -0700103// Return timeout duration for a test, in ms.
104static int GetTimeoutMs(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800105 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800106}
107
Elliott Hughesa456fae2016-08-31 13:30:14 -0700108// Return threshold for calling a test slow, in ms.
109static int GetSlowThresholdMs(const std::string& /*test_name*/) {
110 return global_test_run_slow_threshold_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800111}
112
Yabin Cuibe837362015-01-02 18:45:37 -0800113static void PrintHelpInfo() {
114 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -0800115 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800116 " Run up to JOB_COUNT tests in parallel.\n"
117 " Use isolation mode, Run each test in a separate process.\n"
118 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
119 " --no-isolate\n"
120 " Don't use isolation mode, run all tests in a single process.\n"
121 " --deadline=[TIME_IN_MS]\n"
122 " Run each test in no longer than [TIME_IN_MS] time.\n"
Elliott Hughesa456fae2016-08-31 13:30:14 -0700123 " Only valid in isolation mode. Default deadline is 90000 ms.\n"
124 " --slow-threshold=[TIME_IN_MS]\n"
125 " Test running longer than [TIME_IN_MS] will be called slow.\n"
126 " Only valid in isolation mode. Default slow threshold is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -0800127 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
128 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -0800129 "Default bionic unit test option is -j.\n"
130 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
131 "running tests, or send SIGINT to the parent process to stop testing and\n"
132 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800133 "\n");
134}
135
Yabin Cui294d1e22014-12-07 20:43:37 -0800136enum TestResult {
137 TEST_SUCCESS = 0,
138 TEST_FAILED,
139 TEST_TIMEOUT
140};
141
Yabin Cui657b1f92015-01-22 19:26:12 -0800142class Test {
143 public:
144 Test() {} // For std::vector<Test>.
145 explicit Test(const char* name) : name_(name) {}
146
147 const std::string& GetName() const { return name_; }
148
Elliott Hughes93a89f82017-07-21 18:51:06 -0700149 void SetResult(TestResult result) {
150 // Native xfails are inherently likely to actually be relying on undefined
151 // behavior/uninitialized memory, and thus likely to pass from time to time
152 // on CTS. Avoid that unpleasantness by just rewriting all xfail failures
153 // as successes. You'll still see the actual failure details.
154 if (GetName().find("xfail") == 0) result = TEST_SUCCESS;
155 result_ = result;
156 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800157
158 TestResult GetResult() const { return result_; }
159
160 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
161
162 int64_t GetTestTime() const { return elapsed_time_ns_; }
163
Yabin Cuiea9c9332015-02-24 14:39:19 -0800164 void AppendTestOutput(const std::string& s) { output_ += s; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800165
Yabin Cuiea9c9332015-02-24 14:39:19 -0800166 const std::string& GetTestOutput() const { return output_; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800167
168 private:
169 const std::string name_;
170 TestResult result_;
171 int64_t elapsed_time_ns_;
Yabin Cuiea9c9332015-02-24 14:39:19 -0800172 std::string output_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800173};
174
Yabin Cui294d1e22014-12-07 20:43:37 -0800175class TestCase {
176 public:
177 TestCase() {} // For std::vector<TestCase>.
178 explicit TestCase(const char* name) : name_(name) {}
179
180 const std::string& GetName() const { return name_; }
181
Yabin Cui657b1f92015-01-22 19:26:12 -0800182 void AppendTest(const char* test_name) {
183 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800184 }
185
Yabin Cuibe837362015-01-02 18:45:37 -0800186 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800187
Yabin Cuibe837362015-01-02 18:45:37 -0800188 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800189 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800190 return name_ + "." + test_list_[test_id].GetName();
191 }
192
193 Test& GetTest(size_t test_id) {
194 VerifyTestId(test_id);
195 return test_list_[test_id];
196 }
197
198 const Test& GetTest(size_t test_id) const {
199 VerifyTestId(test_id);
200 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800201 }
202
Yabin Cuibe837362015-01-02 18:45:37 -0800203 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800204 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800205 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800206 }
207
Yabin Cuibe837362015-01-02 18:45:37 -0800208 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800209 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800210 return test_list_[test_id].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800211 }
212
Josh Gao01052222017-01-09 16:43:33 -0800213 bool GetTestSuccess(size_t test_id) const {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700214 return GetTestResult(test_id) == TEST_SUCCESS;
Josh Gao01052222017-01-09 16:43:33 -0800215 }
216
Yabin Cui657b1f92015-01-22 19:26:12 -0800217 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800218 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800219 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800220 }
221
Yabin Cuibe837362015-01-02 18:45:37 -0800222 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800223 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800224 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800225 }
226
227 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800228 void VerifyTestId(size_t test_id) const {
229 if(test_id >= test_list_.size()) {
230 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800231 exit(1);
232 }
233 }
234
235 private:
236 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800237 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800238};
239
Yabin Cui294d1e22014-12-07 20:43:37 -0800240class TestResultPrinter : public testing::EmptyTestEventListener {
241 public:
242 TestResultPrinter() : pinfo_(NULL) {}
243 virtual void OnTestStart(const testing::TestInfo& test_info) {
244 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
245 }
246 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800247
248 private:
249 const testing::TestInfo* pinfo_;
250};
251
252// Called after an assertion failure.
253void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
254 // If the test part succeeded, we don't need to do anything.
255 if (result.type() == testing::TestPartResult::kSuccess)
256 return;
257
258 // Print failure message from the assertion (e.g. expected this and got that).
Yabin Cuiea9c9332015-02-24 14:39:19 -0800259 printf("%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), result.line_number(),
260 pinfo_->test_case_name(), pinfo_->name(), result.message());
261 fflush(stdout);
Yabin Cui294d1e22014-12-07 20:43:37 -0800262}
263
Yabin Cui294d1e22014-12-07 20:43:37 -0800264static int64_t NanoTime() {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700265 std::chrono::nanoseconds duration(std::chrono::steady_clock::now().time_since_epoch());
266 return static_cast<int64_t>(duration.count());
Yabin Cui294d1e22014-12-07 20:43:37 -0800267}
268
269static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
Elliott Hughes5cec3772018-01-19 15:45:23 -0800270 std::vector<const char*> args(argv, argv + argc);
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800271 args.push_back("--gtest_list_tests");
272 args.push_back(nullptr);
273
274 // We use posix_spawn(3) rather than the simpler popen(3) because we don't want an intervening
275 // surprise shell invocation making quoting interesting for --gtest_filter (http://b/68949647).
276
277 android::base::unique_fd read_fd;
278 android::base::unique_fd write_fd;
279 if (!android::base::Pipe(&read_fd, &write_fd)) {
280 perror("pipe");
Yabin Cui294d1e22014-12-07 20:43:37 -0800281 return false;
282 }
283
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800284 posix_spawn_file_actions_t fa;
285 posix_spawn_file_actions_init(&fa);
286 posix_spawn_file_actions_addclose(&fa, read_fd);
287 posix_spawn_file_actions_adddup2(&fa, write_fd, 1);
288 posix_spawn_file_actions_adddup2(&fa, write_fd, 2);
289 posix_spawn_file_actions_addclose(&fa, write_fd);
Yabin Cui294d1e22014-12-07 20:43:37 -0800290
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800291 pid_t pid;
292 int result = posix_spawnp(&pid, argv[0], &fa, nullptr, const_cast<char**>(args.data()), nullptr);
293 posix_spawn_file_actions_destroy(&fa);
294 if (result == -1) {
295 perror("posix_spawn");
296 return false;
297 }
298 write_fd.reset();
299
300 std::string content;
301 if (!android::base::ReadFdToString(read_fd, &content)) {
302 perror("ReadFdToString");
303 return false;
304 }
305
306 for (auto& line : android::base::Split(content, "\n")) {
Yabin Cui5e235c82017-11-16 16:20:28 -0800307 line = android::base::Split(line, "#")[0];
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800308 line = android::base::Trim(line);
309 if (line.empty()) continue;
310 if (android::base::EndsWith(line, ".")) {
311 line.pop_back();
312 testcase_list.push_back(TestCase(line.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -0800313 } else {
Tao Bao99327892018-03-23 00:27:26 -0700314 if (testcase_list.empty()) {
315 // Invalid response from gtest - likely it has been upset by an invalid --gtest_* flag.
316 // Relay the message to user.
317 fprintf(stderr, "%s", content.c_str());
318 return false;
319 }
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800320 testcase_list.back().AppendTest(line.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800321 }
322 }
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800323
324 int status;
Elliott Hughescabc77f2017-11-28 12:55:19 -0800325 if (TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)) != pid) {
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800326 perror("waitpid");
327 return false;
328 }
329 return (WIFEXITED(status) && WEXITSTATUS(status) == 0);
Yabin Cui294d1e22014-12-07 20:43:37 -0800330}
331
Yabin Cui294d1e22014-12-07 20:43:37 -0800332// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
333// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
334// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800335static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
Elliott Hughes48de71e2016-10-28 10:04:44 -0700336 int iteration_count, size_t job_count) {
Christopher Ferris119cb552015-04-02 12:02:55 -0700337 if (iteration_count != 1) {
Yabin Cuibe837362015-01-02 18:45:37 -0800338 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800339 }
340 ColoredPrintf(COLOR_GREEN, "[==========] ");
341
Yabin Cuibe837362015-01-02 18:45:37 -0800342 size_t testcase_count = testcase_list.size();
343 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800344 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800345 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800346 }
347
Elliott Hughes48de71e2016-10-28 10:04:44 -0700348 printf("Running %zu %s from %zu %s (%zu %s).\n",
Yabin Cuibe837362015-01-02 18:45:37 -0800349 test_count, (test_count == 1) ? "test" : "tests",
Elliott Hughes48de71e2016-10-28 10:04:44 -0700350 testcase_count, (testcase_count == 1) ? "test case" : "test cases",
351 job_count, (job_count == 1) ? "job" : "jobs");
Yabin Cui294d1e22014-12-07 20:43:37 -0800352 fflush(stdout);
353}
354
Yabin Cuif6237472015-02-26 19:03:54 -0800355// bionic cts test needs gtest output format.
356#if defined(USING_GTEST_OUTPUT_FORMAT)
357
358static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
359 ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
360 printf("%s\n", testcase.GetTestName(test_id).c_str());
361
362 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
363 printf("%s", test_output.c_str());
364
365 TestResult result = testcase.GetTestResult(test_id);
Elliott Hughes93a89f82017-07-21 18:51:06 -0700366 if (result == TEST_SUCCESS) {
Yabin Cuif6237472015-02-26 19:03:54 -0800367 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
368 } else {
369 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
370 }
371 printf("%s", testcase.GetTestName(test_id).c_str());
372 if (testing::GTEST_FLAG(print_time)) {
373 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
374 }
375 printf("\n");
376 fflush(stdout);
377}
378
379#else // !defined(USING_GTEST_OUTPUT_FORMAT)
380
Yabin Cui657b1f92015-01-22 19:26:12 -0800381static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
382 TestResult result = testcase.GetTestResult(test_id);
383 if (result == TEST_SUCCESS) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700384 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800385 } else if (result == TEST_FAILED) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700386 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800387 } else if (result == TEST_TIMEOUT) {
388 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
389 }
Yabin Cuibe837362015-01-02 18:45:37 -0800390
Yabin Cui657b1f92015-01-22 19:26:12 -0800391 printf("%s", testcase.GetTestName(test_id).c_str());
392 if (testing::GTEST_FLAG(print_time)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800393 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
Yabin Cui657b1f92015-01-22 19:26:12 -0800394 }
Yabin Cuif6237472015-02-26 19:03:54 -0800395 printf("\n");
Yabin Cui657b1f92015-01-22 19:26:12 -0800396
Yabin Cuiea9c9332015-02-24 14:39:19 -0800397 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
398 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800399 fflush(stdout);
400}
401
Yabin Cuif6237472015-02-26 19:03:54 -0800402#endif // !defined(USING_GTEST_OUTPUT_FORMAT)
403
Yabin Cuibe837362015-01-02 18:45:37 -0800404static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800405 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800406
407 std::vector<std::string> fail_test_name_list;
408 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
409
Elliott Hughesa456fae2016-08-31 13:30:14 -0700410 // For tests that were slow but didn't time out.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800411 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800412 size_t testcase_count = testcase_list.size();
413 size_t test_count = 0;
414 size_t success_test_count = 0;
Josh Gao01052222017-01-09 16:43:33 -0800415 size_t expected_failure_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800416
417 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800418 test_count += testcase.TestCount();
419 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800420 TestResult result = testcase.GetTestResult(i);
Josh Gao01052222017-01-09 16:43:33 -0800421 if (result == TEST_TIMEOUT) {
422 timeout_test_list.push_back(
423 std::make_pair(testcase.GetTestName(i), testcase.GetTestTime(i)));
Elliott Hughes93a89f82017-07-21 18:51:06 -0700424 } else if (result == TEST_SUCCESS) {
425 ++success_test_count;
426 if (testcase.GetTestName(i).find(".xfail_") != std::string::npos) ++expected_failure_count;
427 } else if (result == TEST_FAILED) {
Josh Gao01052222017-01-09 16:43:33 -0800428 fail_test_name_list.push_back(testcase.GetTestName(i));
Yabin Cui294d1e22014-12-07 20:43:37 -0800429 }
430 if (result != TEST_TIMEOUT &&
Elliott Hughesa456fae2016-08-31 13:30:14 -0700431 testcase.GetTestTime(i) / 1000000 >= GetSlowThresholdMs(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800432 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
433 testcase.GetTestTime(i),
Elliott Hughesa456fae2016-08-31 13:30:14 -0700434 GetSlowThresholdMs(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800435 }
436 }
437 }
438
Yabin Cui294d1e22014-12-07 20:43:37 -0800439 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800440 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
441 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800442 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800443 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800444 }
445 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800446 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Josh Gao01052222017-01-09 16:43:33 -0800447 printf("%zu %s.", success_test_count, (success_test_count == 1) ? "test" : "tests");
448 if (expected_failure_count > 0) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700449 printf(" (%zu expected failure%s.)", expected_failure_count,
Josh Gao01052222017-01-09 16:43:33 -0800450 (expected_failure_count == 1) ? "" : "s");
451 }
452 printf("\n");
Yabin Cui294d1e22014-12-07 20:43:37 -0800453
Elliott Hughesa456fae2016-08-31 13:30:14 -0700454 // Print tests that timed out.
Yabin Cuibe837362015-01-02 18:45:37 -0800455 size_t timeout_test_count = timeout_test_list.size();
456 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800457 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800458 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800459 for (const auto& timeout_pair : timeout_test_list) {
460 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800461 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
462 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800463 }
464 }
465
Elliott Hughesa456fae2016-08-31 13:30:14 -0700466 // Print tests that were slow.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800467 size_t slow_test_count = slow_test_list.size();
468 if (slow_test_count > 0) {
469 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
470 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
471 for (const auto& slow_tuple : slow_test_list) {
472 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
Elliott Hughesa456fae2016-08-31 13:30:14 -0700473 printf("%s (%" PRId64 " ms, exceeded %d ms)\n", std::get<0>(slow_tuple).c_str(),
Yabin Cui4a82ede2015-01-26 17:19:37 -0800474 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800475 }
476 }
477
Elliott Hughesa456fae2016-08-31 13:30:14 -0700478 // Print tests that failed.
479 size_t fail_test_count = fail_test_name_list.size();
Yabin Cuibe837362015-01-02 18:45:37 -0800480 if (fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700481 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
482 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
483 for (const auto& name : fail_test_name_list) {
484 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
485 printf("%s\n", name.c_str());
486 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800487 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700488
Elliott Hughes93a89f82017-07-21 18:51:06 -0700489 if (timeout_test_count > 0 || slow_test_count > 0 || fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700490 printf("\n");
491 }
492
Yabin Cuibe837362015-01-02 18:45:37 -0800493 if (timeout_test_count > 0) {
494 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800495 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800496 if (slow_test_count > 0) {
497 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800498 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700499 if (fail_test_count > 0) {
500 printf("%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
501 }
Josh Gao01052222017-01-09 16:43:33 -0800502
Yabin Cui294d1e22014-12-07 20:43:37 -0800503 fflush(stdout);
504}
505
Dan Albert09a99642016-01-13 21:48:56 -0800506std::string XmlEscape(const std::string& xml) {
507 std::string escaped;
508 escaped.reserve(xml.size());
509
510 for (auto c : xml) {
511 switch (c) {
512 case '<':
513 escaped.append("&lt;");
514 break;
515 case '>':
516 escaped.append("&gt;");
517 break;
518 case '&':
519 escaped.append("&amp;");
520 break;
521 case '\'':
522 escaped.append("&apos;");
523 break;
524 case '"':
525 escaped.append("&quot;");
526 break;
527 default:
528 escaped.append(1, c);
529 break;
530 }
531 }
532
533 return escaped;
534}
535
Yabin Cui657b1f92015-01-22 19:26:12 -0800536// Output xml file when --gtest_output is used, write this function as we can't reuse
537// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
538// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
539// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
540void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
541 const std::vector<TestCase>& testcase_list,
542 time_t epoch_iteration_start_time,
543 int64_t elapsed_time_ns) {
Elliott Hughes5cec3772018-01-19 15:45:23 -0800544 FILE* fp = fopen(xml_output_filename.c_str(), "we");
Yabin Cui657b1f92015-01-22 19:26:12 -0800545 if (fp == NULL) {
546 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
547 exit(1);
548 }
549
550 size_t total_test_count = 0;
551 size_t total_failed_count = 0;
552 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
553 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
554 for (size_t i = 0; i < testcase_list.size(); ++i) {
555 auto& testcase = testcase_list[i];
556 total_test_count += testcase.TestCount();
557 for (size_t j = 0; j < testcase.TestCount(); ++j) {
Josh Gao01052222017-01-09 16:43:33 -0800558 if (!testcase.GetTestSuccess(j)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800559 ++failed_count_list[i];
560 }
561 elapsed_time_list[i] += testcase.GetTestTime(j);
562 }
563 total_failed_count += failed_count_list[i];
564 }
565
566 const tm* time_struct = localtime(&epoch_iteration_start_time);
567 char timestamp[40];
568 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
569 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
570 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
571
572 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
573 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
574 total_test_count, total_failed_count);
575 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
576 for (size_t i = 0; i < testcase_list.size(); ++i) {
577 auto& testcase = testcase_list[i];
578 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
579 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
580 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
581
582 for (size_t j = 0; j < testcase.TestCount(); ++j) {
583 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
584 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
585 testcase.GetName().c_str());
Josh Gao01052222017-01-09 16:43:33 -0800586 if (!testcase.GetTestSuccess(j)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800587 fputs(" />\n", fp);
588 } else {
589 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800590 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
Dan Albert09a99642016-01-13 21:48:56 -0800591 const std::string escaped_test_output = XmlEscape(test_output);
592 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", escaped_test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800593 fputs(" </failure>\n", fp);
594 fputs(" </testcase>\n", fp);
595 }
596 }
597
598 fputs(" </testsuite>\n", fp);
599 }
600 fputs("</testsuites>\n", fp);
601 fclose(fp);
602}
603
Yabin Cui767fb1c2015-09-01 15:06:39 -0700604static bool sigint_flag;
605static bool sigquit_flag;
606
607static void signal_handler(int sig) {
608 if (sig == SIGINT) {
609 sigint_flag = true;
610 } else if (sig == SIGQUIT) {
611 sigquit_flag = true;
612 }
613}
614
615static bool RegisterSignalHandler() {
616 sigint_flag = false;
617 sigquit_flag = false;
618 sig_t ret = signal(SIGINT, signal_handler);
619 if (ret != SIG_ERR) {
620 ret = signal(SIGQUIT, signal_handler);
621 }
622 if (ret == SIG_ERR) {
623 perror("RegisterSignalHandler");
624 return false;
625 }
626 return true;
627}
628
629static bool UnregisterSignalHandler() {
630 sig_t ret = signal(SIGINT, SIG_DFL);
631 if (ret != SIG_ERR) {
632 ret = signal(SIGQUIT, SIG_DFL);
633 }
634 if (ret == SIG_ERR) {
635 perror("UnregisterSignalHandler");
636 return false;
637 }
638 return true;
639}
640
Yabin Cui1d4c7802015-02-02 19:14:05 -0800641struct ChildProcInfo {
642 pid_t pid;
643 int64_t start_time_ns;
644 int64_t end_time_ns;
645 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
646 size_t testcase_id, test_id;
647 bool finished;
648 bool timed_out;
649 int exit_status;
650 int child_read_fd; // File descriptor to read child test failure info.
651};
652
Yabin Cui294d1e22014-12-07 20:43:37 -0800653// Forked Child process, run the single test.
654static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800655 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800656 memcpy(new_argv, argv, sizeof(char*) * argc);
657
658 char* filter_arg = new char [test_name.size() + 20];
659 strcpy(filter_arg, "--gtest_filter=");
660 strcat(filter_arg, test_name.c_str());
661 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800662 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800663
664 int new_argc = argc + 1;
665 testing::InitGoogleTest(&new_argc, new_argv);
666 int result = RUN_ALL_TESTS();
667 exit(result);
668}
669
Yabin Cui1d4c7802015-02-02 19:14:05 -0800670static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700671 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800672 int pipefd[2];
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800673 if (pipe(pipefd) == -1) {
674 perror("pipe in RunTestInSeparateProc");
675 exit(1);
676 }
677 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
678 perror("fcntl in RunTestInSeparateProc");
Yabin Cui1d4c7802015-02-02 19:14:05 -0800679 exit(1);
680 }
681 pid_t pid = fork();
682 if (pid == -1) {
683 perror("fork in RunTestInSeparateProc");
684 exit(1);
685 } else if (pid == 0) {
686 // In child process, run a single test.
687 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800688 close(STDOUT_FILENO);
689 close(STDERR_FILENO);
690 dup2(pipefd[1], STDOUT_FILENO);
691 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800692
Yabin Cui767fb1c2015-09-01 15:06:39 -0700693 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800694 exit(1);
695 }
696 ChildProcessFn(argc, argv, test_name);
697 // Unreachable.
698 }
699 // In parent process, initialize child process info.
700 close(pipefd[1]);
701 ChildProcInfo child_proc;
702 child_proc.child_read_fd = pipefd[0];
703 child_proc.pid = pid;
704 child_proc.start_time_ns = NanoTime();
Elliott Hughesa456fae2016-08-31 13:30:14 -0700705 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetTimeoutMs(test_name) * 1000000LL;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800706 child_proc.testcase_id = testcase_id;
707 child_proc.test_id = test_id;
708 child_proc.finished = false;
709 return child_proc;
710}
Yabin Cui294d1e22014-12-07 20:43:37 -0800711
Yabin Cui1d4c7802015-02-02 19:14:05 -0800712static void HandleSignals(std::vector<TestCase>& testcase_list,
713 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700714 if (sigquit_flag) {
715 sigquit_flag = false;
716 // Print current running tests.
717 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700718 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700719 if (child_proc.pid != 0) {
720 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
721 int64_t current_time_ns = NanoTime();
722 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
723 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800724 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800725 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700726 } else if (sigint_flag) {
727 sigint_flag = false;
728 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700729 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700730 if (child_proc.pid != 0) {
731 // Send SIGKILL to ensure the child process can be killed unconditionally.
732 kill(child_proc.pid, SIGKILL);
733 }
734 }
735 // SIGINT kills the parent process as well.
736 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800737 }
738}
739
740static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
741 std::vector<ChildProcInfo>& child_proc_list) {
742 for (size_t i = 0; i < child_proc_list.size(); ++i) {
743 if (child_proc_list[i].pid == exit_pid) {
744 child_proc_list[i].finished = true;
745 child_proc_list[i].timed_out = false;
746 child_proc_list[i].exit_status = exit_status;
747 child_proc_list[i].end_time_ns = NanoTime();
748 return true;
749 }
750 }
751 return false;
752}
753
754static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
755 int64_t current_time_ns = NanoTime();
756 size_t timeout_child_count = 0;
757 for (size_t i = 0; i < child_proc_list.size(); ++i) {
758 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
759 child_proc_list[i].finished = true;
760 child_proc_list[i].timed_out = true;
761 child_proc_list[i].end_time_ns = current_time_ns;
762 ++timeout_child_count;
763 }
764 }
765 return timeout_child_count;
766}
767
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800768static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
769 std::vector<ChildProcInfo>& child_proc_list) {
770 for (const auto& child_proc : child_proc_list) {
771 TestCase& testcase = testcase_list[child_proc.testcase_id];
772 int test_id = child_proc.test_id;
773 while (true) {
774 char buf[1024];
775 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
776 if (bytes_read > 0) {
777 buf[bytes_read] = '\0';
778 testcase.GetTest(test_id).AppendTestOutput(buf);
779 } else if (bytes_read == 0) {
780 break; // Read end.
781 } else {
782 if (errno == EAGAIN) {
783 break;
784 }
785 perror("failed to read child_read_fd");
786 exit(1);
787 }
788 }
789 }
790}
791
Yabin Cui1d4c7802015-02-02 19:14:05 -0800792static void WaitChildProcs(std::vector<TestCase>& testcase_list,
793 std::vector<ChildProcInfo>& child_proc_list) {
794 size_t finished_child_count = 0;
795 while (true) {
796 int status;
797 pid_t result;
798 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
799 if (CheckChildProcExit(result, status, child_proc_list)) {
800 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800801 }
802 }
803
804 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800805 if (errno == ECHILD) {
806 // This happens when we have no running child processes.
807 return;
808 } else {
809 perror("waitpid");
810 exit(1);
811 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800812 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800813 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800814 }
815
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800816 ReadChildProcOutput(testcase_list, child_proc_list);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800817 if (finished_child_count > 0) {
818 return;
819 }
820
821 HandleSignals(testcase_list, child_proc_list);
822
Yabin Cui294d1e22014-12-07 20:43:37 -0800823 // sleep 1 ms to avoid busy looping.
824 timespec sleep_time;
825 sleep_time.tv_sec = 0;
826 sleep_time.tv_nsec = 1000000;
827 nanosleep(&sleep_time, NULL);
828 }
829}
830
Yabin Cui1d4c7802015-02-02 19:14:05 -0800831static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800832 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800833 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800834
835 TestResult test_result = TEST_SUCCESS;
836 if (result != pid || WEXITSTATUS(exit_status) != 0) {
837 test_result = TEST_FAILED;
838 }
839 return test_result;
840}
841
Yabin Cui1d4c7802015-02-02 19:14:05 -0800842static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
843 int test_id = child_proc.test_id;
844 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
845 if (child_proc.timed_out) {
846 // The child process marked as timed_out has not exited, and we should kill it manually.
847 kill(child_proc.pid, SIGKILL);
848 WaitForOneChild(child_proc.pid);
849 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800850 close(child_proc.child_read_fd);
851
852 if (child_proc.timed_out) {
853 testcase.SetTestResult(test_id, TEST_TIMEOUT);
854 char buf[1024];
855 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
856 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800857 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800858
859 } else if (WIFSIGNALED(child_proc.exit_status)) {
860 // Record signal terminated test as failed.
861 testcase.SetTestResult(test_id, TEST_FAILED);
862 char buf[1024];
863 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
864 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800865 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800866
867 } else {
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800868 int exitcode = WEXITSTATUS(child_proc.exit_status);
869 testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
870 if (exitcode != 0) {
Yabin Cuia32fc862015-12-03 16:28:03 -0800871 char buf[1024];
872 snprintf(buf, sizeof(buf), "%s exited with exitcode %d.\n",
873 testcase.GetTestName(test_id).c_str(), exitcode);
874 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800875 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800876 }
877}
878
Yabin Cui294d1e22014-12-07 20:43:37 -0800879// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
880// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700881// Returns true if all tests run successfully, otherwise return false.
882static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700883 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800884 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800885 // Stop default result printer to avoid environment setup/teardown information for each test.
886 testing::UnitTest::GetInstance()->listeners().Release(
887 testing::UnitTest::GetInstance()->listeners().default_result_printer());
888 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
889
Yabin Cui767fb1c2015-09-01 15:06:39 -0700890 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800891 exit(1);
892 }
893
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700894 bool all_tests_passed = true;
895
Christopher Ferris119cb552015-04-02 12:02:55 -0700896 for (size_t iteration = 1;
897 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
898 ++iteration) {
Elliott Hughes48de71e2016-10-28 10:04:44 -0700899 OnTestIterationStartPrint(testcase_list, iteration, iteration_count, job_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800900 int64_t iteration_start_time_ns = NanoTime();
901 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800902
Yabin Cuibe837362015-01-02 18:45:37 -0800903 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800904 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800905
Yabin Cuibe837362015-01-02 18:45:37 -0800906 // Next test to run is [next_testcase_id:next_test_id].
907 size_t next_testcase_id = 0;
908 size_t next_test_id = 0;
909
910 // Record how many tests are finished.
911 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
912 size_t finished_testcase_count = 0;
913
914 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800915 // run up to job_count child processes.
916 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
917 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
918 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700919 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800920 child_proc_list.push_back(child_proc);
921 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
922 next_test_id = 0;
923 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800924 }
925 }
926
927 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800928 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800929
930 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800931 auto it = child_proc_list.begin();
932 while (it != child_proc_list.end()) {
933 auto& child_proc = *it;
934 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800935 size_t testcase_id = child_proc.testcase_id;
936 size_t test_id = child_proc.test_id;
937 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800938
Yabin Cui1d4c7802015-02-02 19:14:05 -0800939 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800940 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800941
942 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
943 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800944 }
Josh Gao01052222017-01-09 16:43:33 -0800945 if (!testcase.GetTestSuccess(test_id)) {
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700946 all_tests_passed = false;
947 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800948
949 it = child_proc_list.erase(it);
950 } else {
951 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800952 }
953 }
954 }
955
Yabin Cui657b1f92015-01-22 19:26:12 -0800956 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
957 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
958 if (!xml_output_filename.empty()) {
959 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
960 elapsed_time_ns);
961 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800962 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800963
Yabin Cui767fb1c2015-09-01 15:06:39 -0700964 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800965 exit(1);
966 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700967
968 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800969}
970
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700971static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800972 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800973}
974
Yabin Cuiead08142015-02-04 20:53:56 -0800975static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
976 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
977 // test program via a valid path that contains at least one path separator.
978 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
979 // and execve() doesn't read environment variable PATH, so execve() will not success
980 // until we specify the absolute path or relative path of the test program directly.
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -0700981 if (strchr(args[0], '/') == nullptr) {
982 args[0] = strdup(g_executable_path.c_str());
Yabin Cuiead08142015-02-04 20:53:56 -0800983 }
984}
985
Yabin Cui11c43532015-01-28 14:28:14 -0800986static void AddGtestFilterSynonym(std::vector<char*>& args) {
987 // Support --gtest-filter as a synonym for --gtest_filter.
988 for (size_t i = 1; i < args.size(); ++i) {
989 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
990 args[i][7] = '_';
991 }
992 }
993}
994
Yabin Cui657b1f92015-01-22 19:26:12 -0800995struct IsolationTestOptions {
996 bool isolate;
997 size_t job_count;
998 int test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -0700999 int test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001000 std::string gtest_color;
1001 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -07001002 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -08001003 std::string gtest_output;
1004};
1005
1006// 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 -08001007// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -08001008// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
1009// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -08001010// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -08001011// args is used to pass in all command arguments, and pass out only the part of options for gtest.
1012// options is used to pass out test options in isolation mode.
1013// Return false if there is error in arguments.
1014static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
1015 for (size_t i = 1; i < args.size(); ++i) {
1016 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001017 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -08001018 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001019 return true;
1020 }
1021 }
1022
Yabin Cuiead08142015-02-04 20:53:56 -08001023 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -08001024 AddGtestFilterSynonym(args);
1025
Yabin Cui657b1f92015-01-22 19:26:12 -08001026 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
1027 bool enable_selftest = false;
1028 for (size_t i = 1; i < args.size(); ++i) {
1029 if (strcmp(args[i], "--bionic-selftest") == 0) {
1030 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
1031 // Don't remove this option from arguments.
1032 enable_selftest = true;
1033 }
1034 }
1035 std::string gtest_filter_str;
1036 for (size_t i = args.size() - 1; i >= 1; --i) {
1037 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
Yabin Cuic641a952016-12-12 13:32:15 -08001038 gtest_filter_str = args[i] + strlen("--gtest_filter=");
Yabin Cui657b1f92015-01-22 19:26:12 -08001039 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -08001040 break;
1041 }
1042 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001043 if (enable_selftest == true) {
Yabin Cuic641a952016-12-12 13:32:15 -08001044 gtest_filter_str = "bionic_selftest*";
Yabin Cui657b1f92015-01-22 19:26:12 -08001045 } else {
Yabin Cuic641a952016-12-12 13:32:15 -08001046 if (gtest_filter_str.empty()) {
1047 gtest_filter_str = "-bionic_selftest*";
Yabin Cui657b1f92015-01-22 19:26:12 -08001048 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001049 // Find if '-' for NEGATIVE_PATTERNS exists.
wy828b9e12017-05-10 15:21:13 -07001050 if (gtest_filter_str.find('-') != std::string::npos) {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001051 gtest_filter_str += ":bionic_selftest*";
1052 } else {
1053 gtest_filter_str += ":-bionic_selftest*";
1054 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001055 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001056 }
Yabin Cuic641a952016-12-12 13:32:15 -08001057 gtest_filter_str = "--gtest_filter=" + gtest_filter_str;
1058 args.push_back(strdup(gtest_filter_str.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -08001059
Yabin Cui657b1f92015-01-22 19:26:12 -08001060 options.isolate = true;
1061 // Parse arguments that make us can't run in isolation mode.
1062 for (size_t i = 1; i < args.size(); ++i) {
1063 if (strcmp(args[i], "--no-isolate") == 0) {
1064 options.isolate = false;
1065 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
1066 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001067 }
1068 }
1069
Yabin Cui657b1f92015-01-22 19:26:12 -08001070 // Stop parsing if we will not run in isolation mode.
1071 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001072 return true;
1073 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001074
1075 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -07001076 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -08001077 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001078 options.test_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui657b1f92015-01-22 19:26:12 -08001079 options.gtest_color = testing::GTEST_FLAG(color);
1080 options.gtest_print_time = testing::GTEST_FLAG(print_time);
1081 options.gtest_repeat = testing::GTEST_FLAG(repeat);
1082 options.gtest_output = testing::GTEST_FLAG(output);
1083
1084 // Parse arguments speficied for isolation mode.
1085 for (size_t i = 1; i < args.size(); ++i) {
1086 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1087 char* p = args[i] + strlen("-j");
1088 int count = 0;
1089 if (*p != '\0') {
1090 // Argument like -j5.
1091 count = atoi(p);
1092 } else if (args.size() > i + 1) {
1093 // Arguments like -j 5.
1094 count = atoi(args[i + 1]);
1095 ++i;
1096 }
1097 if (count <= 0) {
1098 fprintf(stderr, "invalid job count: %d\n", count);
1099 return false;
1100 }
1101 options.job_count = static_cast<size_t>(count);
1102 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1103 int time_ms = atoi(args[i] + strlen("--deadline="));
1104 if (time_ms <= 0) {
1105 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1106 return false;
1107 }
1108 options.test_deadline_ms = time_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001109 } else if (strncmp(args[i], "--slow-threshold=", strlen("--slow-threshold=")) == 0) {
1110 int time_ms = atoi(args[i] + strlen("--slow-threshold="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001111 if (time_ms <= 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -07001112 fprintf(stderr, "invalid slow test threshold: %d\n", time_ms);
Yabin Cui657b1f92015-01-22 19:26:12 -08001113 return false;
1114 }
Elliott Hughesa456fae2016-08-31 13:30:14 -07001115 options.test_slow_threshold_ms = time_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001116 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1117 options.gtest_color = args[i] + strlen("--gtest_color=");
1118 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1119 options.gtest_print_time = false;
1120 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001121 // If the value of gtest_repeat is < 0, then it indicates the tests
1122 // should be repeated forever.
1123 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001124 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1125 args.erase(args.begin() + i);
1126 --i;
1127 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1128 std::string output = args[i] + strlen("--gtest_output=");
1129 // generate output xml file path according to the strategy in gtest.
1130 bool success = true;
1131 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1132 output = output.substr(strlen("xml:"));
1133 if (output.size() == 0) {
1134 success = false;
1135 }
1136 // Make absolute path.
1137 if (success && output[0] != '/') {
1138 char* cwd = getcwd(NULL, 0);
1139 if (cwd != NULL) {
1140 output = std::string(cwd) + "/" + output;
1141 free(cwd);
1142 } else {
1143 success = false;
1144 }
1145 }
1146 // Add file name if output is a directory.
1147 if (success && output.back() == '/') {
1148 output += "test_details.xml";
1149 }
1150 }
1151 if (success) {
1152 options.gtest_output = output;
1153 } else {
1154 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1155 return false;
1156 }
1157
1158 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1159 args.erase(args.begin() + i);
1160 --i;
1161 }
1162 }
1163
1164 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1165 // As DeathTest will try to call execve(), this argument should always be added.
1166 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001167 return true;
1168}
1169
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001170static std::string get_proc_self_exe() {
1171 char path[PATH_MAX];
1172 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
1173 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
1174 perror("readlink");
1175 exit(1);
1176 }
1177
1178 return std::string(path, path_len);
1179}
1180
Dimitry Ivanov55437462016-07-20 15:33:07 -07001181int main(int argc, char** argv, char** envp) {
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001182 g_executable_path = get_proc_self_exe();
Dimitry Ivanov55437462016-07-20 15:33:07 -07001183 g_argc = argc;
1184 g_argv = argv;
1185 g_envp = envp;
Elliott Hughes5cec3772018-01-19 15:45:23 -08001186 std::vector<char*> arg_list(argv, argv + argc);
Yabin Cuibe837362015-01-02 18:45:37 -08001187
Yabin Cui657b1f92015-01-22 19:26:12 -08001188 IsolationTestOptions options;
1189 if (PickOptions(arg_list, options) == false) {
1190 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001191 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001192
1193 if (options.isolate == true) {
1194 // Set global variables.
1195 global_test_run_deadline_ms = options.test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001196 global_test_run_slow_threshold_ms = options.test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001197 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1198 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1199 std::vector<TestCase> testcase_list;
1200
1201 argc = static_cast<int>(arg_list.size());
1202 arg_list.push_back(NULL);
1203 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1204 return 1;
1205 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001206 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1207 options.gtest_repeat, options.job_count, options.gtest_output);
1208 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001209 } else {
1210 argc = static_cast<int>(arg_list.size());
1211 arg_list.push_back(NULL);
1212 testing::InitGoogleTest(&argc, arg_list.data());
1213 return RUN_ALL_TESTS();
1214 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001215}
1216
1217//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001218// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001219
Yabin Cuibe837362015-01-02 18:45:37 -08001220TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001221 ASSERT_EQ(1, 1);
1222}
1223
Yabin Cuibe837362015-01-02 18:45:37 -08001224TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001225 ASSERT_EQ(0, 1);
1226}
1227
Yabin Cuibe837362015-01-02 18:45:37 -08001228TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001229 sleep(4);
1230}
1231
Yabin Cuibe837362015-01-02 18:45:37 -08001232TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001233 while (1) {}
1234}
Yabin Cuibe837362015-01-02 18:45:37 -08001235
1236TEST(bionic_selftest, test_signal_SEGV_terminated) {
1237 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1238 *p = 3;
1239}
Yabin Cui657b1f92015-01-22 19:26:12 -08001240
Yabin Cui767fb1c2015-09-01 15:06:39 -07001241class bionic_selftest_DeathTest : public ::testing::Test {
1242 protected:
1243 virtual void SetUp() {
1244 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1245 }
1246};
Yabin Cui657b1f92015-01-22 19:26:12 -08001247
1248static void deathtest_helper_success() {
1249 ASSERT_EQ(1, 1);
1250 exit(0);
1251}
1252
1253TEST_F(bionic_selftest_DeathTest, success) {
1254 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1255}
1256
1257static void deathtest_helper_fail() {
1258 ASSERT_EQ(1, 0);
1259}
1260
1261TEST_F(bionic_selftest_DeathTest, fail) {
1262 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1263}
Yabin Cui5e235c82017-11-16 16:20:28 -08001264
1265class BionicSelfTest : public ::testing::TestWithParam<bool> {
1266};
1267
1268TEST_P(BionicSelfTest, test_success) {
1269 ASSERT_EQ(GetParam(), GetParam());
1270}
1271
1272INSTANTIATE_TEST_CASE_P(bionic_selftest, BionicSelfTest, ::testing::Values(true, false));
1273
1274template <typename T>
1275class bionic_selftest_TestT : public ::testing::Test {
1276};
1277
1278typedef ::testing::Types<char, int> MyTypes;
1279
1280TYPED_TEST_CASE(bionic_selftest_TestT, MyTypes);
1281
1282TYPED_TEST(bionic_selftest_TestT, test_success) {
1283 ASSERT_EQ(true, true);
1284}