1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/test/launcher/test_launcher.h"
11 #include "base/at_exit.h"
12 #include "base/bind.h"
13 #include "base/command_line.h"
14 #include "base/environment.h"
15 #include "base/files/file_path.h"
16 #include "base/files/file_util.h"
17 #include "base/files/scoped_file.h"
18 #include "base/format_macros.h"
19 #include "base/hash.h"
20 #include "base/lazy_instance.h"
21 #include "base/logging.h"
22 #include "base/memory/scoped_ptr.h"
23 #include "base/message_loop/message_loop.h"
24 #include "base/process/kill.h"
25 #include "base/process/launch.h"
26 #include "base/strings/string_number_conversions.h"
27 #include "base/strings/string_split.h"
28 #include "base/strings/string_util.h"
29 #include "base/strings/stringize_macros.h"
30 #include "base/strings/stringprintf.h"
31 #include "base/strings/utf_string_conversions.h"
32 #include "base/test/launcher/test_results_tracker.h"
33 #include "base/test/sequenced_worker_pool_owner.h"
34 #include "base/test/test_switches.h"
35 #include "base/test/test_timeouts.h"
36 #include "base/threading/thread_checker.h"
37 #include "base/time/time.h"
38 #include "testing/gtest/include/gtest/gtest.h"
40 #if defined(OS_MACOSX)
41 #include "base/mac/scoped_nsautorelease_pool.h"
45 #include "base/win/windows_version.h"
50 // Launches a child process using |command_line|. If the child process is still
51 // running after |timeout|, it is terminated and |*was_timeout| is set to true.
52 // Returns exit code of the process.
53 int LaunchChildTestProcessWithOptions(const CommandLine& command_line,
54 const LaunchOptions& options,
56 base::TimeDelta timeout,
59 // See https://groups.google.com/a/chromium.org/d/msg/chromium-dev/nkdTP7sstSc/uT3FaE_sgkAJ .
62 // The environment variable name for the total number of test shards.
63 const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
64 // The environment variable name for the test shard index.
65 const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
69 // Global tag for test runs where the results are incomplete or unreliable
70 // for any reason, e.g. early exit because of too many broken tests.
71 const char kUnreliableResultsTag[] = "UNRELIABLE_RESULTS";
73 // Maximum time of no output after which we print list of processes still
74 // running. This deliberately doesn't use TestTimeouts (which is otherwise
75 // a recommended solution), because they can be increased. This would defeat
76 // the purpose of this timeout, which is 1) to avoid buildbot "no output for
77 // X seconds" timeout killing the process 2) help communicate status of
78 // the test launcher to people looking at the output (no output for a long
79 // time is mysterious and gives no info about what is happening) 3) help
80 // debugging in case the process hangs anyway.
81 const int kOutputTimeoutSeconds = 15;
83 // Limit of output snippet lines when printing to stdout.
84 // Avoids flooding the logs with amount of output that gums up
85 // the infrastructure.
86 const size_t kOutputSnippetLinesLimit = 5000;
88 // Set of live launch test processes with corresponding lock (it is allowed
89 // for callers to launch processes on different threads).
90 LazyInstance<std::map<ProcessHandle, CommandLine> > g_live_processes
91 = LAZY_INSTANCE_INITIALIZER;
92 LazyInstance<Lock> g_live_processes_lock = LAZY_INSTANCE_INITIALIZER;
95 // Self-pipe that makes it possible to do complex shutdown handling
96 // outside of the signal handler.
97 int g_shutdown_pipe[2] = { -1, -1 };
99 void ShutdownPipeSignalHandler(int signal) {
100 HANDLE_EINTR(write(g_shutdown_pipe[1], "q", 1));
103 void KillSpawnedTestProcesses() {
104 // Keep the lock until exiting the process to prevent further processes
105 // from being spawned.
106 AutoLock lock(g_live_processes_lock.Get());
109 "Sending SIGTERM to %" PRIuS " child processes... ",
110 g_live_processes.Get().size());
113 for (std::map<ProcessHandle, CommandLine>::iterator i =
114 g_live_processes.Get().begin();
115 i != g_live_processes.Get().end();
117 // Send the signal to entire process group.
118 kill((-1) * (i->first), SIGTERM);
122 "done.\nGiving processes a chance to terminate cleanly... ");
125 PlatformThread::Sleep(TimeDelta::FromMilliseconds(500));
127 fprintf(stdout, "done.\n");
131 "Sending SIGKILL to %" PRIuS " child processes... ",
132 g_live_processes.Get().size());
135 for (std::map<ProcessHandle, CommandLine>::iterator i =
136 g_live_processes.Get().begin();
137 i != g_live_processes.Get().end();
139 // Send the signal to entire process group.
140 kill((-1) * (i->first), SIGKILL);
143 fprintf(stdout, "done.\n");
147 // I/O watcher for the reading end of the self-pipe above.
148 // Terminates any launched child processes and exits the process.
149 class SignalFDWatcher : public MessageLoopForIO::Watcher {
154 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
155 fprintf(stdout, "\nCaught signal. Killing spawned test processes...\n");
158 KillSpawnedTestProcesses();
160 // The signal would normally kill the process, so exit now.
164 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {
169 DISALLOW_COPY_AND_ASSIGN(SignalFDWatcher);
171 #endif // defined(OS_POSIX)
173 // Parses the environment variable var as an Int32. If it is unset, returns
174 // true. If it is set, unsets it then converts it to Int32 before
175 // returning it in |result|. Returns true on success.
176 bool TakeInt32FromEnvironment(const char* const var, int32* result) {
177 scoped_ptr<Environment> env(Environment::Create());
180 if (!env->GetVar(var, &str_val))
183 if (!env->UnSetVar(var)) {
184 LOG(ERROR) << "Invalid environment: we could not unset " << var << ".\n";
188 if (!StringToInt(str_val, result)) {
189 LOG(ERROR) << "Invalid environment: " << var << " is not an integer.\n";
196 // Unsets the environment variable |name| and returns true on success.
197 // Also returns true if the variable just doesn't exist.
198 bool UnsetEnvironmentVariableIfExists(const std::string& name) {
199 scoped_ptr<Environment> env(Environment::Create());
202 if (!env->GetVar(name.c_str(), &str_val))
205 return env->UnSetVar(name.c_str());
208 // Returns true if bot mode has been requested, i.e. defaults optimized
209 // for continuous integration bots. This way developers don't have to remember
210 // special command-line flags.
211 bool BotModeEnabled() {
212 scoped_ptr<Environment> env(Environment::Create());
213 return CommandLine::ForCurrentProcess()->HasSwitch(
214 switches::kTestLauncherBotMode) ||
215 env->HasVar("CHROMIUM_TEST_LAUNCHER_BOT_MODE");
219 const TestLauncher::LaunchChildGTestProcessCallback& callback,
221 const TimeDelta& elapsed_time,
223 const std::string& output) {
224 callback.Run(exit_code, elapsed_time, was_timeout, output);
227 void DoLaunchChildTestProcess(
228 const CommandLine& command_line,
229 base::TimeDelta timeout,
232 scoped_refptr<MessageLoopProxy> message_loop_proxy,
233 const TestLauncher::LaunchChildGTestProcessCallback& callback) {
234 TimeTicks start_time = TimeTicks::Now();
236 // Redirect child process output to a file.
237 base::FilePath output_file;
238 CHECK(base::CreateTemporaryFile(&output_file));
240 LaunchOptions options;
242 win::ScopedHandle handle;
244 if (redirect_stdio) {
245 // Make the file handle inheritable by the child.
246 SECURITY_ATTRIBUTES sa_attr;
247 sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
248 sa_attr.lpSecurityDescriptor = NULL;
249 sa_attr.bInheritHandle = TRUE;
251 handle.Set(CreateFile(output_file.value().c_str(),
253 FILE_SHARE_READ | FILE_SHARE_DELETE,
256 FILE_ATTRIBUTE_TEMPORARY,
258 CHECK(handle.IsValid());
259 options.inherit_handles = true;
260 options.stdin_handle = INVALID_HANDLE_VALUE;
261 options.stdout_handle = handle.Get();
262 options.stderr_handle = handle.Get();
264 #elif defined(OS_POSIX)
265 options.new_process_group = true;
267 base::FileHandleMappingVector fds_mapping;
268 base::ScopedFD output_file_fd;
270 if (redirect_stdio) {
271 output_file_fd.reset(open(output_file.value().c_str(), O_RDWR));
272 CHECK(output_file_fd.is_valid());
274 fds_mapping.push_back(std::make_pair(output_file_fd.get(), STDOUT_FILENO));
275 fds_mapping.push_back(std::make_pair(output_file_fd.get(), STDERR_FILENO));
276 options.fds_to_remap = &fds_mapping;
280 bool was_timeout = false;
281 int exit_code = LaunchChildTestProcessWithOptions(
282 command_line, options, flags, timeout, &was_timeout);
284 if (redirect_stdio) {
286 FlushFileBuffers(handle.Get());
288 #elif defined(OS_POSIX)
289 output_file_fd.reset();
293 std::string output_file_contents;
294 CHECK(base::ReadFileToString(output_file, &output_file_contents));
296 if (!base::DeleteFile(output_file, false)) {
297 // This needs to be non-fatal at least for Windows.
298 LOG(WARNING) << "Failed to delete " << output_file.AsUTF8Unsafe();
301 // Run target callback on the thread it was originating from, not on
302 // a worker pool thread.
303 message_loop_proxy->PostTask(
308 TimeTicks::Now() - start_time,
310 output_file_contents));
315 const char kGTestFilterFlag[] = "gtest_filter";
316 const char kGTestHelpFlag[] = "gtest_help";
317 const char kGTestListTestsFlag[] = "gtest_list_tests";
318 const char kGTestRepeatFlag[] = "gtest_repeat";
319 const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests";
320 const char kGTestOutputFlag[] = "gtest_output";
322 TestLauncherDelegate::~TestLauncherDelegate() {
325 TestLauncher::TestLauncher(TestLauncherDelegate* launcher_delegate,
326 size_t parallel_jobs)
327 : launcher_delegate_(launcher_delegate),
331 test_started_count_(0),
332 test_finished_count_(0),
333 test_success_count_(0),
334 test_broken_count_(0),
338 watchdog_timer_(FROM_HERE,
339 TimeDelta::FromSeconds(kOutputTimeoutSeconds),
341 &TestLauncher::OnOutputTimeout),
342 parallel_jobs_(parallel_jobs) {
345 TestLauncher::~TestLauncher() {
346 if (worker_pool_owner_)
347 worker_pool_owner_->pool()->Shutdown();
350 bool TestLauncher::Run() {
354 // Value of |cycles_| changes after each iteration. Keep track of the
356 int requested_cycles = cycles_;
358 #if defined(OS_POSIX)
359 CHECK_EQ(0, pipe(g_shutdown_pipe));
361 struct sigaction action;
362 memset(&action, 0, sizeof(action));
363 sigemptyset(&action.sa_mask);
364 action.sa_handler = &ShutdownPipeSignalHandler;
366 CHECK_EQ(0, sigaction(SIGINT, &action, NULL));
367 CHECK_EQ(0, sigaction(SIGQUIT, &action, NULL));
368 CHECK_EQ(0, sigaction(SIGTERM, &action, NULL));
370 MessageLoopForIO::FileDescriptorWatcher controller;
371 SignalFDWatcher watcher;
373 CHECK(MessageLoopForIO::current()->WatchFileDescriptor(
376 MessageLoopForIO::WATCH_READ,
379 #endif // defined(OS_POSIX)
381 // Start the watchdog timer.
382 watchdog_timer_.Reset();
384 MessageLoop::current()->PostTask(
386 Bind(&TestLauncher::RunTestIteration, Unretained(this)));
388 MessageLoop::current()->Run();
390 if (requested_cycles != 1)
391 results_tracker_.PrintSummaryOfAllIterations();
393 MaybeSaveSummaryAsJSON();
398 void TestLauncher::LaunchChildGTestProcess(
399 const CommandLine& command_line,
400 const std::string& wrapper,
401 base::TimeDelta timeout,
403 const LaunchChildGTestProcessCallback& callback) {
404 DCHECK(thread_checker_.CalledOnValidThread());
406 // Record the exact command line used to launch the child.
407 CommandLine new_command_line(
408 PrepareCommandLineForGTest(command_line, wrapper));
410 // When running in parallel mode we need to redirect stdio to avoid mixed-up
411 // output. We also always redirect on the bots to get the test output into
413 bool redirect_stdio = (parallel_jobs_ > 1) || BotModeEnabled();
415 worker_pool_owner_->pool()->PostWorkerTask(
417 Bind(&DoLaunchChildTestProcess,
422 MessageLoopProxy::current(),
423 Bind(&TestLauncher::OnLaunchTestProcessFinished,
428 void TestLauncher::OnTestFinished(const TestResult& result) {
429 ++test_finished_count_;
431 bool print_snippet = false;
432 std::string print_test_stdio("auto");
433 if (CommandLine::ForCurrentProcess()->HasSwitch(
434 switches::kTestLauncherPrintTestStdio)) {
435 print_test_stdio = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
436 switches::kTestLauncherPrintTestStdio);
438 if (print_test_stdio == "auto") {
439 print_snippet = (result.status != TestResult::TEST_SUCCESS);
440 } else if (print_test_stdio == "always") {
441 print_snippet = true;
442 } else if (print_test_stdio == "never") {
443 print_snippet = false;
445 LOG(WARNING) << "Invalid value of " << switches::kTestLauncherPrintTestStdio
446 << ": " << print_test_stdio;
449 std::vector<std::string> snippet_lines;
450 SplitString(result.output_snippet, '\n', &snippet_lines);
451 if (snippet_lines.size() > kOutputSnippetLinesLimit) {
452 size_t truncated_size = snippet_lines.size() - kOutputSnippetLinesLimit;
454 snippet_lines.begin(),
455 snippet_lines.begin() + truncated_size);
456 snippet_lines.insert(snippet_lines.begin(), "<truncated>");
458 fprintf(stdout, "%s", JoinString(snippet_lines, "\n").c_str());
462 if (result.status == TestResult::TEST_SUCCESS) {
463 ++test_success_count_;
465 tests_to_retry_.insert(result.full_name);
468 results_tracker_.AddTestResult(result);
470 // TODO(phajdan.jr): Align counter (padding).
471 std::string status_line(
472 StringPrintf("[%" PRIuS "/%" PRIuS "] %s ",
473 test_finished_count_,
475 result.full_name.c_str()));
476 if (result.completed()) {
477 status_line.append(StringPrintf("(%" PRId64 " ms)",
478 result.elapsed_time.InMilliseconds()));
479 } else if (result.status == TestResult::TEST_TIMEOUT) {
480 status_line.append("(TIMED OUT)");
481 } else if (result.status == TestResult::TEST_CRASH) {
482 status_line.append("(CRASHED)");
483 } else if (result.status == TestResult::TEST_SKIPPED) {
484 status_line.append("(SKIPPED)");
485 } else if (result.status == TestResult::TEST_UNKNOWN) {
486 status_line.append("(UNKNOWN)");
488 // Fail very loudly so it's not ignored.
489 CHECK(false) << "Unhandled test result status: " << result.status;
491 fprintf(stdout, "%s\n", status_line.c_str());
494 // We just printed a status line, reset the watchdog timer.
495 watchdog_timer_.Reset();
497 // Do not waste time on timeouts. We include tests with unknown results here
498 // because sometimes (e.g. hang in between unit tests) that's how a timeout
500 if (result.status == TestResult::TEST_TIMEOUT ||
501 result.status == TestResult::TEST_UNKNOWN) {
502 test_broken_count_++;
504 size_t broken_threshold =
505 std::max(static_cast<size_t>(20), test_started_count_ / 10);
506 if (test_broken_count_ >= broken_threshold) {
507 fprintf(stdout, "Too many badly broken tests (%" PRIuS "), exiting now.\n",
511 #if defined(OS_POSIX)
512 KillSpawnedTestProcesses();
513 #endif // defined(OS_POSIX)
515 results_tracker_.AddGlobalTag("BROKEN_TEST_EARLY_EXIT");
516 results_tracker_.AddGlobalTag(kUnreliableResultsTag);
517 MaybeSaveSummaryAsJSON();
522 if (test_finished_count_ != test_started_count_)
525 if (tests_to_retry_.empty() || retry_count_ >= retry_limit_) {
526 OnTestIterationFinished();
530 if (tests_to_retry_.size() >= broken_threshold) {
532 "Too many failing tests (%" PRIuS "), skipping retries.\n",
533 tests_to_retry_.size());
536 results_tracker_.AddGlobalTag("BROKEN_TEST_SKIPPED_RETRIES");
537 results_tracker_.AddGlobalTag(kUnreliableResultsTag);
539 OnTestIterationFinished();
545 std::vector<std::string> test_names(tests_to_retry_.begin(),
546 tests_to_retry_.end());
548 tests_to_retry_.clear();
550 size_t retry_started_count = launcher_delegate_->RetryTests(this, test_names);
551 if (retry_started_count == 0) {
552 // Signal failure, but continue to run all requested test iterations.
553 // With the summary of all iterations at the end this is a good default.
556 OnTestIterationFinished();
560 fprintf(stdout, "Retrying %" PRIuS " test%s (retry #%" PRIuS ")\n",
562 retry_started_count > 1 ? "s" : "",
566 test_started_count_ += retry_started_count;
570 std::string TestLauncher::FormatFullTestName(const std::string& test_case_name,
571 const std::string& test_name) {
572 return test_case_name + "." + test_name;
575 bool TestLauncher::Init() {
576 const CommandLine* command_line = CommandLine::ForCurrentProcess();
578 // Initialize sharding. Command line takes precedence over legacy environment
580 if (command_line->HasSwitch(switches::kTestLauncherTotalShards) &&
581 command_line->HasSwitch(switches::kTestLauncherShardIndex)) {
583 command_line->GetSwitchValueASCII(
584 switches::kTestLauncherTotalShards),
586 LOG(ERROR) << "Invalid value for " << switches::kTestLauncherTotalShards;
590 command_line->GetSwitchValueASCII(
591 switches::kTestLauncherShardIndex),
593 LOG(ERROR) << "Invalid value for " << switches::kTestLauncherShardIndex;
597 "Using sharding settings from command line. This is shard %d/%d\n",
598 shard_index_, total_shards_);
601 if (!TakeInt32FromEnvironment(kTestTotalShards, &total_shards_))
603 if (!TakeInt32FromEnvironment(kTestShardIndex, &shard_index_))
606 "Using sharding settings from environment. This is shard %d/%d\n",
607 shard_index_, total_shards_);
610 if (shard_index_ < 0 ||
612 shard_index_ >= total_shards_) {
613 LOG(ERROR) << "Invalid sharding settings: we require 0 <= "
614 << kTestShardIndex << " < " << kTestTotalShards
615 << ", but you have " << kTestShardIndex << "=" << shard_index_
616 << ", " << kTestTotalShards << "=" << total_shards_ << ".\n";
620 // Make sure we don't pass any sharding-related environment to the child
621 // processes. This test launcher implements the sharding completely.
622 CHECK(UnsetEnvironmentVariableIfExists("GTEST_TOTAL_SHARDS"));
623 CHECK(UnsetEnvironmentVariableIfExists("GTEST_SHARD_INDEX"));
625 if (command_line->HasSwitch(kGTestRepeatFlag) &&
626 !StringToInt(command_line->GetSwitchValueASCII(kGTestRepeatFlag),
628 LOG(ERROR) << "Invalid value for " << kGTestRepeatFlag;
632 if (CommandLine::ForCurrentProcess()->HasSwitch(
633 switches::kTestLauncherRetryLimit)) {
634 int retry_limit = -1;
635 if (!StringToInt(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
636 switches::kTestLauncherRetryLimit), &retry_limit) ||
638 LOG(ERROR) << "Invalid value for " << switches::kTestLauncherRetryLimit;
642 retry_limit_ = retry_limit;
643 } else if (!CommandLine::ForCurrentProcess()->HasSwitch(kGTestFilterFlag)) {
644 // Retry failures 3 times by default if we are running all of the tests.
648 if (CommandLine::ForCurrentProcess()->HasSwitch(
649 switches::kTestLauncherJobs)) {
651 if (!StringToInt(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
652 switches::kTestLauncherJobs), &jobs) ||
654 LOG(ERROR) << "Invalid value for " << switches::kTestLauncherJobs;
658 parallel_jobs_ = jobs;
659 } else if (CommandLine::ForCurrentProcess()->HasSwitch(kGTestFilterFlag)) {
660 // Do not run jobs in parallel by default if we are running a subset of
665 fprintf(stdout, "Using %" PRIuS " parallel jobs.\n", parallel_jobs_);
667 worker_pool_owner_.reset(
668 new SequencedWorkerPoolOwner(parallel_jobs_, "test_launcher"));
670 if (command_line->HasSwitch(switches::kTestLauncherFilterFile) &&
671 command_line->HasSwitch(kGTestFilterFlag)) {
672 LOG(ERROR) << "Only one of --test-launcher-filter-file and --gtest_filter "
673 << "at a time is allowed.";
677 if (command_line->HasSwitch(switches::kTestLauncherFilterFile)) {
679 if (!ReadFileToString(
680 command_line->GetSwitchValuePath(switches::kTestLauncherFilterFile),
682 LOG(ERROR) << "Failed to read the filter file.";
686 std::vector<std::string> filter_lines;
687 SplitString(filter, '\n', &filter_lines);
688 for (size_t i = 0; i < filter_lines.size(); i++) {
689 if (filter_lines[i].empty())
692 if (filter_lines[i][0] == '-')
693 negative_test_filter_.push_back(filter_lines[i].substr(1));
695 positive_test_filter_.push_back(filter_lines[i]);
698 // Split --gtest_filter at '-', if there is one, to separate into
699 // positive filter and negative filter portions.
700 std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag);
701 size_t dash_pos = filter.find('-');
702 if (dash_pos == std::string::npos) {
703 SplitString(filter, ':', &positive_test_filter_);
705 // Everything up to the dash.
706 SplitString(filter.substr(0, dash_pos), ':', &positive_test_filter_);
708 // Everything after the dash.
709 SplitString(filter.substr(dash_pos + 1), ':', &negative_test_filter_);
713 if (!results_tracker_.Init(*command_line)) {
714 LOG(ERROR) << "Failed to initialize test results tracker.";
719 results_tracker_.AddGlobalTag("MODE_RELEASE");
721 results_tracker_.AddGlobalTag("MODE_DEBUG");
724 // Operating systems (sorted alphabetically).
725 // Note that they can deliberately overlap, e.g. OS_LINUX is a subset
727 #if defined(OS_ANDROID)
728 results_tracker_.AddGlobalTag("OS_ANDROID");
732 results_tracker_.AddGlobalTag("OS_BSD");
735 #if defined(OS_FREEBSD)
736 results_tracker_.AddGlobalTag("OS_FREEBSD");
740 results_tracker_.AddGlobalTag("OS_IOS");
743 #if defined(OS_LINUX)
744 results_tracker_.AddGlobalTag("OS_LINUX");
747 #if defined(OS_MACOSX)
748 results_tracker_.AddGlobalTag("OS_MACOSX");
752 results_tracker_.AddGlobalTag("OS_NACL");
755 #if defined(OS_OPENBSD)
756 results_tracker_.AddGlobalTag("OS_OPENBSD");
759 #if defined(OS_POSIX)
760 results_tracker_.AddGlobalTag("OS_POSIX");
763 #if defined(OS_SOLARIS)
764 results_tracker_.AddGlobalTag("OS_SOLARIS");
768 results_tracker_.AddGlobalTag("OS_WIN");
772 #if defined(ARCH_CPU_32_BITS)
773 results_tracker_.AddGlobalTag("CPU_32_BITS");
776 #if defined(ARCH_CPU_64_BITS)
777 results_tracker_.AddGlobalTag("CPU_64_BITS");
783 void TestLauncher::RunTests() {
784 testing::UnitTest* const unit_test = testing::UnitTest::GetInstance();
786 std::vector<std::string> test_names;
788 for (int i = 0; i < unit_test->total_test_case_count(); ++i) {
789 const testing::TestCase* test_case = unit_test->GetTestCase(i);
790 for (int j = 0; j < test_case->total_test_count(); ++j) {
791 const testing::TestInfo* test_info = test_case->GetTestInfo(j);
792 std::string test_name = FormatFullTestName(
793 test_info->test_case_name(), test_info->name());
795 results_tracker_.AddTest(test_name);
797 const CommandLine* command_line = CommandLine::ForCurrentProcess();
798 if (test_name.find("DISABLED") != std::string::npos) {
799 results_tracker_.AddDisabledTest(test_name);
801 // Skip disabled tests unless explicitly requested.
802 if (!command_line->HasSwitch(kGTestRunDisabledTestsFlag))
806 if (!launcher_delegate_->ShouldRunTest(test_case, test_info))
809 // Skip the test that doesn't match the filter (if given).
810 if (!positive_test_filter_.empty()) {
812 for (size_t k = 0; k < positive_test_filter_.size(); ++k) {
813 if (MatchPattern(test_name, positive_test_filter_[k])) {
822 bool excluded = false;
823 for (size_t k = 0; k < negative_test_filter_.size(); ++k) {
824 if (MatchPattern(test_name, negative_test_filter_[k])) {
832 if (base::Hash(test_name) % total_shards_ !=
833 static_cast<uint32>(shard_index_)) {
837 test_names.push_back(test_name);
841 test_started_count_ = launcher_delegate_->RunTests(this, test_names);
843 if (test_started_count_ == 0) {
844 fprintf(stdout, "0 tests run\n");
847 // No tests have actually been started, so kick off the next iteration.
848 MessageLoop::current()->PostTask(
850 Bind(&TestLauncher::RunTestIteration, Unretained(this)));
854 void TestLauncher::RunTestIteration() {
856 MessageLoop::current()->Quit();
860 // Special value "-1" means "repeat indefinitely".
861 cycles_ = (cycles_ == -1) ? cycles_ : cycles_ - 1;
863 test_started_count_ = 0;
864 test_finished_count_ = 0;
865 test_success_count_ = 0;
866 test_broken_count_ = 0;
868 tests_to_retry_.clear();
869 results_tracker_.OnTestIterationStarting();
871 MessageLoop::current()->PostTask(
872 FROM_HERE, Bind(&TestLauncher::RunTests, Unretained(this)));
875 void TestLauncher::MaybeSaveSummaryAsJSON() {
876 const CommandLine* command_line = CommandLine::ForCurrentProcess();
877 if (command_line->HasSwitch(switches::kTestLauncherSummaryOutput)) {
878 FilePath summary_path(command_line->GetSwitchValuePath(
879 switches::kTestLauncherSummaryOutput));
880 if (!results_tracker_.SaveSummaryAsJSON(summary_path)) {
881 LOG(ERROR) << "Failed to save test launcher output summary.";
886 void TestLauncher::OnLaunchTestProcessFinished(
887 const LaunchChildGTestProcessCallback& callback,
889 const TimeDelta& elapsed_time,
891 const std::string& output) {
892 DCHECK(thread_checker_.CalledOnValidThread());
894 callback.Run(exit_code, elapsed_time, was_timeout, output);
897 void TestLauncher::OnTestIterationFinished() {
898 TestResultsTracker::TestStatusMap tests_by_status(
899 results_tracker_.GetTestStatusMapForCurrentIteration());
900 if (!tests_by_status[TestResult::TEST_UNKNOWN].empty())
901 results_tracker_.AddGlobalTag(kUnreliableResultsTag);
903 // When we retry tests, success is determined by having nothing more
904 // to retry (everything eventually passed), as opposed to having
905 // no failures at all.
906 if (tests_to_retry_.empty()) {
907 fprintf(stdout, "SUCCESS: all tests passed.\n");
910 // Signal failure, but continue to run all requested test iterations.
911 // With the summary of all iterations at the end this is a good default.
915 results_tracker_.PrintSummaryOfCurrentIteration();
917 // Kick off the next iteration.
918 MessageLoop::current()->PostTask(
920 Bind(&TestLauncher::RunTestIteration, Unretained(this)));
923 void TestLauncher::OnOutputTimeout() {
924 DCHECK(thread_checker_.CalledOnValidThread());
926 AutoLock lock(g_live_processes_lock.Get());
928 fprintf(stdout, "Still waiting for the following processes to finish:\n");
930 for (std::map<ProcessHandle, CommandLine>::iterator i =
931 g_live_processes.Get().begin();
932 i != g_live_processes.Get().end();
935 fwprintf(stdout, L"\t%s\n", i->second.GetCommandLineString().c_str());
937 fprintf(stdout, "\t%s\n", i->second.GetCommandLineString().c_str());
943 // Arm the timer again - otherwise it would fire only once.
944 watchdog_timer_.Reset();
947 std::string GetTestOutputSnippet(const TestResult& result,
948 const std::string& full_output) {
949 size_t run_pos = full_output.find(std::string("[ RUN ] ") +
951 if (run_pos == std::string::npos)
952 return std::string();
954 size_t end_pos = full_output.find(std::string("[ FAILED ] ") +
957 // Only clip the snippet to the "OK" message if the test really
958 // succeeded. It still might have e.g. crashed after printing it.
959 if (end_pos == std::string::npos &&
960 result.status == TestResult::TEST_SUCCESS) {
961 end_pos = full_output.find(std::string("[ OK ] ") +
965 if (end_pos != std::string::npos) {
966 size_t newline_pos = full_output.find("\n", end_pos);
967 if (newline_pos != std::string::npos)
968 end_pos = newline_pos + 1;
971 std::string snippet(full_output.substr(run_pos));
972 if (end_pos != std::string::npos)
973 snippet = full_output.substr(run_pos, end_pos - run_pos);
978 CommandLine PrepareCommandLineForGTest(const CommandLine& command_line,
979 const std::string& wrapper) {
980 CommandLine new_command_line(command_line.GetProgram());
981 CommandLine::SwitchMap switches = command_line.GetSwitches();
983 // Strip out gtest_repeat flag - this is handled by the launcher process.
984 switches.erase(kGTestRepeatFlag);
986 // Don't try to write the final XML report in child processes.
987 switches.erase(kGTestOutputFlag);
989 for (CommandLine::SwitchMap::const_iterator iter = switches.begin();
990 iter != switches.end(); ++iter) {
991 new_command_line.AppendSwitchNative((*iter).first, (*iter).second);
994 // Prepend wrapper after last CommandLine quasi-copy operation. CommandLine
995 // does not really support removing switches well, and trying to do that
996 // on a CommandLine with a wrapper is known to break.
997 // TODO(phajdan.jr): Give it a try to support CommandLine removing switches.
999 new_command_line.PrependWrapper(ASCIIToWide(wrapper));
1000 #elif defined(OS_POSIX)
1001 new_command_line.PrependWrapper(wrapper);
1004 return new_command_line;
1007 // TODO(phajdan.jr): Move to anonymous namespace.
1008 int LaunchChildTestProcessWithOptions(const CommandLine& command_line,
1009 const LaunchOptions& options,
1011 base::TimeDelta timeout,
1012 bool* was_timeout) {
1013 #if defined(OS_POSIX)
1014 // Make sure an option we rely on is present - see LaunchChildGTestProcess.
1015 DCHECK(options.new_process_group);
1018 LaunchOptions new_options(options);
1021 DCHECK(!new_options.job_handle);
1023 win::ScopedHandle job_handle;
1024 if (flags & TestLauncher::USE_JOB_OBJECTS) {
1025 job_handle.Set(CreateJobObject(NULL, NULL));
1026 if (!job_handle.IsValid()) {
1027 LOG(ERROR) << "Could not create JobObject.";
1031 DWORD job_flags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
1033 // Allow break-away from job since sandbox and few other places rely on it
1034 // on Windows versions prior to Windows 8 (which supports nested jobs).
1035 if (win::GetVersion() < win::VERSION_WIN8 &&
1036 flags & TestLauncher::ALLOW_BREAKAWAY_FROM_JOB) {
1037 job_flags |= JOB_OBJECT_LIMIT_BREAKAWAY_OK;
1040 if (!SetJobObjectLimitFlags(job_handle.Get(), job_flags)) {
1041 LOG(ERROR) << "Could not SetJobObjectLimitFlags.";
1045 new_options.job_handle = job_handle.Get();
1047 #endif // defined(OS_WIN)
1049 #if defined(OS_LINUX)
1050 // To prevent accidental privilege sharing to an untrusted child, processes
1051 // are started with PR_SET_NO_NEW_PRIVS. Do not set that here, since this
1052 // new child will be privileged and trusted.
1053 new_options.allow_new_privs = true;
1056 base::ProcessHandle process_handle;
1059 // Note how we grab the lock before the process possibly gets created.
1060 // This ensures that when the lock is held, ALL the processes are registered
1062 AutoLock lock(g_live_processes_lock.Get());
1064 if (!base::LaunchProcess(command_line, new_options, &process_handle))
1067 g_live_processes.Get().insert(std::make_pair(process_handle, command_line));
1071 if (!base::WaitForExitCodeWithTimeout(process_handle,
1074 *was_timeout = true;
1075 exit_code = -1; // Set a non-zero exit code to signal a failure.
1077 // Ensure that the process terminates.
1078 base::KillProcess(process_handle, -1, true);
1082 // Note how we grab the log before issuing a possibly broad process kill.
1083 // Other code parts that grab the log kill processes, so avoid trying
1084 // to do that twice and trigger all kinds of log messages.
1085 AutoLock lock(g_live_processes_lock.Get());
1087 #if defined(OS_POSIX)
1088 if (exit_code != 0) {
1089 // On POSIX, in case the test does not exit cleanly, either due to a crash
1090 // or due to it timing out, we need to clean up any child processes that
1091 // it might have created. On Windows, child processes are automatically
1092 // cleaned up using JobObjects.
1093 base::KillProcessGroup(process_handle);
1097 g_live_processes.Get().erase(process_handle);
1100 base::CloseProcessHandle(process_handle);