blob: 6f8c4039f65905156f49385d3c92b83b93c84430 [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
Yabin Cui294d1e22014-12-07 20:43:37 -080076namespace testing {
77namespace internal {
78
79// Reuse of testing::internal::ColoredPrintf in gtest.
80enum GTestColor {
81 COLOR_DEFAULT,
82 COLOR_RED,
83 COLOR_GREEN,
84 COLOR_YELLOW
85};
86
87void ColoredPrintf(GTestColor color, const char* fmt, ...);
88
Yabin Cuibe837362015-01-02 18:45:37 -080089} // namespace internal
90} // namespace testing
Yabin Cui294d1e22014-12-07 20:43:37 -080091
92using testing::internal::GTestColor;
Yabin Cui294d1e22014-12-07 20:43:37 -080093using testing::internal::COLOR_RED;
94using testing::internal::COLOR_GREEN;
95using testing::internal::COLOR_YELLOW;
96using testing::internal::ColoredPrintf;
97
Christopher Ferrisdaaaed12015-09-24 18:45:53 -070098constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 90000;
Elliott Hughesa456fae2016-08-31 13:30:14 -070099constexpr int DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -0800100
101// The time each test can run before killed for the reason of timeout.
102// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -0800103static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800104
105// The time each test can run before be warned for too much running time.
106// It takes effect only with --isolate option.
Elliott Hughesa456fae2016-08-31 13:30:14 -0700107static int global_test_run_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800108
Elliott Hughesa456fae2016-08-31 13:30:14 -0700109// Return timeout duration for a test, in ms.
110static int GetTimeoutMs(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800111 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800112}
113
Elliott Hughesa456fae2016-08-31 13:30:14 -0700114// Return threshold for calling a test slow, in ms.
115static int GetSlowThresholdMs(const std::string& /*test_name*/) {
116 return global_test_run_slow_threshold_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800117}
118
Yabin Cuibe837362015-01-02 18:45:37 -0800119static void PrintHelpInfo() {
120 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -0800121 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800122 " Run up to JOB_COUNT tests in parallel.\n"
123 " Use isolation mode, Run each test in a separate process.\n"
124 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
125 " --no-isolate\n"
126 " Don't use isolation mode, run all tests in a single process.\n"
127 " --deadline=[TIME_IN_MS]\n"
128 " Run each test in no longer than [TIME_IN_MS] time.\n"
Elliott Hughesa456fae2016-08-31 13:30:14 -0700129 " Only valid in isolation mode. Default deadline is 90000 ms.\n"
130 " --slow-threshold=[TIME_IN_MS]\n"
131 " Test running longer than [TIME_IN_MS] will be called slow.\n"
132 " Only valid in isolation mode. Default slow threshold is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -0800133 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
134 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -0800135 "Default bionic unit test option is -j.\n"
136 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
137 "running tests, or send SIGINT to the parent process to stop testing and\n"
138 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800139 "\n");
140}
141
Yabin Cui294d1e22014-12-07 20:43:37 -0800142enum TestResult {
143 TEST_SUCCESS = 0,
144 TEST_FAILED,
145 TEST_TIMEOUT
146};
147
Yabin Cui657b1f92015-01-22 19:26:12 -0800148class Test {
149 public:
150 Test() {} // For std::vector<Test>.
151 explicit Test(const char* name) : name_(name) {}
152
153 const std::string& GetName() const { return name_; }
154
Elliott Hughes93a89f82017-07-21 18:51:06 -0700155 void SetResult(TestResult result) {
156 // Native xfails are inherently likely to actually be relying on undefined
157 // behavior/uninitialized memory, and thus likely to pass from time to time
158 // on CTS. Avoid that unpleasantness by just rewriting all xfail failures
159 // as successes. You'll still see the actual failure details.
160 if (GetName().find("xfail") == 0) result = TEST_SUCCESS;
161 result_ = result;
162 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800163
164 TestResult GetResult() const { return result_; }
165
166 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
167
168 int64_t GetTestTime() const { return elapsed_time_ns_; }
169
Yabin Cuiea9c9332015-02-24 14:39:19 -0800170 void AppendTestOutput(const std::string& s) { output_ += s; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800171
Yabin Cuiea9c9332015-02-24 14:39:19 -0800172 const std::string& GetTestOutput() const { return output_; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800173
174 private:
175 const std::string name_;
176 TestResult result_;
177 int64_t elapsed_time_ns_;
Yabin Cuiea9c9332015-02-24 14:39:19 -0800178 std::string output_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800179};
180
Yabin Cui294d1e22014-12-07 20:43:37 -0800181class TestCase {
182 public:
183 TestCase() {} // For std::vector<TestCase>.
184 explicit TestCase(const char* name) : name_(name) {}
185
186 const std::string& GetName() const { return name_; }
187
Yabin Cui657b1f92015-01-22 19:26:12 -0800188 void AppendTest(const char* test_name) {
189 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800190 }
191
Yabin Cuibe837362015-01-02 18:45:37 -0800192 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800193
Yabin Cuibe837362015-01-02 18:45:37 -0800194 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800195 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800196 return name_ + "." + test_list_[test_id].GetName();
197 }
198
199 Test& GetTest(size_t test_id) {
200 VerifyTestId(test_id);
201 return test_list_[test_id];
202 }
203
204 const Test& GetTest(size_t test_id) const {
205 VerifyTestId(test_id);
206 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800207 }
208
Yabin Cuibe837362015-01-02 18:45:37 -0800209 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800210 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800211 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800212 }
213
Yabin Cuibe837362015-01-02 18:45:37 -0800214 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800215 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800216 return test_list_[test_id].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800217 }
218
Josh Gao01052222017-01-09 16:43:33 -0800219 bool GetTestSuccess(size_t test_id) const {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700220 return GetTestResult(test_id) == TEST_SUCCESS;
Josh Gao01052222017-01-09 16:43:33 -0800221 }
222
Yabin Cui657b1f92015-01-22 19:26:12 -0800223 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800224 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800225 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800226 }
227
Yabin Cuibe837362015-01-02 18:45:37 -0800228 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800229 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800230 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800231 }
232
233 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800234 void VerifyTestId(size_t test_id) const {
235 if(test_id >= test_list_.size()) {
236 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800237 exit(1);
238 }
239 }
240
241 private:
242 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800243 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800244};
245
Yabin Cui294d1e22014-12-07 20:43:37 -0800246class TestResultPrinter : public testing::EmptyTestEventListener {
247 public:
248 TestResultPrinter() : pinfo_(NULL) {}
249 virtual void OnTestStart(const testing::TestInfo& test_info) {
250 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
251 }
252 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800253
254 private:
255 const testing::TestInfo* pinfo_;
256};
257
258// Called after an assertion failure.
259void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
260 // If the test part succeeded, we don't need to do anything.
261 if (result.type() == testing::TestPartResult::kSuccess)
262 return;
263
264 // Print failure message from the assertion (e.g. expected this and got that).
Yabin Cuiea9c9332015-02-24 14:39:19 -0800265 printf("%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), result.line_number(),
266 pinfo_->test_case_name(), pinfo_->name(), result.message());
267 fflush(stdout);
Yabin Cui294d1e22014-12-07 20:43:37 -0800268}
269
Yabin Cui294d1e22014-12-07 20:43:37 -0800270static int64_t NanoTime() {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700271 std::chrono::nanoseconds duration(std::chrono::steady_clock::now().time_since_epoch());
272 return static_cast<int64_t>(duration.count());
Yabin Cui294d1e22014-12-07 20:43:37 -0800273}
274
275static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
Elliott Hughes5cec3772018-01-19 15:45:23 -0800276 std::vector<const char*> args(argv, argv + argc);
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800277 args.push_back("--gtest_list_tests");
278 args.push_back(nullptr);
279
280 // We use posix_spawn(3) rather than the simpler popen(3) because we don't want an intervening
281 // surprise shell invocation making quoting interesting for --gtest_filter (http://b/68949647).
282
283 android::base::unique_fd read_fd;
284 android::base::unique_fd write_fd;
285 if (!android::base::Pipe(&read_fd, &write_fd)) {
286 perror("pipe");
Yabin Cui294d1e22014-12-07 20:43:37 -0800287 return false;
288 }
289
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800290 posix_spawn_file_actions_t fa;
291 posix_spawn_file_actions_init(&fa);
292 posix_spawn_file_actions_addclose(&fa, read_fd);
293 posix_spawn_file_actions_adddup2(&fa, write_fd, 1);
294 posix_spawn_file_actions_adddup2(&fa, write_fd, 2);
295 posix_spawn_file_actions_addclose(&fa, write_fd);
Yabin Cui294d1e22014-12-07 20:43:37 -0800296
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800297 pid_t pid;
298 int result = posix_spawnp(&pid, argv[0], &fa, nullptr, const_cast<char**>(args.data()), nullptr);
299 posix_spawn_file_actions_destroy(&fa);
300 if (result == -1) {
301 perror("posix_spawn");
302 return false;
303 }
304 write_fd.reset();
305
306 std::string content;
307 if (!android::base::ReadFdToString(read_fd, &content)) {
308 perror("ReadFdToString");
309 return false;
310 }
311
312 for (auto& line : android::base::Split(content, "\n")) {
Yabin Cui5e235c82017-11-16 16:20:28 -0800313 line = android::base::Split(line, "#")[0];
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800314 line = android::base::Trim(line);
315 if (line.empty()) continue;
316 if (android::base::EndsWith(line, ".")) {
317 line.pop_back();
318 testcase_list.push_back(TestCase(line.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -0800319 } else {
Tao Bao99327892018-03-23 00:27:26 -0700320 if (testcase_list.empty()) {
321 // Invalid response from gtest - likely it has been upset by an invalid --gtest_* flag.
322 // Relay the message to user.
323 fprintf(stderr, "%s", content.c_str());
324 return false;
325 }
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800326 testcase_list.back().AppendTest(line.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800327 }
328 }
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800329
330 int status;
Elliott Hughescabc77f2017-11-28 12:55:19 -0800331 if (TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)) != pid) {
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800332 perror("waitpid");
333 return false;
334 }
335 return (WIFEXITED(status) && WEXITSTATUS(status) == 0);
Yabin Cui294d1e22014-12-07 20:43:37 -0800336}
337
Yabin Cui294d1e22014-12-07 20:43:37 -0800338// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
339// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
340// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800341static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
Elliott Hughes48de71e2016-10-28 10:04:44 -0700342 int iteration_count, size_t job_count) {
Christopher Ferris119cb552015-04-02 12:02:55 -0700343 if (iteration_count != 1) {
Yabin Cuibe837362015-01-02 18:45:37 -0800344 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800345 }
346 ColoredPrintf(COLOR_GREEN, "[==========] ");
347
Yabin Cuibe837362015-01-02 18:45:37 -0800348 size_t testcase_count = testcase_list.size();
349 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800350 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800351 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800352 }
353
Elliott Hughes48de71e2016-10-28 10:04:44 -0700354 printf("Running %zu %s from %zu %s (%zu %s).\n",
Yabin Cuibe837362015-01-02 18:45:37 -0800355 test_count, (test_count == 1) ? "test" : "tests",
Elliott Hughes48de71e2016-10-28 10:04:44 -0700356 testcase_count, (testcase_count == 1) ? "test case" : "test cases",
357 job_count, (job_count == 1) ? "job" : "jobs");
Yabin Cui294d1e22014-12-07 20:43:37 -0800358 fflush(stdout);
359}
360
Yabin Cuif6237472015-02-26 19:03:54 -0800361// bionic cts test needs gtest output format.
362#if defined(USING_GTEST_OUTPUT_FORMAT)
363
364static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
365 ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
366 printf("%s\n", testcase.GetTestName(test_id).c_str());
367
368 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
369 printf("%s", test_output.c_str());
370
371 TestResult result = testcase.GetTestResult(test_id);
Elliott Hughes93a89f82017-07-21 18:51:06 -0700372 if (result == TEST_SUCCESS) {
Yabin Cuif6237472015-02-26 19:03:54 -0800373 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
374 } else {
375 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
376 }
377 printf("%s", testcase.GetTestName(test_id).c_str());
378 if (testing::GTEST_FLAG(print_time)) {
379 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
380 }
381 printf("\n");
382 fflush(stdout);
383}
384
385#else // !defined(USING_GTEST_OUTPUT_FORMAT)
386
Yabin Cui657b1f92015-01-22 19:26:12 -0800387static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
388 TestResult result = testcase.GetTestResult(test_id);
389 if (result == TEST_SUCCESS) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700390 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800391 } else if (result == TEST_FAILED) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700392 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800393 } else if (result == TEST_TIMEOUT) {
394 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
395 }
Yabin Cuibe837362015-01-02 18:45:37 -0800396
Yabin Cui657b1f92015-01-22 19:26:12 -0800397 printf("%s", testcase.GetTestName(test_id).c_str());
398 if (testing::GTEST_FLAG(print_time)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800399 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
Yabin Cui657b1f92015-01-22 19:26:12 -0800400 }
Yabin Cuif6237472015-02-26 19:03:54 -0800401 printf("\n");
Yabin Cui657b1f92015-01-22 19:26:12 -0800402
Yabin Cuiea9c9332015-02-24 14:39:19 -0800403 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
404 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800405 fflush(stdout);
406}
407
Yabin Cuif6237472015-02-26 19:03:54 -0800408#endif // !defined(USING_GTEST_OUTPUT_FORMAT)
409
Yabin Cuibe837362015-01-02 18:45:37 -0800410static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800411 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800412
413 std::vector<std::string> fail_test_name_list;
414 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
415
Elliott Hughesa456fae2016-08-31 13:30:14 -0700416 // For tests that were slow but didn't time out.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800417 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800418 size_t testcase_count = testcase_list.size();
419 size_t test_count = 0;
420 size_t success_test_count = 0;
Josh Gao01052222017-01-09 16:43:33 -0800421 size_t expected_failure_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800422
423 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800424 test_count += testcase.TestCount();
425 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800426 TestResult result = testcase.GetTestResult(i);
Josh Gao01052222017-01-09 16:43:33 -0800427 if (result == TEST_TIMEOUT) {
428 timeout_test_list.push_back(
429 std::make_pair(testcase.GetTestName(i), testcase.GetTestTime(i)));
Elliott Hughes93a89f82017-07-21 18:51:06 -0700430 } else if (result == TEST_SUCCESS) {
431 ++success_test_count;
432 if (testcase.GetTestName(i).find(".xfail_") != std::string::npos) ++expected_failure_count;
433 } else if (result == TEST_FAILED) {
Josh Gao01052222017-01-09 16:43:33 -0800434 fail_test_name_list.push_back(testcase.GetTestName(i));
Yabin Cui294d1e22014-12-07 20:43:37 -0800435 }
436 if (result != TEST_TIMEOUT &&
Elliott Hughesa456fae2016-08-31 13:30:14 -0700437 testcase.GetTestTime(i) / 1000000 >= GetSlowThresholdMs(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800438 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
439 testcase.GetTestTime(i),
Elliott Hughesa456fae2016-08-31 13:30:14 -0700440 GetSlowThresholdMs(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800441 }
442 }
443 }
444
Yabin Cui294d1e22014-12-07 20:43:37 -0800445 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800446 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
447 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800448 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800449 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800450 }
451 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800452 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Josh Gao01052222017-01-09 16:43:33 -0800453 printf("%zu %s.", success_test_count, (success_test_count == 1) ? "test" : "tests");
454 if (expected_failure_count > 0) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700455 printf(" (%zu expected failure%s.)", expected_failure_count,
Josh Gao01052222017-01-09 16:43:33 -0800456 (expected_failure_count == 1) ? "" : "s");
457 }
458 printf("\n");
Yabin Cui294d1e22014-12-07 20:43:37 -0800459
Elliott Hughesa456fae2016-08-31 13:30:14 -0700460 // Print tests that timed out.
Yabin Cuibe837362015-01-02 18:45:37 -0800461 size_t timeout_test_count = timeout_test_list.size();
462 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800463 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800464 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800465 for (const auto& timeout_pair : timeout_test_list) {
466 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800467 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
468 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800469 }
470 }
471
Elliott Hughesa456fae2016-08-31 13:30:14 -0700472 // Print tests that were slow.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800473 size_t slow_test_count = slow_test_list.size();
474 if (slow_test_count > 0) {
475 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
476 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
477 for (const auto& slow_tuple : slow_test_list) {
478 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
Elliott Hughesa456fae2016-08-31 13:30:14 -0700479 printf("%s (%" PRId64 " ms, exceeded %d ms)\n", std::get<0>(slow_tuple).c_str(),
Yabin Cui4a82ede2015-01-26 17:19:37 -0800480 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800481 }
482 }
483
Elliott Hughesa456fae2016-08-31 13:30:14 -0700484 // Print tests that failed.
485 size_t fail_test_count = fail_test_name_list.size();
Yabin Cuibe837362015-01-02 18:45:37 -0800486 if (fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700487 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
488 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
489 for (const auto& name : fail_test_name_list) {
490 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
491 printf("%s\n", name.c_str());
492 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800493 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700494
Elliott Hughes93a89f82017-07-21 18:51:06 -0700495 if (timeout_test_count > 0 || slow_test_count > 0 || fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700496 printf("\n");
497 }
498
Yabin Cuibe837362015-01-02 18:45:37 -0800499 if (timeout_test_count > 0) {
500 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800501 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800502 if (slow_test_count > 0) {
503 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800504 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700505 if (fail_test_count > 0) {
506 printf("%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
507 }
Josh Gao01052222017-01-09 16:43:33 -0800508
Yabin Cui294d1e22014-12-07 20:43:37 -0800509 fflush(stdout);
510}
511
Dan Albert09a99642016-01-13 21:48:56 -0800512std::string XmlEscape(const std::string& xml) {
513 std::string escaped;
514 escaped.reserve(xml.size());
515
516 for (auto c : xml) {
517 switch (c) {
518 case '<':
519 escaped.append("&lt;");
520 break;
521 case '>':
522 escaped.append("&gt;");
523 break;
524 case '&':
525 escaped.append("&amp;");
526 break;
527 case '\'':
528 escaped.append("&apos;");
529 break;
530 case '"':
531 escaped.append("&quot;");
532 break;
533 default:
534 escaped.append(1, c);
535 break;
536 }
537 }
538
539 return escaped;
540}
541
Yabin Cui657b1f92015-01-22 19:26:12 -0800542// Output xml file when --gtest_output is used, write this function as we can't reuse
543// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
544// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
545// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
546void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
547 const std::vector<TestCase>& testcase_list,
548 time_t epoch_iteration_start_time,
549 int64_t elapsed_time_ns) {
Elliott Hughes5cec3772018-01-19 15:45:23 -0800550 FILE* fp = fopen(xml_output_filename.c_str(), "we");
Yabin Cui657b1f92015-01-22 19:26:12 -0800551 if (fp == NULL) {
552 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
553 exit(1);
554 }
555
556 size_t total_test_count = 0;
557 size_t total_failed_count = 0;
558 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
559 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
560 for (size_t i = 0; i < testcase_list.size(); ++i) {
561 auto& testcase = testcase_list[i];
562 total_test_count += testcase.TestCount();
563 for (size_t j = 0; j < testcase.TestCount(); ++j) {
Josh Gao01052222017-01-09 16:43:33 -0800564 if (!testcase.GetTestSuccess(j)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800565 ++failed_count_list[i];
566 }
567 elapsed_time_list[i] += testcase.GetTestTime(j);
568 }
569 total_failed_count += failed_count_list[i];
570 }
571
572 const tm* time_struct = localtime(&epoch_iteration_start_time);
573 char timestamp[40];
574 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
575 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
576 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
577
578 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
579 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
580 total_test_count, total_failed_count);
581 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
582 for (size_t i = 0; i < testcase_list.size(); ++i) {
583 auto& testcase = testcase_list[i];
584 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
585 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
586 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
587
588 for (size_t j = 0; j < testcase.TestCount(); ++j) {
589 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
590 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
591 testcase.GetName().c_str());
Josh Gao01052222017-01-09 16:43:33 -0800592 if (!testcase.GetTestSuccess(j)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800593 fputs(" />\n", fp);
594 } else {
595 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800596 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
Dan Albert09a99642016-01-13 21:48:56 -0800597 const std::string escaped_test_output = XmlEscape(test_output);
598 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", escaped_test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800599 fputs(" </failure>\n", fp);
600 fputs(" </testcase>\n", fp);
601 }
602 }
603
604 fputs(" </testsuite>\n", fp);
605 }
606 fputs("</testsuites>\n", fp);
607 fclose(fp);
608}
609
Yabin Cui767fb1c2015-09-01 15:06:39 -0700610static bool sigint_flag;
611static bool sigquit_flag;
612
613static void signal_handler(int sig) {
614 if (sig == SIGINT) {
615 sigint_flag = true;
616 } else if (sig == SIGQUIT) {
617 sigquit_flag = true;
618 }
619}
620
621static bool RegisterSignalHandler() {
622 sigint_flag = false;
623 sigquit_flag = false;
624 sig_t ret = signal(SIGINT, signal_handler);
625 if (ret != SIG_ERR) {
626 ret = signal(SIGQUIT, signal_handler);
627 }
628 if (ret == SIG_ERR) {
629 perror("RegisterSignalHandler");
630 return false;
631 }
632 return true;
633}
634
635static bool UnregisterSignalHandler() {
636 sig_t ret = signal(SIGINT, SIG_DFL);
637 if (ret != SIG_ERR) {
638 ret = signal(SIGQUIT, SIG_DFL);
639 }
640 if (ret == SIG_ERR) {
641 perror("UnregisterSignalHandler");
642 return false;
643 }
644 return true;
645}
646
Yabin Cui1d4c7802015-02-02 19:14:05 -0800647struct ChildProcInfo {
648 pid_t pid;
649 int64_t start_time_ns;
650 int64_t end_time_ns;
651 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
652 size_t testcase_id, test_id;
653 bool finished;
654 bool timed_out;
655 int exit_status;
656 int child_read_fd; // File descriptor to read child test failure info.
657};
658
Yabin Cui294d1e22014-12-07 20:43:37 -0800659// Forked Child process, run the single test.
660static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800661 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800662 memcpy(new_argv, argv, sizeof(char*) * argc);
663
664 char* filter_arg = new char [test_name.size() + 20];
665 strcpy(filter_arg, "--gtest_filter=");
666 strcat(filter_arg, test_name.c_str());
667 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800668 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800669
670 int new_argc = argc + 1;
671 testing::InitGoogleTest(&new_argc, new_argv);
672 int result = RUN_ALL_TESTS();
673 exit(result);
674}
675
Yabin Cui1d4c7802015-02-02 19:14:05 -0800676static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700677 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800678 int pipefd[2];
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800679 if (pipe(pipefd) == -1) {
680 perror("pipe in RunTestInSeparateProc");
681 exit(1);
682 }
683 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
684 perror("fcntl in RunTestInSeparateProc");
Yabin Cui1d4c7802015-02-02 19:14:05 -0800685 exit(1);
686 }
687 pid_t pid = fork();
688 if (pid == -1) {
689 perror("fork in RunTestInSeparateProc");
690 exit(1);
691 } else if (pid == 0) {
692 // In child process, run a single test.
693 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800694 close(STDOUT_FILENO);
695 close(STDERR_FILENO);
696 dup2(pipefd[1], STDOUT_FILENO);
697 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800698
Yabin Cui767fb1c2015-09-01 15:06:39 -0700699 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800700 exit(1);
701 }
702 ChildProcessFn(argc, argv, test_name);
703 // Unreachable.
704 }
705 // In parent process, initialize child process info.
706 close(pipefd[1]);
707 ChildProcInfo child_proc;
708 child_proc.child_read_fd = pipefd[0];
709 child_proc.pid = pid;
710 child_proc.start_time_ns = NanoTime();
Elliott Hughesa456fae2016-08-31 13:30:14 -0700711 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetTimeoutMs(test_name) * 1000000LL;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800712 child_proc.testcase_id = testcase_id;
713 child_proc.test_id = test_id;
714 child_proc.finished = false;
715 return child_proc;
716}
Yabin Cui294d1e22014-12-07 20:43:37 -0800717
Yabin Cui1d4c7802015-02-02 19:14:05 -0800718static void HandleSignals(std::vector<TestCase>& testcase_list,
719 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700720 if (sigquit_flag) {
721 sigquit_flag = false;
722 // Print current running tests.
723 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700724 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700725 if (child_proc.pid != 0) {
726 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
727 int64_t current_time_ns = NanoTime();
728 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
729 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800730 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800731 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700732 } else if (sigint_flag) {
733 sigint_flag = false;
734 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700735 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700736 if (child_proc.pid != 0) {
737 // Send SIGKILL to ensure the child process can be killed unconditionally.
738 kill(child_proc.pid, SIGKILL);
739 }
740 }
741 // SIGINT kills the parent process as well.
742 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800743 }
744}
745
746static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
747 std::vector<ChildProcInfo>& child_proc_list) {
748 for (size_t i = 0; i < child_proc_list.size(); ++i) {
749 if (child_proc_list[i].pid == exit_pid) {
750 child_proc_list[i].finished = true;
751 child_proc_list[i].timed_out = false;
752 child_proc_list[i].exit_status = exit_status;
753 child_proc_list[i].end_time_ns = NanoTime();
754 return true;
755 }
756 }
757 return false;
758}
759
760static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
761 int64_t current_time_ns = NanoTime();
762 size_t timeout_child_count = 0;
763 for (size_t i = 0; i < child_proc_list.size(); ++i) {
764 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
765 child_proc_list[i].finished = true;
766 child_proc_list[i].timed_out = true;
767 child_proc_list[i].end_time_ns = current_time_ns;
768 ++timeout_child_count;
769 }
770 }
771 return timeout_child_count;
772}
773
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800774static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
775 std::vector<ChildProcInfo>& child_proc_list) {
776 for (const auto& child_proc : child_proc_list) {
777 TestCase& testcase = testcase_list[child_proc.testcase_id];
778 int test_id = child_proc.test_id;
779 while (true) {
780 char buf[1024];
781 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
782 if (bytes_read > 0) {
783 buf[bytes_read] = '\0';
784 testcase.GetTest(test_id).AppendTestOutput(buf);
785 } else if (bytes_read == 0) {
786 break; // Read end.
787 } else {
788 if (errno == EAGAIN) {
789 break;
790 }
791 perror("failed to read child_read_fd");
792 exit(1);
793 }
794 }
795 }
796}
797
Yabin Cui1d4c7802015-02-02 19:14:05 -0800798static void WaitChildProcs(std::vector<TestCase>& testcase_list,
799 std::vector<ChildProcInfo>& child_proc_list) {
800 size_t finished_child_count = 0;
801 while (true) {
802 int status;
803 pid_t result;
804 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
805 if (CheckChildProcExit(result, status, child_proc_list)) {
806 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800807 }
808 }
809
810 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800811 if (errno == ECHILD) {
812 // This happens when we have no running child processes.
813 return;
814 } else {
815 perror("waitpid");
816 exit(1);
817 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800818 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800819 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800820 }
821
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800822 ReadChildProcOutput(testcase_list, child_proc_list);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800823 if (finished_child_count > 0) {
824 return;
825 }
826
827 HandleSignals(testcase_list, child_proc_list);
828
Yabin Cui294d1e22014-12-07 20:43:37 -0800829 // sleep 1 ms to avoid busy looping.
830 timespec sleep_time;
831 sleep_time.tv_sec = 0;
832 sleep_time.tv_nsec = 1000000;
833 nanosleep(&sleep_time, NULL);
834 }
835}
836
Yabin Cui1d4c7802015-02-02 19:14:05 -0800837static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800838 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800839 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800840
841 TestResult test_result = TEST_SUCCESS;
842 if (result != pid || WEXITSTATUS(exit_status) != 0) {
843 test_result = TEST_FAILED;
844 }
845 return test_result;
846}
847
Yabin Cui1d4c7802015-02-02 19:14:05 -0800848static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
849 int test_id = child_proc.test_id;
850 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
851 if (child_proc.timed_out) {
852 // The child process marked as timed_out has not exited, and we should kill it manually.
853 kill(child_proc.pid, SIGKILL);
854 WaitForOneChild(child_proc.pid);
855 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800856 close(child_proc.child_read_fd);
857
858 if (child_proc.timed_out) {
859 testcase.SetTestResult(test_id, TEST_TIMEOUT);
860 char buf[1024];
861 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
862 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800863 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800864
865 } else if (WIFSIGNALED(child_proc.exit_status)) {
866 // Record signal terminated test as failed.
867 testcase.SetTestResult(test_id, TEST_FAILED);
868 char buf[1024];
869 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
870 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800871 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800872
873 } else {
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800874 int exitcode = WEXITSTATUS(child_proc.exit_status);
875 testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
876 if (exitcode != 0) {
Yabin Cuia32fc862015-12-03 16:28:03 -0800877 char buf[1024];
878 snprintf(buf, sizeof(buf), "%s exited with exitcode %d.\n",
879 testcase.GetTestName(test_id).c_str(), exitcode);
880 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800881 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800882 }
883}
884
Yabin Cui294d1e22014-12-07 20:43:37 -0800885// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
886// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700887// Returns true if all tests run successfully, otherwise return false.
888static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700889 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800890 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800891 // Stop default result printer to avoid environment setup/teardown information for each test.
892 testing::UnitTest::GetInstance()->listeners().Release(
893 testing::UnitTest::GetInstance()->listeners().default_result_printer());
894 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
895
Yabin Cui767fb1c2015-09-01 15:06:39 -0700896 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800897 exit(1);
898 }
899
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700900 bool all_tests_passed = true;
901
Christopher Ferris119cb552015-04-02 12:02:55 -0700902 for (size_t iteration = 1;
903 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
904 ++iteration) {
Elliott Hughes48de71e2016-10-28 10:04:44 -0700905 OnTestIterationStartPrint(testcase_list, iteration, iteration_count, job_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800906 int64_t iteration_start_time_ns = NanoTime();
907 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800908
Yabin Cuibe837362015-01-02 18:45:37 -0800909 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800910 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800911
Yabin Cuibe837362015-01-02 18:45:37 -0800912 // Next test to run is [next_testcase_id:next_test_id].
913 size_t next_testcase_id = 0;
914 size_t next_test_id = 0;
915
916 // Record how many tests are finished.
917 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
918 size_t finished_testcase_count = 0;
919
920 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800921 // run up to job_count child processes.
922 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
923 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
924 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700925 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800926 child_proc_list.push_back(child_proc);
927 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
928 next_test_id = 0;
929 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800930 }
931 }
932
933 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800934 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800935
936 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800937 auto it = child_proc_list.begin();
938 while (it != child_proc_list.end()) {
939 auto& child_proc = *it;
940 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800941 size_t testcase_id = child_proc.testcase_id;
942 size_t test_id = child_proc.test_id;
943 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800944
Yabin Cui1d4c7802015-02-02 19:14:05 -0800945 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800946 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800947
948 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
949 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800950 }
Josh Gao01052222017-01-09 16:43:33 -0800951 if (!testcase.GetTestSuccess(test_id)) {
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700952 all_tests_passed = false;
953 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800954
955 it = child_proc_list.erase(it);
956 } else {
957 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800958 }
959 }
960 }
961
Yabin Cui657b1f92015-01-22 19:26:12 -0800962 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
963 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
964 if (!xml_output_filename.empty()) {
965 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
966 elapsed_time_ns);
967 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800968 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800969
Yabin Cui767fb1c2015-09-01 15:06:39 -0700970 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800971 exit(1);
972 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700973
974 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800975}
976
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700977static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800978 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800979}
980
Yabin Cuiead08142015-02-04 20:53:56 -0800981static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
982 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
983 // test program via a valid path that contains at least one path separator.
984 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
985 // and execve() doesn't read environment variable PATH, so execve() will not success
986 // until we specify the absolute path or relative path of the test program directly.
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -0700987 if (strchr(args[0], '/') == nullptr) {
988 args[0] = strdup(g_executable_path.c_str());
Yabin Cuiead08142015-02-04 20:53:56 -0800989 }
990}
991
Yabin Cui11c43532015-01-28 14:28:14 -0800992static void AddGtestFilterSynonym(std::vector<char*>& args) {
993 // Support --gtest-filter as a synonym for --gtest_filter.
994 for (size_t i = 1; i < args.size(); ++i) {
995 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
996 args[i][7] = '_';
997 }
998 }
999}
1000
Yabin Cui657b1f92015-01-22 19:26:12 -08001001struct IsolationTestOptions {
1002 bool isolate;
1003 size_t job_count;
1004 int test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001005 int test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001006 std::string gtest_color;
1007 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -07001008 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -08001009 std::string gtest_output;
1010};
1011
1012// 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 -08001013// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -08001014// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
1015// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -08001016// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -08001017// args is used to pass in all command arguments, and pass out only the part of options for gtest.
1018// options is used to pass out test options in isolation mode.
1019// Return false if there is error in arguments.
1020static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
1021 for (size_t i = 1; i < args.size(); ++i) {
1022 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001023 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -08001024 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001025 return true;
1026 }
1027 }
1028
Yabin Cuiead08142015-02-04 20:53:56 -08001029 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -08001030 AddGtestFilterSynonym(args);
1031
Yabin Cui657b1f92015-01-22 19:26:12 -08001032 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
1033 bool enable_selftest = false;
1034 for (size_t i = 1; i < args.size(); ++i) {
1035 if (strcmp(args[i], "--bionic-selftest") == 0) {
1036 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
1037 // Don't remove this option from arguments.
1038 enable_selftest = true;
1039 }
1040 }
1041 std::string gtest_filter_str;
1042 for (size_t i = args.size() - 1; i >= 1; --i) {
1043 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
Yabin Cuic641a952016-12-12 13:32:15 -08001044 gtest_filter_str = args[i] + strlen("--gtest_filter=");
Yabin Cui657b1f92015-01-22 19:26:12 -08001045 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -08001046 break;
1047 }
1048 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001049 if (enable_selftest == true) {
Yabin Cuic641a952016-12-12 13:32:15 -08001050 gtest_filter_str = "bionic_selftest*";
Yabin Cui657b1f92015-01-22 19:26:12 -08001051 } else {
Yabin Cuic641a952016-12-12 13:32:15 -08001052 if (gtest_filter_str.empty()) {
1053 gtest_filter_str = "-bionic_selftest*";
Yabin Cui657b1f92015-01-22 19:26:12 -08001054 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001055 // Find if '-' for NEGATIVE_PATTERNS exists.
wy828b9e12017-05-10 15:21:13 -07001056 if (gtest_filter_str.find('-') != std::string::npos) {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001057 gtest_filter_str += ":bionic_selftest*";
1058 } else {
1059 gtest_filter_str += ":-bionic_selftest*";
1060 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001061 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001062 }
Yabin Cuic641a952016-12-12 13:32:15 -08001063 gtest_filter_str = "--gtest_filter=" + gtest_filter_str;
1064 args.push_back(strdup(gtest_filter_str.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -08001065
Yabin Cui657b1f92015-01-22 19:26:12 -08001066 options.isolate = true;
1067 // Parse arguments that make us can't run in isolation mode.
1068 for (size_t i = 1; i < args.size(); ++i) {
1069 if (strcmp(args[i], "--no-isolate") == 0) {
1070 options.isolate = false;
1071 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
1072 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001073 }
1074 }
1075
Yabin Cui657b1f92015-01-22 19:26:12 -08001076 // Stop parsing if we will not run in isolation mode.
1077 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001078 return true;
1079 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001080
1081 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -07001082 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -08001083 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001084 options.test_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui657b1f92015-01-22 19:26:12 -08001085 options.gtest_color = testing::GTEST_FLAG(color);
1086 options.gtest_print_time = testing::GTEST_FLAG(print_time);
1087 options.gtest_repeat = testing::GTEST_FLAG(repeat);
1088 options.gtest_output = testing::GTEST_FLAG(output);
1089
1090 // Parse arguments speficied for isolation mode.
1091 for (size_t i = 1; i < args.size(); ++i) {
1092 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1093 char* p = args[i] + strlen("-j");
1094 int count = 0;
1095 if (*p != '\0') {
1096 // Argument like -j5.
1097 count = atoi(p);
1098 } else if (args.size() > i + 1) {
1099 // Arguments like -j 5.
1100 count = atoi(args[i + 1]);
1101 ++i;
1102 }
1103 if (count <= 0) {
1104 fprintf(stderr, "invalid job count: %d\n", count);
1105 return false;
1106 }
1107 options.job_count = static_cast<size_t>(count);
1108 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1109 int time_ms = atoi(args[i] + strlen("--deadline="));
1110 if (time_ms <= 0) {
1111 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1112 return false;
1113 }
1114 options.test_deadline_ms = time_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001115 } else if (strncmp(args[i], "--slow-threshold=", strlen("--slow-threshold=")) == 0) {
1116 int time_ms = atoi(args[i] + strlen("--slow-threshold="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001117 if (time_ms <= 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -07001118 fprintf(stderr, "invalid slow test threshold: %d\n", time_ms);
Yabin Cui657b1f92015-01-22 19:26:12 -08001119 return false;
1120 }
Elliott Hughesa456fae2016-08-31 13:30:14 -07001121 options.test_slow_threshold_ms = time_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001122 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1123 options.gtest_color = args[i] + strlen("--gtest_color=");
1124 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1125 options.gtest_print_time = false;
1126 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001127 // If the value of gtest_repeat is < 0, then it indicates the tests
1128 // should be repeated forever.
1129 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001130 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1131 args.erase(args.begin() + i);
1132 --i;
1133 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1134 std::string output = args[i] + strlen("--gtest_output=");
1135 // generate output xml file path according to the strategy in gtest.
1136 bool success = true;
1137 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1138 output = output.substr(strlen("xml:"));
1139 if (output.size() == 0) {
1140 success = false;
1141 }
1142 // Make absolute path.
1143 if (success && output[0] != '/') {
1144 char* cwd = getcwd(NULL, 0);
1145 if (cwd != NULL) {
1146 output = std::string(cwd) + "/" + output;
1147 free(cwd);
1148 } else {
1149 success = false;
1150 }
1151 }
1152 // Add file name if output is a directory.
1153 if (success && output.back() == '/') {
1154 output += "test_details.xml";
1155 }
1156 }
1157 if (success) {
1158 options.gtest_output = output;
1159 } else {
1160 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1161 return false;
1162 }
1163
1164 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1165 args.erase(args.begin() + i);
1166 --i;
1167 }
1168 }
1169
1170 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1171 // As DeathTest will try to call execve(), this argument should always be added.
1172 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001173 return true;
1174}
1175
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001176static std::string get_proc_self_exe() {
1177 char path[PATH_MAX];
1178 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
1179 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
1180 perror("readlink");
1181 exit(1);
1182 }
1183
1184 return std::string(path, path_len);
1185}
1186
Dimitry Ivanov55437462016-07-20 15:33:07 -07001187int main(int argc, char** argv, char** envp) {
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001188 g_executable_path = get_proc_self_exe();
Dimitry Ivanov55437462016-07-20 15:33:07 -07001189 g_argc = argc;
1190 g_argv = argv;
1191 g_envp = envp;
Elliott Hughes5cec3772018-01-19 15:45:23 -08001192 std::vector<char*> arg_list(argv, argv + argc);
Yabin Cuibe837362015-01-02 18:45:37 -08001193
Yabin Cui657b1f92015-01-22 19:26:12 -08001194 IsolationTestOptions options;
1195 if (PickOptions(arg_list, options) == false) {
1196 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001197 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001198
1199 if (options.isolate == true) {
1200 // Set global variables.
1201 global_test_run_deadline_ms = options.test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001202 global_test_run_slow_threshold_ms = options.test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001203 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1204 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1205 std::vector<TestCase> testcase_list;
1206
1207 argc = static_cast<int>(arg_list.size());
1208 arg_list.push_back(NULL);
1209 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1210 return 1;
1211 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001212 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1213 options.gtest_repeat, options.job_count, options.gtest_output);
1214 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001215 } else {
1216 argc = static_cast<int>(arg_list.size());
1217 arg_list.push_back(NULL);
1218 testing::InitGoogleTest(&argc, arg_list.data());
1219 return RUN_ALL_TESTS();
1220 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001221}
1222
1223//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001224// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001225
Yabin Cuibe837362015-01-02 18:45:37 -08001226TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001227 ASSERT_EQ(1, 1);
1228}
1229
Yabin Cuibe837362015-01-02 18:45:37 -08001230TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001231 ASSERT_EQ(0, 1);
1232}
1233
Yabin Cuibe837362015-01-02 18:45:37 -08001234TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001235 sleep(4);
1236}
1237
Yabin Cuibe837362015-01-02 18:45:37 -08001238TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001239 while (1) {}
1240}
Yabin Cuibe837362015-01-02 18:45:37 -08001241
1242TEST(bionic_selftest, test_signal_SEGV_terminated) {
1243 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1244 *p = 3;
1245}
Yabin Cui657b1f92015-01-22 19:26:12 -08001246
Yabin Cui767fb1c2015-09-01 15:06:39 -07001247class bionic_selftest_DeathTest : public ::testing::Test {
1248 protected:
1249 virtual void SetUp() {
1250 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1251 }
1252};
Yabin Cui657b1f92015-01-22 19:26:12 -08001253
1254static void deathtest_helper_success() {
1255 ASSERT_EQ(1, 1);
1256 exit(0);
1257}
1258
1259TEST_F(bionic_selftest_DeathTest, success) {
1260 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1261}
1262
1263static void deathtest_helper_fail() {
1264 ASSERT_EQ(1, 0);
1265}
1266
1267TEST_F(bionic_selftest_DeathTest, fail) {
1268 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1269}
Yabin Cui5e235c82017-11-16 16:20:28 -08001270
1271class BionicSelfTest : public ::testing::TestWithParam<bool> {
1272};
1273
1274TEST_P(BionicSelfTest, test_success) {
1275 ASSERT_EQ(GetParam(), GetParam());
1276}
1277
1278INSTANTIATE_TEST_CASE_P(bionic_selftest, BionicSelfTest, ::testing::Values(true, false));
1279
1280template <typename T>
1281class bionic_selftest_TestT : public ::testing::Test {
1282};
1283
1284typedef ::testing::Types<char, int> MyTypes;
1285
1286TYPED_TEST_CASE(bionic_selftest_TestT, MyTypes);
1287
1288TYPED_TEST(bionic_selftest_TestT, test_success) {
1289 ASSERT_EQ(true, true);
1290}