test_launcher.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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)
1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestFilterFlag[] = "gtest_filter";
1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestHelpFlag[]   = "gtest_help";
1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestListTestsFlag[] = "gtest_list_tests";
1988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestRepeatFlag[] = "gtest_repeat";
1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests";
2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestOutputFlag[] = "gtest_output";
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TestLauncherDelegate::~TestLauncherDelegate() {
2038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TestLauncher::TestLauncher(TestLauncherDelegate* launcher_delegate)
2068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : launcher_delegate_(launcher_delegate),
2078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      total_shards_(1),
2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shard_index_(0),
2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      cycles_(1),
2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_started_count_(0),
2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_finished_count_(0),
2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_success_count_(0),
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      retry_count_(0),
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      retry_limit_(3),  // TODO(phajdan.jr): Make a flag control this.
2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      run_result_(true) {
2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TestLauncher::~TestLauncher() {
2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool TestLauncher::Run(int argc, char** argv) {
2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!Init())
2238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_POSIX)
2268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK_EQ(0, pipe(g_shutdown_pipe));
2278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  struct sigaction action;
2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  memset(&action, 0, sizeof(action));
2308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  sigemptyset(&action.sa_mask);
2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  action.sa_handler = &ShutdownPipeSignalHandler;
2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK_EQ(0, sigaction(SIGINT, &action, NULL));
2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK_EQ(0, sigaction(SIGQUIT, &action, NULL));
2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK_EQ(0, sigaction(SIGTERM, &action, NULL));
2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MessageLoopForIO::FileDescriptorWatcher controller;
2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SignalFDWatcher watcher;
2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK(MessageLoopForIO::current()->WatchFileDescriptor(
2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            g_shutdown_pipe[0],
2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            true,
2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            MessageLoopForIO::WATCH_READ,
2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            &controller,
2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            &watcher));
2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif  // defined(OS_POSIX)
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MessageLoop::current()->PostTask(
2498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE,
2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      Bind(&TestLauncher::RunTestIteration, Unretained(this)));
2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MessageLoop::current()->Run();
2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (cycles_ != 1)
2558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    results_tracker_.PrintSummaryOfAllIterations();
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (command_line->HasSwitch(switches::kTestLauncherSummaryOutput)) {
2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    FilePath summary_path(command_line->GetSwitchValuePath(
2608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                              switches::kTestLauncherSummaryOutput));
2618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (!results_tracker_.SaveSummaryAsJSON(summary_path)) {
2628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      LOG(ERROR) << "Failed to save test launcher output summary.";
2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return run_result_;
2678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void TestLauncher::OnTestFinished(const TestResult& result) {
2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ++test_finished_count_;
2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool print_snippet = false;
2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string print_test_stdio("auto");
2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          switches::kTestLauncherPrintTestStdio)) {
2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print_test_stdio = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
2771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        switches::kTestLauncherPrintTestStdio);
2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (print_test_stdio == "auto") {
2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print_snippet = (result.status != TestResult::TEST_SUCCESS);
2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (print_test_stdio == "always") {
2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print_snippet = true;
2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (print_test_stdio == "never") {
2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print_snippet = false;
2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    LOG(WARNING) << "Invalid value of " << switches::kTestLauncherPrintTestStdio
2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 << ": " << print_test_stdio;
2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (print_snippet) {
2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    fprintf(stdout, "%s", result.output_snippet.c_str());
2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    fflush(stdout);
2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (result.status == TestResult::TEST_SUCCESS) {
2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ++test_success_count_;
2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    tests_to_retry_.insert(result.full_name);
2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  results_tracker_.AddTestResult(result);
3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(phajdan.jr): Align counter (padding).
3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string status_line(
3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      StringPrintf("[%" PRIuS "/%" PRIuS "] %s ",
3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   test_finished_count_,
3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   test_started_count_,
3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   result.full_name.c_str()));
3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (result.completed()) {
3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append(StringPrintf("(%" PRId64 " ms)",
3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    result.elapsed_time.InMilliseconds()));
3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (result.status == TestResult::TEST_TIMEOUT) {
3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append("(TIMED OUT)");
3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (result.status == TestResult::TEST_CRASH) {
3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append("(CRASHED)");
3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (result.status == TestResult::TEST_SKIPPED) {
3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append("(SKIPPED)");
3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (result.status == TestResult::TEST_UNKNOWN) {
3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append("(UNKNOWN)");
3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Fail very loudly so it's not ignored.
3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CHECK(false) << "Unhandled test result status: " << result.status;
3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  fprintf(stdout, "%s\n", status_line.c_str());
3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  fflush(stdout);
3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (test_finished_count_ == test_started_count_) {
3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!tests_to_retry_.empty() && retry_count_ < retry_limit_) {
3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      retry_count_++;
3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      std::vector<std::string> test_names(tests_to_retry_.begin(),
3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                          tests_to_retry_.end());
3321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      tests_to_retry_.clear();
3341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      size_t retry_started_count =
3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          launcher_delegate_->RetryTests(this, test_names);
3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (retry_started_count == 0) {
3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        // Signal failure, but continue to run all requested test iterations.
3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        // With the summary of all iterations at the end this is a good default.
3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        run_result_ = false;
3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        // The current iteration is done.
3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        fprintf(stdout, "%" PRIuS " test%s run\n",
3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                test_finished_count_,
3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                test_finished_count_ > 1 ? "s" : "");
3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        fflush(stdout);
3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        results_tracker_.PrintSummaryOfCurrentIteration();
3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        // Kick off the next iteration.
3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        MessageLoop::current()->PostTask(
3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            FROM_HERE,
3531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            Bind(&TestLauncher::RunTestIteration, Unretained(this)));
3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      } else {
3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        fprintf(stdout, "Retrying %" PRIuS " test%s (retry #%" PRIuS ")\n",
3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                retry_started_count,
3571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                retry_started_count > 1 ? "s" : "",
3581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                retry_count_);
3591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        fflush(stdout);
3601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        test_started_count_ += retry_started_count;
3621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      }
3631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    } else {
3641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // The current iteration is done.
3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      fprintf(stdout, "%" PRIuS " test%s run\n",
3661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              test_finished_count_,
3671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              test_finished_count_ > 1 ? "s" : "");
3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      fflush(stdout);
3691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      results_tracker_.PrintSummaryOfCurrentIteration();
3711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // When we retry tests, success is determined by having nothing more
3731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // to retry (everything eventually passed), as opposed to having
3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // no failures at all.
3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (!tests_to_retry_.empty()) {
3761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        // Signal failure, but continue to run all requested test iterations.
3771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        // With the summary of all iterations at the end this is a good default.
3781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        run_result_ = false;
3791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      }
3801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // Kick off the next iteration.
3821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      MessageLoop::current()->PostTask(
3831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          FROM_HERE,
3841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          Bind(&TestLauncher::RunTestIteration, Unretained(this)));
3851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
3861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool TestLauncher::Init() {
3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (command_line->HasSwitch(kGTestListTestsFlag)) {
3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Child gtest processes would list tests instead of running tests.
3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // TODO(phajdan.jr): Restore support for the flag.
3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << kGTestListTestsFlag << " is not supported.";
3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!TakeInt32FromEnvironment(kTestTotalShards, &total_shards_))
4008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!TakeInt32FromEnvironment(kTestShardIndex, &shard_index_))
4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
4038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (shard_index_ < 0 ||
4048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      total_shards_ < 0 ||
4058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shard_index_ >= total_shards_) {
4068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << "Invalid environment variables: we require 0 <= "
4078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               << kTestShardIndex << " < " << kTestTotalShards
4088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               << ", but you have " << kTestShardIndex << "=" << shard_index_
4098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               << ", " << kTestTotalShards << "=" << total_shards_ << ".\n";
4108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
4118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (command_line->HasSwitch(kGTestRepeatFlag) &&
4148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      !StringToInt(command_line->GetSwitchValueASCII(kGTestRepeatFlag),
4158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                   &cycles_)) {
4168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << "Invalid value for " << kGTestRepeatFlag;
4178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
4188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Split --gtest_filter at '-', if there is one, to separate into
4218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // positive filter and negative filter portions.
4228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag);
4238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  positive_test_filter_ = filter;
4248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  size_t dash_pos = filter.find('-');
4258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (dash_pos != std::string::npos) {
4268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Everything up to the dash.
4278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    positive_test_filter_ = filter.substr(0, dash_pos);
4288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Everything after the dash.
4308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    negative_test_filter_ = filter.substr(dash_pos + 1);
4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!results_tracker_.Init(*command_line)) {
4348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << "Failed to initialize test results tracker.";
4358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return 1;
4368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
4398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TestLauncher::RunTests() {
4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  testing::UnitTest* const unit_test = testing::UnitTest::GetInstance();
4434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int num_runnable_tests = 0;
4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<std::string> test_names;
4471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (int i = 0; i < unit_test->total_test_case_count(); ++i) {
4498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const testing::TestCase* test_case = unit_test->GetTestCase(i);
4508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    for (int j = 0; j < test_case->total_test_count(); ++j) {
4518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const testing::TestInfo* test_info = test_case->GetTestInfo(j);
4528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      std::string test_name = test_info->test_case_name();
4538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_name.append(".");
4548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_name.append(test_info->name());
4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      // Skip disabled tests.
4578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const CommandLine* command_line = CommandLine::ForCurrentProcess();
4588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (test_name.find("DISABLED") != std::string::npos &&
4598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          !command_line->HasSwitch(kGTestRunDisabledTestsFlag)) {
4608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        continue;
4618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      }
4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      std::string filtering_test_name =
4648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          launcher_delegate_->GetTestNameForFiltering(test_case, test_info);
4654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      // Skip the test that doesn't match the filter string (if given).
4678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if ((!positive_test_filter_.empty() &&
4688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)           !MatchesFilter(filtering_test_name, positive_test_filter_)) ||
4698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          MatchesFilter(filtering_test_name, negative_test_filter_)) {
4708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        continue;
4718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      }
4724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (!launcher_delegate_->ShouldRunTest(test_case, test_info))
4748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        continue;
4758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (num_runnable_tests++ % total_shards_ != shard_index_)
4778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        continue;
4788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      test_names.push_back(test_name);
4808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
4818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  test_started_count_ = launcher_delegate_->RunTests(this, test_names);
4844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (test_started_count_ == 0) {
4861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    fprintf(stdout, "0 tests run\n");
4871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    fflush(stdout);
4881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // No tests have actually been started, so kick off the next iteration.
4901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    MessageLoop::current()->PostTask(
4911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        FROM_HERE,
4921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        Bind(&TestLauncher::RunTestIteration, Unretained(this)));
4931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TestLauncher::RunTestIteration() {
4978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (cycles_ == 0) {
4988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    MessageLoop::current()->Quit();
4998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
5008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Special value "-1" means "repeat indefinitely".
5038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  cycles_ = (cycles_ == -1) ? cycles_ : cycles_ - 1;
5044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  test_started_count_ = 0;
5068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  test_finished_count_ = 0;
5078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  test_success_count_ = 0;
5081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  retry_count_ = 0;
5091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tests_to_retry_.clear();
5108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  results_tracker_.OnTestIterationStarting();
5118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  launcher_delegate_->OnTestIterationStarting();
5124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MessageLoop::current()->PostTask(
5148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE, Bind(&TestLauncher::RunTests, Unretained(this)));
5154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TestLauncher::OnAllTestsStarted() {
5184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)std::string GetTestOutputSnippet(const TestResult& result,
5214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 const std::string& full_output) {
5224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t run_pos = full_output.find(std::string("[ RUN      ] ") +
5231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    result.full_name);
5244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (run_pos == std::string::npos)
5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return std::string();
5264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t end_pos = full_output.find(std::string("[  FAILED  ] ") +
5281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    result.full_name,
5294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                    run_pos);
5304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (end_pos == std::string::npos) {
5314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    end_pos = full_output.find(std::string("[       OK ] ") +
5321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                               result.full_name,
5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               run_pos);
5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (end_pos != std::string::npos) {
5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    size_t newline_pos = full_output.find("\n", end_pos);
5374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (newline_pos != std::string::npos)
5384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      end_pos = newline_pos + 1;
5394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string snippet(full_output.substr(run_pos));
5424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (end_pos != std::string::npos)
5434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    snippet = full_output.substr(run_pos, end_pos - run_pos);
5444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return snippet;
5464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int LaunchChildGTestProcess(const CommandLine& command_line,
5494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            const std::string& wrapper,
5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            base::TimeDelta timeout,
5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            bool* was_timeout) {
5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  LaunchOptions options;
5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // On POSIX, we launch the test in a new process group with pgid equal to
5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // its pid. Any child processes that the test may create will inherit the
5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // same pgid. This way, if the test is abruptly terminated, we can clean up
5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // any orphaned child processes it may have left behind.
5594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  options.new_process_group = true;
5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return LaunchChildTestProcessWithOptions(
5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      PrepareCommandLineForGTest(command_line, wrapper),
5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      options,
5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      timeout,
5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      was_timeout);
5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CommandLine PrepareCommandLineForGTest(const CommandLine& command_line,
5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                       const std::string& wrapper) {
5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CommandLine new_command_line(command_line.GetProgram());
5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CommandLine::SwitchMap switches = command_line.GetSwitches();
5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Strip out gtest_repeat flag - this is handled by the launcher process.
5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  switches.erase(kGTestRepeatFlag);
5764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (CommandLine::SwitchMap::const_iterator iter = switches.begin();
5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       iter != switches.end(); ++iter) {
5794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    new_command_line.AppendSwitchNative((*iter).first, (*iter).second);
5804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Prepend wrapper after last CommandLine quasi-copy operation. CommandLine
5834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // does not really support removing switches well, and trying to do that
5844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // on a CommandLine with a wrapper is known to break.
5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(phajdan.jr): Give it a try to support CommandLine removing switches.
5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN)
5874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_command_line.PrependWrapper(ASCIIToWide(wrapper));
5884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#elif defined(OS_POSIX)
5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_command_line.PrependWrapper(wrapper);
5904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
5914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return new_command_line;
5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int LaunchChildTestProcessWithOptions(const CommandLine& command_line,
5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      const LaunchOptions& options,
5974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      base::TimeDelta timeout,
5984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      bool* was_timeout) {
5994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Make sure an option we rely on is present - see LaunchChildGTestProcess.
6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(options.new_process_group);
6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  LaunchOptions new_options(options);
6054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN)
6074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!new_options.job_handle);
6084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  win::ScopedHandle job_handle(CreateJobObject(NULL, NULL));
6104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!job_handle.IsValid()) {
6114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Could not create JobObject.";
6124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return -1;
6134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Allow break-away from job since sandbox and few other places rely on it
6164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // on Windows versions prior to Windows 8 (which supports nested jobs).
6174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(phajdan.jr): Do not allow break-away on Windows 8.
6184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!SetJobObjectLimitFlags(job_handle.Get(),
6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE |
6204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              JOB_OBJECT_LIMIT_BREAKAWAY_OK)) {
6214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Could not SetJobObjectLimitFlags.";
6224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return -1;
6234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_options.job_handle = job_handle.Get();
6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(OS_WIN)
6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::ProcessHandle process_handle;
6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Note how we grab the lock before the process possibly gets created.
6324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // This ensures that when the lock is held, ALL the processes are registered
6334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // in the set.
6344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    AutoLock lock(g_live_process_handles_lock.Get());
6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!base::LaunchProcess(command_line, new_options, &process_handle))
6374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return -1;
6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    g_live_process_handles.Get().insert(process_handle);
6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int exit_code = 0;
6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!base::WaitForExitCodeWithTimeout(process_handle,
6444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        &exit_code,
6454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        timeout)) {
6464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    *was_timeout = true;
6474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    exit_code = -1;  // Set a non-zero exit code to signal a failure.
6484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Ensure that the process terminates.
6504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::KillProcess(process_handle, -1, true);
6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Note how we grab the log before issuing a possibly broad process kill.
6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Other code parts that grab the log kill processes, so avoid trying
6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // to do that twice and trigger all kinds of log messages.
6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    AutoLock lock(g_live_process_handles_lock.Get());
6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (exit_code != 0) {
6614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // On POSIX, in case the test does not exit cleanly, either due to a crash
6624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // or due to it timing out, we need to clean up any child processes that
6634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // it might have created. On Windows, child processes are automatically
6644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // cleaned up using JobObjects.
6654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::KillProcessGroup(process_handle);
6664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
6674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
6684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    g_live_process_handles.Get().erase(process_handle);
6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::CloseProcessHandle(process_handle);
6734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return exit_code;
6754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
6764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace base
678