Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / base / test / launcher / test_launcher.cc
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.
4
5 #include "base/test/launcher/test_launcher.h"
6
7 #if defined(OS_POSIX)
8 #include <fcntl.h>
9 #endif
10
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"
39
40 #if defined(OS_MACOSX)
41 #include "base/mac/scoped_nsautorelease_pool.h"
42 #endif
43
44 #if defined(OS_WIN)
45 #include "base/win/windows_version.h"
46 #endif
47
48 namespace base {
49
50 // See https://groups.google.com/a/chromium.org/d/msg/chromium-dev/nkdTP7sstSc/uT3FaE_sgkAJ .
51 using ::operator<<;
52
53 // The environment variable name for the total number of test shards.
54 const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
55 // The environment variable name for the test shard index.
56 const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
57
58 namespace {
59
60 // Global tag for test runs where the results are incomplete or unreliable
61 // for any reason, e.g. early exit because of too many broken tests.
62 const char kUnreliableResultsTag[] = "UNRELIABLE_RESULTS";
63
64 // Maximum time of no output after which we print list of processes still
65 // running. This deliberately doesn't use TestTimeouts (which is otherwise
66 // a recommended solution), because they can be increased. This would defeat
67 // the purpose of this timeout, which is 1) to avoid buildbot "no output for
68 // X seconds" timeout killing the process 2) help communicate status of
69 // the test launcher to people looking at the output (no output for a long
70 // time is mysterious and gives no info about what is happening) 3) help
71 // debugging in case the process hangs anyway.
72 const int kOutputTimeoutSeconds = 15;
73
74 // Limit of output snippet lines when printing to stdout.
75 // Avoids flooding the logs with amount of output that gums up
76 // the infrastructure.
77 const size_t kOutputSnippetLinesLimit = 5000;
78
79 // Set of live launch test processes with corresponding lock (it is allowed
80 // for callers to launch processes on different threads).
81 LazyInstance<std::map<ProcessHandle, CommandLine> > g_live_processes
82     = LAZY_INSTANCE_INITIALIZER;
83 LazyInstance<Lock> g_live_processes_lock = LAZY_INSTANCE_INITIALIZER;
84
85 #if defined(OS_POSIX)
86 // Self-pipe that makes it possible to do complex shutdown handling
87 // outside of the signal handler.
88 int g_shutdown_pipe[2] = { -1, -1 };
89
90 void ShutdownPipeSignalHandler(int signal) {
91   HANDLE_EINTR(write(g_shutdown_pipe[1], "q", 1));
92 }
93
94 void KillSpawnedTestProcesses() {
95   // Keep the lock until exiting the process to prevent further processes
96   // from being spawned.
97   AutoLock lock(g_live_processes_lock.Get());
98
99   fprintf(stdout,
100           "Sending SIGTERM to %" PRIuS " child processes... ",
101           g_live_processes.Get().size());
102   fflush(stdout);
103
104   for (std::map<ProcessHandle, CommandLine>::iterator i =
105            g_live_processes.Get().begin();
106        i != g_live_processes.Get().end();
107        ++i) {
108     // Send the signal to entire process group.
109     kill((-1) * (i->first), SIGTERM);
110   }
111
112   fprintf(stdout,
113           "done.\nGiving processes a chance to terminate cleanly... ");
114   fflush(stdout);
115
116   PlatformThread::Sleep(TimeDelta::FromMilliseconds(500));
117
118   fprintf(stdout, "done.\n");
119   fflush(stdout);
120
121   fprintf(stdout,
122           "Sending SIGKILL to %" PRIuS " child processes... ",
123           g_live_processes.Get().size());
124   fflush(stdout);
125
126   for (std::map<ProcessHandle, CommandLine>::iterator i =
127            g_live_processes.Get().begin();
128        i != g_live_processes.Get().end();
129        ++i) {
130     // Send the signal to entire process group.
131     kill((-1) * (i->first), SIGKILL);
132   }
133
134   fprintf(stdout, "done.\n");
135   fflush(stdout);
136 }
137
138 // I/O watcher for the reading end of the self-pipe above.
139 // Terminates any launched child processes and exits the process.
140 class SignalFDWatcher : public MessageLoopForIO::Watcher {
141  public:
142   SignalFDWatcher() {
143   }
144
145   virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
146     fprintf(stdout, "\nCaught signal. Killing spawned test processes...\n");
147     fflush(stdout);
148
149     KillSpawnedTestProcesses();
150
151     // The signal would normally kill the process, so exit now.
152     exit(1);
153   }
154
155   virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {
156     NOTREACHED();
157   }
158
159  private:
160   DISALLOW_COPY_AND_ASSIGN(SignalFDWatcher);
161 };
162 #endif  // defined(OS_POSIX)
163
164 // Parses the environment variable var as an Int32.  If it is unset, returns
165 // true.  If it is set, unsets it then converts it to Int32 before
166 // returning it in |result|.  Returns true on success.
167 bool TakeInt32FromEnvironment(const char* const var, int32* result) {
168   scoped_ptr<Environment> env(Environment::Create());
169   std::string str_val;
170
171   if (!env->GetVar(var, &str_val))
172     return true;
173
174   if (!env->UnSetVar(var)) {
175     LOG(ERROR) << "Invalid environment: we could not unset " << var << ".\n";
176     return false;
177   }
178
179   if (!StringToInt(str_val, result)) {
180     LOG(ERROR) << "Invalid environment: " << var << " is not an integer.\n";
181     return false;
182   }
183
184   return true;
185 }
186
187 // Unsets the environment variable |name| and returns true on success.
188 // Also returns true if the variable just doesn't exist.
189 bool UnsetEnvironmentVariableIfExists(const std::string& name) {
190   scoped_ptr<Environment> env(Environment::Create());
191   std::string str_val;
192
193   if (!env->GetVar(name.c_str(), &str_val))
194     return true;
195
196   return env->UnSetVar(name.c_str());
197 }
198
199 // Returns true if bot mode has been requested, i.e. defaults optimized
200 // for continuous integration bots. This way developers don't have to remember
201 // special command-line flags.
202 bool BotModeEnabled() {
203   scoped_ptr<Environment> env(Environment::Create());
204   return CommandLine::ForCurrentProcess()->HasSwitch(
205       switches::kTestLauncherBotMode) ||
206       env->HasVar("CHROMIUM_TEST_LAUNCHER_BOT_MODE");
207 }
208
209 // Returns command line command line after gtest-specific processing
210 // and applying |wrapper|.
211 CommandLine PrepareCommandLineForGTest(const CommandLine& command_line,
212                                        const std::string& wrapper) {
213   CommandLine new_command_line(command_line.GetProgram());
214   CommandLine::SwitchMap switches = command_line.GetSwitches();
215
216   // Strip out gtest_repeat flag - this is handled by the launcher process.
217   switches.erase(kGTestRepeatFlag);
218
219   // Don't try to write the final XML report in child processes.
220   switches.erase(kGTestOutputFlag);
221
222   for (CommandLine::SwitchMap::const_iterator iter = switches.begin();
223        iter != switches.end(); ++iter) {
224     new_command_line.AppendSwitchNative((*iter).first, (*iter).second);
225   }
226
227   // Prepend wrapper after last CommandLine quasi-copy operation. CommandLine
228   // does not really support removing switches well, and trying to do that
229   // on a CommandLine with a wrapper is known to break.
230   // TODO(phajdan.jr): Give it a try to support CommandLine removing switches.
231 #if defined(OS_WIN)
232   new_command_line.PrependWrapper(ASCIIToWide(wrapper));
233 #elif defined(OS_POSIX)
234   new_command_line.PrependWrapper(wrapper);
235 #endif
236
237   return new_command_line;
238 }
239
240 // Launches a child process using |command_line|. If the child process is still
241 // running after |timeout|, it is terminated and |*was_timeout| is set to true.
242 // Returns exit code of the process.
243 int LaunchChildTestProcessWithOptions(const CommandLine& command_line,
244                                       const LaunchOptions& options,
245                                       int flags,
246                                       base::TimeDelta timeout,
247                                       bool* was_timeout) {
248 #if defined(OS_POSIX)
249   // Make sure an option we rely on is present - see LaunchChildGTestProcess.
250   DCHECK(options.new_process_group);
251 #endif
252
253   LaunchOptions new_options(options);
254
255 #if defined(OS_WIN)
256   DCHECK(!new_options.job_handle);
257
258   win::ScopedHandle job_handle;
259   if (flags & TestLauncher::USE_JOB_OBJECTS) {
260     job_handle.Set(CreateJobObject(NULL, NULL));
261     if (!job_handle.IsValid()) {
262       LOG(ERROR) << "Could not create JobObject.";
263       return -1;
264     }
265
266     DWORD job_flags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
267
268     // Allow break-away from job since sandbox and few other places rely on it
269     // on Windows versions prior to Windows 8 (which supports nested jobs).
270     if (win::GetVersion() < win::VERSION_WIN8 &&
271         flags & TestLauncher::ALLOW_BREAKAWAY_FROM_JOB) {
272       job_flags |= JOB_OBJECT_LIMIT_BREAKAWAY_OK;
273     }
274
275     if (!SetJobObjectLimitFlags(job_handle.Get(), job_flags)) {
276       LOG(ERROR) << "Could not SetJobObjectLimitFlags.";
277       return -1;
278     }
279
280     new_options.job_handle = job_handle.Get();
281   }
282 #endif  // defined(OS_WIN)
283
284 #if defined(OS_LINUX)
285   // To prevent accidental privilege sharing to an untrusted child, processes
286   // are started with PR_SET_NO_NEW_PRIVS. Do not set that here, since this
287   // new child will be privileged and trusted.
288   new_options.allow_new_privs = true;
289 #endif
290
291   base::ProcessHandle process_handle;
292
293   {
294     // Note how we grab the lock before the process possibly gets created.
295     // This ensures that when the lock is held, ALL the processes are registered
296     // in the set.
297     AutoLock lock(g_live_processes_lock.Get());
298
299     if (!base::LaunchProcess(command_line, new_options, &process_handle))
300       return -1;
301
302     g_live_processes.Get().insert(std::make_pair(process_handle, command_line));
303   }
304
305   int exit_code = 0;
306   if (!base::WaitForExitCodeWithTimeout(process_handle,
307                                         &exit_code,
308                                         timeout)) {
309     *was_timeout = true;
310     exit_code = -1;  // Set a non-zero exit code to signal a failure.
311
312     // Ensure that the process terminates.
313     base::KillProcess(process_handle, -1, true);
314   }
315
316   {
317     // Note how we grab the log before issuing a possibly broad process kill.
318     // Other code parts that grab the log kill processes, so avoid trying
319     // to do that twice and trigger all kinds of log messages.
320     AutoLock lock(g_live_processes_lock.Get());
321
322 #if defined(OS_POSIX)
323     if (exit_code != 0) {
324       // On POSIX, in case the test does not exit cleanly, either due to a crash
325       // or due to it timing out, we need to clean up any child processes that
326       // it might have created. On Windows, child processes are automatically
327       // cleaned up using JobObjects.
328       base::KillProcessGroup(process_handle);
329     }
330 #endif
331
332     g_live_processes.Get().erase(process_handle);
333   }
334
335   base::CloseProcessHandle(process_handle);
336
337   return exit_code;
338 }
339
340 void RunCallback(
341     const TestLauncher::LaunchChildGTestProcessCallback& callback,
342     int exit_code,
343     const TimeDelta& elapsed_time,
344     bool was_timeout,
345     const std::string& output) {
346   callback.Run(exit_code, elapsed_time, was_timeout, output);
347 }
348
349 void DoLaunchChildTestProcess(
350     const CommandLine& command_line,
351     base::TimeDelta timeout,
352     int flags,
353     bool redirect_stdio,
354     scoped_refptr<MessageLoopProxy> message_loop_proxy,
355     const TestLauncher::LaunchChildGTestProcessCallback& callback) {
356   TimeTicks start_time = TimeTicks::Now();
357
358   // Redirect child process output to a file.
359   base::FilePath output_file;
360   CHECK(base::CreateTemporaryFile(&output_file));
361
362   LaunchOptions options;
363 #if defined(OS_WIN)
364   win::ScopedHandle handle;
365
366   if (redirect_stdio) {
367     // Make the file handle inheritable by the child.
368     SECURITY_ATTRIBUTES sa_attr;
369     sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
370     sa_attr.lpSecurityDescriptor = NULL;
371     sa_attr.bInheritHandle = TRUE;
372
373     handle.Set(CreateFile(output_file.value().c_str(),
374                           GENERIC_WRITE,
375                           FILE_SHARE_READ | FILE_SHARE_DELETE,
376                           &sa_attr,
377                           OPEN_EXISTING,
378                           FILE_ATTRIBUTE_TEMPORARY,
379                           NULL));
380     CHECK(handle.IsValid());
381     options.inherit_handles = true;
382     options.stdin_handle = INVALID_HANDLE_VALUE;
383     options.stdout_handle = handle.Get();
384     options.stderr_handle = handle.Get();
385   }
386 #elif defined(OS_POSIX)
387   options.new_process_group = true;
388
389   base::FileHandleMappingVector fds_mapping;
390   base::ScopedFD output_file_fd;
391
392   if (redirect_stdio) {
393     output_file_fd.reset(open(output_file.value().c_str(), O_RDWR));
394     CHECK(output_file_fd.is_valid());
395
396     fds_mapping.push_back(std::make_pair(output_file_fd.get(), STDOUT_FILENO));
397     fds_mapping.push_back(std::make_pair(output_file_fd.get(), STDERR_FILENO));
398     options.fds_to_remap = &fds_mapping;
399   }
400 #endif
401
402   bool was_timeout = false;
403   int exit_code = LaunchChildTestProcessWithOptions(
404       command_line, options, flags, timeout, &was_timeout);
405
406   if (redirect_stdio) {
407 #if defined(OS_WIN)
408     FlushFileBuffers(handle.Get());
409     handle.Close();
410 #elif defined(OS_POSIX)
411     output_file_fd.reset();
412 #endif
413   }
414
415   std::string output_file_contents;
416   CHECK(base::ReadFileToString(output_file, &output_file_contents));
417
418   if (!base::DeleteFile(output_file, false)) {
419     // This needs to be non-fatal at least for Windows.
420     LOG(WARNING) << "Failed to delete " << output_file.AsUTF8Unsafe();
421   }
422
423   // Run target callback on the thread it was originating from, not on
424   // a worker pool thread.
425   message_loop_proxy->PostTask(
426       FROM_HERE,
427       Bind(&RunCallback,
428            callback,
429            exit_code,
430            TimeTicks::Now() - start_time,
431            was_timeout,
432            output_file_contents));
433 }
434
435 }  // namespace
436
437 const char kGTestFilterFlag[] = "gtest_filter";
438 const char kGTestHelpFlag[]   = "gtest_help";
439 const char kGTestListTestsFlag[] = "gtest_list_tests";
440 const char kGTestRepeatFlag[] = "gtest_repeat";
441 const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests";
442 const char kGTestOutputFlag[] = "gtest_output";
443
444 TestLauncherDelegate::~TestLauncherDelegate() {
445 }
446
447 TestLauncher::TestLauncher(TestLauncherDelegate* launcher_delegate,
448                            size_t parallel_jobs)
449     : launcher_delegate_(launcher_delegate),
450       total_shards_(1),
451       shard_index_(0),
452       cycles_(1),
453       test_started_count_(0),
454       test_finished_count_(0),
455       test_success_count_(0),
456       test_broken_count_(0),
457       retry_count_(0),
458       retry_limit_(0),
459       run_result_(true),
460       watchdog_timer_(FROM_HERE,
461                       TimeDelta::FromSeconds(kOutputTimeoutSeconds),
462                       this,
463                       &TestLauncher::OnOutputTimeout),
464       parallel_jobs_(parallel_jobs) {
465 }
466
467 TestLauncher::~TestLauncher() {
468   if (worker_pool_owner_)
469     worker_pool_owner_->pool()->Shutdown();
470 }
471
472 bool TestLauncher::Run() {
473   if (!Init())
474     return false;
475
476   // Value of |cycles_| changes after each iteration. Keep track of the
477   // original value.
478   int requested_cycles = cycles_;
479
480 #if defined(OS_POSIX)
481   CHECK_EQ(0, pipe(g_shutdown_pipe));
482
483   struct sigaction action;
484   memset(&action, 0, sizeof(action));
485   sigemptyset(&action.sa_mask);
486   action.sa_handler = &ShutdownPipeSignalHandler;
487
488   CHECK_EQ(0, sigaction(SIGINT, &action, NULL));
489   CHECK_EQ(0, sigaction(SIGQUIT, &action, NULL));
490   CHECK_EQ(0, sigaction(SIGTERM, &action, NULL));
491
492   MessageLoopForIO::FileDescriptorWatcher controller;
493   SignalFDWatcher watcher;
494
495   CHECK(MessageLoopForIO::current()->WatchFileDescriptor(
496             g_shutdown_pipe[0],
497             true,
498             MessageLoopForIO::WATCH_READ,
499             &controller,
500             &watcher));
501 #endif  // defined(OS_POSIX)
502
503   // Start the watchdog timer.
504   watchdog_timer_.Reset();
505
506   MessageLoop::current()->PostTask(
507       FROM_HERE,
508       Bind(&TestLauncher::RunTestIteration, Unretained(this)));
509
510   MessageLoop::current()->Run();
511
512   if (requested_cycles != 1)
513     results_tracker_.PrintSummaryOfAllIterations();
514
515   MaybeSaveSummaryAsJSON();
516
517   return run_result_;
518 }
519
520 void TestLauncher::LaunchChildGTestProcess(
521     const CommandLine& command_line,
522     const std::string& wrapper,
523     base::TimeDelta timeout,
524     int flags,
525     const LaunchChildGTestProcessCallback& callback) {
526   DCHECK(thread_checker_.CalledOnValidThread());
527
528   // Record the exact command line used to launch the child.
529   CommandLine new_command_line(
530       PrepareCommandLineForGTest(command_line, wrapper));
531
532   // When running in parallel mode we need to redirect stdio to avoid mixed-up
533   // output. We also always redirect on the bots to get the test output into
534   // JSON summary.
535   bool redirect_stdio = (parallel_jobs_ > 1) || BotModeEnabled();
536
537   worker_pool_owner_->pool()->PostWorkerTask(
538       FROM_HERE,
539       Bind(&DoLaunchChildTestProcess,
540            new_command_line,
541            timeout,
542            flags,
543            redirect_stdio,
544            MessageLoopProxy::current(),
545            Bind(&TestLauncher::OnLaunchTestProcessFinished,
546                 Unretained(this),
547                 callback)));
548 }
549
550 void TestLauncher::OnTestFinished(const TestResult& result) {
551   ++test_finished_count_;
552
553   bool print_snippet = false;
554   std::string print_test_stdio("auto");
555   if (CommandLine::ForCurrentProcess()->HasSwitch(
556           switches::kTestLauncherPrintTestStdio)) {
557     print_test_stdio = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
558         switches::kTestLauncherPrintTestStdio);
559   }
560   if (print_test_stdio == "auto") {
561     print_snippet = (result.status != TestResult::TEST_SUCCESS);
562   } else if (print_test_stdio == "always") {
563     print_snippet = true;
564   } else if (print_test_stdio == "never") {
565     print_snippet = false;
566   } else {
567     LOG(WARNING) << "Invalid value of " << switches::kTestLauncherPrintTestStdio
568                  << ": " << print_test_stdio;
569   }
570   if (print_snippet) {
571     std::vector<std::string> snippet_lines;
572     SplitString(result.output_snippet, '\n', &snippet_lines);
573     if (snippet_lines.size() > kOutputSnippetLinesLimit) {
574       size_t truncated_size = snippet_lines.size() - kOutputSnippetLinesLimit;
575       snippet_lines.erase(
576           snippet_lines.begin(),
577           snippet_lines.begin() + truncated_size);
578       snippet_lines.insert(snippet_lines.begin(), "<truncated>");
579     }
580     fprintf(stdout, "%s", JoinString(snippet_lines, "\n").c_str());
581     fflush(stdout);
582   }
583
584   if (result.status == TestResult::TEST_SUCCESS) {
585     ++test_success_count_;
586   } else {
587     tests_to_retry_.insert(result.full_name);
588   }
589
590   results_tracker_.AddTestResult(result);
591
592   // TODO(phajdan.jr): Align counter (padding).
593   std::string status_line(
594       StringPrintf("[%" PRIuS "/%" PRIuS "] %s ",
595                    test_finished_count_,
596                    test_started_count_,
597                    result.full_name.c_str()));
598   if (result.completed()) {
599     status_line.append(StringPrintf("(%" PRId64 " ms)",
600                                     result.elapsed_time.InMilliseconds()));
601   } else if (result.status == TestResult::TEST_TIMEOUT) {
602     status_line.append("(TIMED OUT)");
603   } else if (result.status == TestResult::TEST_CRASH) {
604     status_line.append("(CRASHED)");
605   } else if (result.status == TestResult::TEST_SKIPPED) {
606     status_line.append("(SKIPPED)");
607   } else if (result.status == TestResult::TEST_UNKNOWN) {
608     status_line.append("(UNKNOWN)");
609   } else {
610     // Fail very loudly so it's not ignored.
611     CHECK(false) << "Unhandled test result status: " << result.status;
612   }
613   fprintf(stdout, "%s\n", status_line.c_str());
614   fflush(stdout);
615
616   // We just printed a status line, reset the watchdog timer.
617   watchdog_timer_.Reset();
618
619   // Do not waste time on timeouts. We include tests with unknown results here
620   // because sometimes (e.g. hang in between unit tests) that's how a timeout
621   // gets reported.
622   if (result.status == TestResult::TEST_TIMEOUT ||
623       result.status == TestResult::TEST_UNKNOWN) {
624     test_broken_count_++;
625   }
626   size_t broken_threshold =
627       std::max(static_cast<size_t>(20), test_started_count_ / 10);
628   if (test_broken_count_ >= broken_threshold) {
629     fprintf(stdout, "Too many badly broken tests (%" PRIuS "), exiting now.\n",
630             test_broken_count_);
631     fflush(stdout);
632
633 #if defined(OS_POSIX)
634     KillSpawnedTestProcesses();
635 #endif  // defined(OS_POSIX)
636
637     results_tracker_.AddGlobalTag("BROKEN_TEST_EARLY_EXIT");
638     results_tracker_.AddGlobalTag(kUnreliableResultsTag);
639     MaybeSaveSummaryAsJSON();
640
641     exit(1);
642   }
643
644   if (test_finished_count_ != test_started_count_)
645     return;
646
647   if (tests_to_retry_.empty() || retry_count_ >= retry_limit_) {
648     OnTestIterationFinished();
649     return;
650   }
651
652   if (tests_to_retry_.size() >= broken_threshold) {
653     fprintf(stdout,
654             "Too many failing tests (%" PRIuS "), skipping retries.\n",
655             tests_to_retry_.size());
656     fflush(stdout);
657
658     results_tracker_.AddGlobalTag("BROKEN_TEST_SKIPPED_RETRIES");
659     results_tracker_.AddGlobalTag(kUnreliableResultsTag);
660
661     OnTestIterationFinished();
662     return;
663   }
664
665   retry_count_++;
666
667   std::vector<std::string> test_names(tests_to_retry_.begin(),
668                                       tests_to_retry_.end());
669
670   tests_to_retry_.clear();
671
672   size_t retry_started_count = launcher_delegate_->RetryTests(this, test_names);
673   if (retry_started_count == 0) {
674     // Signal failure, but continue to run all requested test iterations.
675     // With the summary of all iterations at the end this is a good default.
676     run_result_ = false;
677
678     OnTestIterationFinished();
679     return;
680   }
681
682   fprintf(stdout, "Retrying %" PRIuS " test%s (retry #%" PRIuS ")\n",
683           retry_started_count,
684           retry_started_count > 1 ? "s" : "",
685           retry_count_);
686   fflush(stdout);
687
688   test_started_count_ += retry_started_count;
689 }
690
691 // static
692 std::string TestLauncher::FormatFullTestName(const std::string& test_case_name,
693                                              const std::string& test_name) {
694   return test_case_name + "." + test_name;
695 }
696
697 bool TestLauncher::Init() {
698   const CommandLine* command_line = CommandLine::ForCurrentProcess();
699
700   // Initialize sharding. Command line takes precedence over legacy environment
701   // variables.
702   if (command_line->HasSwitch(switches::kTestLauncherTotalShards) &&
703       command_line->HasSwitch(switches::kTestLauncherShardIndex)) {
704     if (!StringToInt(
705             command_line->GetSwitchValueASCII(
706                 switches::kTestLauncherTotalShards),
707             &total_shards_)) {
708       LOG(ERROR) << "Invalid value for " << switches::kTestLauncherTotalShards;
709       return false;
710     }
711     if (!StringToInt(
712             command_line->GetSwitchValueASCII(
713                 switches::kTestLauncherShardIndex),
714             &shard_index_)) {
715       LOG(ERROR) << "Invalid value for " << switches::kTestLauncherShardIndex;
716       return false;
717     }
718     fprintf(stdout,
719             "Using sharding settings from command line. This is shard %d/%d\n",
720             shard_index_, total_shards_);
721     fflush(stdout);
722   } else {
723     if (!TakeInt32FromEnvironment(kTestTotalShards, &total_shards_))
724       return false;
725     if (!TakeInt32FromEnvironment(kTestShardIndex, &shard_index_))
726       return false;
727     fprintf(stdout,
728             "Using sharding settings from environment. This is shard %d/%d\n",
729             shard_index_, total_shards_);
730     fflush(stdout);
731   }
732   if (shard_index_ < 0 ||
733       total_shards_ < 0 ||
734       shard_index_ >= total_shards_) {
735     LOG(ERROR) << "Invalid sharding settings: we require 0 <= "
736                << kTestShardIndex << " < " << kTestTotalShards
737                << ", but you have " << kTestShardIndex << "=" << shard_index_
738                << ", " << kTestTotalShards << "=" << total_shards_ << ".\n";
739     return false;
740   }
741
742   // Make sure we don't pass any sharding-related environment to the child
743   // processes. This test launcher implements the sharding completely.
744   CHECK(UnsetEnvironmentVariableIfExists("GTEST_TOTAL_SHARDS"));
745   CHECK(UnsetEnvironmentVariableIfExists("GTEST_SHARD_INDEX"));
746
747   if (command_line->HasSwitch(kGTestRepeatFlag) &&
748       !StringToInt(command_line->GetSwitchValueASCII(kGTestRepeatFlag),
749                    &cycles_)) {
750     LOG(ERROR) << "Invalid value for " << kGTestRepeatFlag;
751     return false;
752   }
753
754   if (command_line->HasSwitch(switches::kTestLauncherRetryLimit)) {
755     int retry_limit = -1;
756     if (!StringToInt(command_line->GetSwitchValueASCII(
757                          switches::kTestLauncherRetryLimit), &retry_limit) ||
758         retry_limit < 0) {
759       LOG(ERROR) << "Invalid value for " << switches::kTestLauncherRetryLimit;
760       return false;
761     }
762
763     retry_limit_ = retry_limit;
764   } else if (!command_line->HasSwitch(kGTestFilterFlag) || BotModeEnabled()) {
765     // Retry failures 3 times by default if we are running all of the tests or
766     // in bot mode.
767     retry_limit_ = 3;
768   }
769
770   if (command_line->HasSwitch(switches::kTestLauncherJobs)) {
771     int jobs = -1;
772     if (!StringToInt(command_line->GetSwitchValueASCII(
773                          switches::kTestLauncherJobs), &jobs) ||
774         jobs < 0) {
775       LOG(ERROR) << "Invalid value for " << switches::kTestLauncherJobs;
776       return false;
777     }
778
779     parallel_jobs_ = jobs;
780   } else if (command_line->HasSwitch(kGTestFilterFlag) && !BotModeEnabled()) {
781     // Do not run jobs in parallel by default if we are running a subset of
782     // the tests and if bot mode is off.
783     parallel_jobs_ = 1;
784   }
785
786   fprintf(stdout, "Using %" PRIuS " parallel jobs.\n", parallel_jobs_);
787   fflush(stdout);
788   worker_pool_owner_.reset(
789       new SequencedWorkerPoolOwner(parallel_jobs_, "test_launcher"));
790
791   if (command_line->HasSwitch(switches::kTestLauncherFilterFile) &&
792       command_line->HasSwitch(kGTestFilterFlag)) {
793     LOG(ERROR) << "Only one of --test-launcher-filter-file and --gtest_filter "
794                << "at a time is allowed.";
795     return false;
796   }
797
798   if (command_line->HasSwitch(switches::kTestLauncherFilterFile)) {
799     std::string filter;
800     if (!ReadFileToString(
801             command_line->GetSwitchValuePath(switches::kTestLauncherFilterFile),
802             &filter)) {
803       LOG(ERROR) << "Failed to read the filter file.";
804       return false;
805     }
806
807     std::vector<std::string> filter_lines;
808     SplitString(filter, '\n', &filter_lines);
809     for (size_t i = 0; i < filter_lines.size(); i++) {
810       if (filter_lines[i].empty())
811         continue;
812
813       if (filter_lines[i][0] == '-')
814         negative_test_filter_.push_back(filter_lines[i].substr(1));
815       else
816         positive_test_filter_.push_back(filter_lines[i]);
817     }
818   } else {
819     // Split --gtest_filter at '-', if there is one, to separate into
820     // positive filter and negative filter portions.
821     std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag);
822     size_t dash_pos = filter.find('-');
823     if (dash_pos == std::string::npos) {
824       SplitString(filter, ':', &positive_test_filter_);
825     } else {
826       // Everything up to the dash.
827       SplitString(filter.substr(0, dash_pos), ':', &positive_test_filter_);
828
829       // Everything after the dash.
830       SplitString(filter.substr(dash_pos + 1), ':', &negative_test_filter_);
831     }
832   }
833
834   if (!results_tracker_.Init(*command_line)) {
835     LOG(ERROR) << "Failed to initialize test results tracker.";
836     return 1;
837   }
838
839 #if defined(NDEBUG)
840   results_tracker_.AddGlobalTag("MODE_RELEASE");
841 #else
842   results_tracker_.AddGlobalTag("MODE_DEBUG");
843 #endif
844
845   // Operating systems (sorted alphabetically).
846   // Note that they can deliberately overlap, e.g. OS_LINUX is a subset
847   // of OS_POSIX.
848 #if defined(OS_ANDROID)
849   results_tracker_.AddGlobalTag("OS_ANDROID");
850 #endif
851
852 #if defined(OS_BSD)
853   results_tracker_.AddGlobalTag("OS_BSD");
854 #endif
855
856 #if defined(OS_FREEBSD)
857   results_tracker_.AddGlobalTag("OS_FREEBSD");
858 #endif
859
860 #if defined(OS_IOS)
861   results_tracker_.AddGlobalTag("OS_IOS");
862 #endif
863
864 #if defined(OS_LINUX)
865   results_tracker_.AddGlobalTag("OS_LINUX");
866 #endif
867
868 #if defined(OS_MACOSX)
869   results_tracker_.AddGlobalTag("OS_MACOSX");
870 #endif
871
872 #if defined(OS_NACL)
873   results_tracker_.AddGlobalTag("OS_NACL");
874 #endif
875
876 #if defined(OS_OPENBSD)
877   results_tracker_.AddGlobalTag("OS_OPENBSD");
878 #endif
879
880 #if defined(OS_POSIX)
881   results_tracker_.AddGlobalTag("OS_POSIX");
882 #endif
883
884 #if defined(OS_SOLARIS)
885   results_tracker_.AddGlobalTag("OS_SOLARIS");
886 #endif
887
888 #if defined(OS_WIN)
889   results_tracker_.AddGlobalTag("OS_WIN");
890 #endif
891
892   // CPU-related tags.
893 #if defined(ARCH_CPU_32_BITS)
894   results_tracker_.AddGlobalTag("CPU_32_BITS");
895 #endif
896
897 #if defined(ARCH_CPU_64_BITS)
898   results_tracker_.AddGlobalTag("CPU_64_BITS");
899 #endif
900
901   return true;
902 }
903
904 void TestLauncher::RunTests() {
905   testing::UnitTest* const unit_test = testing::UnitTest::GetInstance();
906
907   std::vector<std::string> test_names;
908
909   for (int i = 0; i < unit_test->total_test_case_count(); ++i) {
910     const testing::TestCase* test_case = unit_test->GetTestCase(i);
911     for (int j = 0; j < test_case->total_test_count(); ++j) {
912       const testing::TestInfo* test_info = test_case->GetTestInfo(j);
913       std::string test_name = FormatFullTestName(
914           test_info->test_case_name(), test_info->name());
915
916       results_tracker_.AddTest(test_name);
917
918       const CommandLine* command_line = CommandLine::ForCurrentProcess();
919       if (test_name.find("DISABLED") != std::string::npos) {
920         results_tracker_.AddDisabledTest(test_name);
921
922         // Skip disabled tests unless explicitly requested.
923         if (!command_line->HasSwitch(kGTestRunDisabledTestsFlag))
924           continue;
925       }
926
927       if (!launcher_delegate_->ShouldRunTest(test_case, test_info))
928         continue;
929
930       // Skip the test that doesn't match the filter (if given).
931       if (!positive_test_filter_.empty()) {
932         bool found = false;
933         for (size_t k = 0; k < positive_test_filter_.size(); ++k) {
934           if (MatchPattern(test_name, positive_test_filter_[k])) {
935             found = true;
936             break;
937           }
938         }
939
940         if (!found)
941           continue;
942       }
943       bool excluded = false;
944       for (size_t k = 0; k < negative_test_filter_.size(); ++k) {
945         if (MatchPattern(test_name, negative_test_filter_[k])) {
946           excluded = true;
947           break;
948         }
949       }
950       if (excluded)
951         continue;
952
953       if (base::Hash(test_name) % total_shards_ !=
954           static_cast<uint32>(shard_index_)) {
955         continue;
956       }
957
958       test_names.push_back(test_name);
959     }
960   }
961
962   test_started_count_ = launcher_delegate_->RunTests(this, test_names);
963
964   if (test_started_count_ == 0) {
965     fprintf(stdout, "0 tests run\n");
966     fflush(stdout);
967
968     // No tests have actually been started, so kick off the next iteration.
969     MessageLoop::current()->PostTask(
970         FROM_HERE,
971         Bind(&TestLauncher::RunTestIteration, Unretained(this)));
972   }
973 }
974
975 void TestLauncher::RunTestIteration() {
976   if (cycles_ == 0) {
977     MessageLoop::current()->Quit();
978     return;
979   }
980
981   // Special value "-1" means "repeat indefinitely".
982   cycles_ = (cycles_ == -1) ? cycles_ : cycles_ - 1;
983
984   test_started_count_ = 0;
985   test_finished_count_ = 0;
986   test_success_count_ = 0;
987   test_broken_count_ = 0;
988   retry_count_ = 0;
989   tests_to_retry_.clear();
990   results_tracker_.OnTestIterationStarting();
991
992   MessageLoop::current()->PostTask(
993       FROM_HERE, Bind(&TestLauncher::RunTests, Unretained(this)));
994 }
995
996 void TestLauncher::MaybeSaveSummaryAsJSON() {
997   const CommandLine* command_line = CommandLine::ForCurrentProcess();
998   if (command_line->HasSwitch(switches::kTestLauncherSummaryOutput)) {
999     FilePath summary_path(command_line->GetSwitchValuePath(
1000                               switches::kTestLauncherSummaryOutput));
1001     if (!results_tracker_.SaveSummaryAsJSON(summary_path)) {
1002       LOG(ERROR) << "Failed to save test launcher output summary.";
1003     }
1004   }
1005 }
1006
1007 void TestLauncher::OnLaunchTestProcessFinished(
1008     const LaunchChildGTestProcessCallback& callback,
1009     int exit_code,
1010     const TimeDelta& elapsed_time,
1011     bool was_timeout,
1012     const std::string& output) {
1013   DCHECK(thread_checker_.CalledOnValidThread());
1014
1015   callback.Run(exit_code, elapsed_time, was_timeout, output);
1016 }
1017
1018 void TestLauncher::OnTestIterationFinished() {
1019   TestResultsTracker::TestStatusMap tests_by_status(
1020       results_tracker_.GetTestStatusMapForCurrentIteration());
1021   if (!tests_by_status[TestResult::TEST_UNKNOWN].empty())
1022     results_tracker_.AddGlobalTag(kUnreliableResultsTag);
1023
1024   // When we retry tests, success is determined by having nothing more
1025   // to retry (everything eventually passed), as opposed to having
1026   // no failures at all.
1027   if (tests_to_retry_.empty()) {
1028     fprintf(stdout, "SUCCESS: all tests passed.\n");
1029     fflush(stdout);
1030   } else {
1031     // Signal failure, but continue to run all requested test iterations.
1032     // With the summary of all iterations at the end this is a good default.
1033     run_result_ = false;
1034   }
1035
1036   results_tracker_.PrintSummaryOfCurrentIteration();
1037
1038   // Kick off the next iteration.
1039   MessageLoop::current()->PostTask(
1040       FROM_HERE,
1041       Bind(&TestLauncher::RunTestIteration, Unretained(this)));
1042 }
1043
1044 void TestLauncher::OnOutputTimeout() {
1045   DCHECK(thread_checker_.CalledOnValidThread());
1046
1047   AutoLock lock(g_live_processes_lock.Get());
1048
1049   fprintf(stdout, "Still waiting for the following processes to finish:\n");
1050
1051   for (std::map<ProcessHandle, CommandLine>::iterator i =
1052            g_live_processes.Get().begin();
1053        i != g_live_processes.Get().end();
1054        ++i) {
1055 #if defined(OS_WIN)
1056     fwprintf(stdout, L"\t%s\n", i->second.GetCommandLineString().c_str());
1057 #else
1058     fprintf(stdout, "\t%s\n", i->second.GetCommandLineString().c_str());
1059 #endif
1060   }
1061
1062   fflush(stdout);
1063
1064   // Arm the timer again - otherwise it would fire only once.
1065   watchdog_timer_.Reset();
1066 }
1067
1068 std::string GetTestOutputSnippet(const TestResult& result,
1069                                  const std::string& full_output) {
1070   size_t run_pos = full_output.find(std::string("[ RUN      ] ") +
1071                                     result.full_name);
1072   if (run_pos == std::string::npos)
1073     return std::string();
1074
1075   size_t end_pos = full_output.find(std::string("[  FAILED  ] ") +
1076                                     result.full_name,
1077                                     run_pos);
1078   // Only clip the snippet to the "OK" message if the test really
1079   // succeeded. It still might have e.g. crashed after printing it.
1080   if (end_pos == std::string::npos &&
1081       result.status == TestResult::TEST_SUCCESS) {
1082     end_pos = full_output.find(std::string("[       OK ] ") +
1083                                result.full_name,
1084                                run_pos);
1085   }
1086   if (end_pos != std::string::npos) {
1087     size_t newline_pos = full_output.find("\n", end_pos);
1088     if (newline_pos != std::string::npos)
1089       end_pos = newline_pos + 1;
1090   }
1091
1092   std::string snippet(full_output.substr(run_pos));
1093   if (end_pos != std::string::npos)
1094     snippet = full_output.substr(run_pos, end_pos - run_pos);
1095
1096   return snippet;
1097 }
1098
1099 }  // namespace base