blob: 664e4a1d3f3f215ab595273515e531af3970c6c7 [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>
29#include <time.h>
30#include <unistd.h>
31
32#include <string>
33#include <tuple>
34#include <utility>
35#include <vector>
36
Yabin Cui657b1f92015-01-22 19:26:12 -080037#include "BionicDeathTest.h" // For selftest.
38
Yabin Cui294d1e22014-12-07 20:43:37 -080039namespace testing {
40namespace internal {
41
42// Reuse of testing::internal::ColoredPrintf in gtest.
43enum GTestColor {
44 COLOR_DEFAULT,
45 COLOR_RED,
46 COLOR_GREEN,
47 COLOR_YELLOW
48};
49
50void ColoredPrintf(GTestColor color, const char* fmt, ...);
51
Yabin Cuibe837362015-01-02 18:45:37 -080052} // namespace internal
53} // namespace testing
Yabin Cui294d1e22014-12-07 20:43:37 -080054
55using testing::internal::GTestColor;
56using testing::internal::COLOR_DEFAULT;
57using testing::internal::COLOR_RED;
58using testing::internal::COLOR_GREEN;
59using testing::internal::COLOR_YELLOW;
60using testing::internal::ColoredPrintf;
61
Yabin Cui657b1f92015-01-22 19:26:12 -080062constexpr int DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS = 60000;
63constexpr int DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS = 2000;
Yabin Cui294d1e22014-12-07 20:43:37 -080064
65// The time each test can run before killed for the reason of timeout.
66// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080067static int global_test_run_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080068
69// The time each test can run before be warned for too much running time.
70// It takes effect only with --isolate option.
Yabin Cui657b1f92015-01-22 19:26:12 -080071static int global_test_run_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
Yabin Cui294d1e22014-12-07 20:43:37 -080072
73// Return deadline duration for a test, in ms.
74static int GetDeadlineInfo(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -080075 return global_test_run_deadline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -080076}
77
78// Return warnline duration for a test, in ms.
79static int GetWarnlineInfo(const std::string& /*test_name*/) {
Yabin Cui657b1f92015-01-22 19:26:12 -080080 return global_test_run_warnline_ms;
Yabin Cui294d1e22014-12-07 20:43:37 -080081}
82
Yabin Cuibe837362015-01-02 18:45:37 -080083static void PrintHelpInfo() {
84 printf("Bionic Unit Test Options:\n"
Yabin Cui657b1f92015-01-22 19:26:12 -080085 " -j [JOB_COUNT] or -j[JOB_COUNT]\n"
Yabin Cuibe837362015-01-02 18:45:37 -080086 " Run up to JOB_COUNT tests in parallel.\n"
87 " Use isolation mode, Run each test in a separate process.\n"
88 " If JOB_COUNT is not given, it is set to the count of available processors.\n"
89 " --no-isolate\n"
90 " Don't use isolation mode, run all tests in a single process.\n"
91 " --deadline=[TIME_IN_MS]\n"
92 " Run each test in no longer than [TIME_IN_MS] time.\n"
93 " It takes effect only in isolation mode. Deafult deadline is 60000 ms.\n"
94 " --warnline=[TIME_IN_MS]\n"
95 " Test running longer than [TIME_IN_MS] will be warned.\n"
96 " It takes effect only in isolation mode. Default warnline is 2000 ms.\n"
Yabin Cui11c43532015-01-28 14:28:14 -080097 " --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
98 " Used as a synonym for --gtest_filter option in gtest.\n"
Yabin Cui1d4c7802015-02-02 19:14:05 -080099 "Default bionic unit test option is -j.\n"
100 "In isolation mode, you can send SIGQUIT to the parent process to show current\n"
101 "running tests, or send SIGINT to the parent process to stop testing and\n"
102 "clean up current running tests.\n"
Yabin Cuibe837362015-01-02 18:45:37 -0800103 "\n");
104}
105
Yabin Cui294d1e22014-12-07 20:43:37 -0800106enum TestResult {
107 TEST_SUCCESS = 0,
108 TEST_FAILED,
109 TEST_TIMEOUT
110};
111
Yabin Cui657b1f92015-01-22 19:26:12 -0800112class Test {
113 public:
114 Test() {} // For std::vector<Test>.
115 explicit Test(const char* name) : name_(name) {}
116
117 const std::string& GetName() const { return name_; }
118
119 void SetResult(TestResult result) { result_ = result; }
120
121 TestResult GetResult() const { return result_; }
122
123 void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
124
125 int64_t GetTestTime() const { return elapsed_time_ns_; }
126
Yabin Cuiea9c9332015-02-24 14:39:19 -0800127 void AppendTestOutput(const std::string& s) { output_ += s; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800128
Yabin Cuiea9c9332015-02-24 14:39:19 -0800129 const std::string& GetTestOutput() const { return output_; }
Yabin Cui657b1f92015-01-22 19:26:12 -0800130
131 private:
132 const std::string name_;
133 TestResult result_;
134 int64_t elapsed_time_ns_;
Yabin Cuiea9c9332015-02-24 14:39:19 -0800135 std::string output_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800136};
137
Yabin Cui294d1e22014-12-07 20:43:37 -0800138class TestCase {
139 public:
140 TestCase() {} // For std::vector<TestCase>.
141 explicit TestCase(const char* name) : name_(name) {}
142
143 const std::string& GetName() const { return name_; }
144
Yabin Cui657b1f92015-01-22 19:26:12 -0800145 void AppendTest(const char* test_name) {
146 test_list_.push_back(Test(test_name));
Yabin Cui294d1e22014-12-07 20:43:37 -0800147 }
148
Yabin Cuibe837362015-01-02 18:45:37 -0800149 size_t TestCount() const { return test_list_.size(); }
Yabin Cui294d1e22014-12-07 20:43:37 -0800150
Yabin Cuibe837362015-01-02 18:45:37 -0800151 std::string GetTestName(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800152 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800153 return name_ + "." + test_list_[test_id].GetName();
154 }
155
156 Test& GetTest(size_t test_id) {
157 VerifyTestId(test_id);
158 return test_list_[test_id];
159 }
160
161 const Test& GetTest(size_t test_id) const {
162 VerifyTestId(test_id);
163 return test_list_[test_id];
Yabin Cui294d1e22014-12-07 20:43:37 -0800164 }
165
Yabin Cuibe837362015-01-02 18:45:37 -0800166 void SetTestResult(size_t test_id, TestResult result) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800167 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800168 test_list_[test_id].SetResult(result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800169 }
170
Yabin Cuibe837362015-01-02 18:45:37 -0800171 TestResult GetTestResult(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800172 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800173 return test_list_[test_id].GetResult();
Yabin Cui294d1e22014-12-07 20:43:37 -0800174 }
175
Yabin Cui657b1f92015-01-22 19:26:12 -0800176 void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800177 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800178 test_list_[test_id].SetTestTime(elapsed_time_ns);
Yabin Cui294d1e22014-12-07 20:43:37 -0800179 }
180
Yabin Cuibe837362015-01-02 18:45:37 -0800181 int64_t GetTestTime(size_t test_id) const {
Yabin Cui294d1e22014-12-07 20:43:37 -0800182 VerifyTestId(test_id);
Yabin Cui657b1f92015-01-22 19:26:12 -0800183 return test_list_[test_id].GetTestTime();
Yabin Cui294d1e22014-12-07 20:43:37 -0800184 }
185
186 private:
Yabin Cuibe837362015-01-02 18:45:37 -0800187 void VerifyTestId(size_t test_id) const {
188 if(test_id >= test_list_.size()) {
189 fprintf(stderr, "test_id %zu out of range [0, %zu)\n", test_id, test_list_.size());
Yabin Cui294d1e22014-12-07 20:43:37 -0800190 exit(1);
191 }
192 }
193
194 private:
195 const std::string name_;
Yabin Cui657b1f92015-01-22 19:26:12 -0800196 std::vector<Test> test_list_;
Yabin Cui294d1e22014-12-07 20:43:37 -0800197};
198
Yabin Cui294d1e22014-12-07 20:43:37 -0800199class TestResultPrinter : public testing::EmptyTestEventListener {
200 public:
201 TestResultPrinter() : pinfo_(NULL) {}
202 virtual void OnTestStart(const testing::TestInfo& test_info) {
203 pinfo_ = &test_info; // Record test_info for use in OnTestPartResult.
204 }
205 virtual void OnTestPartResult(const testing::TestPartResult& result);
Yabin Cui294d1e22014-12-07 20:43:37 -0800206
207 private:
208 const testing::TestInfo* pinfo_;
209};
210
211// Called after an assertion failure.
212void TestResultPrinter::OnTestPartResult(const testing::TestPartResult& result) {
213 // If the test part succeeded, we don't need to do anything.
214 if (result.type() == testing::TestPartResult::kSuccess)
215 return;
216
217 // Print failure message from the assertion (e.g. expected this and got that).
Yabin Cuiea9c9332015-02-24 14:39:19 -0800218 printf("%s:(%d) Failure in test %s.%s\n%s\n", result.file_name(), result.line_number(),
219 pinfo_->test_case_name(), pinfo_->name(), result.message());
220 fflush(stdout);
Yabin Cui294d1e22014-12-07 20:43:37 -0800221}
222
Yabin Cui294d1e22014-12-07 20:43:37 -0800223static int64_t NanoTime() {
224 struct timespec t;
225 t.tv_sec = t.tv_nsec = 0;
226 clock_gettime(CLOCK_MONOTONIC, &t);
227 return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
228}
229
230static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
231 std::string command;
232 for (int i = 0; i < argc; ++i) {
233 command += argv[i];
234 command += " ";
235 }
236 command += "--gtest_list_tests";
237 FILE* fp = popen(command.c_str(), "r");
238 if (fp == NULL) {
239 perror("popen");
240 return false;
241 }
242
243 char buf[200];
244 while (fgets(buf, sizeof(buf), fp) != NULL) {
245 char* p = buf;
246
247 while (*p != '\0' && isspace(*p)) {
248 ++p;
249 }
250 if (*p == '\0') continue;
251 char* start = p;
252 while (*p != '\0' && !isspace(*p)) {
253 ++p;
254 }
255 char* end = p;
256 while (*p != '\0' && isspace(*p)) {
257 ++p;
258 }
259 if (*p != '\0') {
260 // This is not we want, gtest must meet with some error when parsing the arguments.
261 fprintf(stderr, "argument error, check with --help\n");
262 return false;
263 }
264 *end = '\0';
265 if (*(end - 1) == '.') {
266 *(end - 1) = '\0';
267 testcase_list.push_back(TestCase(start));
268 } else {
269 testcase_list.back().AppendTest(start);
270 }
271 }
272 int result = pclose(fp);
273 return (result != -1 && WEXITSTATUS(result) == 0);
274}
275
Yabin Cui294d1e22014-12-07 20:43:37 -0800276// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
277// PrettyUnitTestResultPrinter. The reason for copy is that PrettyUnitTestResultPrinter
278// is defined and used in gtest.cc, which is hard to reuse.
Yabin Cuibe837362015-01-02 18:45:37 -0800279static void OnTestIterationStartPrint(const std::vector<TestCase>& testcase_list, size_t iteration,
280 size_t iteration_count) {
281 if (iteration_count > 1) {
282 printf("\nRepeating all tests (iteration %zu) . . .\n\n", iteration);
Yabin Cui294d1e22014-12-07 20:43:37 -0800283 }
284 ColoredPrintf(COLOR_GREEN, "[==========] ");
285
Yabin Cuibe837362015-01-02 18:45:37 -0800286 size_t testcase_count = testcase_list.size();
287 size_t test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800288 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800289 test_count += testcase.TestCount();
Yabin Cui294d1e22014-12-07 20:43:37 -0800290 }
291
Yabin Cuibe837362015-01-02 18:45:37 -0800292 printf("Running %zu %s from %zu %s.\n",
293 test_count, (test_count == 1) ? "test" : "tests",
294 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800295 fflush(stdout);
296}
297
Yabin Cui657b1f92015-01-22 19:26:12 -0800298static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
299 TestResult result = testcase.GetTestResult(test_id);
300 if (result == TEST_SUCCESS) {
301 ColoredPrintf(COLOR_GREEN, "[ OK ] ");
302 } else if (result == TEST_FAILED) {
303 ColoredPrintf(COLOR_RED, "[ FAILED ] ");
304 } else if (result == TEST_TIMEOUT) {
305 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
306 }
Yabin Cuibe837362015-01-02 18:45:37 -0800307
Yabin Cui657b1f92015-01-22 19:26:12 -0800308 printf("%s", testcase.GetTestName(test_id).c_str());
309 if (testing::GTEST_FLAG(print_time)) {
310 printf(" (%" PRId64 " ms)\n", testcase.GetTestTime(test_id) / 1000000);
311 } else {
312 printf("\n");
313 }
314
Yabin Cuiea9c9332015-02-24 14:39:19 -0800315 const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
316 printf("%s", test_output.c_str());
Yabin Cui294d1e22014-12-07 20:43:37 -0800317 fflush(stdout);
318}
319
Yabin Cuibe837362015-01-02 18:45:37 -0800320static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
Yabin Cui657b1f92015-01-22 19:26:12 -0800321 int64_t elapsed_time_ns) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800322
323 std::vector<std::string> fail_test_name_list;
324 std::vector<std::pair<std::string, int64_t>> timeout_test_list;
325
326 // For tests run exceed warnline but not timeout.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800327 std::vector<std::tuple<std::string, int64_t, int>> slow_test_list;
Yabin Cuibe837362015-01-02 18:45:37 -0800328 size_t testcase_count = testcase_list.size();
329 size_t test_count = 0;
330 size_t success_test_count = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800331
332 for (const auto& testcase : testcase_list) {
Yabin Cuibe837362015-01-02 18:45:37 -0800333 test_count += testcase.TestCount();
334 for (size_t i = 0; i < testcase.TestCount(); ++i) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800335 TestResult result = testcase.GetTestResult(i);
336 if (result == TEST_SUCCESS) {
Yabin Cuibe837362015-01-02 18:45:37 -0800337 ++success_test_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800338 } else if (result == TEST_FAILED) {
339 fail_test_name_list.push_back(testcase.GetTestName(i));
340 } else if (result == TEST_TIMEOUT) {
341 timeout_test_list.push_back(std::make_pair(testcase.GetTestName(i),
342 testcase.GetTestTime(i)));
343 }
344 if (result != TEST_TIMEOUT &&
345 testcase.GetTestTime(i) / 1000000 >= GetWarnlineInfo(testcase.GetTestName(i))) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800346 slow_test_list.push_back(std::make_tuple(testcase.GetTestName(i),
347 testcase.GetTestTime(i),
348 GetWarnlineInfo(testcase.GetTestName(i))));
Yabin Cui294d1e22014-12-07 20:43:37 -0800349 }
350 }
351 }
352
Yabin Cui294d1e22014-12-07 20:43:37 -0800353 ColoredPrintf(COLOR_GREEN, "[==========] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800354 printf("%zu %s from %zu %s ran.", test_count, (test_count == 1) ? "test" : "tests",
355 testcase_count, (testcase_count == 1) ? "test case" : "test cases");
Yabin Cui294d1e22014-12-07 20:43:37 -0800356 if (testing::GTEST_FLAG(print_time)) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800357 printf(" (%" PRId64 " ms total)", elapsed_time_ns / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800358 }
359 printf("\n");
Yabin Cui4a82ede2015-01-26 17:19:37 -0800360 ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800361 printf("%zu %s.\n", success_test_count, (success_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800362
363 // Print tests failed.
Yabin Cuibe837362015-01-02 18:45:37 -0800364 size_t fail_test_count = fail_test_name_list.size();
365 if (fail_test_count > 0) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800366 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800367 printf("%zu %s, listed below:\n", fail_test_count, (fail_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800368 for (const auto& name : fail_test_name_list) {
Yabin Cui4a82ede2015-01-26 17:19:37 -0800369 ColoredPrintf(COLOR_RED, "[ FAIL ] ");
Yabin Cui294d1e22014-12-07 20:43:37 -0800370 printf("%s\n", name.c_str());
371 }
372 }
373
374 // Print tests run timeout.
Yabin Cuibe837362015-01-02 18:45:37 -0800375 size_t timeout_test_count = timeout_test_list.size();
376 if (timeout_test_count > 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800377 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cuibe837362015-01-02 18:45:37 -0800378 printf("%zu %s, listed below:\n", timeout_test_count, (timeout_test_count == 1) ? "test" : "tests");
Yabin Cui294d1e22014-12-07 20:43:37 -0800379 for (const auto& timeout_pair : timeout_test_list) {
380 ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
Yabin Cui657b1f92015-01-22 19:26:12 -0800381 printf("%s (stopped at %" PRId64 " ms)\n", timeout_pair.first.c_str(),
382 timeout_pair.second / 1000000);
Yabin Cui294d1e22014-12-07 20:43:37 -0800383 }
384 }
385
386 // Print tests run exceed warnline.
Yabin Cui4a82ede2015-01-26 17:19:37 -0800387 size_t slow_test_count = slow_test_list.size();
388 if (slow_test_count > 0) {
389 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
390 printf("%zu %s, listed below:\n", slow_test_count, (slow_test_count == 1) ? "test" : "tests");
391 for (const auto& slow_tuple : slow_test_list) {
392 ColoredPrintf(COLOR_YELLOW, "[ SLOW ] ");
393 printf("%s (%" PRId64 " ms, exceed warnline %d ms)\n", std::get<0>(slow_tuple).c_str(),
394 std::get<1>(slow_tuple) / 1000000, std::get<2>(slow_tuple));
Yabin Cui294d1e22014-12-07 20:43:37 -0800395 }
396 }
397
Yabin Cuibe837362015-01-02 18:45:37 -0800398 if (fail_test_count > 0) {
399 printf("\n%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800400 }
Yabin Cuibe837362015-01-02 18:45:37 -0800401 if (timeout_test_count > 0) {
402 printf("%2zu TIMEOUT %s\n", timeout_test_count, (timeout_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800403 }
Yabin Cui4a82ede2015-01-26 17:19:37 -0800404 if (slow_test_count > 0) {
405 printf("%2zu SLOW %s\n", slow_test_count, (slow_test_count == 1) ? "TEST" : "TESTS");
Yabin Cui294d1e22014-12-07 20:43:37 -0800406 }
407 fflush(stdout);
408}
409
Yabin Cui657b1f92015-01-22 19:26:12 -0800410// Output xml file when --gtest_output is used, write this function as we can't reuse
411// gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
412// defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
413// the parent process, we don't have gtest classes which are needed by XmlUnitTestResultPrinter.
414void OnTestIterationEndXmlPrint(const std::string& xml_output_filename,
415 const std::vector<TestCase>& testcase_list,
416 time_t epoch_iteration_start_time,
417 int64_t elapsed_time_ns) {
418 FILE* fp = fopen(xml_output_filename.c_str(), "w");
419 if (fp == NULL) {
420 fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
421 exit(1);
422 }
423
424 size_t total_test_count = 0;
425 size_t total_failed_count = 0;
426 std::vector<size_t> failed_count_list(testcase_list.size(), 0);
427 std::vector<int64_t> elapsed_time_list(testcase_list.size(), 0);
428 for (size_t i = 0; i < testcase_list.size(); ++i) {
429 auto& testcase = testcase_list[i];
430 total_test_count += testcase.TestCount();
431 for (size_t j = 0; j < testcase.TestCount(); ++j) {
432 if (testcase.GetTestResult(j) != TEST_SUCCESS) {
433 ++failed_count_list[i];
434 }
435 elapsed_time_list[i] += testcase.GetTestTime(j);
436 }
437 total_failed_count += failed_count_list[i];
438 }
439
440 const tm* time_struct = localtime(&epoch_iteration_start_time);
441 char timestamp[40];
442 snprintf(timestamp, sizeof(timestamp), "%4d-%02d-%02dT%02d:%02d:%02d",
443 time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
444 time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
445
446 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
447 fprintf(fp, "<testsuites tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
448 total_test_count, total_failed_count);
449 fprintf(fp, " timestamp=\"%s\" time=\"%.3lf\" name=\"AllTests\">\n", timestamp, elapsed_time_ns / 1e9);
450 for (size_t i = 0; i < testcase_list.size(); ++i) {
451 auto& testcase = testcase_list[i];
452 fprintf(fp, " <testsuite name=\"%s\" tests=\"%zu\" failures=\"%zu\" disabled=\"0\" errors=\"0\"",
453 testcase.GetName().c_str(), testcase.TestCount(), failed_count_list[i]);
454 fprintf(fp, " time=\"%.3lf\">\n", elapsed_time_list[i] / 1e9);
455
456 for (size_t j = 0; j < testcase.TestCount(); ++j) {
457 fprintf(fp, " <testcase name=\"%s\" status=\"run\" time=\"%.3lf\" classname=\"%s\"",
458 testcase.GetTest(j).GetName().c_str(), testcase.GetTestTime(j) / 1e9,
459 testcase.GetName().c_str());
460 if (testcase.GetTestResult(j) == TEST_SUCCESS) {
461 fputs(" />\n", fp);
462 } else {
463 fputs(">\n", fp);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800464 const std::string& test_output = testcase.GetTest(j).GetTestOutput();
465 fprintf(fp, " <failure message=\"%s\" type=\"\">\n", test_output.c_str());
Yabin Cui657b1f92015-01-22 19:26:12 -0800466 fputs(" </failure>\n", fp);
467 fputs(" </testcase>\n", fp);
468 }
469 }
470
471 fputs(" </testsuite>\n", fp);
472 }
473 fputs("</testsuites>\n", fp);
474 fclose(fp);
475}
476
Yabin Cui1d4c7802015-02-02 19:14:05 -0800477struct ChildProcInfo {
478 pid_t pid;
479 int64_t start_time_ns;
480 int64_t end_time_ns;
481 int64_t deadline_end_time_ns; // The time when the test is thought of as timeout.
482 size_t testcase_id, test_id;
483 bool finished;
484 bool timed_out;
485 int exit_status;
486 int child_read_fd; // File descriptor to read child test failure info.
487};
488
Yabin Cui294d1e22014-12-07 20:43:37 -0800489// Forked Child process, run the single test.
490static void ChildProcessFn(int argc, char** argv, const std::string& test_name) {
Yabin Cui657b1f92015-01-22 19:26:12 -0800491 char** new_argv = new char*[argc + 2];
Yabin Cui294d1e22014-12-07 20:43:37 -0800492 memcpy(new_argv, argv, sizeof(char*) * argc);
493
494 char* filter_arg = new char [test_name.size() + 20];
495 strcpy(filter_arg, "--gtest_filter=");
496 strcat(filter_arg, test_name.c_str());
497 new_argv[argc] = filter_arg;
Yabin Cui657b1f92015-01-22 19:26:12 -0800498 new_argv[argc + 1] = NULL;
Yabin Cui294d1e22014-12-07 20:43:37 -0800499
500 int new_argc = argc + 1;
501 testing::InitGoogleTest(&new_argc, new_argv);
502 int result = RUN_ALL_TESTS();
503 exit(result);
504}
505
Yabin Cui1d4c7802015-02-02 19:14:05 -0800506static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
507 sigset_t sigmask, int argc, char** argv) {
508 int pipefd[2];
509 int ret = pipe2(pipefd, O_NONBLOCK);
510 if (ret == -1) {
511 perror("pipe2 in RunTestInSeparateProc");
512 exit(1);
513 }
514 pid_t pid = fork();
515 if (pid == -1) {
516 perror("fork in RunTestInSeparateProc");
517 exit(1);
518 } else if (pid == 0) {
519 // In child process, run a single test.
520 close(pipefd[0]);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800521 close(STDOUT_FILENO);
522 close(STDERR_FILENO);
523 dup2(pipefd[1], STDOUT_FILENO);
524 dup2(pipefd[1], STDERR_FILENO);
Yabin Cui294d1e22014-12-07 20:43:37 -0800525
Yabin Cui1d4c7802015-02-02 19:14:05 -0800526 if (sigprocmask(SIG_SETMASK, &sigmask, NULL) == -1) {
527 perror("sigprocmask SIG_SETMASK");
528 exit(1);
529 }
530 ChildProcessFn(argc, argv, test_name);
531 // Unreachable.
532 }
533 // In parent process, initialize child process info.
534 close(pipefd[1]);
535 ChildProcInfo child_proc;
536 child_proc.child_read_fd = pipefd[0];
537 child_proc.pid = pid;
538 child_proc.start_time_ns = NanoTime();
539 child_proc.deadline_end_time_ns = child_proc.start_time_ns + GetDeadlineInfo(test_name) * 1000000LL;
540 child_proc.testcase_id = testcase_id;
541 child_proc.test_id = test_id;
542 child_proc.finished = false;
543 return child_proc;
544}
Yabin Cui294d1e22014-12-07 20:43:37 -0800545
Yabin Cui1d4c7802015-02-02 19:14:05 -0800546static void HandleSignals(std::vector<TestCase>& testcase_list,
547 std::vector<ChildProcInfo>& child_proc_list) {
548 sigset_t waiting_mask;
549 sigemptyset(&waiting_mask);
550 sigaddset(&waiting_mask, SIGINT);
551 sigaddset(&waiting_mask, SIGQUIT);
552 timespec timeout;
553 timeout.tv_sec = timeout.tv_nsec = 0;
Yabin Cui294d1e22014-12-07 20:43:37 -0800554 while (true) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800555 int signo = TEMP_FAILURE_RETRY(sigtimedwait(&waiting_mask, NULL, &timeout));
556 if (signo == -1) {
557 if (errno == EAGAIN) {
558 return; // Timeout, no pending signals.
559 }
560 perror("sigtimedwait");
561 exit(1);
562 } else if (signo == SIGQUIT) {
563 // Print current running tests.
564 printf("List of current running tests:\n");
565 for (auto& child_proc : child_proc_list) {
566 if (child_proc.pid != 0) {
567 std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
568 int64_t current_time_ns = NanoTime();
569 int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
570 printf(" %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
571 }
572 }
573 } else if (signo == SIGINT) {
574 // Kill current running tests.
575 for (auto& child_proc : child_proc_list) {
576 if (child_proc.pid != 0) {
577 // Send SIGKILL to ensure the child process can be killed unconditionally.
578 kill(child_proc.pid, SIGKILL);
579 }
580 }
581 // SIGINT kills the parent process as well.
582 exit(1);
583 }
584 }
585}
586
587static bool CheckChildProcExit(pid_t exit_pid, int exit_status,
588 std::vector<ChildProcInfo>& child_proc_list) {
589 for (size_t i = 0; i < child_proc_list.size(); ++i) {
590 if (child_proc_list[i].pid == exit_pid) {
591 child_proc_list[i].finished = true;
592 child_proc_list[i].timed_out = false;
593 child_proc_list[i].exit_status = exit_status;
594 child_proc_list[i].end_time_ns = NanoTime();
595 return true;
596 }
597 }
598 return false;
599}
600
601static size_t CheckChildProcTimeout(std::vector<ChildProcInfo>& child_proc_list) {
602 int64_t current_time_ns = NanoTime();
603 size_t timeout_child_count = 0;
604 for (size_t i = 0; i < child_proc_list.size(); ++i) {
605 if (child_proc_list[i].deadline_end_time_ns <= current_time_ns) {
606 child_proc_list[i].finished = true;
607 child_proc_list[i].timed_out = true;
608 child_proc_list[i].end_time_ns = current_time_ns;
609 ++timeout_child_count;
610 }
611 }
612 return timeout_child_count;
613}
614
615static void WaitChildProcs(std::vector<TestCase>& testcase_list,
616 std::vector<ChildProcInfo>& child_proc_list) {
617 size_t finished_child_count = 0;
618 while (true) {
619 int status;
620 pid_t result;
621 while ((result = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
622 if (CheckChildProcExit(result, status, child_proc_list)) {
623 ++finished_child_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800624 }
625 }
626
627 if (result == -1) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800628 if (errno == ECHILD) {
629 // This happens when we have no running child processes.
630 return;
631 } else {
632 perror("waitpid");
633 exit(1);
634 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800635 } else if (result == 0) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800636 finished_child_count += CheckChildProcTimeout(child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800637 }
638
Yabin Cui1d4c7802015-02-02 19:14:05 -0800639 if (finished_child_count > 0) {
640 return;
641 }
642
643 HandleSignals(testcase_list, child_proc_list);
644
Yabin Cui294d1e22014-12-07 20:43:37 -0800645 // sleep 1 ms to avoid busy looping.
646 timespec sleep_time;
647 sleep_time.tv_sec = 0;
648 sleep_time.tv_nsec = 1000000;
649 nanosleep(&sleep_time, NULL);
650 }
651}
652
Yabin Cui1d4c7802015-02-02 19:14:05 -0800653static TestResult WaitForOneChild(pid_t pid) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800654 int exit_status;
Yabin Cui1d4c7802015-02-02 19:14:05 -0800655 pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &exit_status, 0));
Yabin Cui294d1e22014-12-07 20:43:37 -0800656
657 TestResult test_result = TEST_SUCCESS;
658 if (result != pid || WEXITSTATUS(exit_status) != 0) {
659 test_result = TEST_FAILED;
660 }
661 return test_result;
662}
663
Yabin Cui1d4c7802015-02-02 19:14:05 -0800664static void CollectChildTestResult(const ChildProcInfo& child_proc, TestCase& testcase) {
665 int test_id = child_proc.test_id;
666 testcase.SetTestTime(test_id, child_proc.end_time_ns - child_proc.start_time_ns);
667 if (child_proc.timed_out) {
668 // The child process marked as timed_out has not exited, and we should kill it manually.
669 kill(child_proc.pid, SIGKILL);
670 WaitForOneChild(child_proc.pid);
671 }
672
673 while (true) {
674 char buf[1024];
675 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
676 if (bytes_read > 0) {
677 buf[bytes_read] = '\0';
Yabin Cuiea9c9332015-02-24 14:39:19 -0800678 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800679 } else if (bytes_read == 0) {
680 break; // Read end.
681 } else {
682 if (errno == EAGAIN) {
683 // No data is available. This rarely happens, only when the child process created other
684 // processes which have not exited so far. But the child process has already exited or
685 // been killed, so the test has finished, and we shouldn't wait further.
686 break;
687 }
688 perror("read child_read_fd in RunTestInSeparateProc");
689 exit(1);
690 }
691 }
692 close(child_proc.child_read_fd);
693
694 if (child_proc.timed_out) {
695 testcase.SetTestResult(test_id, TEST_TIMEOUT);
696 char buf[1024];
697 snprintf(buf, sizeof(buf), "%s killed because of timeout at %" PRId64 " ms.\n",
698 testcase.GetTestName(test_id).c_str(), testcase.GetTestTime(test_id) / 1000000);
Yabin Cuiea9c9332015-02-24 14:39:19 -0800699 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800700
701 } else if (WIFSIGNALED(child_proc.exit_status)) {
702 // Record signal terminated test as failed.
703 testcase.SetTestResult(test_id, TEST_FAILED);
704 char buf[1024];
705 snprintf(buf, sizeof(buf), "%s terminated by signal: %s.\n",
706 testcase.GetTestName(test_id).c_str(), strsignal(WTERMSIG(child_proc.exit_status)));
Yabin Cuiea9c9332015-02-24 14:39:19 -0800707 testcase.GetTest(test_id).AppendTestOutput(buf);
Yabin Cui1d4c7802015-02-02 19:14:05 -0800708
709 } else {
710 testcase.SetTestResult(test_id, WEXITSTATUS(child_proc.exit_status) == 0 ?
711 TEST_SUCCESS : TEST_FAILED);
712 }
713}
714
Yabin Cui294d1e22014-12-07 20:43:37 -0800715// We choose to use multi-fork and multi-wait here instead of multi-thread, because it always
716// makes deadlock to use fork in multi-thread.
717static void RunTestInSeparateProc(int argc, char** argv, std::vector<TestCase>& testcase_list,
Yabin Cui657b1f92015-01-22 19:26:12 -0800718 size_t iteration_count, size_t job_count,
719 const std::string& xml_output_filename) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800720 // Stop default result printer to avoid environment setup/teardown information for each test.
721 testing::UnitTest::GetInstance()->listeners().Release(
722 testing::UnitTest::GetInstance()->listeners().default_result_printer());
723 testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
724
Yabin Cui1d4c7802015-02-02 19:14:05 -0800725 // Signals are blocked here as we want to handle them in HandleSignals() later.
726 sigset_t block_mask, orig_mask;
727 sigemptyset(&block_mask);
728 sigaddset(&block_mask, SIGINT);
729 sigaddset(&block_mask, SIGQUIT);
730 if (sigprocmask(SIG_BLOCK, &block_mask, &orig_mask) == -1) {
731 perror("sigprocmask SIG_BLOCK");
732 exit(1);
733 }
734
Yabin Cuibe837362015-01-02 18:45:37 -0800735 for (size_t iteration = 1; iteration <= iteration_count; ++iteration) {
736 OnTestIterationStartPrint(testcase_list, iteration, iteration_count);
Yabin Cui657b1f92015-01-22 19:26:12 -0800737 int64_t iteration_start_time_ns = NanoTime();
738 time_t epoch_iteration_start_time = time(NULL);
Yabin Cui294d1e22014-12-07 20:43:37 -0800739
Yabin Cuibe837362015-01-02 18:45:37 -0800740 // Run up to job_count tests in parallel, each test in a child process.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800741 std::vector<ChildProcInfo> child_proc_list;
Yabin Cui294d1e22014-12-07 20:43:37 -0800742
Yabin Cuibe837362015-01-02 18:45:37 -0800743 // Next test to run is [next_testcase_id:next_test_id].
744 size_t next_testcase_id = 0;
745 size_t next_test_id = 0;
746
747 // Record how many tests are finished.
748 std::vector<size_t> finished_test_count_list(testcase_list.size(), 0);
749 size_t finished_testcase_count = 0;
750
751 while (finished_testcase_count < testcase_list.size()) {
Yabin Cui1d4c7802015-02-02 19:14:05 -0800752 // run up to job_count child processes.
753 while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
754 std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
755 ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
756 orig_mask, argc, argv);
757 child_proc_list.push_back(child_proc);
758 if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
759 next_test_id = 0;
760 ++next_testcase_id;
Yabin Cui294d1e22014-12-07 20:43:37 -0800761 }
762 }
763
764 // Wait for any child proc finish or timeout.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800765 WaitChildProcs(testcase_list, child_proc_list);
Yabin Cui294d1e22014-12-07 20:43:37 -0800766
767 // Collect result.
Yabin Cui1d4c7802015-02-02 19:14:05 -0800768 auto it = child_proc_list.begin();
769 while (it != child_proc_list.end()) {
770 auto& child_proc = *it;
771 if (child_proc.finished == true) {
Yabin Cuibe837362015-01-02 18:45:37 -0800772 size_t testcase_id = child_proc.testcase_id;
773 size_t test_id = child_proc.test_id;
774 TestCase& testcase = testcase_list[testcase_id];
Yabin Cuibe837362015-01-02 18:45:37 -0800775
Yabin Cui1d4c7802015-02-02 19:14:05 -0800776 CollectChildTestResult(child_proc, testcase);
Yabin Cui657b1f92015-01-22 19:26:12 -0800777 OnTestEndPrint(testcase, test_id);
Yabin Cuibe837362015-01-02 18:45:37 -0800778
779 if (++finished_test_count_list[testcase_id] == testcase.TestCount()) {
780 ++finished_testcase_count;
Yabin Cui294d1e22014-12-07 20:43:37 -0800781 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800782
783 it = child_proc_list.erase(it);
784 } else {
785 ++it;
Yabin Cui294d1e22014-12-07 20:43:37 -0800786 }
787 }
788 }
789
Yabin Cui657b1f92015-01-22 19:26:12 -0800790 int64_t elapsed_time_ns = NanoTime() - iteration_start_time_ns;
791 OnTestIterationEndPrint(testcase_list, iteration, elapsed_time_ns);
792 if (!xml_output_filename.empty()) {
793 OnTestIterationEndXmlPrint(xml_output_filename, testcase_list, epoch_iteration_start_time,
794 elapsed_time_ns);
795 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800796 }
Yabin Cui1d4c7802015-02-02 19:14:05 -0800797
798 // Restore signal mask.
799 if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) == -1) {
800 perror("sigprocmask SIG_SETMASK");
801 exit(1);
802 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800803}
804
Yabin Cuibe837362015-01-02 18:45:37 -0800805static size_t GetProcessorCount() {
806 return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
Yabin Cui294d1e22014-12-07 20:43:37 -0800807}
808
Yabin Cuiead08142015-02-04 20:53:56 -0800809static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
810 // To run DeathTest in threadsafe mode, gtest requires that the user must invoke the
811 // test program via a valid path that contains at least one path separator.
812 // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
813 // and execve() doesn't read environment variable PATH, so execve() will not success
814 // until we specify the absolute path or relative path of the test program directly.
815 if (strchr(args[0], '/') == NULL) {
816 char path[PATH_MAX];
817 ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
818 if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
819 perror("readlink");
820 exit(1);
821 }
822 path[path_len] = '\0';
823 args[0] = strdup(path);
824 }
825}
826
Yabin Cui11c43532015-01-28 14:28:14 -0800827static void AddGtestFilterSynonym(std::vector<char*>& args) {
828 // Support --gtest-filter as a synonym for --gtest_filter.
829 for (size_t i = 1; i < args.size(); ++i) {
830 if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
831 args[i][7] = '_';
832 }
833 }
834}
835
Yabin Cui657b1f92015-01-22 19:26:12 -0800836struct IsolationTestOptions {
837 bool isolate;
838 size_t job_count;
839 int test_deadline_ms;
840 int test_warnline_ms;
841 std::string gtest_color;
842 bool gtest_print_time;
843 size_t gtest_repeat;
844 std::string gtest_output;
845};
846
847// 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 -0800848// as described in PrintHelpInfo(), the other part is handled by testing::InitGoogleTest() in
Yabin Cui657b1f92015-01-22 19:26:12 -0800849// gtest. PickOptions() picks the first part into IsolationTestOptions structure, leaving the second
850// part in args.
Yabin Cuibe837362015-01-02 18:45:37 -0800851// Arguments:
Yabin Cui657b1f92015-01-22 19:26:12 -0800852// args is used to pass in all command arguments, and pass out only the part of options for gtest.
853// options is used to pass out test options in isolation mode.
854// Return false if there is error in arguments.
855static bool PickOptions(std::vector<char*>& args, IsolationTestOptions& options) {
856 for (size_t i = 1; i < args.size(); ++i) {
857 if (strcmp(args[i], "--help") == 0 || strcmp(args[i], "-h") == 0) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800858 PrintHelpInfo();
Yabin Cui657b1f92015-01-22 19:26:12 -0800859 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800860 return true;
861 }
862 }
863
Yabin Cuiead08142015-02-04 20:53:56 -0800864 AddPathSeparatorInTestProgramPath(args);
Yabin Cui11c43532015-01-28 14:28:14 -0800865 AddGtestFilterSynonym(args);
866
Yabin Cui657b1f92015-01-22 19:26:12 -0800867 // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
868 bool enable_selftest = false;
869 for (size_t i = 1; i < args.size(); ++i) {
870 if (strcmp(args[i], "--bionic-selftest") == 0) {
871 // This argument is to enable "bionic_selftest*" for self test, and is not shown in help info.
872 // Don't remove this option from arguments.
873 enable_selftest = true;
874 }
875 }
876 std::string gtest_filter_str;
877 for (size_t i = args.size() - 1; i >= 1; --i) {
878 if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
879 gtest_filter_str = std::string(args[i]);
880 args.erase(args.begin() + i);
Yabin Cui294d1e22014-12-07 20:43:37 -0800881 break;
882 }
883 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800884 if (enable_selftest == true) {
885 args.push_back(strdup("--gtest_filter=bionic_selftest*"));
886 } else {
887 if (gtest_filter_str == "") {
888 gtest_filter_str = "--gtest_filter=-bionic_selftest*";
889 } else {
Yabin Cui0bc4e962015-01-27 11:22:46 -0800890 // Find if '-' for NEGATIVE_PATTERNS exists.
891 if (gtest_filter_str.find(":-") != std::string::npos) {
892 gtest_filter_str += ":bionic_selftest*";
893 } else {
894 gtest_filter_str += ":-bionic_selftest*";
895 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800896 }
897 args.push_back(strdup(gtest_filter_str.c_str()));
898 }
Yabin Cui294d1e22014-12-07 20:43:37 -0800899
Yabin Cui657b1f92015-01-22 19:26:12 -0800900 options.isolate = true;
901 // Parse arguments that make us can't run in isolation mode.
902 for (size_t i = 1; i < args.size(); ++i) {
903 if (strcmp(args[i], "--no-isolate") == 0) {
904 options.isolate = false;
905 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
906 options.isolate = false;
Yabin Cui294d1e22014-12-07 20:43:37 -0800907 }
908 }
909
Yabin Cui657b1f92015-01-22 19:26:12 -0800910 // Stop parsing if we will not run in isolation mode.
911 if (options.isolate == false) {
Yabin Cui294d1e22014-12-07 20:43:37 -0800912 return true;
913 }
Yabin Cui657b1f92015-01-22 19:26:12 -0800914
915 // Init default isolation test options.
916 options.job_count = GetProcessorCount();
917 options.test_deadline_ms = DEFAULT_GLOBAL_TEST_RUN_DEADLINE_MS;
918 options.test_warnline_ms = DEFAULT_GLOBAL_TEST_RUN_WARNLINE_MS;
919 options.gtest_color = testing::GTEST_FLAG(color);
920 options.gtest_print_time = testing::GTEST_FLAG(print_time);
921 options.gtest_repeat = testing::GTEST_FLAG(repeat);
922 options.gtest_output = testing::GTEST_FLAG(output);
923
924 // Parse arguments speficied for isolation mode.
925 for (size_t i = 1; i < args.size(); ++i) {
926 if (strncmp(args[i], "-j", strlen("-j")) == 0) {
927 char* p = args[i] + strlen("-j");
928 int count = 0;
929 if (*p != '\0') {
930 // Argument like -j5.
931 count = atoi(p);
932 } else if (args.size() > i + 1) {
933 // Arguments like -j 5.
934 count = atoi(args[i + 1]);
935 ++i;
936 }
937 if (count <= 0) {
938 fprintf(stderr, "invalid job count: %d\n", count);
939 return false;
940 }
941 options.job_count = static_cast<size_t>(count);
942 } else if (strncmp(args[i], "--deadline=", strlen("--deadline=")) == 0) {
943 int time_ms = atoi(args[i] + strlen("--deadline="));
944 if (time_ms <= 0) {
945 fprintf(stderr, "invalid deadline: %d\n", time_ms);
946 return false;
947 }
948 options.test_deadline_ms = time_ms;
949 } else if (strncmp(args[i], "--warnline=", strlen("--warnline=")) == 0) {
950 int time_ms = atoi(args[i] + strlen("--warnline="));
951 if (time_ms <= 0) {
952 fprintf(stderr, "invalid warnline: %d\n", time_ms);
953 return false;
954 }
955 options.test_warnline_ms = time_ms;
956 } else if (strncmp(args[i], "--gtest_color=", strlen("--gtest_color=")) == 0) {
957 options.gtest_color = args[i] + strlen("--gtest_color=");
958 } else if (strcmp(args[i], "--gtest_print_time=0") == 0) {
959 options.gtest_print_time = false;
960 } else if (strncmp(args[i], "--gtest_repeat=", strlen("--gtest_repeat=")) == 0) {
961 int repeat = atoi(args[i] + strlen("--gtest_repeat="));
962 if (repeat < 0) {
963 fprintf(stderr, "invalid gtest_repeat count: %d\n", repeat);
964 return false;
965 }
966 options.gtest_repeat = repeat;
967 // Remove --gtest_repeat=xx from arguments, so child process only run one iteration for a single test.
968 args.erase(args.begin() + i);
969 --i;
970 } else if (strncmp(args[i], "--gtest_output=", strlen("--gtest_output=")) == 0) {
971 std::string output = args[i] + strlen("--gtest_output=");
972 // generate output xml file path according to the strategy in gtest.
973 bool success = true;
974 if (strncmp(output.c_str(), "xml:", strlen("xml:")) == 0) {
975 output = output.substr(strlen("xml:"));
976 if (output.size() == 0) {
977 success = false;
978 }
979 // Make absolute path.
980 if (success && output[0] != '/') {
981 char* cwd = getcwd(NULL, 0);
982 if (cwd != NULL) {
983 output = std::string(cwd) + "/" + output;
984 free(cwd);
985 } else {
986 success = false;
987 }
988 }
989 // Add file name if output is a directory.
990 if (success && output.back() == '/') {
991 output += "test_details.xml";
992 }
993 }
994 if (success) {
995 options.gtest_output = output;
996 } else {
997 fprintf(stderr, "invalid gtest_output file: %s\n", args[i]);
998 return false;
999 }
1000
1001 // Remove --gtest_output=xxx from arguments, so child process will not write xml file.
1002 args.erase(args.begin() + i);
1003 --i;
1004 }
1005 }
1006
1007 // Add --no-isolate in args to prevent child process from running in isolation mode again.
1008 // As DeathTest will try to call execve(), this argument should always be added.
1009 args.insert(args.begin() + 1, strdup("--no-isolate"));
Yabin Cui294d1e22014-12-07 20:43:37 -08001010 return true;
1011}
1012
1013int main(int argc, char** argv) {
Yabin Cuibe837362015-01-02 18:45:37 -08001014 std::vector<char*> arg_list;
1015 for (int i = 0; i < argc; ++i) {
1016 arg_list.push_back(argv[i]);
1017 }
Yabin Cuibe837362015-01-02 18:45:37 -08001018
Yabin Cui657b1f92015-01-22 19:26:12 -08001019 IsolationTestOptions options;
1020 if (PickOptions(arg_list, options) == false) {
1021 return 1;
Yabin Cui294d1e22014-12-07 20:43:37 -08001022 }
Yabin Cui657b1f92015-01-22 19:26:12 -08001023
1024 if (options.isolate == true) {
1025 // Set global variables.
1026 global_test_run_deadline_ms = options.test_deadline_ms;
1027 global_test_run_warnline_ms = options.test_warnline_ms;
1028 testing::GTEST_FLAG(color) = options.gtest_color.c_str();
1029 testing::GTEST_FLAG(print_time) = options.gtest_print_time;
1030 std::vector<TestCase> testcase_list;
1031
1032 argc = static_cast<int>(arg_list.size());
1033 arg_list.push_back(NULL);
1034 if (EnumerateTests(argc, arg_list.data(), testcase_list) == false) {
1035 return 1;
1036 }
1037 RunTestInSeparateProc(argc, arg_list.data(), testcase_list, options.gtest_repeat,
1038 options.job_count, options.gtest_output);
1039 } else {
1040 argc = static_cast<int>(arg_list.size());
1041 arg_list.push_back(NULL);
1042 testing::InitGoogleTest(&argc, arg_list.data());
1043 return RUN_ALL_TESTS();
1044 }
1045 return 0;
Yabin Cui294d1e22014-12-07 20:43:37 -08001046}
1047
1048//################################################################################
Yabin Cuibe837362015-01-02 18:45:37 -08001049// Bionic Gtest self test, run this by --bionic-selftest option.
Yabin Cui294d1e22014-12-07 20:43:37 -08001050
Yabin Cuibe837362015-01-02 18:45:37 -08001051TEST(bionic_selftest, test_success) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001052 ASSERT_EQ(1, 1);
1053}
1054
Yabin Cuibe837362015-01-02 18:45:37 -08001055TEST(bionic_selftest, test_fail) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001056 ASSERT_EQ(0, 1);
1057}
1058
Yabin Cuibe837362015-01-02 18:45:37 -08001059TEST(bionic_selftest, test_time_warn) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001060 sleep(4);
1061}
1062
Yabin Cuibe837362015-01-02 18:45:37 -08001063TEST(bionic_selftest, test_timeout) {
Yabin Cui294d1e22014-12-07 20:43:37 -08001064 while (1) {}
1065}
Yabin Cuibe837362015-01-02 18:45:37 -08001066
1067TEST(bionic_selftest, test_signal_SEGV_terminated) {
1068 char* p = reinterpret_cast<char*>(static_cast<intptr_t>(atoi("0")));
1069 *p = 3;
1070}
Yabin Cui657b1f92015-01-22 19:26:12 -08001071
1072class bionic_selftest_DeathTest : public BionicDeathTest {};
1073
1074static void deathtest_helper_success() {
1075 ASSERT_EQ(1, 1);
1076 exit(0);
1077}
1078
1079TEST_F(bionic_selftest_DeathTest, success) {
1080 ASSERT_EXIT(deathtest_helper_success(), ::testing::ExitedWithCode(0), "");
1081}
1082
1083static void deathtest_helper_fail() {
1084 ASSERT_EQ(1, 0);
1085}
1086
1087TEST_F(bionic_selftest_DeathTest, fail) {
1088 ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
1089}