blob: 2b5864688bdca9a554a49821ed07441b627ad705 [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>
Yabin Cuiead08142015-02-04 20:53:56 -080023#include <limits.h>
Yabin Cui1d4c7802015-02-02 19:14:05 -080024#include <signal.h>
Yabin Cui294d1e22014-12-07 20:43:37 -080025#include <stdarg.h>
26#include <stdio.h>
27#include <string.h>
28#include <sys/wait.h>
Yabin Cui294d1e22014-12-07 20:43:37 -080029#include <unistd.h>
30
Yabin Cui767fb1c2015-09-01 15:06:39 -070031#include <chrono>
Yabin Cui294d1e22014-12-07 20:43:37 -080032#include <string>
33#include <tuple>
34#include <utility>
35#include <vector>
36
Yabin Cui767fb1c2015-09-01 15:06:39 -070037#ifndef TEMP_FAILURE_RETRY
38
39/* Used to retry syscalls that can return EINTR. */
40#define TEMP_FAILURE_RETRY(exp) ({ \
41 __typeof__(exp) _rc; \
42 do { \
43 _rc = (exp); \
44 } while (_rc == -1 && errno == EINTR); \
45 _rc; })
46
47#endif
Yabin Cui657b1f92015-01-22 19:26:12 -080048
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -070049static std::string g_executable_path;
Dimitry Ivanovd17a3772016-03-01 13:11:28 -080050
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -070051const std::string& get_executable_path() {
52 return g_executable_path;
Dimitry Ivanovd17a3772016-03-01 13:11:28 -080053}
54
Yabin Cui294d1e22014-12-07 20:43:37 -080055namespace testing {
56namespace internal {
57
58// Reuse of testing::internal::ColoredPrintf in gtest.
59enum GTestColor {
60 COLOR_DEFAULT,
61 COLOR_RED,
62 COLOR_GREEN,
63 COLOR_YELLOW
64};
65
66void ColoredPrintf(GTestColor color, const char* fmt, ...);
67
Yabin Cuibe837362015-01-02 18:45:37 -080068} // namespace internal
69} // namespace testing
Yabin Cui294d1e22014-12-07 20:43:37 -080070
71using testing::internal::GTestColor;
72using testing::internal::COLOR_DEFAULT;
73using testing::internal::COLOR_RED;
74using testing::internal::COLOR_GREEN;
75using testing::internal::COLOR_YELLOW;
76using testing::internal::ColoredPrintf;
77
Christopher Ferrisdaaaed12015-09-24 18:45:53 -070078constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 90000;
Yabin Cui657b1f92015-01-22 19:26:12 -080079constexpr int DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -080080
81// The time each test can run before killed for the reason of timeout.
82// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080083static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080084
85// The time each test can run before be warned for too much running time.
86// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080087static int global_test_run_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080088
89// Return deadline duration for a test, in ms.
90static int GetDeadlineInfo(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -080091 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -080092}
93
94// Return warnline duration for a test, in ms.
95static int GetWarnlineInfo(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -080096 return global_test_run_warnline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -080097}
98
Yabin Cuibe837362015-01-02 18:45:37 -080099static void PrintHelpInfo() {
100 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -0800101 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800102 " Run up to JOB_COUNT tests in parallel.\n"
103 " Use isolation mode, Run each test in a separate process.\n"
104 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
105 " --no-isolate\n"
106 " Don't use isolation mode, run all tests in a single process.\n"
107 " --deadline=[TIME_IN_MS]\n"
108 " Run each test in no longer than [TIME_IN_MS] time.\n"
Yabin Cuibc6379d2015-10-06 16:30:14 -0700109 " It takes effect only in isolation mode. Deafult deadline is 90000 ms.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800110 " --warnline=[TIME_IN_MS]\n"
111 " Test running longer than [TIME_IN_MS] will be warned.\n"
112 " It takes effect only in isolation mode. Default warnline is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -0800113 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
114 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -0800115 "Default bionic unit test option is -j.\n"
116 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
117 "running tests, or send SIGINT to the parent process to stop testing and\n"
118 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800119 "\n");
120}
121
Yabin Cui294d1e22014-12-07 20:43:37 -0800122enum TestResult {
123 TEST_SUCCESS = 0,
124 TEST_FAILED,
125 TEST_TIMEOUT
126};
127
Yabin Cui657b1f92015-01-22 19:26:12 -0800128class Test {
129 public:
130 Test() {} // For std::vector<Test>.
131 explicit Test(const char* name) : name_(name) {}
132
133 const std::string& GetName() const { return name_; }
134
135 void SetResult(TestResult result) { result_ = result; }
136
137 TestResult GetResult() const { return result_; }
138
139 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
140
141 int64_t GetTestTime() const { return elapsed_time_ns_; }
142
Yabin Cuiea9c9332015-02-24 14:39:19 -0800143 void AppendTestOutput(const std::string& s) { output_ += s; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800144
Yabin Cuiea9c9332015-02-24 14:39:19 -0800145 const std::string& GetTestOutput() const { return output_; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800146
147 private:
148 const std::string name_;
149 TestResult result_;
150 int64_t elapsed_time_ns_;
Yabin Cuiea9c9332015-02-24 14:39:19 -0800151 std::string output_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800152};
153
Yabin Cui294d1e22014-12-07 20:43:37 -0800154class TestCase {
155 public:
156 TestCase() {} // For std::vector<TestCase>.
157 explicit TestCase(const char* name) : name_(name) {}
158
159 const std::string& GetName() const { return name_; }
160
Yabin Cui657b1f92015-01-22 19:26:12 -0800161 void AppendTest(const char* test_name) {
162 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800163 }
164
Yabin Cuibe837362015-01-02 18:45:37 -0800165 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800166
Yabin Cuibe837362015-01-02 18:45:37 -0800167 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800168 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800169 return name_ + "." + test_list_[test_id].GetName();
170 }
171
172 Test& GetTest(size_t test_id) {
173 VerifyTestId(test_id);
174 return test_list_[test_id];
175 }
176
177 const Test& GetTest(size_t test_id) const {
178 VerifyTestId(test_id);
179 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800180 }
181
Yabin Cuibe837362015-01-02 18:45:37 -0800182 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800183 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800184 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800185 }
186
Yabin Cuibe837362015-01-02 18:45:37 -0800187 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800188 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800189 return test_list_[test_id].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800190 }
191
Yabin Cui657b1f92015-01-22 19:26:12 -0800192 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800193 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800194 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800195 }
196
Yabin Cuibe837362015-01-02 18:45:37 -0800197 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800198 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800199 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800200 }
201
202 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800203 void VerifyTestId(size_t test_id) const {
204 if(test_id >= test_list_.size()) {
205 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800206 exit(1);
207 }
208 }
209
210 private:
211 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800212 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800213};
214
Yabin Cui294d1e22014-12-07 20:43:37 -0800215class TestResultPrinter : public testing::EmptyTestEventListener {
216 public:
217 TestResultPrinter() : pinfo_(NULL) {}
218 virtual void OnTestStart(const testing::TestInfo& test_info) {
219 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
220 }
221 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800222
223 private:
224 const testing::TestInfo* pinfo_;
225};
226
227// Called after an assertion failure.
228void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
229 // If the test part succeeded, we don't need to do anything.
230 if (result.type() == testing::TestPartResult::kSuccess)
231 return;
232
233 // Print failure message from the assertion (e.g. expected this and got that).
Yabin Cuiea9c9332015-02-24 14:39:19 -0800234 printf("%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), result.line_number(),
235 pinfo_->test_case_name(), pinfo_->name(), result.message());
236 fflush(stdout);
Yabin Cui294d1e22014-12-07 20:43:37 -0800237}
238
Yabin Cui294d1e22014-12-07 20:43:37 -0800239static int64_t NanoTime() {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700240 std::chrono::nanoseconds duration(std::chrono::steady_clock::now().time_since_epoch());
241 return static_cast<int64_t>(duration.count());
Yabin Cui294d1e22014-12-07 20:43:37 -0800242}
243
244static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
245 std::string command;
246 for (int i = 0; i < argc; ++i) {
247 command += argv[i];
248 command += " ";
249 }
250 command += "--gtest_list_tests";
251 FILE* fp = popen(command.c_str(), "r");
252 if (fp == NULL) {
253 perror("popen");
254 return false;
255 }
256
257 char buf[200];
258 while (fgets(buf, sizeof(buf), fp) != NULL) {
259 char* p = buf;
260
261 while (*p != '\0' && isspace(*p)) {
262 ++p;
263 }
264 if (*p == '\0') continue;
265 char* start = p;
266 while (*p != '\0' && !isspace(*p)) {
267 ++p;
268 }
269 char* end = p;
270 while (*p != '\0' && isspace(*p)) {
271 ++p;
272 }
Yabin Cuibf830ad2015-08-10 12:12:39 -0700273 if (*p != '\0' && *p != '#') {
Yabin Cui294d1e22014-12-07 20:43:37 -0800274 // This is not we want, gtest must meet with some error when parsing the arguments.
275 fprintf(stderr, "argument error, check with --help\n");
276 return false;
277 }
278 *end = '\0';
279 if (*(end - 1) == '.') {
280 *(end - 1) = '\0';
281 testcase_list.push_back(TestCase(start));
282 } else {
283 testcase_list.back().AppendTest(start);
284 }
285 }
286 int result = pclose(fp);
287 return (result != -1 && WEXITSTATUS(result) == 0);
288}
289
Yabin Cui294d1e22014-12-07 20:43:37 -0800290// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
291// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
292// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800293static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
Christopher Ferris119cb552015-04-02 12:02:55 -0700294 int iteration_count) {
295 if (iteration_count != 1) {
Yabin Cuibe837362015-01-02 18:45:37 -0800296 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800297 }
298 ColoredPrintf(COLOR_GREEN, "[==========] ");
299
Yabin Cuibe837362015-01-02 18:45:37 -0800300 size_t testcase_count = testcase_list.size();
301 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800302 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800303 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800304 }
305
Yabin Cuibe837362015-01-02 18:45:37 -0800306 printf("Running %zu %s from %zu %s.\n",
307 test_count, (test_count == 1) ? "test" : "tests",
308 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800309 fflush(stdout);
310}
311
Yabin Cuif6237472015-02-26 19:03:54 -0800312// bionic cts test needs gtest output format.
313#if defined(USING_GTEST_OUTPUT_FORMAT)
314
315static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
316 ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
317 printf("%s\n", testcase.GetTestName(test_id).c_str());
318
319 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
320 printf("%s", test_output.c_str());
321
322 TestResult result = testcase.GetTestResult(test_id);
323 if (result == TEST_SUCCESS) {
324 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
325 } else {
326 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
327 }
328 printf("%s", testcase.GetTestName(test_id).c_str());
329 if (testing::GTEST_FLAG(print_time)) {
330 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
331 }
332 printf("\n");
333 fflush(stdout);
334}
335
336#else // !defined(USING_GTEST_OUTPUT_FORMAT)
337
Yabin Cui657b1f92015-01-22 19:26:12 -0800338static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
339 TestResult result = testcase.GetTestResult(test_id);
340 if (result == TEST_SUCCESS) {
341 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
342 } else if (result == TEST_FAILED) {
343 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
344 } else if (result == TEST_TIMEOUT) {
345 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
346 }
Yabin Cuibe837362015-01-02 18:45:37 -0800347
Yabin Cui657b1f92015-01-22 19:26:12 -0800348 printf("%s", testcase.GetTestName(test_id).c_str());
349 if (testing::GTEST_FLAG(print_time)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800350 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
Yabin Cui657b1f92015-01-22 19:26:12 -0800351 }
Yabin Cuif6237472015-02-26 19:03:54 -0800352 printf("\n");
Yabin Cui657b1f92015-01-22 19:26:12 -0800353
Yabin Cuiea9c9332015-02-24 14:39:19 -0800354 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
355 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800356 fflush(stdout);
357}
358
Yabin Cuif6237472015-02-26 19:03:54 -0800359#endif // !defined(USING_GTEST_OUTPUT_FORMAT)
360
Yabin Cuibe837362015-01-02 18:45:37 -0800361static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800362 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800363
364 std::vector<std::string> fail_test_name_list;
365 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
366
367 // For tests run exceed warnline but not timeout.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800368 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800369 size_t testcase_count = testcase_list.size();
370 size_t test_count = 0;
371 size_t success_test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800372
373 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800374 test_count += testcase.TestCount();
375 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800376 TestResult result = testcase.GetTestResult(i);
377 if (result == TEST_SUCCESS) {
Yabin Cuibe837362015-01-02 18:45:37 -0800378 ++success_test_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800379 } else if (result == TEST_FAILED) {
380 fail_test_name_list.push_back(testcase.GetTestName(i));
381 } else if (result == TEST_TIMEOUT) {
382 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i),
383 testcase.GetTestTime(i)));
384 }
385 if (result != TEST_TIMEOUT &&
386 testcase.GetTestTime(i) / 1000000 >= GetWarnlineInfo(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800387 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
388 testcase.GetTestTime(i),
389 GetWarnlineInfo(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800390 }
391 }
392 }
393
Yabin Cui294d1e22014-12-07 20:43:37 -0800394 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800395 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
396 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800397 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800398 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800399 }
400 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800401 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800402 printf("%zu %s.\n", success_test_count, (success_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800403
404 // Print tests failed.
Yabin Cuibe837362015-01-02 18:45:37 -0800405 size_t fail_test_count = fail_test_name_list.size();
406 if (fail_test_count > 0) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800407 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800408 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800409 for (const auto& name : fail_test_name_list) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800410 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
Yabin Cui294d1e22014-12-07 20:43:37 -0800411 printf("%s\n", name.c_str());
412 }
413 }
414
415 // Print tests run timeout.
Yabin Cuibe837362015-01-02 18:45:37 -0800416 size_t timeout_test_count = timeout_test_list.size();
417 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800418 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800419 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800420 for (const auto& timeout_pair : timeout_test_list) {
421 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800422 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
423 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800424 }
425 }
426
427 // Print tests run exceed warnline.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800428 size_t slow_test_count = slow_test_list.size();
429 if (slow_test_count > 0) {
430 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
431 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
432 for (const auto& slow_tuple : slow_test_list) {
433 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
434 printf("%s (%" PRId64 " ms, exceed warnline %d ms)\n", std::get<0>(slow_tuple).c_str(),
435 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800436 }
437 }
438
Yabin Cuibe837362015-01-02 18:45:37 -0800439 if (fail_test_count > 0) {
440 printf("\n%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800441 }
Yabin Cuibe837362015-01-02 18:45:37 -0800442 if (timeout_test_count > 0) {
443 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800444 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800445 if (slow_test_count > 0) {
446 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800447 }
448 fflush(stdout);
449}
450
Dan Albert09a99642016-01-13 21:48:56 -0800451std::string XmlEscape(const std::string& xml) {
452 std::string escaped;
453 escaped.reserve(xml.size());
454
455 for (auto c : xml) {
456 switch (c) {
457 case '<':
458 escaped.append("&lt;");
459 break;
460 case '>':
461 escaped.append("&gt;");
462 break;
463 case '&':
464 escaped.append("&amp;");
465 break;
466 case '\'':
467 escaped.append("&apos;");
468 break;
469 case '"':
470 escaped.append("&quot;");
471 break;
472 default:
473 escaped.append(1, c);
474 break;
475 }
476 }
477
478 return escaped;
479}
480
Yabin Cui657b1f92015-01-22 19:26:12 -0800481// Output xml file when --gtest_output is used, write this function as we can't reuse
482// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
483// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
484// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
485void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
486 const std::vector<TestCase>& testcase_list,
487 time_t epoch_iteration_start_time,
488 int64_t elapsed_time_ns) {
489 FILE* fp = fopen(xml_output_filename.c_str(), "w");
490 if (fp == NULL) {
491 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
492 exit(1);
493 }
494
495 size_t total_test_count = 0;
496 size_t total_failed_count = 0;
497 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
498 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
499 for (size_t i = 0; i < testcase_list.size(); ++i) {
500 auto& testcase = testcase_list[i];
501 total_test_count += testcase.TestCount();
502 for (size_t j = 0; j < testcase.TestCount(); ++j) {
503 if (testcase.GetTestResult(j) != TEST_SUCCESS) {
504 ++failed_count_list[i];
505 }
506 elapsed_time_list[i] += testcase.GetTestTime(j);
507 }
508 total_failed_count += failed_count_list[i];
509 }
510
511 const tm* time_struct = localtime(&epoch_iteration_start_time);
512 char timestamp[40];
513 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
514 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
515 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
516
517 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
518 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
519 total_test_count, total_failed_count);
520 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
521 for (size_t i = 0; i < testcase_list.size(); ++i) {
522 auto& testcase = testcase_list[i];
523 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
524 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
525 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
526
527 for (size_t j = 0; j < testcase.TestCount(); ++j) {
528 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
529 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
530 testcase.GetName().c_str());
531 if (testcase.GetTestResult(j) == TEST_SUCCESS) {
532 fputs(" />\n", fp);
533 } else {
534 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800535 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
Dan Albert09a99642016-01-13 21:48:56 -0800536 const std::string escaped_test_output = XmlEscape(test_output);
537 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", escaped_test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800538 fputs(" </failure>\n", fp);
539 fputs(" </testcase>\n", fp);
540 }
541 }
542
543 fputs(" </testsuite>\n", fp);
544 }
545 fputs("</testsuites>\n", fp);
546 fclose(fp);
547}
548
Yabin Cui767fb1c2015-09-01 15:06:39 -0700549static bool sigint_flag;
550static bool sigquit_flag;
551
552static void signal_handler(int sig) {
553 if (sig == SIGINT) {
554 sigint_flag = true;
555 } else if (sig == SIGQUIT) {
556 sigquit_flag = true;
557 }
558}
559
560static bool RegisterSignalHandler() {
561 sigint_flag = false;
562 sigquit_flag = false;
563 sig_t ret = signal(SIGINT, signal_handler);
564 if (ret != SIG_ERR) {
565 ret = signal(SIGQUIT, signal_handler);
566 }
567 if (ret == SIG_ERR) {
568 perror("RegisterSignalHandler");
569 return false;
570 }
571 return true;
572}
573
574static bool UnregisterSignalHandler() {
575 sig_t ret = signal(SIGINT, SIG_DFL);
576 if (ret != SIG_ERR) {
577 ret = signal(SIGQUIT, SIG_DFL);
578 }
579 if (ret == SIG_ERR) {
580 perror("UnregisterSignalHandler");
581 return false;
582 }
583 return true;
584}
585
Yabin Cui1d4c7802015-02-02 19:14:05 -0800586struct ChildProcInfo {
587 pid_t pid;
588 int64_t start_time_ns;
589 int64_t end_time_ns;
590 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
591 size_t testcase_id, test_id;
592 bool finished;
593 bool timed_out;
594 int exit_status;
595 int child_read_fd; // File descriptor to read child test failure info.
596};
597
Yabin Cui294d1e22014-12-07 20:43:37 -0800598// Forked Child process, run the single test.
599static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800600 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800601 memcpy(new_argv, argv, sizeof(char*) * argc);
602
603 char* filter_arg = new char [test_name.size() + 20];
604 strcpy(filter_arg, "--gtest_filter=");
605 strcat(filter_arg, test_name.c_str());
606 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800607 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800608
609 int new_argc = argc + 1;
610 testing::InitGoogleTest(&new_argc, new_argv);
611 int result = RUN_ALL_TESTS();
612 exit(result);
613}
614
Yabin Cui1d4c7802015-02-02 19:14:05 -0800615static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700616 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800617 int pipefd[2];
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800618 if (pipe(pipefd) == -1) {
619 perror("pipe in RunTestInSeparateProc");
620 exit(1);
621 }
622 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
623 perror("fcntl in RunTestInSeparateProc");
Yabin Cui1d4c7802015-02-02 19:14:05 -0800624 exit(1);
625 }
626 pid_t pid = fork();
627 if (pid == -1) {
628 perror("fork in RunTestInSeparateProc");
629 exit(1);
630 } else if (pid == 0) {
631 // In child process, run a single test.
632 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800633 close(STDOUT_FILENO);
634 close(STDERR_FILENO);
635 dup2(pipefd[1], STDOUT_FILENO);
636 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800637
Yabin Cui767fb1c2015-09-01 15:06:39 -0700638 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800639 exit(1);
640 }
641 ChildProcessFn(argc, argv, test_name);
642 // Unreachable.
643 }
644 // In parent process, initialize child process info.
645 close(pipefd[1]);
646 ChildProcInfo child_proc;
647 child_proc.child_read_fd = pipefd[0];
648 child_proc.pid = pid;
649 child_proc.start_time_ns = NanoTime();
650 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetDeadlineInfo(test_name) * 1000000LL;
651 child_proc.testcase_id = testcase_id;
652 child_proc.test_id = test_id;
653 child_proc.finished = false;
654 return child_proc;
655}
Yabin Cui294d1e22014-12-07 20:43:37 -0800656
Yabin Cui1d4c7802015-02-02 19:14:05 -0800657static void HandleSignals(std::vector<TestCase>& testcase_list,
658 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700659 if (sigquit_flag) {
660 sigquit_flag = false;
661 // Print current running tests.
662 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700663 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700664 if (child_proc.pid != 0) {
665 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
666 int64_t current_time_ns = NanoTime();
667 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
668 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800669 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800670 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700671 } else if (sigint_flag) {
672 sigint_flag = false;
673 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700674 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700675 if (child_proc.pid != 0) {
676 // Send SIGKILL to ensure the child process can be killed unconditionally.
677 kill(child_proc.pid, SIGKILL);
678 }
679 }
680 // SIGINT kills the parent process as well.
681 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800682 }
683}
684
685static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
686 std::vector<ChildProcInfo>& child_proc_list) {
687 for (size_t i = 0; i < child_proc_list.size(); ++i) {
688 if (child_proc_list[i].pid == exit_pid) {
689 child_proc_list[i].finished = true;
690 child_proc_list[i].timed_out = false;
691 child_proc_list[i].exit_status = exit_status;
692 child_proc_list[i].end_time_ns = NanoTime();
693 return true;
694 }
695 }
696 return false;
697}
698
699static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
700 int64_t current_time_ns = NanoTime();
701 size_t timeout_child_count = 0;
702 for (size_t i = 0; i < child_proc_list.size(); ++i) {
703 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
704 child_proc_list[i].finished = true;
705 child_proc_list[i].timed_out = true;
706 child_proc_list[i].end_time_ns = current_time_ns;
707 ++timeout_child_count;
708 }
709 }
710 return timeout_child_count;
711}
712
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800713static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
714 std::vector<ChildProcInfo>& child_proc_list) {
715 for (const auto& child_proc : child_proc_list) {
716 TestCase& testcase = testcase_list[child_proc.testcase_id];
717 int test_id = child_proc.test_id;
718 while (true) {
719 char buf[1024];
720 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
721 if (bytes_read > 0) {
722 buf[bytes_read] = '\0';
723 testcase.GetTest(test_id).AppendTestOutput(buf);
724 } else if (bytes_read == 0) {
725 break; // Read end.
726 } else {
727 if (errno == EAGAIN) {
728 break;
729 }
730 perror("failed to read child_read_fd");
731 exit(1);
732 }
733 }
734 }
735}
736
Yabin Cui1d4c7802015-02-02 19:14:05 -0800737static void WaitChildProcs(std::vector<TestCase>& testcase_list,
738 std::vector<ChildProcInfo>& child_proc_list) {
739 size_t finished_child_count = 0;
740 while (true) {
741 int status;
742 pid_t result;
743 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
744 if (CheckChildProcExit(result, status, child_proc_list)) {
745 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800746 }
747 }
748
749 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800750 if (errno == ECHILD) {
751 // This happens when we have no running child processes.
752 return;
753 } else {
754 perror("waitpid");
755 exit(1);
756 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800757 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800758 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800759 }
760
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800761 ReadChildProcOutput(testcase_list, child_proc_list);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800762 if (finished_child_count > 0) {
763 return;
764 }
765
766 HandleSignals(testcase_list, child_proc_list);
767
Yabin Cui294d1e22014-12-07 20:43:37 -0800768 // sleep 1 ms to avoid busy looping.
769 timespec sleep_time;
770 sleep_time.tv_sec = 0;
771 sleep_time.tv_nsec = 1000000;
772 nanosleep(&sleep_time, NULL);
773 }
774}
775
Yabin Cui1d4c7802015-02-02 19:14:05 -0800776static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800777 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800778 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800779
780 TestResult test_result = TEST_SUCCESS;
781 if (result != pid || WEXITSTATUS(exit_status) != 0) {
782 test_result = TEST_FAILED;
783 }
784 return test_result;
785}
786
Yabin Cui1d4c7802015-02-02 19:14:05 -0800787static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
788 int test_id = child_proc.test_id;
789 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
790 if (child_proc.timed_out) {
791 // The child process marked as timed_out has not exited, and we should kill it manually.
792 kill(child_proc.pid, SIGKILL);
793 WaitForOneChild(child_proc.pid);
794 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800795 close(child_proc.child_read_fd);
796
797 if (child_proc.timed_out) {
798 testcase.SetTestResult(test_id, TEST_TIMEOUT);
799 char buf[1024];
800 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
801 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800802 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800803
804 } else if (WIFSIGNALED(child_proc.exit_status)) {
805 // Record signal terminated test as failed.
806 testcase.SetTestResult(test_id, TEST_FAILED);
807 char buf[1024];
808 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
809 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800810 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800811
812 } else {
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800813 int exitcode = WEXITSTATUS(child_proc.exit_status);
814 testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
815 if (exitcode != 0) {
Yabin Cuia32fc862015-12-03 16:28:03 -0800816 char buf[1024];
817 snprintf(buf, sizeof(buf), "%s exited with exitcode %d.\n",
818 testcase.GetTestName(test_id).c_str(), exitcode);
819 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800820 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800821 }
822}
823
Yabin Cui294d1e22014-12-07 20:43:37 -0800824// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
825// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700826// Returns true if all tests run successfully, otherwise return false.
827static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700828 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800829 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800830 // Stop default result printer to avoid environment setup/teardown information for each test.
831 testing::UnitTest::GetInstance()->listeners().Release(
832 testing::UnitTest::GetInstance()->listeners().default_result_printer());
833 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
834
Yabin Cui767fb1c2015-09-01 15:06:39 -0700835 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800836 exit(1);
837 }
838
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700839 bool all_tests_passed = true;
840
Christopher Ferris119cb552015-04-02 12:02:55 -0700841 for (size_t iteration = 1;
842 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
843 ++iteration) {
Yabin Cuibe837362015-01-02 18:45:37 -0800844 OnTestIterationStartPrint(testcase_list, iteration, iteration_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800845 int64_t iteration_start_time_ns = NanoTime();
846 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800847
Yabin Cuibe837362015-01-02 18:45:37 -0800848 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800849 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800850
Yabin Cuibe837362015-01-02 18:45:37 -0800851 // Next test to run is [next_testcase_id:next_test_id].
852 size_t next_testcase_id = 0;
853 size_t next_test_id = 0;
854
855 // Record how many tests are finished.
856 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
857 size_t finished_testcase_count = 0;
858
859 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800860 // run up to job_count child processes.
861 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
862 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
863 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700864 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800865 child_proc_list.push_back(child_proc);
866 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
867 next_test_id = 0;
868 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800869 }
870 }
871
872 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800873 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800874
875 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800876 auto it = child_proc_list.begin();
877 while (it != child_proc_list.end()) {
878 auto& child_proc = *it;
879 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800880 size_t testcase_id = child_proc.testcase_id;
881 size_t test_id = child_proc.test_id;
882 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800883
Yabin Cui1d4c7802015-02-02 19:14:05 -0800884 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800885 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800886
887 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
888 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800889 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700890 if (testcase.GetTestResult(test_id) != TEST_SUCCESS) {
891 all_tests_passed = false;
892 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800893
894 it = child_proc_list.erase(it);
895 } else {
896 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800897 }
898 }
899 }
900
Yabin Cui657b1f92015-01-22 19:26:12 -0800901 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
902 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
903 if (!xml_output_filename.empty()) {
904 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
905 elapsed_time_ns);
906 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800907 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800908
Yabin Cui767fb1c2015-09-01 15:06:39 -0700909 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800910 exit(1);
911 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700912
913 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800914}
915
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700916static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800917 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800918}
919
Yabin Cuiead08142015-02-04 20:53:56 -0800920static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
921 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
922 // test program via a valid path that contains at least one path separator.
923 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
924 // and execve() doesn't read environment variable PATH, so execve() will not success
925 // until we specify the absolute path or relative path of the test program directly.
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -0700926 if (strchr(args[0], '/') == nullptr) {
927 args[0] = strdup(g_executable_path.c_str());
Yabin Cuiead08142015-02-04 20:53:56 -0800928 }
929}
930
Yabin Cui11c43532015-01-28 14:28:14 -0800931static void AddGtestFilterSynonym(std::vector<char*>& args) {
932 // Support --gtest-filter as a synonym for --gtest_filter.
933 for (size_t i = 1; i < args.size(); ++i) {
934 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
935 args[i][7] = '_';
936 }
937 }
938}
939
Yabin Cui657b1f92015-01-22 19:26:12 -0800940struct IsolationTestOptions {
941 bool isolate;
942 size_t job_count;
943 int test_deadline_ms;
944 int test_warnline_ms;
945 std::string gtest_color;
946 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -0700947 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -0800948 std::string gtest_output;
949};
950
951// 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 -0800952// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -0800953// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
954// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -0800955// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -0800956// args is used to pass in all command arguments, and pass out only the part of options for gtest.
957// options is used to pass out test options in isolation mode.
958// Return false if there is error in arguments.
959static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
960 for (size_t i = 1; i < args.size(); ++i) {
961 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800962 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -0800963 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800964 return true;
965 }
966 }
967
Yabin Cuiead08142015-02-04 20:53:56 -0800968 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -0800969 AddGtestFilterSynonym(args);
970
Yabin Cui657b1f92015-01-22 19:26:12 -0800971 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
972 bool enable_selftest = false;
973 for (size_t i = 1; i < args.size(); ++i) {
974 if (strcmp(args[i], "--bionic-selftest") == 0) {
975 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
976 // Don't remove this option from arguments.
977 enable_selftest = true;
978 }
979 }
980 std::string gtest_filter_str;
981 for (size_t i = args.size() - 1; i >= 1; --i) {
982 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
983 gtest_filter_str = std::string(args[i]);
984 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800985 break;
986 }
987 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800988 if (enable_selftest == true) {
989 args.push_back(strdup("--gtest_filter=bionic_selftest*"));
990 } else {
991 if (gtest_filter_str == "") {
992 gtest_filter_str = "--gtest_filter=-bionic_selftest*";
993 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -0800994 // Find if '-' for NEGATIVE_PATTERNS exists.
995 if (gtest_filter_str.find(":-") != std::string::npos) {
996 gtest_filter_str += ":bionic_selftest*";
997 } else {
998 gtest_filter_str += ":-bionic_selftest*";
999 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001000 }
1001 args.push_back(strdup(gtest_filter_str.c_str()));
1002 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001003
Yabin Cui657b1f92015-01-22 19:26:12 -08001004 options.isolate = true;
1005 // Parse arguments that make us can't run in isolation mode.
1006 for (size_t i = 1; i < args.size(); ++i) {
1007 if (strcmp(args[i], "--no-isolate") == 0) {
1008 options.isolate = false;
1009 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
1010 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001011 }
1012 }
1013
Yabin Cui657b1f92015-01-22 19:26:12 -08001014 // Stop parsing if we will not run in isolation mode.
1015 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001016 return true;
1017 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001018
1019 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -07001020 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -08001021 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
1022 options.test_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
1023 options.gtest_color = testing::GTEST_FLAG(color);
1024 options.gtest_print_time = testing::GTEST_FLAG(print_time);
1025 options.gtest_repeat = testing::GTEST_FLAG(repeat);
1026 options.gtest_output = testing::GTEST_FLAG(output);
1027
1028 // Parse arguments speficied for isolation mode.
1029 for (size_t i = 1; i < args.size(); ++i) {
1030 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1031 char* p = args[i] + strlen("-j");
1032 int count = 0;
1033 if (*p != '\0') {
1034 // Argument like -j5.
1035 count = atoi(p);
1036 } else if (args.size() > i + 1) {
1037 // Arguments like -j 5.
1038 count = atoi(args[i + 1]);
1039 ++i;
1040 }
1041 if (count <= 0) {
1042 fprintf(stderr, "invalid job count: %d\n", count);
1043 return false;
1044 }
1045 options.job_count = static_cast<size_t>(count);
1046 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1047 int time_ms = atoi(args[i] + strlen("--deadline="));
1048 if (time_ms <= 0) {
1049 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1050 return false;
1051 }
1052 options.test_deadline_ms = time_ms;
1053 } else if (strncmp(args[i], "--warnline=", strlen("--warnline=")) == 0) {
1054 int time_ms = atoi(args[i] + strlen("--warnline="));
1055 if (time_ms <= 0) {
1056 fprintf(stderr, "invalid warnline: %d\n", time_ms);
1057 return false;
1058 }
1059 options.test_warnline_ms = time_ms;
1060 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1061 options.gtest_color = args[i] + strlen("--gtest_color=");
1062 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1063 options.gtest_print_time = false;
1064 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001065 // If the value of gtest_repeat is < 0, then it indicates the tests
1066 // should be repeated forever.
1067 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001068 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1069 args.erase(args.begin() + i);
1070 --i;
1071 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1072 std::string output = args[i] + strlen("--gtest_output=");
1073 // generate output xml file path according to the strategy in gtest.
1074 bool success = true;
1075 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1076 output = output.substr(strlen("xml:"));
1077 if (output.size() == 0) {
1078 success = false;
1079 }
1080 // Make absolute path.
1081 if (success && output[0] != '/') {
1082 char* cwd = getcwd(NULL, 0);
1083 if (cwd != NULL) {
1084 output = std::string(cwd) + "/" + output;
1085 free(cwd);
1086 } else {
1087 success = false;
1088 }
1089 }
1090 // Add file name if output is a directory.
1091 if (success && output.back() == '/') {
1092 output += "test_details.xml";
1093 }
1094 }
1095 if (success) {
1096 options.gtest_output = output;
1097 } else {
1098 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1099 return false;
1100 }
1101
1102 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1103 args.erase(args.begin() + i);
1104 --i;
1105 }
1106 }
1107
1108 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1109 // As DeathTest will try to call execve(), this argument should always be added.
1110 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001111 return true;
1112}
1113
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001114static std::string get_proc_self_exe() {
1115 char path[PATH_MAX];
1116 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
1117 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
1118 perror("readlink");
1119 exit(1);
1120 }
1121
1122 return std::string(path, path_len);
1123}
1124
Yabin Cui294d1e22014-12-07 20:43:37 -08001125int main(int argc, char** argv) {
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001126 g_executable_path = get_proc_self_exe();
Yabin Cuibe837362015-01-02 18:45:37 -08001127 std::vector<char*> arg_list;
1128 for (int i = 0; i < argc; ++i) {
1129 arg_list.push_back(argv[i]);
1130 }
Yabin Cuibe837362015-01-02 18:45:37 -08001131
Yabin Cui657b1f92015-01-22 19:26:12 -08001132 IsolationTestOptions options;
1133 if (PickOptions(arg_list, options) == false) {
1134 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001135 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001136
1137 if (options.isolate == true) {
1138 // Set global variables.
1139 global_test_run_deadline_ms = options.test_deadline_ms;
1140 global_test_run_warnline_ms = options.test_warnline_ms;
1141 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1142 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1143 std::vector<TestCase> testcase_list;
1144
1145 argc = static_cast<int>(arg_list.size());
1146 arg_list.push_back(NULL);
1147 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1148 return 1;
1149 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001150 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1151 options.gtest_repeat, options.job_count, options.gtest_output);
1152 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001153 } else {
1154 argc = static_cast<int>(arg_list.size());
1155 arg_list.push_back(NULL);
1156 testing::InitGoogleTest(&argc, arg_list.data());
1157 return RUN_ALL_TESTS();
1158 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001159}
1160
1161//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001162// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001163
Yabin Cuibe837362015-01-02 18:45:37 -08001164TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001165 ASSERT_EQ(1, 1);
1166}
1167
Yabin Cuibe837362015-01-02 18:45:37 -08001168TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001169 ASSERT_EQ(0, 1);
1170}
1171
Yabin Cuibe837362015-01-02 18:45:37 -08001172TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001173 sleep(4);
1174}
1175
Yabin Cuibe837362015-01-02 18:45:37 -08001176TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001177 while (1) {}
1178}
Yabin Cuibe837362015-01-02 18:45:37 -08001179
1180TEST(bionic_selftest, test_signal_SEGV_terminated) {
1181 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1182 *p = 3;
1183}
Yabin Cui657b1f92015-01-22 19:26:12 -08001184
Yabin Cui767fb1c2015-09-01 15:06:39 -07001185class bionic_selftest_DeathTest : public ::testing::Test {
1186 protected:
1187 virtual void SetUp() {
1188 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1189 }
1190};
Yabin Cui657b1f92015-01-22 19:26:12 -08001191
1192static void deathtest_helper_success() {
1193 ASSERT_EQ(1, 1);
1194 exit(0);
1195}
1196
1197TEST_F(bionic_selftest_DeathTest, success) {
1198 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1199}
1200
1201static void deathtest_helper_fail() {
1202 ASSERT_EQ(1, 0);
1203}
1204
1205TEST_F(bionic_selftest_DeathTest, fail) {
1206 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1207}