blob: b12c28f469d7b6aa545f88ace24082f9f6a8e729 [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>
Yabin Cui294d1e22014-12-07 20:43:37 -080026#include <stdarg.h>
27#include <stdio.h>
28#include <string.h>
29#include <sys/wait.h>
Yabin Cui294d1e22014-12-07 20:43:37 -080030#include <unistd.h>
31
Yabin Cui767fb1c2015-09-01 15:06:39 -070032#include <chrono>
Yabin Cui294d1e22014-12-07 20:43:37 -080033#include <string>
34#include <tuple>
35#include <utility>
36#include <vector>
37
Yabin Cui767fb1c2015-09-01 15:06:39 -070038#ifndef TEMP_FAILURE_RETRY
39
40/* Used to retry syscalls that can return EINTR. */
41#define TEMP_FAILURE_RETRY(exp) ({ \
42 __typeof__(exp) _rc; \
43 do { \
44 _rc = (exp); \
45 } while (_rc == -1 && errno == EINTR); \
46 _rc; })
47
48#endif
Yabin Cui657b1f92015-01-22 19:26:12 -080049
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -070050static std::string g_executable_path;
Dimitry Ivanov55437462016-07-20 15:33:07 -070051static int g_argc;
52static char** g_argv;
53static char** g_envp;
Dimitry Ivanovd17a3772016-03-01 13:11:28 -080054
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -070055const std::string& get_executable_path() {
56 return g_executable_path;
Dimitry Ivanovd17a3772016-03-01 13:11:28 -080057}
58
Dimitry Ivanova36e59b2016-09-01 11:37:39 -070059bool get_realpath(const std::string& path, std::string* real_path) {
60 char realpath_buf[PATH_MAX];
61 if (realpath(path.c_str(), realpath_buf) != realpath_buf) {
62 return false;
63 }
64
65 *real_path = realpath_buf;
66 return true;
67}
68
Dimitry Ivanovd0b5c3a2016-11-25 12:23:11 -080069std::string get_dirname(const char* path) {
70#if defined(__BIONIC__)
71 return dirname(path);
72#else
73 // GLIBC does not have const char* dirname
74 return dirname(const_cast<char*>(path));
75#endif
76}
77
Dimitry Ivanov55437462016-07-20 15:33:07 -070078int get_argc() {
79 return g_argc;
80}
81
82char** get_argv() {
83 return g_argv;
84}
85
86char** get_envp() {
87 return g_envp;
88}
89
Yabin Cui294d1e22014-12-07 20:43:37 -080090namespace testing {
91namespace internal {
92
93// Reuse of testing::internal::ColoredPrintf in gtest.
94enum GTestColor {
95 COLOR_DEFAULT,
96 COLOR_RED,
97 COLOR_GREEN,
98 COLOR_YELLOW
99};
100
101void ColoredPrintf(GTestColor color, const char* fmt, ...);
102
Yabin Cuibe837362015-01-02 18:45:37 -0800103} // namespace internal
104} // namespace testing
Yabin Cui294d1e22014-12-07 20:43:37 -0800105
106using testing::internal::GTestColor;
107using testing::internal::COLOR_DEFAULT;
108using testing::internal::COLOR_RED;
109using testing::internal::COLOR_GREEN;
110using testing::internal::COLOR_YELLOW;
111using testing::internal::ColoredPrintf;
112
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700113constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 90000;
Elliott Hughesa456fae2016-08-31 13:30:14 -0700114constexpr int DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -0800115
116// The time each test can run before killed for the reason of timeout.
117// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -0800118static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800119
120// The time each test can run before be warned for too much running time.
121// It takes effect only with --isolate option.
Elliott Hughesa456fae2016-08-31 13:30:14 -0700122static int global_test_run_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -0800123
Elliott Hughesa456fae2016-08-31 13:30:14 -0700124// Return timeout duration for a test, in ms.
125static int GetTimeoutMs(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800126 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800127}
128
Elliott Hughesa456fae2016-08-31 13:30:14 -0700129// Return threshold for calling a test slow, in ms.
130static int GetSlowThresholdMs(const std::string& /*test_name*/) {
131 return global_test_run_slow_threshold_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -0800132}
133
Yabin Cuibe837362015-01-02 18:45:37 -0800134static void PrintHelpInfo() {
135 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -0800136 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800137 " Run up to JOB_COUNT tests in parallel.\n"
138 " Use isolation mode, Run each test in a separate process.\n"
139 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
140 " --no-isolate\n"
141 " Don't use isolation mode, run all tests in a single process.\n"
142 " --deadline=[TIME_IN_MS]\n"
143 " Run each test in no longer than [TIME_IN_MS] time.\n"
Elliott Hughesa456fae2016-08-31 13:30:14 -0700144 " Only valid in isolation mode. Default deadline is 90000 ms.\n"
145 " --slow-threshold=[TIME_IN_MS]\n"
146 " Test running longer than [TIME_IN_MS] will be called slow.\n"
147 " Only valid in isolation mode. Default slow threshold is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -0800148 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
149 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -0800150 "Default bionic unit test option is -j.\n"
151 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
152 "running tests, or send SIGINT to the parent process to stop testing and\n"
153 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800154 "\n");
155}
156
Yabin Cui294d1e22014-12-07 20:43:37 -0800157enum TestResult {
158 TEST_SUCCESS = 0,
159 TEST_FAILED,
160 TEST_TIMEOUT
161};
162
Yabin Cui657b1f92015-01-22 19:26:12 -0800163class Test {
164 public:
165 Test() {} // For std::vector<Test>.
166 explicit Test(const char* name) : name_(name) {}
167
168 const std::string& GetName() const { return name_; }
169
170 void SetResult(TestResult result) { result_ = result; }
171
172 TestResult GetResult() const { return result_; }
173
174 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
175
176 int64_t GetTestTime() const { return elapsed_time_ns_; }
177
Yabin Cuiea9c9332015-02-24 14:39:19 -0800178 void AppendTestOutput(const std::string& s) { output_ += s; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800179
Yabin Cuiea9c9332015-02-24 14:39:19 -0800180 const std::string& GetTestOutput() const { return output_; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800181
182 private:
183 const std::string name_;
184 TestResult result_;
185 int64_t elapsed_time_ns_;
Yabin Cuiea9c9332015-02-24 14:39:19 -0800186 std::string output_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800187};
188
Yabin Cui294d1e22014-12-07 20:43:37 -0800189class TestCase {
190 public:
191 TestCase() {} // For std::vector<TestCase>.
192 explicit TestCase(const char* name) : name_(name) {}
193
194 const std::string& GetName() const { return name_; }
195
Yabin Cui657b1f92015-01-22 19:26:12 -0800196 void AppendTest(const char* test_name) {
197 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800198 }
199
Yabin Cuibe837362015-01-02 18:45:37 -0800200 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800201
Yabin Cuibe837362015-01-02 18:45:37 -0800202 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800203 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800204 return name_ + "." + test_list_[test_id].GetName();
205 }
206
207 Test& GetTest(size_t test_id) {
208 VerifyTestId(test_id);
209 return test_list_[test_id];
210 }
211
212 const Test& GetTest(size_t test_id) const {
213 VerifyTestId(test_id);
214 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800215 }
216
Yabin Cuibe837362015-01-02 18:45:37 -0800217 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800218 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800219 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800220 }
221
Yabin Cuibe837362015-01-02 18:45:37 -0800222 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800223 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800224 return test_list_[test_id].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800225 }
226
Yabin Cui657b1f92015-01-22 19:26:12 -0800227 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800228 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800229 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800230 }
231
Yabin Cuibe837362015-01-02 18:45:37 -0800232 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800233 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800234 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800235 }
236
237 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800238 void VerifyTestId(size_t test_id) const {
239 if(test_id >= test_list_.size()) {
240 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800241 exit(1);
242 }
243 }
244
245 private:
246 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800247 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800248};
249
Yabin Cui294d1e22014-12-07 20:43:37 -0800250class TestResultPrinter : public testing::EmptyTestEventListener {
251 public:
252 TestResultPrinter() : pinfo_(NULL) {}
253 virtual void OnTestStart(const testing::TestInfo& test_info) {
254 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
255 }
256 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800257
258 private:
259 const testing::TestInfo* pinfo_;
260};
261
262// Called after an assertion failure.
263void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
264 // If the test part succeeded, we don't need to do anything.
265 if (result.type() == testing::TestPartResult::kSuccess)
266 return;
267
268 // Print failure message from the assertion (e.g. expected this and got that).
Yabin Cuiea9c9332015-02-24 14:39:19 -0800269 printf("%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), result.line_number(),
270 pinfo_->test_case_name(), pinfo_->name(), result.message());
271 fflush(stdout);
Yabin Cui294d1e22014-12-07 20:43:37 -0800272}
273
Yabin Cui294d1e22014-12-07 20:43:37 -0800274static int64_t NanoTime() {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700275 std::chrono::nanoseconds duration(std::chrono::steady_clock::now().time_since_epoch());
276 return static_cast<int64_t>(duration.count());
Yabin Cui294d1e22014-12-07 20:43:37 -0800277}
278
279static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
280 std::string command;
281 for (int i = 0; i < argc; ++i) {
282 command += argv[i];
283 command += " ";
284 }
285 command += "--gtest_list_tests";
286 FILE* fp = popen(command.c_str(), "r");
287 if (fp == NULL) {
288 perror("popen");
289 return false;
290 }
291
292 char buf[200];
293 while (fgets(buf, sizeof(buf), fp) != NULL) {
294 char* p = buf;
295
296 while (*p != '\0' && isspace(*p)) {
297 ++p;
298 }
299 if (*p == '\0') continue;
300 char* start = p;
301 while (*p != '\0' && !isspace(*p)) {
302 ++p;
303 }
304 char* end = p;
305 while (*p != '\0' && isspace(*p)) {
306 ++p;
307 }
Yabin Cuibf830ad2015-08-10 12:12:39 -0700308 if (*p != '\0' && *p != '#') {
Yabin Cui294d1e22014-12-07 20:43:37 -0800309 // This is not we want, gtest must meet with some error when parsing the arguments.
310 fprintf(stderr, "argument error, check with --help\n");
311 return false;
312 }
313 *end = '\0';
314 if (*(end - 1) == '.') {
315 *(end - 1) = '\0';
316 testcase_list.push_back(TestCase(start));
317 } else {
318 testcase_list.back().AppendTest(start);
319 }
320 }
321 int result = pclose(fp);
322 return (result != -1 && WEXITSTATUS(result) == 0);
323}
324
Yabin Cui294d1e22014-12-07 20:43:37 -0800325// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
326// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
327// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800328static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
Elliott Hughes48de71e2016-10-28 10:04:44 -0700329 int iteration_count, size_t job_count) {
Christopher Ferris119cb552015-04-02 12:02:55 -0700330 if (iteration_count != 1) {
Yabin Cuibe837362015-01-02 18:45:37 -0800331 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800332 }
333 ColoredPrintf(COLOR_GREEN, "[==========] ");
334
Yabin Cuibe837362015-01-02 18:45:37 -0800335 size_t testcase_count = testcase_list.size();
336 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800337 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800338 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800339 }
340
Elliott Hughes48de71e2016-10-28 10:04:44 -0700341 printf("Running %zu %s from %zu %s (%zu %s).\n",
Yabin Cuibe837362015-01-02 18:45:37 -0800342 test_count, (test_count == 1) ? "test" : "tests",
Elliott Hughes48de71e2016-10-28 10:04:44 -0700343 testcase_count, (testcase_count == 1) ? "test case" : "test cases",
344 job_count, (job_count == 1) ? "job" : "jobs");
Yabin Cui294d1e22014-12-07 20:43:37 -0800345 fflush(stdout);
346}
347
Yabin Cuif6237472015-02-26 19:03:54 -0800348// bionic cts test needs gtest output format.
349#if defined(USING_GTEST_OUTPUT_FORMAT)
350
351static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
352 ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
353 printf("%s\n", testcase.GetTestName(test_id).c_str());
354
355 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
356 printf("%s", test_output.c_str());
357
358 TestResult result = testcase.GetTestResult(test_id);
359 if (result == TEST_SUCCESS) {
360 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
361 } else {
362 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
363 }
364 printf("%s", testcase.GetTestName(test_id).c_str());
365 if (testing::GTEST_FLAG(print_time)) {
366 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
367 }
368 printf("\n");
369 fflush(stdout);
370}
371
372#else // !defined(USING_GTEST_OUTPUT_FORMAT)
373
Yabin Cui657b1f92015-01-22 19:26:12 -0800374static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
375 TestResult result = testcase.GetTestResult(test_id);
376 if (result == TEST_SUCCESS) {
377 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
378 } else if (result == TEST_FAILED) {
379 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
380 } else if (result == TEST_TIMEOUT) {
381 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
382 }
Yabin Cuibe837362015-01-02 18:45:37 -0800383
Yabin Cui657b1f92015-01-22 19:26:12 -0800384 printf("%s", testcase.GetTestName(test_id).c_str());
385 if (testing::GTEST_FLAG(print_time)) {
Yabin Cuif6237472015-02-26 19:03:54 -0800386 printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
Yabin Cui657b1f92015-01-22 19:26:12 -0800387 }
Yabin Cuif6237472015-02-26 19:03:54 -0800388 printf("\n");
Yabin Cui657b1f92015-01-22 19:26:12 -0800389
Yabin Cuiea9c9332015-02-24 14:39:19 -0800390 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
391 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800392 fflush(stdout);
393}
394
Yabin Cuif6237472015-02-26 19:03:54 -0800395#endif // !defined(USING_GTEST_OUTPUT_FORMAT)
396
Yabin Cuibe837362015-01-02 18:45:37 -0800397static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800398 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800399
400 std::vector<std::string> fail_test_name_list;
401 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
402
Elliott Hughesa456fae2016-08-31 13:30:14 -0700403 // For tests that were slow but didn't time out.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800404 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800405 size_t testcase_count = testcase_list.size();
406 size_t test_count = 0;
407 size_t success_test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800408
409 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800410 test_count += testcase.TestCount();
411 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800412 TestResult result = testcase.GetTestResult(i);
413 if (result == TEST_SUCCESS) {
Yabin Cuibe837362015-01-02 18:45:37 -0800414 ++success_test_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800415 } else if (result == TEST_FAILED) {
416 fail_test_name_list.push_back(testcase.GetTestName(i));
417 } else if (result == TEST_TIMEOUT) {
418 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i),
419 testcase.GetTestTime(i)));
420 }
421 if (result != TEST_TIMEOUT &&
Elliott Hughesa456fae2016-08-31 13:30:14 -0700422 testcase.GetTestTime(i) / 1000000 >= GetSlowThresholdMs(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800423 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
424 testcase.GetTestTime(i),
Elliott Hughesa456fae2016-08-31 13:30:14 -0700425 GetSlowThresholdMs(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800426 }
427 }
428 }
429
Yabin Cui294d1e22014-12-07 20:43:37 -0800430 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800431 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
432 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800433 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800434 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800435 }
436 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800437 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800438 printf("%zu %s.\n", success_test_count, (success_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800439
Elliott Hughesa456fae2016-08-31 13:30:14 -0700440 // Print tests that timed out.
Yabin Cuibe837362015-01-02 18:45:37 -0800441 size_t timeout_test_count = timeout_test_list.size();
442 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800443 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800444 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800445 for (const auto& timeout_pair : timeout_test_list) {
446 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800447 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
448 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800449 }
450 }
451
Elliott Hughesa456fae2016-08-31 13:30:14 -0700452 // Print tests that were slow.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800453 size_t slow_test_count = slow_test_list.size();
454 if (slow_test_count > 0) {
455 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
456 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
457 for (const auto& slow_tuple : slow_test_list) {
458 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
Elliott Hughesa456fae2016-08-31 13:30:14 -0700459 printf("%s (%" PRId64 " ms, exceeded %d ms)\n", std::get<0>(slow_tuple).c_str(),
Yabin Cui4a82ede2015-01-26 17:19:37 -0800460 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800461 }
462 }
463
Elliott Hughesa456fae2016-08-31 13:30:14 -0700464 // Print tests that failed.
465 size_t fail_test_count = fail_test_name_list.size();
Yabin Cuibe837362015-01-02 18:45:37 -0800466 if (fail_test_count > 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -0700467 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
468 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
469 for (const auto& name : fail_test_name_list) {
470 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
471 printf("%s\n", name.c_str());
472 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800473 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700474
475 if (timeout_test_count > 0 || slow_test_count > 0 || fail_test_count > 0) {
476 printf("\n");
477 }
478
Yabin Cuibe837362015-01-02 18:45:37 -0800479 if (timeout_test_count > 0) {
480 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800481 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800482 if (slow_test_count > 0) {
483 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800484 }
Elliott Hughesa456fae2016-08-31 13:30:14 -0700485 if (fail_test_count > 0) {
486 printf("%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
487 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800488 fflush(stdout);
489}
490
Dan Albert09a99642016-01-13 21:48:56 -0800491std::string XmlEscape(const std::string& xml) {
492 std::string escaped;
493 escaped.reserve(xml.size());
494
495 for (auto c : xml) {
496 switch (c) {
497 case '<':
498 escaped.append("&lt;");
499 break;
500 case '>':
501 escaped.append("&gt;");
502 break;
503 case '&':
504 escaped.append("&amp;");
505 break;
506 case '\'':
507 escaped.append("&apos;");
508 break;
509 case '"':
510 escaped.append("&quot;");
511 break;
512 default:
513 escaped.append(1, c);
514 break;
515 }
516 }
517
518 return escaped;
519}
520
Yabin Cui657b1f92015-01-22 19:26:12 -0800521// Output xml file when --gtest_output is used, write this function as we can't reuse
522// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
523// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
524// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
525void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
526 const std::vector<TestCase>& testcase_list,
527 time_t epoch_iteration_start_time,
528 int64_t elapsed_time_ns) {
529 FILE* fp = fopen(xml_output_filename.c_str(), "w");
530 if (fp == NULL) {
531 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
532 exit(1);
533 }
534
535 size_t total_test_count = 0;
536 size_t total_failed_count = 0;
537 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
538 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
539 for (size_t i = 0; i < testcase_list.size(); ++i) {
540 auto& testcase = testcase_list[i];
541 total_test_count += testcase.TestCount();
542 for (size_t j = 0; j < testcase.TestCount(); ++j) {
543 if (testcase.GetTestResult(j) != TEST_SUCCESS) {
544 ++failed_count_list[i];
545 }
546 elapsed_time_list[i] += testcase.GetTestTime(j);
547 }
548 total_failed_count += failed_count_list[i];
549 }
550
551 const tm* time_struct = localtime(&epoch_iteration_start_time);
552 char timestamp[40];
553 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
554 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
555 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
556
557 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
558 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
559 total_test_count, total_failed_count);
560 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
561 for (size_t i = 0; i < testcase_list.size(); ++i) {
562 auto& testcase = testcase_list[i];
563 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
564 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
565 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
566
567 for (size_t j = 0; j < testcase.TestCount(); ++j) {
568 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
569 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
570 testcase.GetName().c_str());
571 if (testcase.GetTestResult(j) == TEST_SUCCESS) {
572 fputs(" />\n", fp);
573 } else {
574 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800575 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
Dan Albert09a99642016-01-13 21:48:56 -0800576 const std::string escaped_test_output = XmlEscape(test_output);
577 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", escaped_test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800578 fputs(" </failure>\n", fp);
579 fputs(" </testcase>\n", fp);
580 }
581 }
582
583 fputs(" </testsuite>\n", fp);
584 }
585 fputs("</testsuites>\n", fp);
586 fclose(fp);
587}
588
Yabin Cui767fb1c2015-09-01 15:06:39 -0700589static bool sigint_flag;
590static bool sigquit_flag;
591
592static void signal_handler(int sig) {
593 if (sig == SIGINT) {
594 sigint_flag = true;
595 } else if (sig == SIGQUIT) {
596 sigquit_flag = true;
597 }
598}
599
600static bool RegisterSignalHandler() {
601 sigint_flag = false;
602 sigquit_flag = false;
603 sig_t ret = signal(SIGINT, signal_handler);
604 if (ret != SIG_ERR) {
605 ret = signal(SIGQUIT, signal_handler);
606 }
607 if (ret == SIG_ERR) {
608 perror("RegisterSignalHandler");
609 return false;
610 }
611 return true;
612}
613
614static bool UnregisterSignalHandler() {
615 sig_t ret = signal(SIGINT, SIG_DFL);
616 if (ret != SIG_ERR) {
617 ret = signal(SIGQUIT, SIG_DFL);
618 }
619 if (ret == SIG_ERR) {
620 perror("UnregisterSignalHandler");
621 return false;
622 }
623 return true;
624}
625
Yabin Cui1d4c7802015-02-02 19:14:05 -0800626struct ChildProcInfo {
627 pid_t pid;
628 int64_t start_time_ns;
629 int64_t end_time_ns;
630 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
631 size_t testcase_id, test_id;
632 bool finished;
633 bool timed_out;
634 int exit_status;
635 int child_read_fd; // File descriptor to read child test failure info.
636};
637
Yabin Cui294d1e22014-12-07 20:43:37 -0800638// Forked Child process, run the single test.
639static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800640 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800641 memcpy(new_argv, argv, sizeof(char*) * argc);
642
643 char* filter_arg = new char [test_name.size() + 20];
644 strcpy(filter_arg, "--gtest_filter=");
645 strcat(filter_arg, test_name.c_str());
646 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800647 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800648
649 int new_argc = argc + 1;
650 testing::InitGoogleTest(&new_argc, new_argv);
651 int result = RUN_ALL_TESTS();
652 exit(result);
653}
654
Yabin Cui1d4c7802015-02-02 19:14:05 -0800655static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700656 int argc, char** argv) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800657 int pipefd[2];
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800658 if (pipe(pipefd) == -1) {
659 perror("pipe in RunTestInSeparateProc");
660 exit(1);
661 }
662 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
663 perror("fcntl in RunTestInSeparateProc");
Yabin Cui1d4c7802015-02-02 19:14:05 -0800664 exit(1);
665 }
666 pid_t pid = fork();
667 if (pid == -1) {
668 perror("fork in RunTestInSeparateProc");
669 exit(1);
670 } else if (pid == 0) {
671 // In child process, run a single test.
672 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800673 close(STDOUT_FILENO);
674 close(STDERR_FILENO);
675 dup2(pipefd[1], STDOUT_FILENO);
676 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800677
Yabin Cui767fb1c2015-09-01 15:06:39 -0700678 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800679 exit(1);
680 }
681 ChildProcessFn(argc, argv, test_name);
682 // Unreachable.
683 }
684 // In parent process, initialize child process info.
685 close(pipefd[1]);
686 ChildProcInfo child_proc;
687 child_proc.child_read_fd = pipefd[0];
688 child_proc.pid = pid;
689 child_proc.start_time_ns = NanoTime();
Elliott Hughesa456fae2016-08-31 13:30:14 -0700690 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetTimeoutMs(test_name) * 1000000LL;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800691 child_proc.testcase_id = testcase_id;
692 child_proc.test_id = test_id;
693 child_proc.finished = false;
694 return child_proc;
695}
Yabin Cui294d1e22014-12-07 20:43:37 -0800696
Yabin Cui1d4c7802015-02-02 19:14:05 -0800697static void HandleSignals(std::vector<TestCase>& testcase_list,
698 std::vector<ChildProcInfo>& child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700699 if (sigquit_flag) {
700 sigquit_flag = false;
701 // Print current running tests.
702 printf("List of current running tests:\n");
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700703 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700704 if (child_proc.pid != 0) {
705 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
706 int64_t current_time_ns = NanoTime();
707 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
708 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800709 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800710 }
Yabin Cui767fb1c2015-09-01 15:06:39 -0700711 } else if (sigint_flag) {
712 sigint_flag = false;
713 // Kill current running tests.
Elliott Hughes0b2acdf2015-10-02 18:25:19 -0700714 for (const auto& child_proc : child_proc_list) {
Yabin Cui767fb1c2015-09-01 15:06:39 -0700715 if (child_proc.pid != 0) {
716 // Send SIGKILL to ensure the child process can be killed unconditionally.
717 kill(child_proc.pid, SIGKILL);
718 }
719 }
720 // SIGINT kills the parent process as well.
721 exit(1);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800722 }
723}
724
725static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
726 std::vector<ChildProcInfo>& child_proc_list) {
727 for (size_t i = 0; i < child_proc_list.size(); ++i) {
728 if (child_proc_list[i].pid == exit_pid) {
729 child_proc_list[i].finished = true;
730 child_proc_list[i].timed_out = false;
731 child_proc_list[i].exit_status = exit_status;
732 child_proc_list[i].end_time_ns = NanoTime();
733 return true;
734 }
735 }
736 return false;
737}
738
739static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
740 int64_t current_time_ns = NanoTime();
741 size_t timeout_child_count = 0;
742 for (size_t i = 0; i < child_proc_list.size(); ++i) {
743 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
744 child_proc_list[i].finished = true;
745 child_proc_list[i].timed_out = true;
746 child_proc_list[i].end_time_ns = current_time_ns;
747 ++timeout_child_count;
748 }
749 }
750 return timeout_child_count;
751}
752
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800753static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
754 std::vector<ChildProcInfo>& child_proc_list) {
755 for (const auto& child_proc : child_proc_list) {
756 TestCase& testcase = testcase_list[child_proc.testcase_id];
757 int test_id = child_proc.test_id;
758 while (true) {
759 char buf[1024];
760 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
761 if (bytes_read > 0) {
762 buf[bytes_read] = '\0';
763 testcase.GetTest(test_id).AppendTestOutput(buf);
764 } else if (bytes_read == 0) {
765 break; // Read end.
766 } else {
767 if (errno == EAGAIN) {
768 break;
769 }
770 perror("failed to read child_read_fd");
771 exit(1);
772 }
773 }
774 }
775}
776
Yabin Cui1d4c7802015-02-02 19:14:05 -0800777static void WaitChildProcs(std::vector<TestCase>& testcase_list,
778 std::vector<ChildProcInfo>& child_proc_list) {
779 size_t finished_child_count = 0;
780 while (true) {
781 int status;
782 pid_t result;
783 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
784 if (CheckChildProcExit(result, status, child_proc_list)) {
785 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800786 }
787 }
788
789 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800790 if (errno == ECHILD) {
791 // This happens when we have no running child processes.
792 return;
793 } else {
794 perror("waitpid");
795 exit(1);
796 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800797 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800798 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800799 }
800
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800801 ReadChildProcOutput(testcase_list, child_proc_list);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800802 if (finished_child_count > 0) {
803 return;
804 }
805
806 HandleSignals(testcase_list, child_proc_list);
807
Yabin Cui294d1e22014-12-07 20:43:37 -0800808 // sleep 1 ms to avoid busy looping.
809 timespec sleep_time;
810 sleep_time.tv_sec = 0;
811 sleep_time.tv_nsec = 1000000;
812 nanosleep(&sleep_time, NULL);
813 }
814}
815
Yabin Cui1d4c7802015-02-02 19:14:05 -0800816static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800817 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800818 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800819
820 TestResult test_result = TEST_SUCCESS;
821 if (result != pid || WEXITSTATUS(exit_status) != 0) {
822 test_result = TEST_FAILED;
823 }
824 return test_result;
825}
826
Yabin Cui1d4c7802015-02-02 19:14:05 -0800827static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
828 int test_id = child_proc.test_id;
829 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
830 if (child_proc.timed_out) {
831 // The child process marked as timed_out has not exited, and we should kill it manually.
832 kill(child_proc.pid, SIGKILL);
833 WaitForOneChild(child_proc.pid);
834 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800835 close(child_proc.child_read_fd);
836
837 if (child_proc.timed_out) {
838 testcase.SetTestResult(test_id, TEST_TIMEOUT);
839 char buf[1024];
840 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
841 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800842 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800843
844 } else if (WIFSIGNALED(child_proc.exit_status)) {
845 // Record signal terminated test as failed.
846 testcase.SetTestResult(test_id, TEST_FAILED);
847 char buf[1024];
848 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
849 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800850 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800851
852 } else {
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800853 int exitcode = WEXITSTATUS(child_proc.exit_status);
854 testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
855 if (exitcode != 0) {
Yabin Cuia32fc862015-12-03 16:28:03 -0800856 char buf[1024];
857 snprintf(buf, sizeof(buf), "%s exited with exitcode %d.\n",
858 testcase.GetTestName(test_id).c_str(), exitcode);
859 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cuid4c9b9d2015-11-16 20:39:58 -0800860 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800861 }
862}
863
Yabin Cui294d1e22014-12-07 20:43:37 -0800864// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
865// makes deadlock to use fork in multi-thread.
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700866// Returns true if all tests run successfully, otherwise return false.
867static bool RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Christopher Ferris119cb552015-04-02 12:02:55 -0700868 int iteration_count, size_t job_count,
Yabin Cui657b1f92015-01-22 19:26:12 -0800869 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800870 // Stop default result printer to avoid environment setup/teardown information for each test.
871 testing::UnitTest::GetInstance()->listeners().Release(
872 testing::UnitTest::GetInstance()->listeners().default_result_printer());
873 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
874
Yabin Cui767fb1c2015-09-01 15:06:39 -0700875 if (!RegisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800876 exit(1);
877 }
878
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700879 bool all_tests_passed = true;
880
Christopher Ferris119cb552015-04-02 12:02:55 -0700881 for (size_t iteration = 1;
882 iteration_count < 0 || iteration <= static_cast<size_t>(iteration_count);
883 ++iteration) {
Elliott Hughes48de71e2016-10-28 10:04:44 -0700884 OnTestIterationStartPrint(testcase_list, iteration, iteration_count, job_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800885 int64_t iteration_start_time_ns = NanoTime();
886 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800887
Yabin Cuibe837362015-01-02 18:45:37 -0800888 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800889 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800890
Yabin Cuibe837362015-01-02 18:45:37 -0800891 // Next test to run is [next_testcase_id:next_test_id].
892 size_t next_testcase_id = 0;
893 size_t next_test_id = 0;
894
895 // Record how many tests are finished.
896 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
897 size_t finished_testcase_count = 0;
898
899 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800900 // run up to job_count child processes.
901 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
902 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
903 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
Yabin Cui767fb1c2015-09-01 15:06:39 -0700904 argc, argv);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800905 child_proc_list.push_back(child_proc);
906 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
907 next_test_id = 0;
908 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800909 }
910 }
911
912 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800913 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800914
915 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800916 auto it = child_proc_list.begin();
917 while (it != child_proc_list.end()) {
918 auto& child_proc = *it;
919 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800920 size_t testcase_id = child_proc.testcase_id;
921 size_t test_id = child_proc.test_id;
922 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800923
Yabin Cui1d4c7802015-02-02 19:14:05 -0800924 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800925 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800926
927 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
928 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800929 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700930 if (testcase.GetTestResult(test_id) != TEST_SUCCESS) {
931 all_tests_passed = false;
932 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800933
934 it = child_proc_list.erase(it);
935 } else {
936 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800937 }
938 }
939 }
940
Yabin Cui657b1f92015-01-22 19:26:12 -0800941 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
942 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
943 if (!xml_output_filename.empty()) {
944 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
945 elapsed_time_ns);
946 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800947 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800948
Yabin Cui767fb1c2015-09-01 15:06:39 -0700949 if (!UnregisterSignalHandler()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800950 exit(1);
951 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -0700952
953 return all_tests_passed;
Yabin Cui294d1e22014-12-07 20:43:37 -0800954}
955
Christopher Ferrisdaaaed12015-09-24 18:45:53 -0700956static size_t GetDefaultJobCount() {
Yabin Cuibe837362015-01-02 18:45:37 -0800957 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800958}
959
Yabin Cuiead08142015-02-04 20:53:56 -0800960static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
961 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
962 // test program via a valid path that contains at least one path separator.
963 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
964 // and execve() doesn't read environment variable PATH, so execve() will not success
965 // until we specify the absolute path or relative path of the test program directly.
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -0700966 if (strchr(args[0], '/') == nullptr) {
967 args[0] = strdup(g_executable_path.c_str());
Yabin Cuiead08142015-02-04 20:53:56 -0800968 }
969}
970
Yabin Cui11c43532015-01-28 14:28:14 -0800971static void AddGtestFilterSynonym(std::vector<char*>& args) {
972 // Support --gtest-filter as a synonym for --gtest_filter.
973 for (size_t i = 1; i < args.size(); ++i) {
974 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
975 args[i][7] = '_';
976 }
977 }
978}
979
Yabin Cui657b1f92015-01-22 19:26:12 -0800980struct IsolationTestOptions {
981 bool isolate;
982 size_t job_count;
983 int test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -0700984 int test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -0800985 std::string gtest_color;
986 bool gtest_print_time;
Christopher Ferris119cb552015-04-02 12:02:55 -0700987 int gtest_repeat;
Yabin Cui657b1f92015-01-22 19:26:12 -0800988 std::string gtest_output;
989};
990
991// 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 -0800992// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -0800993// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
994// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -0800995// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -0800996// args is used to pass in all command arguments, and pass out only the part of options for gtest.
997// options is used to pass out test options in isolation mode.
998// Return false if there is error in arguments.
999static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
1000 for (size_t i = 1; i < args.size(); ++i) {
1001 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001002 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -08001003 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001004 return true;
1005 }
1006 }
1007
Yabin Cuiead08142015-02-04 20:53:56 -08001008 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -08001009 AddGtestFilterSynonym(args);
1010
Yabin Cui657b1f92015-01-22 19:26:12 -08001011 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
1012 bool enable_selftest = false;
1013 for (size_t i = 1; i < args.size(); ++i) {
1014 if (strcmp(args[i], "--bionic-selftest") == 0) {
1015 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
1016 // Don't remove this option from arguments.
1017 enable_selftest = true;
1018 }
1019 }
1020 std::string gtest_filter_str;
1021 for (size_t i = args.size() - 1; i >= 1; --i) {
1022 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
1023 gtest_filter_str = std::string(args[i]);
1024 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -08001025 break;
1026 }
1027 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001028 if (enable_selftest == true) {
1029 args.push_back(strdup("--gtest_filter=bionic_selftest*"));
1030 } else {
1031 if (gtest_filter_str == "") {
1032 gtest_filter_str = "--gtest_filter=-bionic_selftest*";
1033 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -08001034 // Find if '-' for NEGATIVE_PATTERNS exists.
1035 if (gtest_filter_str.find(":-") != std::string::npos) {
1036 gtest_filter_str += ":bionic_selftest*";
1037 } else {
1038 gtest_filter_str += ":-bionic_selftest*";
1039 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001040 }
1041 args.push_back(strdup(gtest_filter_str.c_str()));
1042 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001043
Yabin Cui657b1f92015-01-22 19:26:12 -08001044 options.isolate = true;
1045 // Parse arguments that make us can't run in isolation mode.
1046 for (size_t i = 1; i < args.size(); ++i) {
1047 if (strcmp(args[i], "--no-isolate") == 0) {
1048 options.isolate = false;
1049 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
1050 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -08001051 }
1052 }
1053
Yabin Cui657b1f92015-01-22 19:26:12 -08001054 // Stop parsing if we will not run in isolation mode.
1055 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001056 return true;
1057 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001058
1059 // Init default isolation test options.
Christopher Ferrisdaaaed12015-09-24 18:45:53 -07001060 options.job_count = GetDefaultJobCount();
Yabin Cui657b1f92015-01-22 19:26:12 -08001061 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001062 options.test_slow_threshold_ms = DEFAULT_GLOBAL_TEST_RUN_SLOW_THRESHOLD_MS;
Yabin Cui657b1f92015-01-22 19:26:12 -08001063 options.gtest_color = testing::GTEST_FLAG(color);
1064 options.gtest_print_time = testing::GTEST_FLAG(print_time);
1065 options.gtest_repeat = testing::GTEST_FLAG(repeat);
1066 options.gtest_output = testing::GTEST_FLAG(output);
1067
1068 // Parse arguments speficied for isolation mode.
1069 for (size_t i = 1; i < args.size(); ++i) {
1070 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
1071 char* p = args[i] + strlen("-j");
1072 int count = 0;
1073 if (*p != '\0') {
1074 // Argument like -j5.
1075 count = atoi(p);
1076 } else if (args.size() > i + 1) {
1077 // Arguments like -j 5.
1078 count = atoi(args[i + 1]);
1079 ++i;
1080 }
1081 if (count <= 0) {
1082 fprintf(stderr, "invalid job count: %d\n", count);
1083 return false;
1084 }
1085 options.job_count = static_cast<size_t>(count);
1086 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
1087 int time_ms = atoi(args[i] + strlen("--deadline="));
1088 if (time_ms <= 0) {
1089 fprintf(stderr, "invalid deadline: %d\n", time_ms);
1090 return false;
1091 }
1092 options.test_deadline_ms = time_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001093 } else if (strncmp(args[i], "--slow-threshold=", strlen("--slow-threshold=")) == 0) {
1094 int time_ms = atoi(args[i] + strlen("--slow-threshold="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001095 if (time_ms <= 0) {
Elliott Hughesa456fae2016-08-31 13:30:14 -07001096 fprintf(stderr, "invalid slow test threshold: %d\n", time_ms);
Yabin Cui657b1f92015-01-22 19:26:12 -08001097 return false;
1098 }
Elliott Hughesa456fae2016-08-31 13:30:14 -07001099 options.test_slow_threshold_ms = time_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001100 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
1101 options.gtest_color = args[i] + strlen("--gtest_color=");
1102 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
1103 options.gtest_print_time = false;
1104 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
Christopher Ferris119cb552015-04-02 12:02:55 -07001105 // If the value of gtest_repeat is < 0, then it indicates the tests
1106 // should be repeated forever.
1107 options.gtest_repeat = atoi(args[i] + strlen("--gtest_repeat="));
Yabin Cui657b1f92015-01-22 19:26:12 -08001108 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
1109 args.erase(args.begin() + i);
1110 --i;
1111 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
1112 std::string output = args[i] + strlen("--gtest_output=");
1113 // generate output xml file path according to the strategy in gtest.
1114 bool success = true;
1115 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
1116 output = output.substr(strlen("xml:"));
1117 if (output.size() == 0) {
1118 success = false;
1119 }
1120 // Make absolute path.
1121 if (success && output[0] != '/') {
1122 char* cwd = getcwd(NULL, 0);
1123 if (cwd != NULL) {
1124 output = std::string(cwd) + "/" + output;
1125 free(cwd);
1126 } else {
1127 success = false;
1128 }
1129 }
1130 // Add file name if output is a directory.
1131 if (success && output.back() == '/') {
1132 output += "test_details.xml";
1133 }
1134 }
1135 if (success) {
1136 options.gtest_output = output;
1137 } else {
1138 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
1139 return false;
1140 }
1141
1142 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1143 args.erase(args.begin() + i);
1144 --i;
1145 }
1146 }
1147
1148 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1149 // As DeathTest will try to call execve(), this argument should always be added.
1150 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001151 return true;
1152}
1153
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001154static std::string get_proc_self_exe() {
1155 char path[PATH_MAX];
1156 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
1157 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
1158 perror("readlink");
1159 exit(1);
1160 }
1161
1162 return std::string(path, path_len);
1163}
1164
Dimitry Ivanov55437462016-07-20 15:33:07 -07001165int main(int argc, char** argv, char** envp) {
Dimitry Ivanov2ba1cf32016-05-17 13:29:37 -07001166 g_executable_path = get_proc_self_exe();
Dimitry Ivanov55437462016-07-20 15:33:07 -07001167 g_argc = argc;
1168 g_argv = argv;
1169 g_envp = envp;
Yabin Cuibe837362015-01-02 18:45:37 -08001170 std::vector<char*> arg_list;
1171 for (int i = 0; i < argc; ++i) {
1172 arg_list.push_back(argv[i]);
1173 }
Yabin Cuibe837362015-01-02 18:45:37 -08001174
Yabin Cui657b1f92015-01-22 19:26:12 -08001175 IsolationTestOptions options;
1176 if (PickOptions(arg_list, options) == false) {
1177 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001178 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001179
1180 if (options.isolate == true) {
1181 // Set global variables.
1182 global_test_run_deadline_ms = options.test_deadline_ms;
Elliott Hughesa456fae2016-08-31 13:30:14 -07001183 global_test_run_slow_threshold_ms = options.test_slow_threshold_ms;
Yabin Cui657b1f92015-01-22 19:26:12 -08001184 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1185 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1186 std::vector<TestCase> testcase_list;
1187
1188 argc = static_cast<int>(arg_list.size());
1189 arg_list.push_back(NULL);
1190 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1191 return 1;
1192 }
Yabin Cui64a9c4f2015-03-12 22:16:03 -07001193 bool all_test_passed = RunTestInSeparateProc(argc, arg_list.data(), testcase_list,
1194 options.gtest_repeat, options.job_count, options.gtest_output);
1195 return all_test_passed ? 0 : 1;
Yabin Cui657b1f92015-01-22 19:26:12 -08001196 } else {
1197 argc = static_cast<int>(arg_list.size());
1198 arg_list.push_back(NULL);
1199 testing::InitGoogleTest(&argc, arg_list.data());
1200 return RUN_ALL_TESTS();
1201 }
Yabin Cui294d1e22014-12-07 20:43:37 -08001202}
1203
1204//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001205// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001206
Yabin Cuibe837362015-01-02 18:45:37 -08001207TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001208 ASSERT_EQ(1, 1);
1209}
1210
Yabin Cuibe837362015-01-02 18:45:37 -08001211TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001212 ASSERT_EQ(0, 1);
1213}
1214
Yabin Cuibe837362015-01-02 18:45:37 -08001215TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001216 sleep(4);
1217}
1218
Yabin Cuibe837362015-01-02 18:45:37 -08001219TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001220 while (1) {}
1221}
Yabin Cuibe837362015-01-02 18:45:37 -08001222
1223TEST(bionic_selftest, test_signal_SEGV_terminated) {
1224 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1225 *p = 3;
1226}
Yabin Cui657b1f92015-01-22 19:26:12 -08001227
Yabin Cui767fb1c2015-09-01 15:06:39 -07001228class bionic_selftest_DeathTest : public ::testing::Test {
1229 protected:
1230 virtual void SetUp() {
1231 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1232 }
1233};
Yabin Cui657b1f92015-01-22 19:26:12 -08001234
1235static void deathtest_helper_success() {
1236 ASSERT_EQ(1, 1);
1237 exit(0);
1238}
1239
1240TEST_F(bionic_selftest_DeathTest, success) {
1241 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1242}
1243
1244static void deathtest_helper_fail() {
1245 ASSERT_EQ(1, 0);
1246}
1247
1248TEST_F(bionic_selftest_DeathTest, fail) {
1249 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1250}