blob: 781acce8c14c49cd5cb395c1731b486a0cd4f610 [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;
93using testing::internal::COLOR_DEFAULT;
94using testing::internal::COLOR_RED;
95using testing::internal::COLOR_GREEN;
96using testing::internal::COLOR_YELLOW;
97using testing::internal::ColoredPrintf;
98
Christopher Ferrisdaaaed12015-09-24 18:45:53 -070099constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 90000;
Elliott Hughesa456fae2016-08-31 13:30:14 -0700100constexpr int DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -0800101
102// The time each test can run before killed for the reason of timeout.
103// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -0800104static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800105
106// The time each test can run before be warned for too much running time.
107// It takes effect only with --isolate option.
Elliott Hughesa456fae2016-08-31 13:30:14 -0700108static int global_test_run_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800109
Elliott Hughesa456fae2016-08-31 13:30:14 -0700110// Return timeout duration for a test, in ms.
111static int GetTimeoutMs(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800112 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800113}
114
Elliott Hughesa456fae2016-08-31 13:30:14 -0700115// Return threshold for calling a test slow, in ms.
116static int GetSlowThresholdMs(const std::string& /*test_name*/) {
117 return global_test_run_slow_threshold_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800118}
119
Yabin Cuibe837362015-01-02 18:45:37 -0800120static void PrintHelpInfo() {
121 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -0800122 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800123 " Run up to JOB_COUNT tests in parallel.\n"
124 " Use isolation mode, Run each test in a separate process.\n"
125 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
126 " --no-isolate\n"
127 " Don't use isolation mode, run all tests in a single process.\n"
128 " --deadline=[TIME_IN_MS]\n"
129 " Run each test in no longer than [TIME_IN_MS] time.\n"
Elliott Hughesa456fae2016-08-31 13:30:14 -0700130 " Only valid in isolation mode. Default deadline is 90000 ms.\n"
131 " --slow-threshold=[TIME_IN_MS]\n"
132 " Test running longer than [TIME_IN_MS] will be called slow.\n"
133 " Only valid in isolation mode. Default slow threshold is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -0800134 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
135 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -0800136 "Default bionic unit test option is -j.\n"
137 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
138 "running tests, or send SIGINT to the parent process to stop testing and\n"
139 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800140 "\n");
141}
142
Yabin Cui294d1e22014-12-07 20:43:37 -0800143enum TestResult {
144 TEST_SUCCESS = 0,
145 TEST_FAILED,
146 TEST_TIMEOUT
147};
148
Yabin Cui657b1f92015-01-22 19:26:12 -0800149class Test {
150 public:
151 Test() {} // For std::vector<Test>.
152 explicit Test(const char* name) : name_(name) {}
153
154 const std::string& GetName() const { return name_; }
155
Elliott Hughes93a89f82017-07-21 18:51:06 -0700156 void SetResult(TestResult result) {
157 // Native xfails are inherently likely to actually be relying on undefined
158 // behavior/uninitialized memory, and thus likely to pass from time to time
159 // on CTS. Avoid that unpleasantness by just rewriting all xfail failures
160 // as successes. You'll still see the actual failure details.
161 if (GetName().find("xfail") == 0) result = TEST_SUCCESS;
162 result_ = result;
163 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800164
165 TestResult GetResult() const { return result_; }
166
167 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
168
169 int64_t GetTestTime() const { return elapsed_time_ns_; }
170
Yabin Cuiea9c9332015-02-24 14:39:19 -0800171 void AppendTestOutput(const std::string& s) { output_ += s; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800172
Yabin Cuiea9c9332015-02-24 14:39:19 -0800173 const std::string& GetTestOutput() const { return output_; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800174
175 private:
176 const std::string name_;
177 TestResult result_;
178 int64_t elapsed_time_ns_;
Yabin Cuiea9c9332015-02-24 14:39:19 -0800179 std::string output_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800180};
181
Yabin Cui294d1e22014-12-07 20:43:37 -0800182class TestCase {
183 public:
184 TestCase() {} // For std::vector<TestCase>.
185 explicit TestCase(const char* name) : name_(name) {}
186
187 const std::string& GetName() const { return name_; }
188
Yabin Cui657b1f92015-01-22 19:26:12 -0800189 void AppendTest(const char* test_name) {
190 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800191 }
192
Yabin Cuibe837362015-01-02 18:45:37 -0800193 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800194
Yabin Cuibe837362015-01-02 18:45:37 -0800195 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800196 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800197 return name_ + "." + test_list_[test_id].GetName();
198 }
199
200 Test& GetTest(size_t test_id) {
201 VerifyTestId(test_id);
202 return test_list_[test_id];
203 }
204
205 const Test& GetTest(size_t test_id) const {
206 VerifyTestId(test_id);
207 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800208 }
209
Yabin Cuibe837362015-01-02 18:45:37 -0800210 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800211 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800212 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800213 }
214
Yabin Cuibe837362015-01-02 18:45:37 -0800215 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800216 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800217 return test_list_[test_id].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800218 }
219
Josh Gao01052222017-01-09 16:43:33 -0800220 bool GetTestSuccess(size_t test_id) const {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700221 return GetTestResult(test_id) == TEST_SUCCESS;
Josh Gao01052222017-01-09 16:43:33 -0800222 }
223
Yabin Cui657b1f92015-01-22 19:26:12 -0800224 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800225 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800226 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800227 }
228
Yabin Cuibe837362015-01-02 18:45:37 -0800229 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800230 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800231 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800232 }
233
234 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800235 void VerifyTestId(size_t test_id) const {
236 if(test_id >= test_list_.size()) {
237 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800238 exit(1);
239 }
240 }
241
242 private:
243 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800244 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800245};
246
Yabin Cui294d1e22014-12-07 20:43:37 -0800247class TestResultPrinter : public testing::EmptyTestEventListener {
248 public:
249 TestResultPrinter() : pinfo_(NULL) {}
250 virtual void OnTestStart(const testing::TestInfo& test_info) {
251 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
252 }
253 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800254
255 private:
256 const testing::TestInfo* pinfo_;
257};
258
259// Called after an assertion failure.
260void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
261 // If the test part succeeded, we don't need to do anything.
262 if (result.type() == testing::TestPartResult::kSuccess)
263 return;
264
265 // Print failure message from the assertion (e.g. expected this and got that).
Yabin Cuiea9c9332015-02-24 14:39:19 -0800266 printf("%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), result.line_number(),
267 pinfo_->test_case_name(), pinfo_->name(), result.message());
268 fflush(stdout);
Yabin Cui294d1e22014-12-07 20:43:37 -0800269}
270
Yabin Cui294d1e22014-12-07 20:43:37 -0800271static int64_t NanoTime() {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700272 std::chrono::nanoseconds duration(std::chrono::steady_clock::now().time_since_epoch());
273 return static_cast<int64_t>(duration.count());
Yabin Cui294d1e22014-12-07 20:43:37 -0800274}
275
276static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800277 std::vector<const char*> args;
278 for (int i = 0; i < argc; ++i) args.push_back(argv[i]);
279 args.push_back("--gtest_list_tests");
280 args.push_back(nullptr);
281
282 // We use posix_spawn(3) rather than the simpler popen(3) because we don't want an intervening
283 // surprise shell invocation making quoting interesting for --gtest_filter (http://b/68949647).
284
285 android::base::unique_fd read_fd;
286 android::base::unique_fd write_fd;
287 if (!android::base::Pipe(&read_fd, &write_fd)) {
288 perror("pipe");
Yabin Cui294d1e22014-12-07 20:43:37 -0800289 return false;
290 }
291
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800292 posix_spawn_file_actions_t fa;
293 posix_spawn_file_actions_init(&fa);
294 posix_spawn_file_actions_addclose(&fa, read_fd);
295 posix_spawn_file_actions_adddup2(&fa, write_fd, 1);
296 posix_spawn_file_actions_adddup2(&fa, write_fd, 2);
297 posix_spawn_file_actions_addclose(&fa, write_fd);
Yabin Cui294d1e22014-12-07 20:43:37 -0800298
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800299 pid_t pid;
300 int result = posix_spawnp(&pid, argv[0], &fa, nullptr, const_cast<char**>(args.data()), nullptr);
301 posix_spawn_file_actions_destroy(&fa);
302 if (result == -1) {
303 perror("posix_spawn");
304 return false;
305 }
306 write_fd.reset();
307
308 std::string content;
309 if (!android::base::ReadFdToString(read_fd, &content)) {
310 perror("ReadFdToString");
311 return false;
312 }
313
314 for (auto& line : android::base::Split(content, "\n")) {
315 line = android::base::Trim(line);
316 if (line.empty()) continue;
317 if (android::base::EndsWith(line, ".")) {
318 line.pop_back();
319 testcase_list.push_back(TestCase(line.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -0800320 } else {
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800321 testcase_list.back().AppendTest(line.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800322 }
323 }
Elliott Hughes10ba4bd2017-11-14 13:11:41 -0800324
325 int status;
326 if (waitpid(pid, &status, 0) != pid) {
327 perror("waitpid");
328 return false;
329 }
330 return (WIFEXITED(status) && WEXITSTATUS(status) == 0);
Yabin Cui294d1e22014-12-07 20:43:37 -0800331}
332
Yabin Cui294d1e22014-12-07 20:43:37 -0800333// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
334// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
335// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800336static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
Elliott Hughes48de71e2016-10-28 10:04:44 -0700337 int iteration_count, size_t job_count) {
Christopher Ferris119cb552015-04-02 12:02:55 -0700338 if (iteration_count != 1) {
Yabin Cuibe837362015-01-02 18:45:37 -0800339 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800340 }
341 ColoredPrintf(COLOR_GREEN, "[==========] ");
342
Yabin Cuibe837362015-01-02 18:45:37 -0800343 size_t testcase_count = testcase_list.size();
344 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800345 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800346 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800347 }
348
Elliott Hughes48de71e2016-10-28 10:04:44 -0700349 printf("Running %zu %s from %zu %s (%zu %s).\n",
Yabin Cuibe837362015-01-02 18:45:37 -0800350 test_count, (test_count == 1) ? "test" : "tests",
Elliott Hughes48de71e2016-10-28 10:04:44 -0700351 testcase_count, (testcase_count == 1) ? "test case" : "test cases",
352 job_count, (job_count == 1) ? "job" : "jobs");
Yabin Cui294d1e22014-12-07 20:43:37 -0800353 fflush(stdout);
354}
355
Yabin Cuif6237472015-02-26 19:03:54 -0800356// bionic cts test needs gtest output format.
357#if defined(USING_GTEST_OUTPUT_FORMAT)
358
359static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
360 ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
361 printf("%s\n", testcase.GetTestName(test_id).c_str());
362
363 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
364 printf("%s", test_output.c_str());
365
366 TestResult result = testcase.GetTestResult(test_id);
Elliott Hughes93a89f82017-07-21 18:51:06 -0700367 if (result == TEST_SUCCESS) {
Yabin Cuif6237472015-02-26 19:03:54 -0800368 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
369 } else {
370 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
371 }
372 printf("%s", testcase.GetTestName(test_id).c_str());
373 if (testing::GTEST_FLAG(print_time)) {
374 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
375 }
376 printf("\n");
377 fflush(stdout);
378}
379
380#else // !defined(USING_GTEST_OUTPUT_FORMAT)
381
Yabin Cui657b1f92015-01-22 19:26:12 -0800382static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
383 TestResult result = testcase.GetTestResult(test_id);
384 if (result == TEST_SUCCESS) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700385 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800386 } else if (result == TEST_FAILED) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700387 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800388 } else if (result == TEST_TIMEOUT) {
389 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
390 }
Yabin Cuibe837362015-01-02 18:45:37 -0800391
Yabin Cui657b1f92015-01-22 19:26:12 -0800392 printf("%s", testcase.GetTestName(test_id).c_str());
393 if (testing::GTEST_FLAG(print_time)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800394 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
Yabin Cui657b1f92015-01-22 19:26:12 -0800395 }
Yabin Cuif6237472015-02-26 19:03:54 -0800396 printf("\n");
Yabin Cui657b1f92015-01-22 19:26:12 -0800397
Yabin Cuiea9c9332015-02-24 14:39:19 -0800398 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
399 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800400 fflush(stdout);
401}
402
Yabin Cuif6237472015-02-26 19:03:54 -0800403#endif // !defined(USING_GTEST_OUTPUT_FORMAT)
404
Yabin Cuibe837362015-01-02 18:45:37 -0800405static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800406 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800407
408 std::vector<std::string> fail_test_name_list;
409 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
410
Elliott Hughesa456fae2016-08-31 13:30:14 -0700411 // For tests that were slow but didn't time out.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800412 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800413 size_t testcase_count = testcase_list.size();
414 size_t test_count = 0;
415 size_t success_test_count = 0;
Josh Gao01052222017-01-09 16:43:33 -0800416 size_t expected_failure_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800417
418 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800419 test_count += testcase.TestCount();
420 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800421 TestResult result = testcase.GetTestResult(i);
Josh Gao01052222017-01-09 16:43:33 -0800422 if (result == TEST_TIMEOUT) {
423 timeout_test_list.push_back(
424 std::make_pair(testcase.GetTestName(i), testcase.GetTestTime(i)));
Elliott Hughes93a89f82017-07-21 18:51:06 -0700425 } else if (result == TEST_SUCCESS) {
426 ++success_test_count;
427 if (testcase.GetTestName(i).find(".xfail_") != std::string::npos) ++expected_failure_count;
428 } else if (result == TEST_FAILED) {
Josh Gao01052222017-01-09 16:43:33 -0800429 fail_test_name_list.push_back(testcase.GetTestName(i));
Yabin Cui294d1e22014-12-07 20:43:37 -0800430 }
431 if (result != TEST_TIMEOUT &&
Elliott Hughesa456fae2016-08-31 13:30:14 -0700432 testcase.GetTestTime(i) / 1000000 >= GetSlowThresholdMs(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800433 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
434 testcase.GetTestTime(i),
Elliott Hughesa456fae2016-08-31 13:30:14 -0700435 GetSlowThresholdMs(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800436 }
437 }
438 }
439
Yabin Cui294d1e22014-12-07 20:43:37 -0800440 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800441 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
442 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800443 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800444 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800445 }
446 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800447 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Josh Gao01052222017-01-09 16:43:33 -0800448 printf("%zu %s.", success_test_count, (success_test_count == 1) ? "test" : "tests");
449 if (expected_failure_count > 0) {
Elliott Hughes93a89f82017-07-21 18:51:06 -0700450 printf(" (%zu expected failure%s.)", expected_failure_count,
Josh Gao01052222017-01-09 16:43:33 -0800451 (expected_failure_count == 1) ? "" : "s");
452 }
453 printf("\n");
Yabin Cui294d1e22014-12-07 20:43:37 -0800454
Elliott Hughesa456fae2016-08-31 13:30:14 -0700455 // Print tests that timed out.
Yabin Cuibe837362015-01-02 18:45:37 -0800456 size_t timeout_test_count = timeout_test_list.size();
457 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800458 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800459 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800460 for (const auto& timeout_pair : timeout_test_list) {
461 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800462 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
463 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800464 }
465 }
466
Elliott Hughesa456fae2016-08-31 13:30:14 -0700467 // Print tests that were slow.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800468 size_t slow_test_count = slow_test_list.size();
469 if (slow_test_count > 0) {
470 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
471 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
472 for (const auto& slow_tuple : slow_test_list) {
473 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
Elliott Hughesa456fae2016-08-31 13:30:14 -0700474 printf("%s (%" PRId64 " ms, exceeded %d ms)\n", std::get<0>(slow_tuple).c_str(),
Yabin Cui4a82ede2015-01-26 17:19:37 -0800475 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800476 }
477 }
478
Elliott Hughesa456fae2016-08-31 13:30:14 -0700479 // Print tests that failed.
480 size_t fail_test_count = fail_test_name_list.size();
Yabin Cuibe837362015-01-02 18:45:37 -0800481 if (fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700482 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
483 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
484 for (const auto& name : fail_test_name_list) {
485 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
486 printf("%s\n", name.c_str());
487 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800488 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700489
Elliott Hughes93a89f82017-07-21 18:51:06 -0700490 if (timeout_test_count > 0 || slow_test_count > 0 || fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700491 printf("\n");
492 }
493
Yabin Cuibe837362015-01-02 18:45:37 -0800494 if (timeout_test_count > 0) {
495 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800496 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800497 if (slow_test_count > 0) {
498 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800499 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700500 if (fail_test_count > 0) {
501 printf("%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
502 }
Josh Gao01052222017-01-09 16:43:33 -0800503
Yabin Cui294d1e22014-12-07 20:43:37 -0800504 fflush(stdout);
505}
506
Dan Albert09a99642016-01-13 21:48:56 -0800507std::string XmlEscape(const std::string& xml) {
508 std::string escaped;
509 escaped.reserve(xml.size());
510
511 for (auto c : xml) {
512 switch (c) {
513 case '<':
514 escaped.append("&lt;");
515 break;
516 case '>':
517 escaped.append("&gt;");
518 break;
519 case '&':
520 escaped.append("&amp;");
521 break;
522 case '\'':
523 escaped.append("&apos;");
524 break;
525 case '"':
526 escaped.append("&quot;");
527 break;
528 default:
529 escaped.append(1, c);
530 break;
531 }
532 }
533
534 return escaped;
535}
536
Yabin Cui657b1f92015-01-22 19:26:12 -0800537// Output xml file when --gtest_output is used, write this function as we can't reuse
538// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
539// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
540// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
541void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
542 const std::vector<TestCase>& testcase_list,
543 time_t epoch_iteration_start_time,
544 int64_t elapsed_time_ns) {
545 FILE* fp = fopen(xml_output_filename.c_str(), "w");
546 if (fp == NULL) {
547 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
548 exit(1);
549 }
550
551 size_t total_test_count = 0;
552 size_t total_failed_count = 0;
553 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
554 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
555 for (size_t i = 0; i < testcase_list.size(); ++i) {
556 auto& testcase = testcase_list[i];
557 total_test_count += testcase.TestCount();
558 for (size_t j = 0; j < testcase.TestCount(); ++j) {
Josh Gao01052222017-01-09 16:43:33 -0800559 if (!testcase.GetTestSuccess(j)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800560 ++failed_count_list[i];
561 }
562 elapsed_time_list[i] += testcase.GetTestTime(j);
563 }
564 total_failed_count += failed_count_list[i];
565 }
566
567 const tm* time_struct = localtime(&epoch_iteration_start_time);
568 char timestamp[40];
569 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
570 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
571 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
572
573 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
574 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
575 total_test_count, total_failed_count);
576 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
577 for (size_t i = 0; i < testcase_list.size(); ++i) {
578 auto& testcase = testcase_list[i];
579 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
580 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
581 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
582
583 for (size_t j = 0; j < testcase.TestCount(); ++j) {
584 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
585 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
586 testcase.GetName().c_str());
Josh Gao01052222017-01-09 16:43:33 -0800587 if (!testcase.GetTestSuccess(j)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800588 fputs(" />\n", fp);
589 } else {
590 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800591 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
Dan Albert09a99642016-01-13 21:48:56 -0800592 const std::string escaped_test_output = XmlEscape(test_output);
593 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", escaped_test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800594 fputs(" </failure>\n", fp);
595 fputs(" </testcase>\n", fp);
596 }
597 }
598
599 fputs(" </testsuite>\n", fp);
600 }
601 fputs("</testsuites>\n", fp);
602 fclose(fp);
603}
604
Yabin Cui767fb1c2015-09-01 15:06:39 -0700605static bool sigint_flag;
606static bool sigquit_flag;
607
608static void signal_handler(int sig) {
609 if (sig == SIGINT) {
610 sigint_flag = true;
611 } else if (sig == SIGQUIT) {
612 sigquit_flag = true;
613 }
614}
615
616static bool RegisterSignalHandler() {
617 sigint_flag = false;
618 sigquit_flag = false;
619 sig_t ret = signal(SIGINT, signal_handler);
620 if (ret != SIG_ERR) {
621 ret = signal(SIGQUIT, signal_handler);
622 }
623 if (ret == SIG_ERR) {
624 perror("RegisterSignalHandler");
625 return false;
626 }
627 return true;
628}
629
630static bool UnregisterSignalHandler() {
631 sig_t ret = signal(SIGINT, SIG_DFL);
632 if (ret != SIG_ERR) {
633 ret = signal(SIGQUIT, SIG_DFL);
634 }
635 if (ret == SIG_ERR) {
636 perror("UnregisterSignalHandler");
637 return false;
638 }
639 return true;
640}
641
Yabin Cui1d4c7802015-02-02 19:14:05 -0800642struct ChildProcInfo {
643 pid_t pid;
644 int64_t start_time_ns;
645 int64_t end_time_ns;
646 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
647 size_t testcase_id, test_id;
648 bool finished;
649 bool timed_out;
650 int exit_status;
651 int child_read_fd; // File descriptor to read child test failure info.
652};
653
Yabin Cui294d1e22014-12-07 20:43:37 -0800654// Forked Child process, run the single test.
655static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800656 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800657 memcpy(new_argv, argv, sizeof(char*) * argc);
658
659 char* filter_arg = new char [test_name.size() + 20];
660 strcpy(filter_arg, "--gtest_filter=");
661 strcat(filter_arg, test_name.c_str());
662 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800663 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800664
665 int new_argc = argc + 1;
666 testing::InitGoogleTest(&new_argc, new_argv);
667 int result = RUN_ALL_TESTS();
668 exit(result);
669}
670
Yabin Cui1d4c7802015-02-02 19:14:05 -0800671static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700672 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800673 int pipefd[2];
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800674 if (pipe(pipefd) == -1) {
675 perror("pipe in RunTestInSeparateProc");
676 exit(1);
677 }
678 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
679 perror("fcntl in RunTestInSeparateProc");
Yabin Cui1d4c7802015-02-02 19:14:05 -0800680 exit(1);
681 }
682 pid_t pid = fork();
683 if (pid == -1) {
684 perror("fork in RunTestInSeparateProc");
685 exit(1);
686 } else if (pid == 0) {
687 // In child process, run a single test.
688 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800689 close(STDOUT_FILENO);
690 close(STDERR_FILENO);
691 dup2(pipefd[1], STDOUT_FILENO);
692 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800693
Yabin Cui767fb1c2015-09-01 15:06:39 -0700694 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800695 exit(1);
696 }
697 ChildProcessFn(argc, argv, test_name);
698 // Unreachable.
699 }
700 // In parent process, initialize child process info.
701 close(pipefd[1]);
702 ChildProcInfo child_proc;
703 child_proc.child_read_fd = pipefd[0];
704 child_proc.pid = pid;
705 child_proc.start_time_ns = NanoTime();
Elliott Hughesa456fae2016-08-31 13:30:14 -0700706 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetTimeoutMs(test_name) * 1000000LL;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800707 child_proc.testcase_id = testcase_id;
708 child_proc.test_id = test_id;
709 child_proc.finished = false;
710 return child_proc;
711}
Yabin Cui294d1e22014-12-07 20:43:37 -0800712
Yabin Cui1d4c7802015-02-02 19:14:05 -0800713static void HandleSignals(std::vector<TestCase>& testcase_list,
714 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700715 if (sigquit_flag) {
716 sigquit_flag = false;
717 // Print current running tests.
718 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700719 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700720 if (child_proc.pid != 0) {
721 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
722 int64_t current_time_ns = NanoTime();
723 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
724 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800725 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800726 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700727 } else if (sigint_flag) {
728 sigint_flag = false;
729 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700730 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700731 if (child_proc.pid != 0) {
732 // Send SIGKILL to ensure the child process can be killed unconditionally.
733 kill(child_proc.pid, SIGKILL);
734 }
735 }
736 // SIGINT kills the parent process as well.
737 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800738 }
739}
740
741static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
742 std::vector<ChildProcInfo>& child_proc_list) {
743 for (size_t i = 0; i < child_proc_list.size(); ++i) {
744 if (child_proc_list[i].pid == exit_pid) {
745 child_proc_list[i].finished = true;
746 child_proc_list[i].timed_out = false;
747 child_proc_list[i].exit_status = exit_status;
748 child_proc_list[i].end_time_ns = NanoTime();
749 return true;
750 }
751 }
752 return false;
753}
754
755static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
756 int64_t current_time_ns = NanoTime();
757 size_t timeout_child_count = 0;
758 for (size_t i = 0; i < child_proc_list.size(); ++i) {
759 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
760 child_proc_list[i].finished = true;
761 child_proc_list[i].timed_out = true;
762 child_proc_list[i].end_time_ns = current_time_ns;
763 ++timeout_child_count;
764 }
765 }
766 return timeout_child_count;
767}
768
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800769static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
770 std::vector<ChildProcInfo>& child_proc_list) {
771 for (const auto& child_proc : child_proc_list) {
772 TestCase& testcase = testcase_list[child_proc.testcase_id];
773 int test_id = child_proc.test_id;
774 while (true) {
775 char buf[1024];
776 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
777 if (bytes_read > 0) {
778 buf[bytes_read] = '\0';
779 testcase.GetTest(test_id).AppendTestOutput(buf);
780 } else if (bytes_read == 0) {
781 break; // Read end.
782 } else {
783 if (errno == EAGAIN) {
784 break;
785 }
786 perror("failed to read child_read_fd");
787 exit(1);
788 }
789 }
790 }
791}
792
Yabin Cui1d4c7802015-02-02 19:14:05 -0800793static void WaitChildProcs(std::vector<TestCase>& testcase_list,
794 std::vector<ChildProcInfo>& child_proc_list) {
795 size_t finished_child_count = 0;
796 while (true) {
797 int status;
798 pid_t result;
799 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
800 if (CheckChildProcExit(result, status, child_proc_list)) {
801 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800802 }
803 }
804
805 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800806 if (errno == ECHILD) {
807 // This happens when we have no running child processes.
808 return;
809 } else {
810 perror("waitpid");
811 exit(1);
812 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800813 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800814 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800815 }
816
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800817 ReadChildProcOutput(testcase_list, child_proc_list);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800818 if (finished_child_count > 0) {
819 return;
820 }
821
822 HandleSignals(testcase_list, child_proc_list);
823
Yabin Cui294d1e22014-12-07 20:43:37 -0800824 // sleep 1 ms to avoid busy looping.
825 timespec sleep_time;
826 sleep_time.tv_sec = 0;
827 sleep_time.tv_nsec = 1000000;
828 nanosleep(&sleep_time, NULL);
829 }
830}
831
Yabin Cui1d4c7802015-02-02 19:14:05 -0800832static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800833 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800834 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800835
836 TestResult test_result = TEST_SUCCESS;
837 if (result != pid || WEXITSTATUS(exit_status) != 0) {
838 test_result = TEST_FAILED;
839 }
840 return test_result;
841}
842
Yabin Cui1d4c7802015-02-02 19:14:05 -0800843static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
844 int test_id = child_proc.test_id;
845 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
846 if (child_proc.timed_out) {
847 // The child process marked as timed_out has not exited, and we should kill it manually.
848 kill(child_proc.pid, SIGKILL);
849 WaitForOneChild(child_proc.pid);
850 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800851 close(child_proc.child_read_fd);
852
853 if (child_proc.timed_out) {
854 testcase.SetTestResult(test_id, TEST_TIMEOUT);
855 char buf[1024];
856 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
857 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800858 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800859
860 } else if (WIFSIGNALED(child_proc.exit_status)) {
861 // Record signal terminated test as failed.
862 testcase.SetTestResult(test_id, TEST_FAILED);
863 char buf[1024];
864 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
865 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800866 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800867
868 } else {
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800869 int exitcode = WEXITSTATUS(child_proc.exit_status);
870 testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
871 if (exitcode != 0) {
Yabin Cuia32fc862015-12-03 16:28:03 -0800872 char buf[1024];
873 snprintf(buf, sizeof(buf), "%s exited with exitcode %d.\n",
874 testcase.GetTestName(test_id).c_str(), exitcode);
875 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800876 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800877 }
878}
879
Yabin Cui294d1e22014-12-07 20:43:37 -0800880// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
881// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700882// Returns true if all tests run successfully, otherwise return false.
883static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700884 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800885 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800886 // Stop default result printer to avoid environment setup/teardown information for each test.
887 testing::UnitTest::GetInstance()->listeners().Release(
888 testing::UnitTest::GetInstance()->listeners().default_result_printer());
889 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
890
Yabin Cui767fb1c2015-09-01 15:06:39 -0700891 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800892 exit(1);
893 }
894
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700895 bool all_tests_passed = true;
896
Christopher Ferris119cb552015-04-02 12:02:55 -0700897 for (size_t iteration = 1;
898 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
899 ++iteration) {
Elliott Hughes48de71e2016-10-28 10:04:44 -0700900 OnTestIterationStartPrint(testcase_list, iteration, iteration_count, job_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800901 int64_t iteration_start_time_ns = NanoTime();
902 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800903
Yabin Cuibe837362015-01-02 18:45:37 -0800904 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800905 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800906
Yabin Cuibe837362015-01-02 18:45:37 -0800907 // Next test to run is [next_testcase_id:next_test_id].
908 size_t next_testcase_id = 0;
909 size_t next_test_id = 0;
910
911 // Record how many tests are finished.
912 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
913 size_t finished_testcase_count = 0;
914
915 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800916 // run up to job_count child processes.
917 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
918 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
919 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700920 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800921 child_proc_list.push_back(child_proc);
922 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
923 next_test_id = 0;
924 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800925 }
926 }
927
928 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800929 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800930
931 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800932 auto it = child_proc_list.begin();
933 while (it != child_proc_list.end()) {
934 auto& child_proc = *it;
935 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800936 size_t testcase_id = child_proc.testcase_id;
937 size_t test_id = child_proc.test_id;
938 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800939
Yabin Cui1d4c7802015-02-02 19:14:05 -0800940 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800941 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800942
943 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
944 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800945 }
Josh Gao01052222017-01-09 16:43:33 -0800946 if (!testcase.GetTestSuccess(test_id)) {
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700947 all_tests_passed = false;
948 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800949
950 it = child_proc_list.erase(it);
951 } else {
952 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800953 }
954 }
955 }
956
Yabin Cui657b1f92015-01-22 19:26:12 -0800957 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
958 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
959 if (!xml_output_filename.empty()) {
960 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
961 elapsed_time_ns);
962 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800963 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800964
Yabin Cui767fb1c2015-09-01 15:06:39 -0700965 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800966 exit(1);
967 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700968
969 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800970}
971
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700972static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800973 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800974}
975
Yabin Cuiead08142015-02-04 20:53:56 -0800976static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
977 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
978 // test program via a valid path that contains at least one path separator.
979 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
980 // and execve() doesn't read environment variable PATH, so execve() will not success
981 // until we specify the absolute path or relative path of the test program directly.
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -0700982 if (strchr(args[0], '/') == nullptr) {
983 args[0] = strdup(g_executable_path.c_str());
Yabin Cuiead08142015-02-04 20:53:56 -0800984 }
985}
986
Yabin Cui11c43532015-01-28 14:28:14 -0800987static void AddGtestFilterSynonym(std::vector<char*>& args) {
988 // Support --gtest-filter as a synonym for --gtest_filter.
989 for (size_t i = 1; i < args.size(); ++i) {
990 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
991 args[i][7] = '_';
992 }
993 }
994}
995
Yabin Cui657b1f92015-01-22 19:26:12 -0800996struct IsolationTestOptions {
997 bool isolate;
998 size_t job_count;
999 int test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001000 int test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001001 std::string gtest_color;
1002 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -07001003 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -08001004 std::string gtest_output;
1005};
1006
1007// 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 -08001008// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -08001009// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
1010// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -08001011// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -08001012// args is used to pass in all command arguments, and pass out only the part of options for gtest.
1013// options is used to pass out test options in isolation mode.
1014// Return false if there is error in arguments.
1015static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
1016 for (size_t i = 1; i < args.size(); ++i) {
1017 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001018 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -08001019 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001020 return true;
1021 }
1022 }
1023
Yabin Cuiead08142015-02-04 20:53:56 -08001024 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -08001025 AddGtestFilterSynonym(args);
1026
Yabin Cui657b1f92015-01-22 19:26:12 -08001027 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
1028 bool enable_selftest = false;
1029 for (size_t i = 1; i < args.size(); ++i) {
1030 if (strcmp(args[i], "--bionic-selftest") == 0) {
1031 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
1032 // Don't remove this option from arguments.
1033 enable_selftest = true;
1034 }
1035 }
1036 std::string gtest_filter_str;
1037 for (size_t i = args.size() - 1; i >= 1; --i) {
1038 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
Yabin Cuic641a952016-12-12 13:32:15 -08001039 gtest_filter_str = args[i] + strlen("--gtest_filter=");
Yabin Cui657b1f92015-01-22 19:26:12 -08001040 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -08001041 break;
1042 }
1043 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001044 if (enable_selftest == true) {
Yabin Cuic641a952016-12-12 13:32:15 -08001045 gtest_filter_str = "bionic_selftest*";
Yabin Cui657b1f92015-01-22 19:26:12 -08001046 } else {
Yabin Cuic641a952016-12-12 13:32:15 -08001047 if (gtest_filter_str.empty()) {
1048 gtest_filter_str = "-bionic_selftest*";
Yabin Cui657b1f92015-01-22 19:26:12 -08001049 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001050 // Find if '-' for NEGATIVE_PATTERNS exists.
wy828b9e12017-05-10 15:21:13 -07001051 if (gtest_filter_str.find('-') != std::string::npos) {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001052 gtest_filter_str += ":bionic_selftest*";
1053 } else {
1054 gtest_filter_str += ":-bionic_selftest*";
1055 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001056 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001057 }
Yabin Cuic641a952016-12-12 13:32:15 -08001058 gtest_filter_str = "--gtest_filter=" + gtest_filter_str;
1059 args.push_back(strdup(gtest_filter_str.c_str()));
Yabin Cui294d1e22014-12-07 20:43:37 -08001060
Yabin Cui657b1f92015-01-22 19:26:12 -08001061 options.isolate = true;
1062 // Parse arguments that make us can't run in isolation mode.
1063 for (size_t i = 1; i < args.size(); ++i) {
1064 if (strcmp(args[i], "--no-isolate") == 0) {
1065 options.isolate = false;
1066 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
1067 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001068 }
1069 }
1070
Yabin Cui657b1f92015-01-22 19:26:12 -08001071 // Stop parsing if we will not run in isolation mode.
1072 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001073 return true;
1074 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001075
1076 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -07001077 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -08001078 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001079 options.test_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui657b1f92015-01-22 19:26:12 -08001080 options.gtest_color = testing::GTEST_FLAG(color);
1081 options.gtest_print_time = testing::GTEST_FLAG(print_time);
1082 options.gtest_repeat = testing::GTEST_FLAG(repeat);
1083 options.gtest_output = testing::GTEST_FLAG(output);
1084
1085 // Parse arguments speficied for isolation mode.
1086 for (size_t i = 1; i < args.size(); ++i) {
1087 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1088 char* p = args[i] + strlen("-j");
1089 int count = 0;
1090 if (*p != '\0') {
1091 // Argument like -j5.
1092 count = atoi(p);
1093 } else if (args.size() > i + 1) {
1094 // Arguments like -j 5.
1095 count = atoi(args[i + 1]);
1096 ++i;
1097 }
1098 if (count <= 0) {
1099 fprintf(stderr, "invalid job count: %d\n", count);
1100 return false;
1101 }
1102 options.job_count = static_cast<size_t>(count);
1103 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1104 int time_ms = atoi(args[i] + strlen("--deadline="));
1105 if (time_ms <= 0) {
1106 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1107 return false;
1108 }
1109 options.test_deadline_ms = time_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001110 } else if (strncmp(args[i], "--slow-threshold=", strlen("--slow-threshold=")) == 0) {
1111 int time_ms = atoi(args[i] + strlen("--slow-threshold="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001112 if (time_ms <= 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -07001113 fprintf(stderr, "invalid slow test threshold: %d\n", time_ms);
Yabin Cui657b1f92015-01-22 19:26:12 -08001114 return false;
1115 }
Elliott Hughesa456fae2016-08-31 13:30:14 -07001116 options.test_slow_threshold_ms = time_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001117 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1118 options.gtest_color = args[i] + strlen("--gtest_color=");
1119 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1120 options.gtest_print_time = false;
1121 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001122 // If the value of gtest_repeat is < 0, then it indicates the tests
1123 // should be repeated forever.
1124 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001125 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1126 args.erase(args.begin() + i);
1127 --i;
1128 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1129 std::string output = args[i] + strlen("--gtest_output=");
1130 // generate output xml file path according to the strategy in gtest.
1131 bool success = true;
1132 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1133 output = output.substr(strlen("xml:"));
1134 if (output.size() == 0) {
1135 success = false;
1136 }
1137 // Make absolute path.
1138 if (success && output[0] != '/') {
1139 char* cwd = getcwd(NULL, 0);
1140 if (cwd != NULL) {
1141 output = std::string(cwd) + "/" + output;
1142 free(cwd);
1143 } else {
1144 success = false;
1145 }
1146 }
1147 // Add file name if output is a directory.
1148 if (success && output.back() == '/') {
1149 output += "test_details.xml";
1150 }
1151 }
1152 if (success) {
1153 options.gtest_output = output;
1154 } else {
1155 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1156 return false;
1157 }
1158
1159 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1160 args.erase(args.begin() + i);
1161 --i;
1162 }
1163 }
1164
1165 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1166 // As DeathTest will try to call execve(), this argument should always be added.
1167 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001168 return true;
1169}
1170
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001171static std::string get_proc_self_exe() {
1172 char path[PATH_MAX];
1173 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
1174 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
1175 perror("readlink");
1176 exit(1);
1177 }
1178
1179 return std::string(path, path_len);
1180}
1181
Dimitry Ivanov55437462016-07-20 15:33:07 -07001182int main(int argc, char** argv, char** envp) {
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001183 g_executable_path = get_proc_self_exe();
Dimitry Ivanov55437462016-07-20 15:33:07 -07001184 g_argc = argc;
1185 g_argv = argv;
1186 g_envp = envp;
Yabin Cuibe837362015-01-02 18:45:37 -08001187 std::vector<char*> arg_list;
1188 for (int i = 0; i < argc; ++i) {
1189 arg_list.push_back(argv[i]);
1190 }
Yabin Cuibe837362015-01-02 18:45:37 -08001191
Yabin Cui657b1f92015-01-22 19:26:12 -08001192 IsolationTestOptions options;
1193 if (PickOptions(arg_list, options) == false) {
1194 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001195 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001196
1197 if (options.isolate == true) {
1198 // Set global variables.
1199 global_test_run_deadline_ms = options.test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001200 global_test_run_slow_threshold_ms = options.test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001201 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1202 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1203 std::vector<TestCase> testcase_list;
1204
1205 argc = static_cast<int>(arg_list.size());
1206 arg_list.push_back(NULL);
1207 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1208 return 1;
1209 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001210 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1211 options.gtest_repeat, options.job_count, options.gtest_output);
1212 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001213 } else {
1214 argc = static_cast<int>(arg_list.size());
1215 arg_list.push_back(NULL);
1216 testing::InitGoogleTest(&argc, arg_list.data());
1217 return RUN_ALL_TESTS();
1218 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001219}
1220
1221//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001222// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001223
Yabin Cuibe837362015-01-02 18:45:37 -08001224TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001225 ASSERT_EQ(1, 1);
1226}
1227
Yabin Cuibe837362015-01-02 18:45:37 -08001228TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001229 ASSERT_EQ(0, 1);
1230}
1231
Yabin Cuibe837362015-01-02 18:45:37 -08001232TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001233 sleep(4);
1234}
1235
Yabin Cuibe837362015-01-02 18:45:37 -08001236TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001237 while (1) {}
1238}
Yabin Cuibe837362015-01-02 18:45:37 -08001239
1240TEST(bionic_selftest, test_signal_SEGV_terminated) {
1241 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1242 *p = 3;
1243}
Yabin Cui657b1f92015-01-22 19:26:12 -08001244
Yabin Cui767fb1c2015-09-01 15:06:39 -07001245class bionic_selftest_DeathTest : public ::testing::Test {
1246 protected:
1247 virtual void SetUp() {
1248 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1249 }
1250};
Yabin Cui657b1f92015-01-22 19:26:12 -08001251
1252static void deathtest_helper_success() {
1253 ASSERT_EQ(1, 1);
1254 exit(0);
1255}
1256
1257TEST_F(bionic_selftest_DeathTest, success) {
1258 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1259}
1260
1261static void deathtest_helper_fail() {
1262 ASSERT_EQ(1, 0);
1263}
1264
1265TEST_F(bionic_selftest_DeathTest, fail) {
1266 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1267}