test_launcher.cc revision f2477e01787aa58f445919b809d89e252beef54f
14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/launcher/test_launcher.h"
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <fcntl.h>
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/at_exit.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/bind.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/command_line.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/environment.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/file_util.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/files/file_path.h"
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/format_macros.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/lazy_instance.h"
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/logging.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/message_loop/message_loop.h"
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/process/kill.h"
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/process/launch.h"
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/stringprintf.h"
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/launcher/test_results_tracker.h"
280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/test/sequenced_worker_pool_owner.h"
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/test_switches.h"
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/test_timeouts.h"
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/threading/thread_checker.h"
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/time/time.h"
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_MACOSX)
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/mac/scoped_nsautorelease_pool.h"
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace base {
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// See https://groups.google.com/a/chromium.org/d/msg/chromium-dev/nkdTP7sstSc/uT3FaE_sgkAJ .
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using ::operator<<;
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The environment variable name for the total number of test shards.
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The environment variable name for the test shard index.
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Maximum time of no output after which we print list of processes still
520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// running. This deliberately doesn't use TestTimeouts (which is otherwise
530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// a recommended solution), because they can be increased. This would defeat
540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// the purpose of this timeout, which is 1) to avoid buildbot "no output for
550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// X seconds" timeout killing the process 2) help communicate status of
560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// the test launcher to people looking at the output (no output for a long
570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// time is mysterious and gives no info about what is happening) 3) help
580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// debugging in case the process hangs anyway.
590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)const int kOutputTimeoutSeconds = 15;
600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Set of live launch test processes with corresponding lock (it is allowed
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// for callers to launch processes on different threads).
630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)LazyInstance<std::map<ProcessHandle, CommandLine> > g_live_processes
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    = LAZY_INSTANCE_INITIALIZER;
650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)LazyInstance<Lock> g_live_processes_lock = LAZY_INSTANCE_INITIALIZER;
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Self-pipe that makes it possible to do complex shutdown handling
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// outside of the signal handler.
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int g_shutdown_pipe[2] = { -1, -1 };
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShutdownPipeSignalHandler(int signal) {
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HANDLE_EINTR(write(g_shutdown_pipe[1], "q", 1));
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void KillSpawnedTestProcesses() {
770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Keep the lock until exiting the process to prevent further processes
780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // from being spawned.
790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AutoLock lock(g_live_processes_lock.Get());
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fprintf(stdout,
820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          "Sending SIGTERM to %" PRIuS " child processes... ",
830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          g_live_processes.Get().size());
840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fflush(stdout);
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (std::map<ProcessHandle, CommandLine>::iterator i =
870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           g_live_processes.Get().begin();
880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       i != g_live_processes.Get().end();
890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       ++i) {
900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // Send the signal to entire process group.
910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    kill((-1) * (i->first), SIGTERM);
920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fprintf(stdout,
950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          "done.\nGiving processes a chance to terminate cleanly... ");
960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fflush(stdout);
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  PlatformThread::Sleep(TimeDelta::FromMilliseconds(500));
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fprintf(stdout, "done.\n");
1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fflush(stdout);
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fprintf(stdout,
1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          "Sending SIGKILL to %" PRIuS " child processes... ",
1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          g_live_processes.Get().size());
1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fflush(stdout);
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (std::map<ProcessHandle, CommandLine>::iterator i =
1090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           g_live_processes.Get().begin();
1100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       i != g_live_processes.Get().end();
1110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       ++i) {
1120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // Send the signal to entire process group.
1130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    kill((-1) * (i->first), SIGKILL);
1140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fprintf(stdout, "done.\n");
1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fflush(stdout);
1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// I/O watcher for the reading end of the self-pipe above.
1210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Terminates any launched child processes and exits the process.
1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class SignalFDWatcher : public MessageLoopForIO::Watcher {
1230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SignalFDWatcher() {
1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
1280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fprintf(stdout, "\nCaught signal. Killing spawned test processes...\n");
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fflush(stdout);
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    KillSpawnedTestProcesses();
1320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // The signal would normally kill the process, so exit now.
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    exit(1);
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NOTREACHED();
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SignalFDWatcher);
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(OS_POSIX)
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Parses the environment variable var as an Int32.  If it is unset, returns
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// true.  If it is set, unsets it then converts it to Int32 before
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// returning it in |result|.  Returns true on success.
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool TakeInt32FromEnvironment(const char* const var, int32* result) {
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<Environment> env(Environment::Create());
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string str_val;
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!env->GetVar(var, &str_val))
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return true;
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!env->UnSetVar(var)) {
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Invalid environment: we could not unset " << var << ".\n";
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!StringToInt(str_val, result)) {
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Invalid environment: " << var << " is not an integer.\n";
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return true;
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Unsets the environment variable |name| and returns true on success.
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Also returns true if the variable just doesn't exist.
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool UnsetEnvironmentVariableIfExists(const std::string& name) {
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<Environment> env(Environment::Create());
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string str_val;
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!env->GetVar(name.c_str(), &str_val))
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return true;
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return env->UnSetVar(name.c_str());
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Returns true if bot mode has been requested, i.e. defaults optimized
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// for continuous integration bots. This way developers don't have to remember
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// special command-line flags.
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool BotModeEnabled() {
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<Environment> env(Environment::Create());
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return CommandLine::ForCurrentProcess()->HasSwitch(
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      switches::kTestLauncherBotMode) ||
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      env->HasVar("CHROMIUM_TEST_LAUNCHER_BOT_MODE");
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// For a basic pattern matching for gtest_filter options.  (Copied from
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// gtest.cc, see the comment below and http://crbug.com/44497)
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool PatternMatchesString(const char* pattern, const char* str) {
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  switch (*pattern) {
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case '\0':
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case ':':  // Either ':' or '\0' marks the end of the pattern.
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return *str == '\0';
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case '?':  // Matches any single character.
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return *str != '\0' && PatternMatchesString(pattern + 1, str + 1);
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case '*':  // Matches any string (possibly empty) of characters.
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return (*str != '\0' && PatternMatchesString(pattern, str + 1)) ||
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          PatternMatchesString(pattern + 1, str);
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    default:  // Non-special character.  Matches itself.
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return *pattern == *str &&
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          PatternMatchesString(pattern + 1, str + 1);
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// TODO(phajdan.jr): Avoid duplicating gtest code. (http://crbug.com/44497)
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// For basic pattern matching for gtest_filter options.  (Copied from
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// gtest.cc)
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool MatchesFilter(const std::string& name, const std::string& filter) {
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const char *cur_pattern = filter.c_str();
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (;;) {
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (PatternMatchesString(cur_pattern, name.c_str())) {
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return true;
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Finds the next pattern in the filter.
2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    cur_pattern = strchr(cur_pattern, ':');
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Returns if no more pattern can be found.
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (cur_pattern == NULL) {
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return false;
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Skips the pattern separater (the ':' character).
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    cur_pattern++;
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void RunCallback(
2330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const TestLauncher::LaunchChildGTestProcessCallback& callback,
2340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    int exit_code,
2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const TimeDelta& elapsed_time,
2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    bool was_timeout,
2370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const std::string& output) {
2380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback.Run(exit_code, elapsed_time, was_timeout, output);
2390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void DoLaunchChildTestProcess(
2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const CommandLine& command_line,
2430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::TimeDelta timeout,
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool redirect_stdio,
2450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    scoped_refptr<MessageLoopProxy> message_loop_proxy,
2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const TestLauncher::LaunchChildGTestProcessCallback& callback) {
2470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  TimeTicks start_time = TimeTicks::Now();
2480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Redirect child process output to a file.
2500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::FilePath output_file;
2510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CHECK(file_util::CreateTemporaryFile(&output_file));
2520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  LaunchOptions options;
2540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(OS_WIN)
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  win::ScopedHandle handle;
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (redirect_stdio) {
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Make the file handle inheritable by the child.
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SECURITY_ATTRIBUTES sa_attr;
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sa_attr.lpSecurityDescriptor = NULL;
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sa_attr.bInheritHandle = TRUE;
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    handle.Set(CreateFile(output_file.value().c_str(),
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          GENERIC_WRITE,
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          FILE_SHARE_READ | FILE_SHARE_DELETE,
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          &sa_attr,
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          OPEN_EXISTING,
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          FILE_ATTRIBUTE_TEMPORARY,
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          NULL));
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CHECK(handle.IsValid());
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    options.inherit_handles = true;
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    options.stdin_handle = INVALID_HANDLE_VALUE;
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    options.stdout_handle = handle.Get();
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    options.stderr_handle = handle.Get();
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
2770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#elif defined(OS_POSIX)
2780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  options.new_process_group = true;
2790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::FileHandleMappingVector fds_mapping;
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  file_util::ScopedFD output_file_fd_closer;
2820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (redirect_stdio) {
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int output_file_fd = open(output_file.value().c_str(), O_RDWR);
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CHECK_GE(output_file_fd, 0);
2860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    output_file_fd_closer.reset(&output_file_fd);
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fds_mapping.push_back(std::make_pair(output_file_fd, STDOUT_FILENO));
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fds_mapping.push_back(std::make_pair(output_file_fd, STDERR_FILENO));
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    options.fds_to_remap = &fds_mapping;
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
2930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif
2940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool was_timeout = false;
2960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  int exit_code = LaunchChildTestProcessWithOptions(
2970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      command_line, options, timeout, &was_timeout);
2980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (redirect_stdio) {
3000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(OS_WIN)
3010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  FlushFileBuffers(handle.Get());
3020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  handle.Close();
3030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#elif defined(OS_POSIX)
3040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  output_file_fd_closer.reset();
3050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
3070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::string output_file_contents;
3090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CHECK(base::ReadFileToString(output_file, &output_file_contents));
3100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!base::DeleteFile(output_file, false)) {
3120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // This needs to be non-fatal at least for Windows.
3130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    LOG(WARNING) << "Failed to delete " << output_file.AsUTF8Unsafe();
3140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
3150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Run target callback on the thread it was originating from, not on
3170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // a worker pool thread.
3180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  message_loop_proxy->PostTask(
3190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      FROM_HERE,
3200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      Bind(&RunCallback,
3210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           callback,
3220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           exit_code,
3230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           TimeTicks::Now() - start_time,
3240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           was_timeout,
3250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           output_file_contents));
3260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
3270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestFilterFlag[] = "gtest_filter";
3318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestHelpFlag[]   = "gtest_help";
3328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestListTestsFlag[] = "gtest_list_tests";
3338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestRepeatFlag[] = "gtest_repeat";
3348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests";
3358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestOutputFlag[] = "gtest_output";
3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TestLauncherDelegate::~TestLauncherDelegate() {
3388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TestLauncher::TestLauncher(TestLauncherDelegate* launcher_delegate,
3410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                           size_t parallel_jobs)
3428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : launcher_delegate_(launcher_delegate),
3438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      total_shards_(1),
3448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shard_index_(0),
3458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      cycles_(1),
3468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_started_count_(0),
3478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_finished_count_(0),
3488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_success_count_(0),
3490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      test_broken_count_(0),
3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      retry_count_(0),
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      retry_limit_(0),
3520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      run_result_(true),
3530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      watchdog_timer_(FROM_HERE,
3540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                      TimeDelta::FromSeconds(kOutputTimeoutSeconds),
3550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                      this,
3560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                      &TestLauncher::OnOutputTimeout),
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      parallel_jobs_(parallel_jobs) {
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (BotModeEnabled()) {
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fprintf(stdout,
360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            "Enabling defaults optimized for continuous integration bots.\n");
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fflush(stdout);
362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Enable test retries by default for bots. This can be still overridden
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // from command line using --test-launcher-retry-limit flag.
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    retry_limit_ = 3;
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Default to serial test execution if not running on a bot. This makes it
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // possible to disable stdio redirection and can still be overridden with
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // --test-launcher-jobs flag.
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    parallel_jobs_ = 1;
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
3728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TestLauncher::~TestLauncher() {
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (worker_pool_owner_)
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    worker_pool_owner_->pool()->Shutdown();
3771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool TestLauncher::Run(int argc, char** argv) {
3808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!Init())
3818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_POSIX)
3848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK_EQ(0, pipe(g_shutdown_pipe));
3858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  struct sigaction action;
3878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  memset(&action, 0, sizeof(action));
3888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  sigemptyset(&action.sa_mask);
3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  action.sa_handler = &ShutdownPipeSignalHandler;
3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK_EQ(0, sigaction(SIGINT, &action, NULL));
3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK_EQ(0, sigaction(SIGQUIT, &action, NULL));
3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK_EQ(0, sigaction(SIGTERM, &action, NULL));
3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MessageLoopForIO::FileDescriptorWatcher controller;
3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SignalFDWatcher watcher;
3978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK(MessageLoopForIO::current()->WatchFileDescriptor(
3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            g_shutdown_pipe[0],
4008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            true,
4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            MessageLoopForIO::WATCH_READ,
4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            &controller,
4038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            &watcher));
4048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif  // defined(OS_POSIX)
4054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Start the watchdog timer.
4070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  watchdog_timer_.Reset();
4080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MessageLoop::current()->PostTask(
4108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE,
4118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      Bind(&TestLauncher::RunTestIteration, Unretained(this)));
4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MessageLoop::current()->Run();
4144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (cycles_ != 1)
4168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    results_tracker_.PrintSummaryOfAllIterations();
4174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  MaybeSaveSummaryAsJSON();
4194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return run_result_;
4218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void TestLauncher::LaunchChildGTestProcess(
4240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const CommandLine& command_line,
4250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const std::string& wrapper,
4260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::TimeDelta timeout,
4270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const LaunchChildGTestProcessCallback& callback) {
4280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Record the exact command line used to launch the child.
4310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CommandLine new_command_line(
4320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      PrepareCommandLineForGTest(command_line, wrapper));
4330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // When running in parallel mode we need to redirect stdio to avoid mixed-up
435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // output. We also always redirect on the bots to get the test output into
436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // JSON summary.
437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool redirect_stdio = (parallel_jobs_ > 1) || BotModeEnabled();
438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  worker_pool_owner_->pool()->PostWorkerTask(
4400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      FROM_HERE,
4410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      Bind(&DoLaunchChildTestProcess,
4420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           new_command_line,
4430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           timeout,
444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)           redirect_stdio,
4450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           MessageLoopProxy::current(),
4460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           Bind(&TestLauncher::OnLaunchTestProcessFinished,
4470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                Unretained(this),
4480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                callback)));
4490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
4500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void TestLauncher::OnTestFinished(const TestResult& result) {
4521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ++test_finished_count_;
4531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool print_snippet = false;
4551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string print_test_stdio("auto");
4561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
4571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          switches::kTestLauncherPrintTestStdio)) {
4581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print_test_stdio = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
4591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        switches::kTestLauncherPrintTestStdio);
4601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (print_test_stdio == "auto") {
4621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print_snippet = (result.status != TestResult::TEST_SUCCESS);
4631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (print_test_stdio == "always") {
4641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print_snippet = true;
4651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (print_test_stdio == "never") {
4661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print_snippet = false;
4671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
4681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    LOG(WARNING) << "Invalid value of " << switches::kTestLauncherPrintTestStdio
4691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 << ": " << print_test_stdio;
4701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (print_snippet) {
4721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    fprintf(stdout, "%s", result.output_snippet.c_str());
4731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    fflush(stdout);
4741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (result.status == TestResult::TEST_SUCCESS) {
4771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ++test_success_count_;
4781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
4791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    tests_to_retry_.insert(result.full_name);
4801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  results_tracker_.AddTestResult(result);
4831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(phajdan.jr): Align counter (padding).
4851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string status_line(
4861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      StringPrintf("[%" PRIuS "/%" PRIuS "] %s ",
4871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   test_finished_count_,
4881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   test_started_count_,
4891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   result.full_name.c_str()));
4901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (result.completed()) {
4911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append(StringPrintf("(%" PRId64 " ms)",
4921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    result.elapsed_time.InMilliseconds()));
4931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (result.status == TestResult::TEST_TIMEOUT) {
4941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append("(TIMED OUT)");
4951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (result.status == TestResult::TEST_CRASH) {
4961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append("(CRASHED)");
4971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (result.status == TestResult::TEST_SKIPPED) {
4981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append("(SKIPPED)");
4991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (result.status == TestResult::TEST_UNKNOWN) {
5001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append("(UNKNOWN)");
5011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
5021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Fail very loudly so it's not ignored.
5031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CHECK(false) << "Unhandled test result status: " << result.status;
5041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
5051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  fprintf(stdout, "%s\n", status_line.c_str());
5061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  fflush(stdout);
5071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // We just printed a status line, reset the watchdog timer.
5090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  watchdog_timer_.Reset();
5100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
5111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (test_finished_count_ == test_started_count_) {
5121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!tests_to_retry_.empty() && retry_count_ < retry_limit_) {
5131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      retry_count_++;
5141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      std::vector<std::string> test_names(tests_to_retry_.begin(),
5161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                          tests_to_retry_.end());
5171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      tests_to_retry_.clear();
5191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      size_t retry_started_count =
5211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          launcher_delegate_->RetryTests(this, test_names);
5221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (retry_started_count == 0) {
5231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        // Signal failure, but continue to run all requested test iterations.
5241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        // With the summary of all iterations at the end this is a good default.
5251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        run_result_ = false;
5261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        // The current iteration is done.
5281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        fprintf(stdout, "%" PRIuS " test%s run\n",
5291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                test_finished_count_,
5301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                test_finished_count_ > 1 ? "s" : "");
5311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        fflush(stdout);
5321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        results_tracker_.PrintSummaryOfCurrentIteration();
5341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        // Kick off the next iteration.
5361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        MessageLoop::current()->PostTask(
5371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            FROM_HERE,
5381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            Bind(&TestLauncher::RunTestIteration, Unretained(this)));
5391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      } else {
5401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        fprintf(stdout, "Retrying %" PRIuS " test%s (retry #%" PRIuS ")\n",
5411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                retry_started_count,
5421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                retry_started_count > 1 ? "s" : "",
5431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                retry_count_);
5441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        fflush(stdout);
5451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        test_started_count_ += retry_started_count;
5471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      }
5481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    } else {
5491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // The current iteration is done.
5501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      fprintf(stdout, "%" PRIuS " test%s run\n",
5511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              test_finished_count_,
5521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              test_finished_count_ > 1 ? "s" : "");
5531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      fflush(stdout);
5541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      results_tracker_.PrintSummaryOfCurrentIteration();
5561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // When we retry tests, success is determined by having nothing more
5581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // to retry (everything eventually passed), as opposed to having
5591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // no failures at all.
5601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (!tests_to_retry_.empty()) {
5611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        // Signal failure, but continue to run all requested test iterations.
5621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        // With the summary of all iterations at the end this is a good default.
5631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        run_result_ = false;
5641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      }
5651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // Kick off the next iteration.
5671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      MessageLoop::current()->PostTask(
5681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          FROM_HERE,
5691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          Bind(&TestLauncher::RunTestIteration, Unretained(this)));
5701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
5711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
5720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
5730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Do not waste time on timeouts. We include tests with unknown results here
5740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // because sometimes (e.g. hang in between unit tests) that's how a timeout
5750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // gets reported.
5760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (result.status == TestResult::TEST_TIMEOUT ||
5770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      result.status == TestResult::TEST_UNKNOWN) {
5780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    test_broken_count_++;
5790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
5800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  size_t broken_threshold =
5810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      std::max(static_cast<size_t>(10), test_started_count_ / 10);
5820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (test_broken_count_ >= broken_threshold) {
5830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fprintf(stdout, "Too many badly broken tests (%" PRIuS "), exiting now.\n",
5840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            test_broken_count_);
5850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fflush(stdout);
5860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
5870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(OS_POSIX)
5880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    KillSpawnedTestProcesses();
5890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif  // defined(OS_POSIX)
5900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
5910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    results_tracker_.AddGlobalTag("BROKEN_TEST_EARLY_EXIT");
5920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    MaybeSaveSummaryAsJSON();
5930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
5940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    exit(1);
5950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
5961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
5971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool TestLauncher::Init() {
5998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
6008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (command_line->HasSwitch(kGTestListTestsFlag)) {
6028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Child gtest processes would list tests instead of running tests.
6038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // TODO(phajdan.jr): Restore support for the flag.
6048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << kGTestListTestsFlag << " is not supported.";
6058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Initialize sharding. Command line takes precedence over legacy environment
6090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // variables.
6100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (command_line->HasSwitch(switches::kTestLauncherTotalShards) &&
6110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      command_line->HasSwitch(switches::kTestLauncherShardIndex)) {
6120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!StringToInt(
6130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            command_line->GetSwitchValueASCII(
6140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                switches::kTestLauncherTotalShards),
6150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            &total_shards_)) {
6160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      LOG(ERROR) << "Invalid value for " << switches::kTestLauncherTotalShards;
6170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return false;
6180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
6190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!StringToInt(
6200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            command_line->GetSwitchValueASCII(
6210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                switches::kTestLauncherShardIndex),
6220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            &shard_index_)) {
6230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      LOG(ERROR) << "Invalid value for " << switches::kTestLauncherShardIndex;
6240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return false;
6250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
6260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fprintf(stdout,
6270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            "Using sharding settings from command line. This is shard %d/%d\n",
6280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            shard_index_, total_shards_);
6290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fflush(stdout);
6300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  } else {
6310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!TakeInt32FromEnvironment(kTestTotalShards, &total_shards_))
6320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return false;
6330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!TakeInt32FromEnvironment(kTestShardIndex, &shard_index_))
6340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return false;
6350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fprintf(stdout,
6360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            "Using sharding settings from environment. This is shard %d/%d\n",
6370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            shard_index_, total_shards_);
6380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fflush(stdout);
6390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
6408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (shard_index_ < 0 ||
6418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      total_shards_ < 0 ||
6428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shard_index_ >= total_shards_) {
6430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    LOG(ERROR) << "Invalid sharding settings: we require 0 <= "
6448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               << kTestShardIndex << " < " << kTestTotalShards
6458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               << ", but you have " << kTestShardIndex << "=" << shard_index_
6468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               << ", " << kTestTotalShards << "=" << total_shards_ << ".\n";
6478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
6488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
6494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Make sure we don't pass any sharding-related environment to the child
651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // processes. This test launcher implements the sharding completely.
652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CHECK(UnsetEnvironmentVariableIfExists("GTEST_TOTAL_SHARDS"));
653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CHECK(UnsetEnvironmentVariableIfExists("GTEST_SHARD_INDEX"));
654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
6558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (command_line->HasSwitch(kGTestRepeatFlag) &&
6568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      !StringToInt(command_line->GetSwitchValueASCII(kGTestRepeatFlag),
6578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                   &cycles_)) {
6588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << "Invalid value for " << kGTestRepeatFlag;
6598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
6608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
6614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          switches::kTestLauncherRetryLimit)) {
664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int retry_limit = -1;
665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!StringToInt(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         switches::kTestLauncherRetryLimit), &retry_limit) ||
667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        retry_limit < 0) {
668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      LOG(ERROR) << "Invalid value for " << switches::kTestLauncherRetryLimit;
669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    retry_limit_ = retry_limit;
673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
675f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          switches::kTestLauncherJobs)) {
677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int jobs = -1;
678f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!StringToInt(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         switches::kTestLauncherJobs), &jobs) ||
680f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        jobs < 0) {
681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      LOG(ERROR) << "Invalid value for " << switches::kTestLauncherJobs;
682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    parallel_jobs_ = jobs;
686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  fprintf(stdout, "Using %" PRIuS " parallel jobs.\n", parallel_jobs_);
688f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  fflush(stdout);
689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  worker_pool_owner_.reset(
690f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new SequencedWorkerPoolOwner(parallel_jobs_, "test_launcher"));
691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
6928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Split --gtest_filter at '-', if there is one, to separate into
6938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // positive filter and negative filter portions.
6948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag);
6958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  positive_test_filter_ = filter;
6968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  size_t dash_pos = filter.find('-');
6978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (dash_pos != std::string::npos) {
6988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Everything up to the dash.
6998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    positive_test_filter_ = filter.substr(0, dash_pos);
7008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Everything after the dash.
7028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    negative_test_filter_ = filter.substr(dash_pos + 1);
7034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
7044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!results_tracker_.Init(*command_line)) {
7068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << "Failed to initialize test results tracker.";
7078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return 1;
7088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
7094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
7118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
7124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TestLauncher::RunTests() {
7148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  testing::UnitTest* const unit_test = testing::UnitTest::GetInstance();
7154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int num_runnable_tests = 0;
7174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<std::string> test_names;
7191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (int i = 0; i < unit_test->total_test_case_count(); ++i) {
7218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const testing::TestCase* test_case = unit_test->GetTestCase(i);
7228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    for (int j = 0; j < test_case->total_test_count(); ++j) {
7238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const testing::TestInfo* test_info = test_case->GetTestInfo(j);
7248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      std::string test_name = test_info->test_case_name();
7258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_name.append(".");
7268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_name.append(test_info->name());
7274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      // Skip disabled tests.
7298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const CommandLine* command_line = CommandLine::ForCurrentProcess();
7308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (test_name.find("DISABLED") != std::string::npos &&
7318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          !command_line->HasSwitch(kGTestRunDisabledTestsFlag)) {
7328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        continue;
7338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      }
7344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      std::string filtering_test_name =
7368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          launcher_delegate_->GetTestNameForFiltering(test_case, test_info);
7374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      // Skip the test that doesn't match the filter string (if given).
7398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if ((!positive_test_filter_.empty() &&
7408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)           !MatchesFilter(filtering_test_name, positive_test_filter_)) ||
7418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          MatchesFilter(filtering_test_name, negative_test_filter_)) {
7428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        continue;
7438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      }
7444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (!launcher_delegate_->ShouldRunTest(test_case, test_info))
7468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        continue;
7478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (num_runnable_tests++ % total_shards_ != shard_index_)
7498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        continue;
7508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      test_names.push_back(test_name);
7528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
7538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
7544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  test_started_count_ = launcher_delegate_->RunTests(this, test_names);
7564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (test_started_count_ == 0) {
7581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    fprintf(stdout, "0 tests run\n");
7591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    fflush(stdout);
7601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // No tests have actually been started, so kick off the next iteration.
7621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    MessageLoop::current()->PostTask(
7631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        FROM_HERE,
7641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        Bind(&TestLauncher::RunTestIteration, Unretained(this)));
7651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
7668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
7674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TestLauncher::RunTestIteration() {
7698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (cycles_ == 0) {
7708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    MessageLoop::current()->Quit();
7718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
7728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
7734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Special value "-1" means "repeat indefinitely".
7758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  cycles_ = (cycles_ == -1) ? cycles_ : cycles_ - 1;
7764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  test_started_count_ = 0;
7788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  test_finished_count_ = 0;
7798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  test_success_count_ = 0;
7800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  test_broken_count_ = 0;
7811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  retry_count_ = 0;
7821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tests_to_retry_.clear();
7838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  results_tracker_.OnTestIterationStarting();
7848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  launcher_delegate_->OnTestIterationStarting();
7854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MessageLoop::current()->PostTask(
7878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE, Bind(&TestLauncher::RunTests, Unretained(this)));
7884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
7894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void TestLauncher::MaybeSaveSummaryAsJSON() {
7910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
7920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (command_line->HasSwitch(switches::kTestLauncherSummaryOutput)) {
7930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    FilePath summary_path(command_line->GetSwitchValuePath(
7940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                              switches::kTestLauncherSummaryOutput));
7950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!results_tracker_.SaveSummaryAsJSON(summary_path)) {
7960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      LOG(ERROR) << "Failed to save test launcher output summary.";
7970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
7980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
7990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
8000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void TestLauncher::OnLaunchTestProcessFinished(
8020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const LaunchChildGTestProcessCallback& callback,
8030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    int exit_code,
8040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const TimeDelta& elapsed_time,
8050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    bool was_timeout,
8060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const std::string& output) {
8070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback.Run(exit_code, elapsed_time, was_timeout, output);
8100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
8110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void TestLauncher::OnOutputTimeout() {
8130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AutoLock lock(g_live_processes_lock.Get());
8160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fprintf(stdout, "Still waiting for the following processes to finish:\n");
8180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (std::map<ProcessHandle, CommandLine>::iterator i =
8200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           g_live_processes.Get().begin();
8210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       i != g_live_processes.Get().end();
8220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       ++i) {
8230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(OS_WIN)
8240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fwprintf(stdout, L"\t%s\n", i->second.GetCommandLineString().c_str());
8250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#else
8260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fprintf(stdout, "\t%s\n", i->second.GetCommandLineString().c_str());
8270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif
8280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
8290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fflush(stdout);
8310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Arm the timer again - otherwise it would fire only once.
8330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  watchdog_timer_.Reset();
8344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
8354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)std::string GetTestOutputSnippet(const TestResult& result,
8374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 const std::string& full_output) {
8384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t run_pos = full_output.find(std::string("[ RUN      ] ") +
8391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    result.full_name);
8404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (run_pos == std::string::npos)
8414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return std::string();
8424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t end_pos = full_output.find(std::string("[  FAILED  ] ") +
8441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    result.full_name,
8454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                    run_pos);
846f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Only clip the snippet to the "OK" message if the test really
847f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // succeeded. It still might have e.g. crashed after printing it.
848f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (end_pos == std::string::npos &&
849f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      result.status == TestResult::TEST_SUCCESS) {
8504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    end_pos = full_output.find(std::string("[       OK ] ") +
8511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                               result.full_name,
8524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               run_pos);
8534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (end_pos != std::string::npos) {
8554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    size_t newline_pos = full_output.find("\n", end_pos);
8564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (newline_pos != std::string::npos)
8574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      end_pos = newline_pos + 1;
8584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string snippet(full_output.substr(run_pos));
8614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (end_pos != std::string::npos)
8624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    snippet = full_output.substr(run_pos, end_pos - run_pos);
8634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return snippet;
8654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
8664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int LaunchChildGTestProcess(const CommandLine& command_line,
8684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            const std::string& wrapper,
8694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            base::TimeDelta timeout,
8704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            bool* was_timeout) {
8714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  LaunchOptions options;
8724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
8744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // On POSIX, we launch the test in a new process group with pgid equal to
8754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // its pid. Any child processes that the test may create will inherit the
8764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // same pgid. This way, if the test is abruptly terminated, we can clean up
8774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // any orphaned child processes it may have left behind.
8784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  options.new_process_group = true;
8794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
8804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return LaunchChildTestProcessWithOptions(
8824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      PrepareCommandLineForGTest(command_line, wrapper),
8834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      options,
8844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      timeout,
8854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      was_timeout);
8864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
8874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CommandLine PrepareCommandLineForGTest(const CommandLine& command_line,
8894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                       const std::string& wrapper) {
8904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CommandLine new_command_line(command_line.GetProgram());
8914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CommandLine::SwitchMap switches = command_line.GetSwitches();
8924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Strip out gtest_repeat flag - this is handled by the launcher process.
8944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  switches.erase(kGTestRepeatFlag);
8954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (CommandLine::SwitchMap::const_iterator iter = switches.begin();
8974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       iter != switches.end(); ++iter) {
8984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    new_command_line.AppendSwitchNative((*iter).first, (*iter).second);
8994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Prepend wrapper after last CommandLine quasi-copy operation. CommandLine
9024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // does not really support removing switches well, and trying to do that
9034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // on a CommandLine with a wrapper is known to break.
9044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(phajdan.jr): Give it a try to support CommandLine removing switches.
9054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN)
9064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_command_line.PrependWrapper(ASCIIToWide(wrapper));
9074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#elif defined(OS_POSIX)
9084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_command_line.PrependWrapper(wrapper);
9094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
9104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return new_command_line;
9124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
9134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int LaunchChildTestProcessWithOptions(const CommandLine& command_line,
9154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      const LaunchOptions& options,
9164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      base::TimeDelta timeout,
9174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      bool* was_timeout) {
9184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
9194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Make sure an option we rely on is present - see LaunchChildGTestProcess.
9204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(options.new_process_group);
9214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
9224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  LaunchOptions new_options(options);
9244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN)
9264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!new_options.job_handle);
9274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  win::ScopedHandle job_handle(CreateJobObject(NULL, NULL));
9294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!job_handle.IsValid()) {
9304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Could not create JobObject.";
9314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return -1;
9324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Allow break-away from job since sandbox and few other places rely on it
9354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // on Windows versions prior to Windows 8 (which supports nested jobs).
9364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(phajdan.jr): Do not allow break-away on Windows 8.
9374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!SetJobObjectLimitFlags(job_handle.Get(),
9384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE |
9394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              JOB_OBJECT_LIMIT_BREAKAWAY_OK)) {
9404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Could not SetJobObjectLimitFlags.";
9414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return -1;
9424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_options.job_handle = job_handle.Get();
9454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(OS_WIN)
9464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::ProcessHandle process_handle;
9484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
9504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Note how we grab the lock before the process possibly gets created.
9514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // This ensures that when the lock is held, ALL the processes are registered
9524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // in the set.
9530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    AutoLock lock(g_live_processes_lock.Get());
9544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!base::LaunchProcess(command_line, new_options, &process_handle))
9564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return -1;
9574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    g_live_processes.Get().insert(std::make_pair(process_handle, command_line));
9594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int exit_code = 0;
9624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!base::WaitForExitCodeWithTimeout(process_handle,
9634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        &exit_code,
9644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        timeout)) {
9654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    *was_timeout = true;
9664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    exit_code = -1;  // Set a non-zero exit code to signal a failure.
9674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Ensure that the process terminates.
9694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::KillProcess(process_handle, -1, true);
9704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
9734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Note how we grab the log before issuing a possibly broad process kill.
9744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Other code parts that grab the log kill processes, so avoid trying
9754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // to do that twice and trigger all kinds of log messages.
9760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    AutoLock lock(g_live_processes_lock.Get());
9774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
9794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (exit_code != 0) {
9804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // On POSIX, in case the test does not exit cleanly, either due to a crash
9814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // or due to it timing out, we need to clean up any child processes that
9824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // it might have created. On Windows, child processes are automatically
9834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // cleaned up using JobObjects.
9844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::KillProcessGroup(process_handle);
9854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
9864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
9874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    g_live_processes.Get().erase(process_handle);
9894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::CloseProcessHandle(process_handle);
9924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return exit_code;
9944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
9954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace base
997