test_launcher.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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/files/file_path.h"
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/files/file_util.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/files/scoped_file.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/format_macros.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/hash.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/lazy_instance.h"
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/logging.h"
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/message_loop/message_loop.h"
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/process/kill.h"
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/process/launch.h"
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_split.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_util.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/stringize_macros.h"
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/stringprintf.h"
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/launcher/test_results_tracker.h"
330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/test/sequenced_worker_pool_owner.h"
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/test_switches.h"
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/test_timeouts.h"
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/threading/thread_checker.h"
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/time/time.h"
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_MACOSX)
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/mac/scoped_nsautorelease_pool.h"
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if defined(OS_WIN)
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/win/windows_version.h"
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace base {
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Launches a child process using |command_line|. If the child process is still
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// running after |timeout|, it is terminated and |*was_timeout| is set to true.
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Returns exit code of the process.
53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int LaunchChildTestProcessWithOptions(const CommandLine& command_line,
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                      const LaunchOptions& options,
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                      int flags,
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                      base::TimeDelta timeout,
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                      bool* was_timeout);
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// See https://groups.google.com/a/chromium.org/d/msg/chromium-dev/nkdTP7sstSc/uT3FaE_sgkAJ .
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using ::operator<<;
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The environment variable name for the total number of test shards.
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The environment variable name for the test shard index.
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Global tag for test runs where the results are incomplete or unreliable
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// for any reason, e.g. early exit because of too many broken tests.
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kUnreliableResultsTag[] = "UNRELIABLE_RESULTS";
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Maximum time of no output after which we print list of processes still
740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// running. This deliberately doesn't use TestTimeouts (which is otherwise
750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// a recommended solution), because they can be increased. This would defeat
760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// the purpose of this timeout, which is 1) to avoid buildbot "no output for
770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// X seconds" timeout killing the process 2) help communicate status of
780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// the test launcher to people looking at the output (no output for a long
790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// time is mysterious and gives no info about what is happening) 3) help
800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// debugging in case the process hangs anyway.
810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)const int kOutputTimeoutSeconds = 15;
820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Limit of output snippet lines when printing to stdout.
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Avoids flooding the logs with amount of output that gums up
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// the infrastructure.
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst size_t kOutputSnippetLinesLimit = 5000;
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Set of live launch test processes with corresponding lock (it is allowed
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// for callers to launch processes on different threads).
900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)LazyInstance<std::map<ProcessHandle, CommandLine> > g_live_processes
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    = LAZY_INSTANCE_INITIALIZER;
920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)LazyInstance<Lock> g_live_processes_lock = LAZY_INSTANCE_INITIALIZER;
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Self-pipe that makes it possible to do complex shutdown handling
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// outside of the signal handler.
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int g_shutdown_pipe[2] = { -1, -1 };
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShutdownPipeSignalHandler(int signal) {
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HANDLE_EINTR(write(g_shutdown_pipe[1], "q", 1));
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void KillSpawnedTestProcesses() {
1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Keep the lock until exiting the process to prevent further processes
1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // from being spawned.
1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AutoLock lock(g_live_processes_lock.Get());
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fprintf(stdout,
1090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          "Sending SIGTERM to %" PRIuS " child processes... ",
1100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          g_live_processes.Get().size());
1110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fflush(stdout);
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (std::map<ProcessHandle, CommandLine>::iterator i =
1140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           g_live_processes.Get().begin();
1150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       i != g_live_processes.Get().end();
1160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       ++i) {
1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // Send the signal to entire process group.
1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    kill((-1) * (i->first), SIGTERM);
1190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fprintf(stdout,
1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          "done.\nGiving processes a chance to terminate cleanly... ");
1230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fflush(stdout);
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  PlatformThread::Sleep(TimeDelta::FromMilliseconds(500));
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fprintf(stdout, "done.\n");
1280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fflush(stdout);
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fprintf(stdout,
1310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          "Sending SIGKILL to %" PRIuS " child processes... ",
1320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          g_live_processes.Get().size());
1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fflush(stdout);
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (std::map<ProcessHandle, CommandLine>::iterator i =
1360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           g_live_processes.Get().begin();
1370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       i != g_live_processes.Get().end();
1380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       ++i) {
1390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // Send the signal to entire process group.
1400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    kill((-1) * (i->first), SIGKILL);
1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fprintf(stdout, "done.\n");
1440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fflush(stdout);
1450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// I/O watcher for the reading end of the self-pipe above.
1480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Terminates any launched child processes and exits the process.
1490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class SignalFDWatcher : public MessageLoopForIO::Watcher {
1500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
1510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SignalFDWatcher() {
1520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fprintf(stdout, "\nCaught signal. Killing spawned test processes...\n");
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    fflush(stdout);
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    KillSpawnedTestProcesses();
1590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // The signal would normally kill the process, so exit now.
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    exit(1);
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NOTREACHED();
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SignalFDWatcher);
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(OS_POSIX)
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Parses the environment variable var as an Int32.  If it is unset, returns
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// true.  If it is set, unsets it then converts it to Int32 before
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// returning it in |result|.  Returns true on success.
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool TakeInt32FromEnvironment(const char* const var, int32* result) {
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<Environment> env(Environment::Create());
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string str_val;
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!env->GetVar(var, &str_val))
1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return true;
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!env->UnSetVar(var)) {
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Invalid environment: we could not unset " << var << ".\n";
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!StringToInt(str_val, result)) {
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Invalid environment: " << var << " is not an integer.\n";
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return true;
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Unsets the environment variable |name| and returns true on success.
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Also returns true if the variable just doesn't exist.
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool UnsetEnvironmentVariableIfExists(const std::string& name) {
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<Environment> env(Environment::Create());
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string str_val;
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!env->GetVar(name.c_str(), &str_val))
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return true;
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return env->UnSetVar(name.c_str());
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Returns true if bot mode has been requested, i.e. defaults optimized
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// for continuous integration bots. This way developers don't have to remember
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// special command-line flags.
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool BotModeEnabled() {
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<Environment> env(Environment::Create());
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return CommandLine::ForCurrentProcess()->HasSwitch(
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      switches::kTestLauncherBotMode) ||
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      env->HasVar("CHROMIUM_TEST_LAUNCHER_BOT_MODE");
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void RunCallback(
2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const TestLauncher::LaunchChildGTestProcessCallback& callback,
2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    int exit_code,
2210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const TimeDelta& elapsed_time,
2220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    bool was_timeout,
2230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const std::string& output) {
2240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback.Run(exit_code, elapsed_time, was_timeout, output);
2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void DoLaunchChildTestProcess(
2280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const CommandLine& command_line,
2290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::TimeDelta timeout,
2306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int flags,
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool redirect_stdio,
2320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    scoped_refptr<MessageLoopProxy> message_loop_proxy,
2330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const TestLauncher::LaunchChildGTestProcessCallback& callback) {
2340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  TimeTicks start_time = TimeTicks::Now();
2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Redirect child process output to a file.
2370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::FilePath output_file;
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CHECK(base::CreateTemporaryFile(&output_file));
2390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  LaunchOptions options;
2410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(OS_WIN)
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  win::ScopedHandle handle;
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (redirect_stdio) {
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Make the file handle inheritable by the child.
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SECURITY_ATTRIBUTES sa_attr;
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sa_attr.lpSecurityDescriptor = NULL;
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sa_attr.bInheritHandle = TRUE;
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    handle.Set(CreateFile(output_file.value().c_str(),
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          GENERIC_WRITE,
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          FILE_SHARE_READ | FILE_SHARE_DELETE,
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          &sa_attr,
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          OPEN_EXISTING,
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          FILE_ATTRIBUTE_TEMPORARY,
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          NULL));
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CHECK(handle.IsValid());
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    options.inherit_handles = true;
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    options.stdin_handle = INVALID_HANDLE_VALUE;
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    options.stdout_handle = handle.Get();
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    options.stderr_handle = handle.Get();
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
2640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#elif defined(OS_POSIX)
2650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  options.new_process_group = true;
2660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::FileHandleMappingVector fds_mapping;
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::ScopedFD output_file_fd;
2690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (redirect_stdio) {
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    output_file_fd.reset(open(output_file.value().c_str(), O_RDWR));
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CHECK(output_file_fd.is_valid());
2730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    fds_mapping.push_back(std::make_pair(output_file_fd.get(), STDOUT_FILENO));
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    fds_mapping.push_back(std::make_pair(output_file_fd.get(), STDERR_FILENO));
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    options.fds_to_remap = &fds_mapping;
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
2780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif
2790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool was_timeout = false;
2810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  int exit_code = LaunchChildTestProcessWithOptions(
2826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      command_line, options, flags, timeout, &was_timeout);
2830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (redirect_stdio) {
2850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(OS_WIN)
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    FlushFileBuffers(handle.Get());
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    handle.Close();
2880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#elif defined(OS_POSIX)
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    output_file_fd.reset();
2900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
2920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::string output_file_contents;
2940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CHECK(base::ReadFileToString(output_file, &output_file_contents));
2950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!base::DeleteFile(output_file, false)) {
2970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // This needs to be non-fatal at least for Windows.
2980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    LOG(WARNING) << "Failed to delete " << output_file.AsUTF8Unsafe();
2990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
3000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Run target callback on the thread it was originating from, not on
3020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // a worker pool thread.
3030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  message_loop_proxy->PostTask(
3040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      FROM_HERE,
3050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      Bind(&RunCallback,
3060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           callback,
3070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           exit_code,
3080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           TimeTicks::Now() - start_time,
3090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           was_timeout,
3100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           output_file_contents));
3110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
3120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace
3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestFilterFlag[] = "gtest_filter";
3168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestHelpFlag[]   = "gtest_help";
3178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestListTestsFlag[] = "gtest_list_tests";
3188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestRepeatFlag[] = "gtest_repeat";
3198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests";
3208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestOutputFlag[] = "gtest_output";
3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TestLauncherDelegate::~TestLauncherDelegate() {
3238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TestLauncher::TestLauncher(TestLauncherDelegate* launcher_delegate,
3260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                           size_t parallel_jobs)
3278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : launcher_delegate_(launcher_delegate),
3288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      total_shards_(1),
3298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shard_index_(0),
3308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      cycles_(1),
3318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_started_count_(0),
3328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_finished_count_(0),
3338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      test_success_count_(0),
3340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      test_broken_count_(0),
3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      retry_count_(0),
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      retry_limit_(0),
3370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      run_result_(true),
3380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      watchdog_timer_(FROM_HERE,
3390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                      TimeDelta::FromSeconds(kOutputTimeoutSeconds),
3400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                      this,
3410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                      &TestLauncher::OnOutputTimeout),
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      parallel_jobs_(parallel_jobs) {
3438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TestLauncher::~TestLauncher() {
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (worker_pool_owner_)
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    worker_pool_owner_->pool()->Shutdown();
3481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool TestLauncher::Run() {
3518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!Init())
3528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Value of |cycles_| changes after each iteration. Keep track of the
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // original value.
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int requested_cycles = cycles_;
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_POSIX)
3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK_EQ(0, pipe(g_shutdown_pipe));
3608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  struct sigaction action;
3628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  memset(&action, 0, sizeof(action));
3638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  sigemptyset(&action.sa_mask);
3648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  action.sa_handler = &ShutdownPipeSignalHandler;
3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK_EQ(0, sigaction(SIGINT, &action, NULL));
3678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK_EQ(0, sigaction(SIGQUIT, &action, NULL));
3688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK_EQ(0, sigaction(SIGTERM, &action, NULL));
3698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MessageLoopForIO::FileDescriptorWatcher controller;
3718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SignalFDWatcher watcher;
3728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK(MessageLoopForIO::current()->WatchFileDescriptor(
3748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            g_shutdown_pipe[0],
3758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            true,
3768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            MessageLoopForIO::WATCH_READ,
3778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            &controller,
3788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            &watcher));
3798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif  // defined(OS_POSIX)
3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Start the watchdog timer.
3820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  watchdog_timer_.Reset();
3830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MessageLoop::current()->PostTask(
3858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE,
3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      Bind(&TestLauncher::RunTestIteration, Unretained(this)));
3874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MessageLoop::current()->Run();
3894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (requested_cycles != 1)
3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    results_tracker_.PrintSummaryOfAllIterations();
3924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  MaybeSaveSummaryAsJSON();
3944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return run_result_;
3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void TestLauncher::LaunchChildGTestProcess(
3990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const CommandLine& command_line,
4000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const std::string& wrapper,
4010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::TimeDelta timeout,
4026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int flags,
4030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const LaunchChildGTestProcessCallback& callback) {
4040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Record the exact command line used to launch the child.
4070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CommandLine new_command_line(
4080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      PrepareCommandLineForGTest(command_line, wrapper));
4090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // When running in parallel mode we need to redirect stdio to avoid mixed-up
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // output. We also always redirect on the bots to get the test output into
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // JSON summary.
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool redirect_stdio = (parallel_jobs_ > 1) || BotModeEnabled();
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  worker_pool_owner_->pool()->PostWorkerTask(
4160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      FROM_HERE,
4170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      Bind(&DoLaunchChildTestProcess,
4180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           new_command_line,
4190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           timeout,
4206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           flags,
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)           redirect_stdio,
4220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           MessageLoopProxy::current(),
4230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           Bind(&TestLauncher::OnLaunchTestProcessFinished,
4240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                Unretained(this),
4250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                callback)));
4260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
4270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void TestLauncher::OnTestFinished(const TestResult& result) {
4291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ++test_finished_count_;
4301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool print_snippet = false;
4321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string print_test_stdio("auto");
4331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
4341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          switches::kTestLauncherPrintTestStdio)) {
4351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print_test_stdio = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        switches::kTestLauncherPrintTestStdio);
4371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (print_test_stdio == "auto") {
4391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print_snippet = (result.status != TestResult::TEST_SUCCESS);
4401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (print_test_stdio == "always") {
4411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print_snippet = true;
4421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (print_test_stdio == "never") {
4431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print_snippet = false;
4441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
4451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    LOG(WARNING) << "Invalid value of " << switches::kTestLauncherPrintTestStdio
4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 << ": " << print_test_stdio;
4471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (print_snippet) {
449f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    std::vector<std::string> snippet_lines;
450f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SplitString(result.output_snippet, '\n', &snippet_lines);
451f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (snippet_lines.size() > kOutputSnippetLinesLimit) {
452f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      size_t truncated_size = snippet_lines.size() - kOutputSnippetLinesLimit;
453f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      snippet_lines.erase(
454f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          snippet_lines.begin(),
455f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          snippet_lines.begin() + truncated_size);
456f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      snippet_lines.insert(snippet_lines.begin(), "<truncated>");
457f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
458f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    fprintf(stdout, "%s", JoinString(snippet_lines, "\n").c_str());
4591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    fflush(stdout);
4601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (result.status == TestResult::TEST_SUCCESS) {
4631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ++test_success_count_;
4641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
4651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    tests_to_retry_.insert(result.full_name);
4661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  results_tracker_.AddTestResult(result);
4691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(phajdan.jr): Align counter (padding).
4711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string status_line(
4721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      StringPrintf("[%" PRIuS "/%" PRIuS "] %s ",
4731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   test_finished_count_,
4741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   test_started_count_,
4751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   result.full_name.c_str()));
4761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (result.completed()) {
4771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append(StringPrintf("(%" PRId64 " ms)",
4781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    result.elapsed_time.InMilliseconds()));
4791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (result.status == TestResult::TEST_TIMEOUT) {
4801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append("(TIMED OUT)");
4811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (result.status == TestResult::TEST_CRASH) {
4821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append("(CRASHED)");
4831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (result.status == TestResult::TEST_SKIPPED) {
4841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append("(SKIPPED)");
4851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (result.status == TestResult::TEST_UNKNOWN) {
4861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    status_line.append("(UNKNOWN)");
4871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
4881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Fail very loudly so it's not ignored.
4891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CHECK(false) << "Unhandled test result status: " << result.status;
4901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  fprintf(stdout, "%s\n", status_line.c_str());
4921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  fflush(stdout);
4931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // We just printed a status line, reset the watchdog timer.
4950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  watchdog_timer_.Reset();
4960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Do not waste time on timeouts. We include tests with unknown results here
4980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // because sometimes (e.g. hang in between unit tests) that's how a timeout
4990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // gets reported.
5000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (result.status == TestResult::TEST_TIMEOUT ||
5010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      result.status == TestResult::TEST_UNKNOWN) {
5020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    test_broken_count_++;
5030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
5040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  size_t broken_threshold =
5054ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      std::max(static_cast<size_t>(20), test_started_count_ / 10);
5060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (test_broken_count_ >= broken_threshold) {
5070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fprintf(stdout, "Too many badly broken tests (%" PRIuS "), exiting now.\n",
5080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            test_broken_count_);
5090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fflush(stdout);
5100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
5110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(OS_POSIX)
5120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    KillSpawnedTestProcesses();
5130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif  // defined(OS_POSIX)
5140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
5150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    results_tracker_.AddGlobalTag("BROKEN_TEST_EARLY_EXIT");
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    results_tracker_.AddGlobalTag(kUnreliableResultsTag);
5170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    MaybeSaveSummaryAsJSON();
5180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
5190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    exit(1);
5200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (test_finished_count_ != test_started_count_)
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (tests_to_retry_.empty() || retry_count_ >= retry_limit_) {
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    OnTestIterationFinished();
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (tests_to_retry_.size() >= broken_threshold) {
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fprintf(stdout,
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "Too many failing tests (%" PRIuS "), skipping retries.\n",
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            tests_to_retry_.size());
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fflush(stdout);
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    results_tracker_.AddGlobalTag("BROKEN_TEST_SKIPPED_RETRIES");
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    results_tracker_.AddGlobalTag(kUnreliableResultsTag);
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    OnTestIterationFinished();
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  retry_count_++;
5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<std::string> test_names(tests_to_retry_.begin(),
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      tests_to_retry_.end());
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  tests_to_retry_.clear();
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t retry_started_count = launcher_delegate_->RetryTests(this, test_names);
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (retry_started_count == 0) {
5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Signal failure, but continue to run all requested test iterations.
5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // With the summary of all iterations at the end this is a good default.
5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    run_result_ = false;
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    OnTestIterationFinished();
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  fprintf(stdout, "Retrying %" PRIuS " test%s (retry #%" PRIuS ")\n",
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          retry_started_count,
5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          retry_started_count > 1 ? "s" : "",
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          retry_count_);
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  fflush(stdout);
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test_started_count_ += retry_started_count;
5671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
5681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
5705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)std::string TestLauncher::FormatFullTestName(const std::string& test_case_name,
5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             const std::string& test_name) {
5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return test_case_name + "." + test_name;
5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool TestLauncher::Init() {
5768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
5778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Initialize sharding. Command line takes precedence over legacy environment
5790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // variables.
5800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (command_line->HasSwitch(switches::kTestLauncherTotalShards) &&
5810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      command_line->HasSwitch(switches::kTestLauncherShardIndex)) {
5820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!StringToInt(
5830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            command_line->GetSwitchValueASCII(
5840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                switches::kTestLauncherTotalShards),
5850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            &total_shards_)) {
5860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      LOG(ERROR) << "Invalid value for " << switches::kTestLauncherTotalShards;
5870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return false;
5880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
5890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!StringToInt(
5900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            command_line->GetSwitchValueASCII(
5910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                switches::kTestLauncherShardIndex),
5920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            &shard_index_)) {
5930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      LOG(ERROR) << "Invalid value for " << switches::kTestLauncherShardIndex;
5940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return false;
5950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
5960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fprintf(stdout,
5970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            "Using sharding settings from command line. This is shard %d/%d\n",
5980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            shard_index_, total_shards_);
5990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fflush(stdout);
6000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  } else {
6010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!TakeInt32FromEnvironment(kTestTotalShards, &total_shards_))
6020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return false;
6030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!TakeInt32FromEnvironment(kTestShardIndex, &shard_index_))
6040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return false;
6050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fprintf(stdout,
6060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            "Using sharding settings from environment. This is shard %d/%d\n",
6070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            shard_index_, total_shards_);
6080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fflush(stdout);
6090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
6108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (shard_index_ < 0 ||
6118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      total_shards_ < 0 ||
6128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      shard_index_ >= total_shards_) {
6130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    LOG(ERROR) << "Invalid sharding settings: we require 0 <= "
6148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               << kTestShardIndex << " < " << kTestTotalShards
6158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               << ", but you have " << kTestShardIndex << "=" << shard_index_
6168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               << ", " << kTestTotalShards << "=" << total_shards_ << ".\n";
6178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
6188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Make sure we don't pass any sharding-related environment to the child
621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // processes. This test launcher implements the sharding completely.
622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CHECK(UnsetEnvironmentVariableIfExists("GTEST_TOTAL_SHARDS"));
623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CHECK(UnsetEnvironmentVariableIfExists("GTEST_SHARD_INDEX"));
624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
6258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (command_line->HasSwitch(kGTestRepeatFlag) &&
6268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      !StringToInt(command_line->GetSwitchValueASCII(kGTestRepeatFlag),
6278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                   &cycles_)) {
6288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << "Invalid value for " << kGTestRepeatFlag;
6298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
6308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          switches::kTestLauncherRetryLimit)) {
634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int retry_limit = -1;
635f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!StringToInt(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         switches::kTestLauncherRetryLimit), &retry_limit) ||
637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        retry_limit < 0) {
638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      LOG(ERROR) << "Invalid value for " << switches::kTestLauncherRetryLimit;
639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    retry_limit_ = retry_limit;
6436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  } else if (!CommandLine::ForCurrentProcess()->HasSwitch(kGTestFilterFlag)) {
6446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Retry failures 3 times by default if we are running all of the tests.
6456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    retry_limit_ = 3;
646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
649f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          switches::kTestLauncherJobs)) {
650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int jobs = -1;
651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!StringToInt(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         switches::kTestLauncherJobs), &jobs) ||
653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        jobs < 0) {
654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      LOG(ERROR) << "Invalid value for " << switches::kTestLauncherJobs;
655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    parallel_jobs_ = jobs;
6596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  } else if (CommandLine::ForCurrentProcess()->HasSwitch(kGTestFilterFlag)) {
6606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Do not run jobs in parallel by default if we are running a subset of
6616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // the tests.
6626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    parallel_jobs_ = 1;
663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
6646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  fprintf(stdout, "Using %" PRIuS " parallel jobs.\n", parallel_jobs_);
666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  fflush(stdout);
667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  worker_pool_owner_.reset(
668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new SequencedWorkerPoolOwner(parallel_jobs_, "test_launcher"));
669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (command_line->HasSwitch(switches::kTestLauncherFilterFile) &&
6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      command_line->HasSwitch(kGTestFilterFlag)) {
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LOG(ERROR) << "Only one of --test-launcher-filter-file and --gtest_filter "
6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               << "at a time is allowed.";
6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (command_line->HasSwitch(switches::kTestLauncherFilterFile)) {
6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string filter;
6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!ReadFileToString(
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            command_line->GetSwitchValuePath(switches::kTestLauncherFilterFile),
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            &filter)) {
6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LOG(ERROR) << "Failed to read the filter file.";
6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::vector<std::string> filter_lines;
6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SplitString(filter, '\n', &filter_lines);
6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (size_t i = 0; i < filter_lines.size(); i++) {
6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (filter_lines[i].empty())
6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        continue;
6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (filter_lines[i][0] == '-')
6935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        negative_test_filter_.push_back(filter_lines[i].substr(1));
6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      else
6955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        positive_test_filter_.push_back(filter_lines[i]);
6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Split --gtest_filter at '-', if there is one, to separate into
6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // positive filter and negative filter portions.
7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag);
7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    size_t dash_pos = filter.find('-');
7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (dash_pos == std::string::npos) {
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SplitString(filter, ':', &positive_test_filter_);
7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Everything up to the dash.
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SplitString(filter.substr(0, dash_pos), ':', &positive_test_filter_);
7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Everything after the dash.
7095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SplitString(filter.substr(dash_pos + 1), ':', &negative_test_filter_);
7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
7114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
7124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!results_tracker_.Init(*command_line)) {
7148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << "Failed to initialize test results tracker.";
7158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return 1;
7168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
7174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(NDEBUG)
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("MODE_RELEASE");
7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else
7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("MODE_DEBUG");
7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Operating systems (sorted alphabetically).
7255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Note that they can deliberately overlap, e.g. OS_LINUX is a subset
7265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // of OS_POSIX.
7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_ANDROID)
7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("OS_ANDROID");
7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_BSD)
7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("OS_BSD");
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_FREEBSD)
7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("OS_FREEBSD");
7375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_IOS)
7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("OS_IOS");
7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_LINUX)
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("OS_LINUX");
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_MACOSX)
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("OS_MACOSX");
7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_NACL)
7525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("OS_NACL");
7535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_OPENBSD)
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("OS_OPENBSD");
7575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_POSIX)
7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("OS_POSIX");
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_SOLARIS)
7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("OS_SOLARIS");
7655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN)
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("OS_WIN");
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // CPU-related tags.
7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(ARCH_CPU_32_BITS)
7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("CPU_32_BITS");
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(ARCH_CPU_64_BITS)
7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.AddGlobalTag("CPU_64_BITS");
7785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
7795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
7818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
7824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TestLauncher::RunTests() {
7848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  testing::UnitTest* const unit_test = testing::UnitTest::GetInstance();
7854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<std::string> test_names;
7871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (int i = 0; i < unit_test->total_test_case_count(); ++i) {
7898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const testing::TestCase* test_case = unit_test->GetTestCase(i);
7908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    for (int j = 0; j < test_case->total_test_count(); ++j) {
7918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const testing::TestInfo* test_info = test_case->GetTestInfo(j);
7925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      std::string test_name = FormatFullTestName(
7935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          test_info->test_case_name(), test_info->name());
7944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      results_tracker_.AddTest(test_name);
7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const CommandLine* command_line = CommandLine::ForCurrentProcess();
7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (test_name.find("DISABLED") != std::string::npos) {
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        results_tracker_.AddDisabledTest(test_name);
8004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Skip disabled tests unless explicitly requested.
8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (!command_line->HasSwitch(kGTestRunDisabledTestsFlag))
8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          continue;
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
8054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (!launcher_delegate_->ShouldRunTest(test_case, test_info))
8076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        continue;
8086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Skip the test that doesn't match the filter (if given).
8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!positive_test_filter_.empty()) {
8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        bool found = false;
8125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        for (size_t k = 0; k < positive_test_filter_.size(); ++k) {
8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          if (MatchPattern(test_name, positive_test_filter_[k])) {
8145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            found = true;
8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            break;
8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          }
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (!found)
8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          continue;
8218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      }
8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool excluded = false;
8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      for (size_t k = 0; k < negative_test_filter_.size(); ++k) {
8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (MatchPattern(test_name, negative_test_filter_[k])) {
8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          excluded = true;
8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          break;
8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (excluded)
8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        continue;
8314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
832cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (base::Hash(test_name) % total_shards_ !=
833cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          static_cast<uint32>(shard_index_)) {
8348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        continue;
835cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
8368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
8371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      test_names.push_back(test_name);
8388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
8398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
8404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  test_started_count_ = launcher_delegate_->RunTests(this, test_names);
8424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (test_started_count_ == 0) {
8441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    fprintf(stdout, "0 tests run\n");
8451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    fflush(stdout);
8461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
8471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // No tests have actually been started, so kick off the next iteration.
8481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    MessageLoop::current()->PostTask(
8491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        FROM_HERE,
8501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        Bind(&TestLauncher::RunTestIteration, Unretained(this)));
8511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
8528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
8534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TestLauncher::RunTestIteration() {
8558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (cycles_ == 0) {
8568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    MessageLoop::current()->Quit();
8578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
8588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
8594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Special value "-1" means "repeat indefinitely".
8618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  cycles_ = (cycles_ == -1) ? cycles_ : cycles_ - 1;
8624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  test_started_count_ = 0;
8648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  test_finished_count_ = 0;
8658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  test_success_count_ = 0;
8660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  test_broken_count_ = 0;
8671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  retry_count_ = 0;
8681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tests_to_retry_.clear();
8698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  results_tracker_.OnTestIterationStarting();
8704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MessageLoop::current()->PostTask(
8728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE, Bind(&TestLauncher::RunTests, Unretained(this)));
8734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
8744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void TestLauncher::MaybeSaveSummaryAsJSON() {
8760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
8770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (command_line->HasSwitch(switches::kTestLauncherSummaryOutput)) {
8780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    FilePath summary_path(command_line->GetSwitchValuePath(
8790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                              switches::kTestLauncherSummaryOutput));
8800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!results_tracker_.SaveSummaryAsJSON(summary_path)) {
8810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      LOG(ERROR) << "Failed to save test launcher output summary.";
8820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
8830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
8840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
8850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void TestLauncher::OnLaunchTestProcessFinished(
8870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const LaunchChildGTestProcessCallback& callback,
8880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    int exit_code,
8890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const TimeDelta& elapsed_time,
8900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    bool was_timeout,
8910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const std::string& output) {
8920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback.Run(exit_code, elapsed_time, was_timeout, output);
8950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
8960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TestLauncher::OnTestIterationFinished() {
898f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  TestResultsTracker::TestStatusMap tests_by_status(
899f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      results_tracker_.GetTestStatusMapForCurrentIteration());
900f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!tests_by_status[TestResult::TEST_UNKNOWN].empty())
901f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    results_tracker_.AddGlobalTag(kUnreliableResultsTag);
902f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
9035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // When we retry tests, success is determined by having nothing more
9045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to retry (everything eventually passed), as opposed to having
9055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // no failures at all.
9065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (tests_to_retry_.empty()) {
9075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fprintf(stdout, "SUCCESS: all tests passed.\n");
9085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fflush(stdout);
9095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
9105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Signal failure, but continue to run all requested test iterations.
9115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // With the summary of all iterations at the end this is a good default.
9125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    run_result_ = false;
9135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
9145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  results_tracker_.PrintSummaryOfCurrentIteration();
9165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Kick off the next iteration.
9185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessageLoop::current()->PostTask(
9195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FROM_HERE,
9205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Bind(&TestLauncher::RunTestIteration, Unretained(this)));
9215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void TestLauncher::OnOutputTimeout() {
9240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AutoLock lock(g_live_processes_lock.Get());
9270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fprintf(stdout, "Still waiting for the following processes to finish:\n");
9290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (std::map<ProcessHandle, CommandLine>::iterator i =
9310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)           g_live_processes.Get().begin();
9320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       i != g_live_processes.Get().end();
9330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       ++i) {
9340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(OS_WIN)
9350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fwprintf(stdout, L"\t%s\n", i->second.GetCommandLineString().c_str());
9360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#else
9370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fprintf(stdout, "\t%s\n", i->second.GetCommandLineString().c_str());
9380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif
9390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
9400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fflush(stdout);
9420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Arm the timer again - otherwise it would fire only once.
9440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  watchdog_timer_.Reset();
9454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
9464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)std::string GetTestOutputSnippet(const TestResult& result,
9484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 const std::string& full_output) {
9494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t run_pos = full_output.find(std::string("[ RUN      ] ") +
9501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    result.full_name);
9514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (run_pos == std::string::npos)
9524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return std::string();
9534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t end_pos = full_output.find(std::string("[  FAILED  ] ") +
9551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    result.full_name,
9564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                    run_pos);
957f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Only clip the snippet to the "OK" message if the test really
958f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // succeeded. It still might have e.g. crashed after printing it.
959f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (end_pos == std::string::npos &&
960f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      result.status == TestResult::TEST_SUCCESS) {
9614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    end_pos = full_output.find(std::string("[       OK ] ") +
9621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                               result.full_name,
9634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               run_pos);
9644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (end_pos != std::string::npos) {
9664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    size_t newline_pos = full_output.find("\n", end_pos);
9674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (newline_pos != std::string::npos)
9684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      end_pos = newline_pos + 1;
9694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string snippet(full_output.substr(run_pos));
9724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (end_pos != std::string::npos)
9734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    snippet = full_output.substr(run_pos, end_pos - run_pos);
9744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return snippet;
9764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
9774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CommandLine PrepareCommandLineForGTest(const CommandLine& command_line,
9794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                       const std::string& wrapper) {
9804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CommandLine new_command_line(command_line.GetProgram());
9814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CommandLine::SwitchMap switches = command_line.GetSwitches();
9824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Strip out gtest_repeat flag - this is handled by the launcher process.
9844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  switches.erase(kGTestRepeatFlag);
9854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
986a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Don't try to write the final XML report in child processes.
987a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  switches.erase(kGTestOutputFlag);
988a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
9894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (CommandLine::SwitchMap::const_iterator iter = switches.begin();
9904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       iter != switches.end(); ++iter) {
9914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    new_command_line.AppendSwitchNative((*iter).first, (*iter).second);
9924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Prepend wrapper after last CommandLine quasi-copy operation. CommandLine
9954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // does not really support removing switches well, and trying to do that
9964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // on a CommandLine with a wrapper is known to break.
9974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(phajdan.jr): Give it a try to support CommandLine removing switches.
9984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN)
9994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_command_line.PrependWrapper(ASCIIToWide(wrapper));
10004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#elif defined(OS_POSIX)
10014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_command_line.PrependWrapper(wrapper);
10024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
10034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return new_command_line;
10054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
10064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1007f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// TODO(phajdan.jr): Move to anonymous namespace.
10084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int LaunchChildTestProcessWithOptions(const CommandLine& command_line,
10094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      const LaunchOptions& options,
10106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                      int flags,
10114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      base::TimeDelta timeout,
10124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      bool* was_timeout) {
10134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
10144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Make sure an option we rely on is present - see LaunchChildGTestProcess.
10154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(options.new_process_group);
10164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
10174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  LaunchOptions new_options(options);
10194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN)
10214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!new_options.job_handle);
10224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1023f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  win::ScopedHandle job_handle;
10246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (flags & TestLauncher::USE_JOB_OBJECTS) {
1025f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    job_handle.Set(CreateJobObject(NULL, NULL));
1026f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!job_handle.IsValid()) {
1027f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      LOG(ERROR) << "Could not create JobObject.";
1028f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return -1;
1029f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
10304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    DWORD job_flags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
10326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1033f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Allow break-away from job since sandbox and few other places rely on it
1034f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // on Windows versions prior to Windows 8 (which supports nested jobs).
10356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (win::GetVersion() < win::VERSION_WIN8 &&
10366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        flags & TestLauncher::ALLOW_BREAKAWAY_FROM_JOB) {
10376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      job_flags |= JOB_OBJECT_LIMIT_BREAKAWAY_OK;
10386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
10396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
10406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!SetJobObjectLimitFlags(job_handle.Get(), job_flags)) {
1041f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      LOG(ERROR) << "Could not SetJobObjectLimitFlags.";
1042f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return -1;
1043f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
10444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1045f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    new_options.job_handle = job_handle.Get();
1046f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
10474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(OS_WIN)
10484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1049c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(OS_LINUX)
1050c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // To prevent accidental privilege sharing to an untrusted child, processes
1051c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // are started with PR_SET_NO_NEW_PRIVS. Do not set that here, since this
1052c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // new child will be privileged and trusted.
1053c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  new_options.allow_new_privs = true;
1054c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
1055c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
10564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::ProcessHandle process_handle;
10574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
10594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Note how we grab the lock before the process possibly gets created.
10604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // This ensures that when the lock is held, ALL the processes are registered
10614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // in the set.
10620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    AutoLock lock(g_live_processes_lock.Get());
10634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!base::LaunchProcess(command_line, new_options, &process_handle))
10654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return -1;
10664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    g_live_processes.Get().insert(std::make_pair(process_handle, command_line));
10684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
10694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int exit_code = 0;
10714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!base::WaitForExitCodeWithTimeout(process_handle,
10724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        &exit_code,
10734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        timeout)) {
10744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    *was_timeout = true;
10754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    exit_code = -1;  // Set a non-zero exit code to signal a failure.
10764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Ensure that the process terminates.
10784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::KillProcess(process_handle, -1, true);
10794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
10804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
10824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Note how we grab the log before issuing a possibly broad process kill.
10834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Other code parts that grab the log kill processes, so avoid trying
10844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // to do that twice and trigger all kinds of log messages.
10850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    AutoLock lock(g_live_processes_lock.Get());
10864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX)
10884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (exit_code != 0) {
10894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // On POSIX, in case the test does not exit cleanly, either due to a crash
10904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // or due to it timing out, we need to clean up any child processes that
10914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // it might have created. On Windows, child processes are automatically
10924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // cleaned up using JobObjects.
10934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::KillProcessGroup(process_handle);
10944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
10954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
10964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    g_live_processes.Get().erase(process_handle);
10984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
10994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::CloseProcessHandle(process_handle);
11014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return exit_code;
11034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
11044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace base
1106