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