test_launcher.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/launcher/test_launcher.h" 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX) 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <fcntl.h> 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/at_exit.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/bind.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/command_line.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/environment.h" 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/file_util.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/files/file_path.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/format_macros.h" 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/lazy_instance.h" 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/logging.h" 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/message_loop/message_loop.h" 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/process/kill.h" 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/process/launch.h" 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/stringprintf.h" 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/utf_string_conversions.h" 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/launcher/test_results_tracker.h" 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/test_switches.h" 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/test_timeouts.h" 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/threading/thread_checker.h" 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/time/time.h" 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_MACOSX) 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/mac/scoped_nsautorelease_pool.h" 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace base { 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// See https://groups.google.com/a/chromium.org/d/msg/chromium-dev/nkdTP7sstSc/uT3FaE_sgkAJ . 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using ::operator<<; 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The environment variable name for the total number of test shards. 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The environment variable name for the test shard index. 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace { 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Set of live launch test processes with corresponding lock (it is allowed 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// for callers to launch processes on different threads). 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)LazyInstance<std::set<ProcessHandle> > g_live_process_handles 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) = LAZY_INSTANCE_INITIALIZER; 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)LazyInstance<Lock> g_live_process_handles_lock = LAZY_INSTANCE_INITIALIZER; 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX) 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Self-pipe that makes it possible to do complex shutdown handling 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// outside of the signal handler. 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int g_shutdown_pipe[2] = { -1, -1 }; 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShutdownPipeSignalHandler(int signal) { 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HANDLE_EINTR(write(g_shutdown_pipe[1], "q", 1)); 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// I/O watcher for the reading end of the self-pipe above. 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Terminates any launched child processes and exits the process. 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class SignalFDWatcher : public MessageLoopForIO::Watcher { 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SignalFDWatcher() { 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE { 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fprintf(stdout, "\nCaught signal. Killing spawned test processes...\n"); 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fflush(stdout); 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Keep the lock until exiting the process to prevent further processes 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // from being spawned. 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AutoLock lock(g_live_process_handles_lock.Get()); 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fprintf(stdout, 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "Sending SIGTERM to %" PRIuS " child processes... ", 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) g_live_process_handles.Get().size()); 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fflush(stdout); 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (std::set<ProcessHandle>::iterator i = 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) g_live_process_handles.Get().begin(); 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) i != g_live_process_handles.Get().end(); 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ++i) { 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kill((-1) * (*i), SIGTERM); // Send the signal to entire process group. 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fprintf(stdout, 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "done.\nGiving processes a chance to terminate cleanly... "); 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fflush(stdout); 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PlatformThread::Sleep(TimeDelta::FromMilliseconds(500)); 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fprintf(stdout, "done.\n"); 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fflush(stdout); 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fprintf(stdout, 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "Sending SIGKILL to %" PRIuS " child processes... ", 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) g_live_process_handles.Get().size()); 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fflush(stdout); 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (std::set<ProcessHandle>::iterator i = 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) g_live_process_handles.Get().begin(); 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) i != g_live_process_handles.Get().end(); 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ++i) { 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kill((-1) * (*i), SIGKILL); // Send the signal to entire process group. 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fprintf(stdout, "done.\n"); 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fflush(stdout); 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // The signal would normally kill the process, so exit now. 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) exit(1); 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE { 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NOTREACHED(); 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SignalFDWatcher); 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif // defined(OS_POSIX) 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Parses the environment variable var as an Int32. If it is unset, returns 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// true. If it is set, unsets it then converts it to Int32 before 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// returning it in |result|. Returns true on success. 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool TakeInt32FromEnvironment(const char* const var, int32* result) { 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<Environment> env(Environment::Create()); 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string str_val; 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!env->GetVar(var, &str_val)) 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!env->UnSetVar(var)) { 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(ERROR) << "Invalid environment: we could not unset " << var << ".\n"; 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!StringToInt(str_val, result)) { 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(ERROR) << "Invalid environment: " << var << " is not an integer.\n"; 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// For a basic pattern matching for gtest_filter options. (Copied from 1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// gtest.cc, see the comment below and http://crbug.com/44497) 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool PatternMatchesString(const char* pattern, const char* str) { 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) switch (*pattern) { 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case '\0': 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case ':': // Either ':' or '\0' marks the end of the pattern. 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return *str == '\0'; 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case '?': // Matches any single character. 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case '*': // Matches any string (possibly empty) of characters. 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PatternMatchesString(pattern + 1, str); 1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) default: // Non-special character. Matches itself. 1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return *pattern == *str && 1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PatternMatchesString(pattern + 1, str + 1); 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// TODO(phajdan.jr): Avoid duplicating gtest code. (http://crbug.com/44497) 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// For basic pattern matching for gtest_filter options. (Copied from 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// gtest.cc) 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool MatchesFilter(const std::string& name, const std::string& filter) { 1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char *cur_pattern = filter.c_str(); 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (;;) { 1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (PatternMatchesString(cur_pattern, name.c_str())) { 1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Finds the next pattern in the filter. 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cur_pattern = strchr(cur_pattern, ':'); 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Returns if no more pattern can be found. 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cur_pattern == NULL) { 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Skips the pattern separater (the ':' character). 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cur_pattern++; 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} // namespace 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestFilterFlag[] = "gtest_filter"; 1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestHelpFlag[] = "gtest_help"; 1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestListTestsFlag[] = "gtest_list_tests"; 1988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestRepeatFlag[] = "gtest_repeat"; 1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests"; 2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kGTestOutputFlag[] = "gtest_output"; 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TestLauncherDelegate::~TestLauncherDelegate() { 2038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TestLauncher::TestLauncher(TestLauncherDelegate* launcher_delegate) 2068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : launcher_delegate_(launcher_delegate), 2078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) total_shards_(1), 2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) shard_index_(0), 2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cycles_(1), 2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) test_started_count_(0), 2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) test_finished_count_(0), 2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) test_success_count_(0), 2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) retry_count_(0), 2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) retry_limit_(3), // TODO(phajdan.jr): Make a flag control this. 2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) run_result_(true) { 2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TestLauncher::~TestLauncher() { 2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool TestLauncher::Run(int argc, char** argv) { 2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!Init()) 2238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_POSIX) 2268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CHECK_EQ(0, pipe(g_shutdown_pipe)); 2278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) struct sigaction action; 2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) memset(&action, 0, sizeof(action)); 2308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sigemptyset(&action.sa_mask); 2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) action.sa_handler = &ShutdownPipeSignalHandler; 2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CHECK_EQ(0, sigaction(SIGINT, &action, NULL)); 2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CHECK_EQ(0, sigaction(SIGQUIT, &action, NULL)); 2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CHECK_EQ(0, sigaction(SIGTERM, &action, NULL)); 2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MessageLoopForIO::FileDescriptorWatcher controller; 2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SignalFDWatcher watcher; 2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CHECK(MessageLoopForIO::current()->WatchFileDescriptor( 2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) g_shutdown_pipe[0], 2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) true, 2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MessageLoopForIO::WATCH_READ, 2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) &controller, 2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) &watcher)); 2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif // defined(OS_POSIX) 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MessageLoop::current()->PostTask( 2498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FROM_HERE, 2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Bind(&TestLauncher::RunTestIteration, Unretained(this))); 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MessageLoop::current()->Run(); 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (cycles_ != 1) 2558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) results_tracker_.PrintSummaryOfAllIterations(); 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const CommandLine* command_line = CommandLine::ForCurrentProcess(); 2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (command_line->HasSwitch(switches::kTestLauncherSummaryOutput)) { 2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FilePath summary_path(command_line->GetSwitchValuePath( 2608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) switches::kTestLauncherSummaryOutput)); 2618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!results_tracker_.SaveSummaryAsJSON(summary_path)) { 2628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LOG(ERROR) << "Failed to save test launcher output summary."; 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return run_result_; 2678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void TestLauncher::OnTestFinished(const TestResult& result) { 2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ++test_finished_count_; 2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool print_snippet = false; 2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string print_test_stdio("auto"); 2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switches::kTestLauncherPrintTestStdio)) { 2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) print_test_stdio = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 2771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switches::kTestLauncherPrintTestStdio); 2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (print_test_stdio == "auto") { 2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) print_snippet = (result.status != TestResult::TEST_SUCCESS); 2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else if (print_test_stdio == "always") { 2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) print_snippet = true; 2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else if (print_test_stdio == "never") { 2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) print_snippet = false; 2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) LOG(WARNING) << "Invalid value of " << switches::kTestLauncherPrintTestStdio 2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) << ": " << print_test_stdio; 2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (print_snippet) { 2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fprintf(stdout, "%s", result.output_snippet.c_str()); 2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fflush(stdout); 2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (result.status == TestResult::TEST_SUCCESS) { 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ++test_success_count_; 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) tests_to_retry_.insert(result.full_name); 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) results_tracker_.AddTestResult(result); 3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // TODO(phajdan.jr): Align counter (padding). 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string status_line( 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) StringPrintf("[%" PRIuS "/%" PRIuS "] %s ", 3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) test_finished_count_, 3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) test_started_count_, 3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) result.full_name.c_str())); 3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (result.completed()) { 3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) status_line.append(StringPrintf("(%" PRId64 " ms)", 3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) result.elapsed_time.InMilliseconds())); 3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else if (result.status == TestResult::TEST_TIMEOUT) { 3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) status_line.append("(TIMED OUT)"); 3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else if (result.status == TestResult::TEST_CRASH) { 3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) status_line.append("(CRASHED)"); 3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else if (result.status == TestResult::TEST_SKIPPED) { 3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) status_line.append("(SKIPPED)"); 3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else if (result.status == TestResult::TEST_UNKNOWN) { 3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) status_line.append("(UNKNOWN)"); 3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Fail very loudly so it's not ignored. 3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CHECK(false) << "Unhandled test result status: " << result.status; 3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fprintf(stdout, "%s\n", status_line.c_str()); 3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fflush(stdout); 3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (test_finished_count_ == test_started_count_) { 3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!tests_to_retry_.empty() && retry_count_ < retry_limit_) { 3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) retry_count_++; 3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::vector<std::string> test_names(tests_to_retry_.begin(), 3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) tests_to_retry_.end()); 3321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) tests_to_retry_.clear(); 3341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t retry_started_count = 3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) launcher_delegate_->RetryTests(this, test_names); 3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (retry_started_count == 0) { 3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Signal failure, but continue to run all requested test iterations. 3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // With the summary of all iterations at the end this is a good default. 3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) run_result_ = false; 3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The current iteration is done. 3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fprintf(stdout, "%" PRIuS " test%s run\n", 3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) test_finished_count_, 3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) test_finished_count_ > 1 ? "s" : ""); 3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fflush(stdout); 3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) results_tracker_.PrintSummaryOfCurrentIteration(); 3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Kick off the next iteration. 3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MessageLoop::current()->PostTask( 3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FROM_HERE, 3531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Bind(&TestLauncher::RunTestIteration, Unretained(this))); 3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fprintf(stdout, "Retrying %" PRIuS " test%s (retry #%" PRIuS ")\n", 3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) retry_started_count, 3571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) retry_started_count > 1 ? "s" : "", 3581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) retry_count_); 3591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fflush(stdout); 3601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) test_started_count_ += retry_started_count; 3621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 3641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The current iteration is done. 3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fprintf(stdout, "%" PRIuS " test%s run\n", 3661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) test_finished_count_, 3671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) test_finished_count_ > 1 ? "s" : ""); 3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fflush(stdout); 3691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) results_tracker_.PrintSummaryOfCurrentIteration(); 3711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // When we retry tests, success is determined by having nothing more 3731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // to retry (everything eventually passed), as opposed to having 3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // no failures at all. 3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!tests_to_retry_.empty()) { 3761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Signal failure, but continue to run all requested test iterations. 3771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // With the summary of all iterations at the end this is a good default. 3781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) run_result_ = false; 3791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Kick off the next iteration. 3821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MessageLoop::current()->PostTask( 3831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FROM_HERE, 3841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Bind(&TestLauncher::RunTestIteration, Unretained(this))); 3851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool TestLauncher::Init() { 3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const CommandLine* command_line = CommandLine::ForCurrentProcess(); 3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (command_line->HasSwitch(kGTestListTestsFlag)) { 3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Child gtest processes would list tests instead of running tests. 3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // TODO(phajdan.jr): Restore support for the flag. 3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LOG(ERROR) << kGTestListTestsFlag << " is not supported."; 3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!TakeInt32FromEnvironment(kTestTotalShards, &total_shards_)) 4008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!TakeInt32FromEnvironment(kTestShardIndex, &shard_index_)) 4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 4038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (shard_index_ < 0 || 4048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) total_shards_ < 0 || 4058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) shard_index_ >= total_shards_) { 4068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LOG(ERROR) << "Invalid environment variables: we require 0 <= " 4078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << kTestShardIndex << " < " << kTestTotalShards 4088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << ", but you have " << kTestShardIndex << "=" << shard_index_ 4098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << ", " << kTestTotalShards << "=" << total_shards_ << ".\n"; 4108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 4118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (command_line->HasSwitch(kGTestRepeatFlag) && 4148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) !StringToInt(command_line->GetSwitchValueASCII(kGTestRepeatFlag), 4158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) &cycles_)) { 4168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LOG(ERROR) << "Invalid value for " << kGTestRepeatFlag; 4178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 4188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Split --gtest_filter at '-', if there is one, to separate into 4218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // positive filter and negative filter portions. 4228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag); 4238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) positive_test_filter_ = filter; 4248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) size_t dash_pos = filter.find('-'); 4258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (dash_pos != std::string::npos) { 4268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Everything up to the dash. 4278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) positive_test_filter_ = filter.substr(0, dash_pos); 4288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Everything after the dash. 4308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) negative_test_filter_ = filter.substr(dash_pos + 1); 4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!results_tracker_.Init(*command_line)) { 4348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LOG(ERROR) << "Failed to initialize test results tracker."; 4358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return 1; 4368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return true; 4398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TestLauncher::RunTests() { 4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) testing::UnitTest* const unit_test = testing::UnitTest::GetInstance(); 4434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int num_runnable_tests = 0; 4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::vector<std::string> test_names; 4471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (int i = 0; i < unit_test->total_test_case_count(); ++i) { 4498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const testing::TestCase* test_case = unit_test->GetTestCase(i); 4508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (int j = 0; j < test_case->total_test_count(); ++j) { 4518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const testing::TestInfo* test_info = test_case->GetTestInfo(j); 4528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::string test_name = test_info->test_case_name(); 4538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) test_name.append("."); 4548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) test_name.append(test_info->name()); 4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Skip disabled tests. 4578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const CommandLine* command_line = CommandLine::ForCurrentProcess(); 4588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (test_name.find("DISABLED") != std::string::npos && 4598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) !command_line->HasSwitch(kGTestRunDisabledTestsFlag)) { 4608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) continue; 4618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::string filtering_test_name = 4648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) launcher_delegate_->GetTestNameForFiltering(test_case, test_info); 4654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Skip the test that doesn't match the filter string (if given). 4678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if ((!positive_test_filter_.empty() && 4688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) !MatchesFilter(filtering_test_name, positive_test_filter_)) || 4698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MatchesFilter(filtering_test_name, negative_test_filter_)) { 4708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) continue; 4718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!launcher_delegate_->ShouldRunTest(test_case, test_info)) 4748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) continue; 4758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (num_runnable_tests++ % total_shards_ != shard_index_) 4778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) continue; 4788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) test_names.push_back(test_name); 4808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) test_started_count_ = launcher_delegate_->RunTests(this, test_names); 4844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (test_started_count_ == 0) { 4861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fprintf(stdout, "0 tests run\n"); 4871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fflush(stdout); 4881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // No tests have actually been started, so kick off the next iteration. 4901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MessageLoop::current()->PostTask( 4911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FROM_HERE, 4921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Bind(&TestLauncher::RunTestIteration, Unretained(this))); 4931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 4948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 4954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TestLauncher::RunTestIteration() { 4978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (cycles_ == 0) { 4988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MessageLoop::current()->Quit(); 4998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 5008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Special value "-1" means "repeat indefinitely". 5038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cycles_ = (cycles_ == -1) ? cycles_ : cycles_ - 1; 5044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) test_started_count_ = 0; 5068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) test_finished_count_ = 0; 5078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) test_success_count_ = 0; 5081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) retry_count_ = 0; 5091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) tests_to_retry_.clear(); 5108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) results_tracker_.OnTestIterationStarting(); 5118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) launcher_delegate_->OnTestIterationStarting(); 5124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MessageLoop::current()->PostTask( 5148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FROM_HERE, Bind(&TestLauncher::RunTests, Unretained(this))); 5154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TestLauncher::OnAllTestsStarted() { 5184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)std::string GetTestOutputSnippet(const TestResult& result, 5214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& full_output) { 5224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t run_pos = full_output.find(std::string("[ RUN ] ") + 5231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) result.full_name); 5244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (run_pos == std::string::npos) 5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return std::string(); 5264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t end_pos = full_output.find(std::string("[ FAILED ] ") + 5281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) result.full_name, 5294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) run_pos); 5304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (end_pos == std::string::npos) { 5314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) end_pos = full_output.find(std::string("[ OK ] ") + 5321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) result.full_name, 5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) run_pos); 5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (end_pos != std::string::npos) { 5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t newline_pos = full_output.find("\n", end_pos); 5374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (newline_pos != std::string::npos) 5384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) end_pos = newline_pos + 1; 5394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string snippet(full_output.substr(run_pos)); 5424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (end_pos != std::string::npos) 5434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) snippet = full_output.substr(run_pos, end_pos - run_pos); 5444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return snippet; 5464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int LaunchChildGTestProcess(const CommandLine& command_line, 5494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& wrapper, 5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta timeout, 5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool* was_timeout) { 5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LaunchOptions options; 5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX) 5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // On POSIX, we launch the test in a new process group with pgid equal to 5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // its pid. Any child processes that the test may create will inherit the 5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // same pgid. This way, if the test is abruptly terminated, we can clean up 5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // any orphaned child processes it may have left behind. 5594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) options.new_process_group = true; 5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return LaunchChildTestProcessWithOptions( 5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PrepareCommandLineForGTest(command_line, wrapper), 5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) options, 5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) timeout, 5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) was_timeout); 5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CommandLine PrepareCommandLineForGTest(const CommandLine& command_line, 5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& wrapper) { 5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CommandLine new_command_line(command_line.GetProgram()); 5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CommandLine::SwitchMap switches = command_line.GetSwitches(); 5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Strip out gtest_repeat flag - this is handled by the launcher process. 5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) switches.erase(kGTestRepeatFlag); 5764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (CommandLine::SwitchMap::const_iterator iter = switches.begin(); 5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) iter != switches.end(); ++iter) { 5794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new_command_line.AppendSwitchNative((*iter).first, (*iter).second); 5804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Prepend wrapper after last CommandLine quasi-copy operation. CommandLine 5834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // does not really support removing switches well, and trying to do that 5844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // on a CommandLine with a wrapper is known to break. 5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // TODO(phajdan.jr): Give it a try to support CommandLine removing switches. 5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN) 5874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new_command_line.PrependWrapper(ASCIIToWide(wrapper)); 5884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#elif defined(OS_POSIX) 5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new_command_line.PrependWrapper(wrapper); 5904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 5914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new_command_line; 5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int LaunchChildTestProcessWithOptions(const CommandLine& command_line, 5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const LaunchOptions& options, 5974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta timeout, 5984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool* was_timeout) { 5994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX) 6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Make sure an option we rely on is present - see LaunchChildGTestProcess. 6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(options.new_process_group); 6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LaunchOptions new_options(options); 6054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN) 6074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!new_options.job_handle); 6084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) win::ScopedHandle job_handle(CreateJobObject(NULL, NULL)); 6104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!job_handle.IsValid()) { 6114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(ERROR) << "Could not create JobObject."; 6124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 6134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Allow break-away from job since sandbox and few other places rely on it 6164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // on Windows versions prior to Windows 8 (which supports nested jobs). 6174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // TODO(phajdan.jr): Do not allow break-away on Windows 8. 6184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!SetJobObjectLimitFlags(job_handle.Get(), 6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | 6204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JOB_OBJECT_LIMIT_BREAKAWAY_OK)) { 6214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(ERROR) << "Could not SetJobObjectLimitFlags."; 6224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 6234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new_options.job_handle = job_handle.Get(); 6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif // defined(OS_WIN) 6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::ProcessHandle process_handle; 6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Note how we grab the lock before the process possibly gets created. 6324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This ensures that when the lock is held, ALL the processes are registered 6334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // in the set. 6344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AutoLock lock(g_live_process_handles_lock.Get()); 6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!base::LaunchProcess(command_line, new_options, &process_handle)) 6374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) g_live_process_handles.Get().insert(process_handle); 6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int exit_code = 0; 6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!base::WaitForExitCodeWithTimeout(process_handle, 6444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &exit_code, 6454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) timeout)) { 6464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *was_timeout = true; 6474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) exit_code = -1; // Set a non-zero exit code to signal a failure. 6484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Ensure that the process terminates. 6504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::KillProcess(process_handle, -1, true); 6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Note how we grab the log before issuing a possibly broad process kill. 6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Other code parts that grab the log kill processes, so avoid trying 6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // to do that twice and trigger all kinds of log messages. 6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AutoLock lock(g_live_process_handles_lock.Get()); 6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_POSIX) 6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (exit_code != 0) { 6614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // On POSIX, in case the test does not exit cleanly, either due to a crash 6624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // or due to it timing out, we need to clean up any child processes that 6634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // it might have created. On Windows, child processes are automatically 6644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // cleaned up using JobObjects. 6654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::KillProcessGroup(process_handle); 6664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 6684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) g_live_process_handles.Get().erase(process_handle); 6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::CloseProcessHandle(process_handle); 6734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return exit_code; 6754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace base 678