test_launcher.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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"
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/test_switches.h"
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/test_timeouts.h"
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/threading/thread_checker.h"
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/time/time.h"
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_MACOSX)
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/mac/scoped_nsautorelease_pool.h"
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace base {
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// See https://groups.google.com/a/chromium.org/d/msg/chromium-dev/nkdTP7sstSc/uT3FaE_sgkAJ .
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using ::operator<<;
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The environment variable name for the total number of test shards.
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The environment variable name for the test shard index.
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Set of live launch test processes with corresponding lock (it is allowed
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// for callers to launch processes on different threads).
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)LazyInstance<std::set<ProcessHandle> > g_live_process_handles
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    = LAZY_INSTANCE_INITIALIZER;
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)LazyInstance<Lock> g_live_process_handles_lock = LAZY_INSTANCE_INITIALIZER;
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Self-pipe that makes it possible to do complex shutdown handling
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// outside of the signal handler.
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int g_shutdown_pipe[2] = { -1, -1 };
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShutdownPipeSignalHandler(int signal) {
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HANDLE_EINTR(write(g_shutdown_pipe[1], "q", 1));
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// I/O watcher for the reading end of the self-pipe above.
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Terminates any launched child processes and exits the process.
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class SignalFDWatcher : public MessageLoopForIO::Watcher {
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SignalFDWatcher() {
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fprintf(stdout, "\nCaught signal. Killing spawned test processes...\n");
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fflush(stdout);
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Keep the lock until exiting the process to prevent further processes
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // from being spawned.
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    AutoLock lock(g_live_process_handles_lock.Get());
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fprintf(stdout,
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            "Sending SIGTERM to %" PRIuS " child processes... ",
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            g_live_process_handles.Get().size());
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fflush(stdout);
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    for (std::set<ProcessHandle>::iterator i =
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             g_live_process_handles.Get().begin();
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)         i != g_live_process_handles.Get().end();
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)         ++i) {
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      kill((-1) * (*i), SIGTERM);  // Send the signal to entire process group.
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fprintf(stdout,
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            "done.\nGiving processes a chance to terminate cleanly... ");
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fflush(stdout);
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    PlatformThread::Sleep(TimeDelta::FromMilliseconds(500));
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fprintf(stdout, "done.\n");
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fflush(stdout);
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fprintf(stdout,
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            "Sending SIGKILL to %" PRIuS " child processes... ",
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            g_live_process_handles.Get().size());
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fflush(stdout);
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    for (std::set<ProcessHandle>::iterator i =
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             g_live_process_handles.Get().begin();
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)         i != g_live_process_handles.Get().end();
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)         ++i) {
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      kill((-1) * (*i), SIGKILL);  // Send the signal to entire process group.
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fprintf(stdout, "done.\n");
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fflush(stdout);
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // The signal would normally kill the process, so exit now.
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    exit(1);
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NOTREACHED();
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SignalFDWatcher);
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(OS_POSIX)
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Parses the environment variable var as an Int32.  If it is unset, returns
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// true.  If it is set, unsets it then converts it to Int32 before
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// returning it in |result|.  Returns true on success.
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool TakeInt32FromEnvironment(const char* const var, int32* result) {
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<Environment> env(Environment::Create());
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string str_val;
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!env->GetVar(var, &str_val))
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return true;
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!env->UnSetVar(var)) {
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Invalid environment: we could not unset " << var << ".\n";
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!StringToInt(str_val, result)) {
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Invalid environment: " << var << " is not an integer.\n";
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return true;
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// For a basic pattern matching for gtest_filter options.  (Copied from
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// gtest.cc, see the comment below and http://crbug.com/44497)
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool PatternMatchesString(const char* pattern, const char* str) {
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  switch (*pattern) {
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case '\0':
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case ':':  // Either ':' or '\0' marks the end of the pattern.
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return *str == '\0';
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case '?':  // Matches any single character.
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return *str != '\0' && PatternMatchesString(pattern + 1, str + 1);
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case '*':  // Matches any string (possibly empty) of characters.
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return (*str != '\0' && PatternMatchesString(pattern, str + 1)) ||
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          PatternMatchesString(pattern + 1, str);
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    default:  // Non-special character.  Matches itself.
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return *pattern == *str &&
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          PatternMatchesString(pattern + 1, str + 1);
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// TODO(phajdan.jr): Avoid duplicating gtest code. (http://crbug.com/44497)
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// For basic pattern matching for gtest_filter options.  (Copied from
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// gtest.cc)
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool MatchesFilter(const std::string& name, const std::string& filter) {
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const char *cur_pattern = filter.c_str();
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (;;) {
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (PatternMatchesString(cur_pattern, name.c_str())) {
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return true;
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Finds the next pattern in the filter.
1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    cur_pattern = strchr(cur_pattern, ':');
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Returns if no more pattern can be found.
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (cur_pattern == NULL) {
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return false;
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Skips the pattern separater (the ':' character).
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    cur_pattern++;
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Launches tests using a TestLauncherDelegate.
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class TestLauncher {
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  explicit TestLauncher(TestLauncherDelegate* launcher_delegate)
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : launcher_delegate_(launcher_delegate),
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        total_shards_(1),
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        shard_index_(0),
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        cycles_(1) {
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Runs the launcher. Must be called at most once.
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool Run(int argc, char** argv) WARN_UNUSED_RESULT {
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!Init())
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return false;
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CHECK_EQ(0, pipe(g_shutdown_pipe));
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    struct sigaction action;
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    memset(&action, 0, sizeof(action));
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    sigemptyset(&action.sa_mask);
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    action.sa_handler = &ShutdownPipeSignalHandler;
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CHECK_EQ(0, sigaction(SIGINT, &action, NULL));
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CHECK_EQ(0, sigaction(SIGQUIT, &action, NULL));
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CHECK_EQ(0, sigaction(SIGTERM, &action, NULL));
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MessageLoopForIO::FileDescriptorWatcher controller;
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    SignalFDWatcher watcher;
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CHECK(MessageLoopForIO::current()->WatchFileDescriptor(
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              g_shutdown_pipe[0],
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              true,
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              MessageLoopForIO::WATCH_READ,
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              &controller,
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              &watcher));
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(OS_POSIX)
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bool success = true;
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MessageLoop::current()->PostTask(
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        FROM_HERE,
2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        Bind(&TestLauncher::RunTestIteration,
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             Unretained(this),
2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             &success,
2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             true));
2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MessageLoop::current()->Run();
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (cycles_ != 1)
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      results_tracker_.PrintSummaryOfAllIterations();
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const CommandLine* command_line = CommandLine::ForCurrentProcess();
2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (command_line->HasSwitch(switches::kTestLauncherSummaryOutput)) {
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      FilePath summary_path(command_line->GetSwitchValuePath(
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                switches::kTestLauncherSummaryOutput));
2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (!results_tracker_.SaveSummaryAsJSON(summary_path)) {
2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        LOG(ERROR) << "Failed to save test launcher output summary.";
2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      }
2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return success;
2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool Init() WARN_UNUSED_RESULT {
2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const CommandLine* command_line = CommandLine::ForCurrentProcess();
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (command_line->HasSwitch(kGTestListTestsFlag)) {
2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Child gtest processes would list tests instead of running tests.
2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // TODO(phajdan.jr): Restore support for the flag.
2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      LOG(ERROR) << kGTestListTestsFlag << " is not supported.";
2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return false;
2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!TakeInt32FromEnvironment(kTestTotalShards, &total_shards_))
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return false;
2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!TakeInt32FromEnvironment(kTestShardIndex, &shard_index_))
2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return false;
2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (shard_index_ < 0 ||
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        total_shards_ < 0 ||
2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        shard_index_ >= total_shards_) {
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      LOG(ERROR) << "Invalid environment variables: we require 0 <= "
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 << kTestShardIndex << " < " << kTestTotalShards
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 << ", but you have " << kTestShardIndex << "=" << shard_index_
2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 << ", " << kTestTotalShards << "=" << total_shards_ << ".\n";
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return false;
2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (command_line->HasSwitch(kGTestRepeatFlag) &&
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        !StringToInt(command_line->GetSwitchValueASCII(kGTestRepeatFlag),
2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     &cycles_)) {
2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      LOG(ERROR) << "Invalid value for " << kGTestRepeatFlag;
2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return false;
2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Split --gtest_filter at '-', if there is one, to separate into
2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // positive filter and negative filter portions.
2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag);
2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    positive_test_filter_ = filter;
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    size_t dash_pos = filter.find('-');
2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (dash_pos != std::string::npos) {
2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Everything up to the dash.
2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      positive_test_filter_ = filter.substr(0, dash_pos);
2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Everything after the dash.
2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      negative_test_filter_ = filter.substr(dash_pos + 1);
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!results_tracker_.Init(*command_line)) {
3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      LOG(ERROR) << "Failed to initialize test results tracker.";
3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return 1;
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return true;
3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Runs all tests in current iteration. Uses callbacks to communicate success.
3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void RunTests() {
3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    testing::UnitTest* const unit_test = testing::UnitTest::GetInstance();
3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int num_runnable_tests = 0;
3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    for (int i = 0; i < unit_test->total_test_case_count(); ++i) {
3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const testing::TestCase* test_case = unit_test->GetTestCase(i);
3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      for (int j = 0; j < test_case->total_test_count(); ++j) {
3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        const testing::TestInfo* test_info = test_case->GetTestInfo(j);
3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        std::string test_name = test_info->test_case_name();
3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        test_name.append(".");
3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        test_name.append(test_info->name());
3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        // Skip disabled tests.
3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        const CommandLine* command_line = CommandLine::ForCurrentProcess();
3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if (test_name.find("DISABLED") != std::string::npos &&
3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            !command_line->HasSwitch(kGTestRunDisabledTestsFlag)) {
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          continue;
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        }
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        std::string filtering_test_name =
3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            launcher_delegate_->GetTestNameForFiltering(test_case, test_info);
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        // Skip the test that doesn't match the filter string (if given).
3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if ((!positive_test_filter_.empty() &&
3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             !MatchesFilter(filtering_test_name, positive_test_filter_)) ||
3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            MatchesFilter(filtering_test_name, negative_test_filter_)) {
3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          continue;
3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        }
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if (!launcher_delegate_->ShouldRunTest(test_case, test_info))
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          continue;
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if (num_runnable_tests++ % total_shards_ != shard_index_)
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          continue;
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        results_tracker_.OnTestStarted(test_name);
3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        MessageLoop::current()->PostTask(
3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            FROM_HERE,
3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            Bind(&TestLauncherDelegate::RunTest,
3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 Unretained(launcher_delegate_),
3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 test_case,
3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 test_info,
3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 Bind(&TestResultsTracker::AddTestResult,
3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      Unretained(&results_tracker_))));
3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      }
3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MessageLoop::current()->PostTask(
3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        FROM_HERE,
3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        Bind(&TestLauncherDelegate::RunRemainingTests,
3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             Unretained(launcher_delegate_)));
3624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MessageLoop::current()->PostTask(
3644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        FROM_HERE,
3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        Bind(&TestResultsTracker::OnAllTestsStarted,
3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             Unretained(&results_tracker_)));
3674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void RunTestIteration(bool* final_result, bool run_tests_success) {
3704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!run_tests_success) {
3714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Signal failure, but continue to run all requested test iterations.
3724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // With the summary of all iterations at the end this is a good default.
3734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      *final_result = false;
3744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (cycles_ == 0) {
3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      MessageLoop::current()->Quit();
3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return;
3794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Special value "-1" means "repeat indefinitely".
3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    cycles_ = (cycles_ == -1) ? cycles_ : cycles_ - 1;
3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    launcher_delegate_->OnTestIterationStarting();
3854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    results_tracker_.OnTestIterationStarting(
3874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        Bind(&TestLauncher::RunTestIteration, Unretained(this), final_result));
3884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MessageLoop::current()->PostTask(
3904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        FROM_HERE, Bind(&TestLauncher::RunTests, Unretained(this)));
3914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestLauncherDelegate* launcher_delegate_;
3944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Support for outer sharding, just like gtest does.
3964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int32 total_shards_;  // Total number of outer shards, at least one.
3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int32 shard_index_;   // Index of shard the launcher is to run.
3984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int cycles_;  // Number of remaining test itreations, or -1 for infinite.
4004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Test filters (empty means no filter). Entries are separated by colons.
4024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string positive_test_filter_;
4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string negative_test_filter_;
4044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestResultsTracker results_tracker_;
4064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestLauncher);
4084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
4094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace
4114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kGTestFilterFlag[] = "gtest_filter";
4134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kGTestHelpFlag[]   = "gtest_help";
4144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kGTestListTestsFlag[] = "gtest_list_tests";
4154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kGTestRepeatFlag[] = "gtest_repeat";
4164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests";
4174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kGTestOutputFlag[] = "gtest_output";
4184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TestResult::TestResult() : status(TEST_UNKNOWN) {
4204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TestResult::~TestResult() {
4234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)std::string TestResult::StatusAsString() const {
4264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  switch (status) {
4274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case TEST_UNKNOWN:
4284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return "UNKNOWN";
4294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case TEST_SUCCESS:
4304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return "SUCCESS";
4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case TEST_FAILURE:
4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return "FAILURE";
4334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case TEST_CRASH:
4344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return "CRASH";
4354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case TEST_TIMEOUT:
4364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return "TIMEOUT";
4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case TEST_SKIPPED:
4384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return "SKIPPED";
4394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)     // Rely on compiler warnings to ensure all possible values are handled.
4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NOTREACHED();
4434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return std::string();
4444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TestLauncherDelegate::~TestLauncherDelegate() {
4474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)std::string GetTestOutputSnippet(const TestResult& result,
4504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 const std::string& full_output) {
4514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t run_pos = full_output.find(std::string("[ RUN      ] ") +
4524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                    result.GetFullName());
4534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (run_pos == std::string::npos)
4544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return std::string();
4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t end_pos = full_output.find(std::string("[  FAILED  ] ") +
4574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                    result.GetFullName(),
4584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                    run_pos);
4594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (end_pos == std::string::npos) {
4604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    end_pos = full_output.find(std::string("[       OK ] ") +
4614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               result.GetFullName(),
4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               run_pos);
4634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (end_pos != std::string::npos) {
4654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    size_t newline_pos = full_output.find("\n", end_pos);
4664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (newline_pos != std::string::npos)
4674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      end_pos = newline_pos + 1;
4684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string snippet(full_output.substr(run_pos));
4714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (end_pos != std::string::npos)
4724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    snippet = full_output.substr(run_pos, end_pos - run_pos);
4734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return snippet;
4754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int LaunchChildGTestProcess(const CommandLine& command_line,
4784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            const std::string& wrapper,
4794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            base::TimeDelta timeout,
4804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            bool* was_timeout) {
4814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  LaunchOptions options;
4824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
4844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // On POSIX, we launch the test in a new process group with pgid equal to
4854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // its pid. Any child processes that the test may create will inherit the
4864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // same pgid. This way, if the test is abruptly terminated, we can clean up
4874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // any orphaned child processes it may have left behind.
4884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  options.new_process_group = true;
4894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
4904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return LaunchChildTestProcessWithOptions(
4924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      PrepareCommandLineForGTest(command_line, wrapper),
4934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      options,
4944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      timeout,
4954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      was_timeout);
4964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CommandLine PrepareCommandLineForGTest(const CommandLine& command_line,
4994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                       const std::string& wrapper) {
5004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CommandLine new_command_line(command_line.GetProgram());
5014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CommandLine::SwitchMap switches = command_line.GetSwitches();
5024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Strip out gtest_repeat flag - this is handled by the launcher process.
5044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  switches.erase(kGTestRepeatFlag);
5054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (CommandLine::SwitchMap::const_iterator iter = switches.begin();
5074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       iter != switches.end(); ++iter) {
5084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    new_command_line.AppendSwitchNative((*iter).first, (*iter).second);
5094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Prepend wrapper after last CommandLine quasi-copy operation. CommandLine
5124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // does not really support removing switches well, and trying to do that
5134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // on a CommandLine with a wrapper is known to break.
5144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(phajdan.jr): Give it a try to support CommandLine removing switches.
5154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN)
5164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_command_line.PrependWrapper(ASCIIToWide(wrapper));
5174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#elif defined(OS_POSIX)
5184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_command_line.PrependWrapper(wrapper);
5194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
5204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return new_command_line;
5224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int LaunchChildTestProcessWithOptions(const CommandLine& command_line,
5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      const LaunchOptions& options,
5264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      base::TimeDelta timeout,
5274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      bool* was_timeout) {
5284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
5294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Make sure an option we rely on is present - see LaunchChildGTestProcess.
5304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(options.new_process_group);
5314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
5324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  LaunchOptions new_options(options);
5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN)
5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!new_options.job_handle);
5374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  win::ScopedHandle job_handle(CreateJobObject(NULL, NULL));
5394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!job_handle.IsValid()) {
5404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Could not create JobObject.";
5414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return -1;
5424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Allow break-away from job since sandbox and few other places rely on it
5454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // on Windows versions prior to Windows 8 (which supports nested jobs).
5464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(phajdan.jr): Do not allow break-away on Windows 8.
5474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!SetJobObjectLimitFlags(job_handle.Get(),
5484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE |
5494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              JOB_OBJECT_LIMIT_BREAKAWAY_OK)) {
5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Could not SetJobObjectLimitFlags.";
5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return -1;
5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_options.job_handle = job_handle.Get();
5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(OS_WIN)
5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::ProcessHandle process_handle;
5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Note how we grab the lock before the process possibly gets created.
5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // This ensures that when the lock is held, ALL the processes are registered
5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // in the set.
5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    AutoLock lock(g_live_process_handles_lock.Get());
5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!base::LaunchProcess(command_line, new_options, &process_handle))
5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return -1;
5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    g_live_process_handles.Get().insert(process_handle);
5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int exit_code = 0;
5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!base::WaitForExitCodeWithTimeout(process_handle,
5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        &exit_code,
5744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        timeout)) {
5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    *was_timeout = true;
5764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    exit_code = -1;  // Set a non-zero exit code to signal a failure.
5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Ensure that the process terminates.
5794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::KillProcess(process_handle, -1, true);
5804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
5834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Note how we grab the log before issuing a possibly broad process kill.
5844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Other code parts that grab the log kill processes, so avoid trying
5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // to do that twice and trigger all kinds of log messages.
5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    AutoLock lock(g_live_process_handles_lock.Get());
5874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (exit_code != 0) {
5904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // On POSIX, in case the test does not exit cleanly, either due to a crash
5914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // or due to it timing out, we need to clean up any child processes that
5924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // it might have created. On Windows, child processes are automatically
5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // cleaned up using JobObjects.
5944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::KillProcessGroup(process_handle);
5954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
5974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    g_live_process_handles.Get().erase(process_handle);
5994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::CloseProcessHandle(process_handle);
6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return exit_code;
6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
6054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int LaunchTests(TestLauncherDelegate* launcher_delegate,
6074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                int argc,
6084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                char** argv) {
6094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(phajdan.jr): Replace usage of LaunchTests with code below.
6104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestLauncher launcher(launcher_delegate);
6114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return launcher.Run(argc, argv) ? 0 : 1;
6124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
6134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace base
615