xref: /aosp_15_r20/external/libchrome/base/test/launcher/test_launcher.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "base/test/launcher/test_launcher.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <stdio.h>
8*635a8641SAndroid Build Coastguard Worker 
9*635a8641SAndroid Build Coastguard Worker #include <algorithm>
10*635a8641SAndroid Build Coastguard Worker #include <map>
11*635a8641SAndroid Build Coastguard Worker #include <random>
12*635a8641SAndroid Build Coastguard Worker #include <utility>
13*635a8641SAndroid Build Coastguard Worker 
14*635a8641SAndroid Build Coastguard Worker #include "base/at_exit.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/command_line.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/environment.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/files/file_path.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/files/file_util.h"
20*635a8641SAndroid Build Coastguard Worker #include "base/files/scoped_file.h"
21*635a8641SAndroid Build Coastguard Worker #include "base/format_macros.h"
22*635a8641SAndroid Build Coastguard Worker #include "base/hash.h"
23*635a8641SAndroid Build Coastguard Worker #include "base/lazy_instance.h"
24*635a8641SAndroid Build Coastguard Worker #include "base/location.h"
25*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
26*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
27*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
28*635a8641SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h"
29*635a8641SAndroid Build Coastguard Worker #include "base/process/kill.h"
30*635a8641SAndroid Build Coastguard Worker #include "base/process/launch.h"
31*635a8641SAndroid Build Coastguard Worker #include "base/run_loop.h"
32*635a8641SAndroid Build Coastguard Worker #include "base/single_thread_task_runner.h"
33*635a8641SAndroid Build Coastguard Worker #include "base/strings/pattern.h"
34*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
35*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
36*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
37*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
38*635a8641SAndroid Build Coastguard Worker #include "base/strings/stringize_macros.h"
39*635a8641SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
40*635a8641SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
41*635a8641SAndroid Build Coastguard Worker #include "base/sys_info.h"
42*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/post_task.h"
43*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/task_scheduler.h"
44*635a8641SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
45*635a8641SAndroid Build Coastguard Worker #include "base/test/launcher/test_launcher_tracer.h"
46*635a8641SAndroid Build Coastguard Worker #include "base/test/launcher/test_results_tracker.h"
47*635a8641SAndroid Build Coastguard Worker #include "base/test/test_switches.h"
48*635a8641SAndroid Build Coastguard Worker #include "base/test/test_timeouts.h"
49*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_restrictions.h"
50*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_task_runner_handle.h"
51*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
52*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
53*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
54*635a8641SAndroid Build Coastguard Worker 
55*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
56*635a8641SAndroid Build Coastguard Worker #include <fcntl.h>
57*635a8641SAndroid Build Coastguard Worker 
58*635a8641SAndroid Build Coastguard Worker #include "base/files/file_descriptor_watcher_posix.h"
59*635a8641SAndroid Build Coastguard Worker #endif
60*635a8641SAndroid Build Coastguard Worker 
61*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
62*635a8641SAndroid Build Coastguard Worker #include "base/mac/scoped_nsautorelease_pool.h"
63*635a8641SAndroid Build Coastguard Worker #endif
64*635a8641SAndroid Build Coastguard Worker 
65*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
66*635a8641SAndroid Build Coastguard Worker #include "base/win/windows_version.h"
67*635a8641SAndroid Build Coastguard Worker #endif
68*635a8641SAndroid Build Coastguard Worker 
69*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
70*635a8641SAndroid Build Coastguard Worker #include <lib/zx/job.h>
71*635a8641SAndroid Build Coastguard Worker #include "base/fuchsia/default_job.h"
72*635a8641SAndroid Build Coastguard Worker #include "base/fuchsia/fuchsia_logging.h"
73*635a8641SAndroid Build Coastguard Worker #endif
74*635a8641SAndroid Build Coastguard Worker 
75*635a8641SAndroid Build Coastguard Worker namespace base {
76*635a8641SAndroid Build Coastguard Worker 
77*635a8641SAndroid Build Coastguard Worker // See https://groups.google.com/a/chromium.org/d/msg/chromium-dev/nkdTP7sstSc/uT3FaE_sgkAJ .
78*635a8641SAndroid Build Coastguard Worker using ::operator<<;
79*635a8641SAndroid Build Coastguard Worker 
80*635a8641SAndroid Build Coastguard Worker // The environment variable name for the total number of test shards.
81*635a8641SAndroid Build Coastguard Worker const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
82*635a8641SAndroid Build Coastguard Worker // The environment variable name for the test shard index.
83*635a8641SAndroid Build Coastguard Worker const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
84*635a8641SAndroid Build Coastguard Worker 
85*635a8641SAndroid Build Coastguard Worker namespace {
86*635a8641SAndroid Build Coastguard Worker 
87*635a8641SAndroid Build Coastguard Worker // Global tag for test runs where the results are incomplete or unreliable
88*635a8641SAndroid Build Coastguard Worker // for any reason, e.g. early exit because of too many broken tests.
89*635a8641SAndroid Build Coastguard Worker const char kUnreliableResultsTag[] = "UNRELIABLE_RESULTS";
90*635a8641SAndroid Build Coastguard Worker 
91*635a8641SAndroid Build Coastguard Worker // Maximum time of no output after which we print list of processes still
92*635a8641SAndroid Build Coastguard Worker // running. This deliberately doesn't use TestTimeouts (which is otherwise
93*635a8641SAndroid Build Coastguard Worker // a recommended solution), because they can be increased. This would defeat
94*635a8641SAndroid Build Coastguard Worker // the purpose of this timeout, which is 1) to avoid buildbot "no output for
95*635a8641SAndroid Build Coastguard Worker // X seconds" timeout killing the process 2) help communicate status of
96*635a8641SAndroid Build Coastguard Worker // the test launcher to people looking at the output (no output for a long
97*635a8641SAndroid Build Coastguard Worker // time is mysterious and gives no info about what is happening) 3) help
98*635a8641SAndroid Build Coastguard Worker // debugging in case the process hangs anyway.
99*635a8641SAndroid Build Coastguard Worker constexpr TimeDelta kOutputTimeout = TimeDelta::FromSeconds(15);
100*635a8641SAndroid Build Coastguard Worker 
101*635a8641SAndroid Build Coastguard Worker // Limit of output snippet lines when printing to stdout.
102*635a8641SAndroid Build Coastguard Worker // Avoids flooding the logs with amount of output that gums up
103*635a8641SAndroid Build Coastguard Worker // the infrastructure.
104*635a8641SAndroid Build Coastguard Worker const size_t kOutputSnippetLinesLimit = 5000;
105*635a8641SAndroid Build Coastguard Worker 
106*635a8641SAndroid Build Coastguard Worker // Limit of output snippet size. Exceeding this limit
107*635a8641SAndroid Build Coastguard Worker // results in truncating the output and failing the test.
108*635a8641SAndroid Build Coastguard Worker const size_t kOutputSnippetBytesLimit = 300 * 1024;
109*635a8641SAndroid Build Coastguard Worker 
110*635a8641SAndroid Build Coastguard Worker // Limit of seed values for gtest shuffling. Arbitrary, but based on
111*635a8641SAndroid Build Coastguard Worker // gtest's similarly arbitrary choice.
112*635a8641SAndroid Build Coastguard Worker const uint32_t kRandomSeedUpperBound = 100000;
113*635a8641SAndroid Build Coastguard Worker 
114*635a8641SAndroid Build Coastguard Worker // Set of live launch test processes with corresponding lock (it is allowed
115*635a8641SAndroid Build Coastguard Worker // for callers to launch processes on different threads).
GetLiveProcessesLock()116*635a8641SAndroid Build Coastguard Worker Lock* GetLiveProcessesLock() {
117*635a8641SAndroid Build Coastguard Worker   static auto* lock = new Lock;
118*635a8641SAndroid Build Coastguard Worker   return lock;
119*635a8641SAndroid Build Coastguard Worker }
120*635a8641SAndroid Build Coastguard Worker 
GetLiveProcesses()121*635a8641SAndroid Build Coastguard Worker std::map<ProcessHandle, CommandLine>* GetLiveProcesses() {
122*635a8641SAndroid Build Coastguard Worker   static auto* map = new std::map<ProcessHandle, CommandLine>;
123*635a8641SAndroid Build Coastguard Worker   return map;
124*635a8641SAndroid Build Coastguard Worker }
125*635a8641SAndroid Build Coastguard Worker 
126*635a8641SAndroid Build Coastguard Worker // Performance trace generator.
GetTestLauncherTracer()127*635a8641SAndroid Build Coastguard Worker TestLauncherTracer* GetTestLauncherTracer() {
128*635a8641SAndroid Build Coastguard Worker   static auto* tracer = new TestLauncherTracer;
129*635a8641SAndroid Build Coastguard Worker   return tracer;
130*635a8641SAndroid Build Coastguard Worker }
131*635a8641SAndroid Build Coastguard Worker 
132*635a8641SAndroid Build Coastguard Worker // Creates and starts a TaskScheduler with |num_parallel_jobs| dedicated to
133*635a8641SAndroid Build Coastguard Worker // foreground blocking tasks (corresponds to the traits used to launch and wait
134*635a8641SAndroid Build Coastguard Worker // for child processes).
CreateAndStartTaskScheduler(int num_parallel_jobs)135*635a8641SAndroid Build Coastguard Worker void CreateAndStartTaskScheduler(int num_parallel_jobs) {
136*635a8641SAndroid Build Coastguard Worker   // These values are taken from TaskScheduler::StartWithDefaultParams(), which
137*635a8641SAndroid Build Coastguard Worker   // is not used directly to allow a custom number of threads in the foreground
138*635a8641SAndroid Build Coastguard Worker   // blocking pool.
139*635a8641SAndroid Build Coastguard Worker   constexpr int kMaxBackgroundThreads = 1;
140*635a8641SAndroid Build Coastguard Worker   constexpr int kMaxBackgroundBlockingThreads = 2;
141*635a8641SAndroid Build Coastguard Worker   const int max_foreground_threads =
142*635a8641SAndroid Build Coastguard Worker       std::max(1, base::SysInfo::NumberOfProcessors());
143*635a8641SAndroid Build Coastguard Worker   constexpr base::TimeDelta kSuggestedReclaimTime =
144*635a8641SAndroid Build Coastguard Worker       base::TimeDelta::FromSeconds(30);
145*635a8641SAndroid Build Coastguard Worker   base::TaskScheduler::Create("TestLauncher");
146*635a8641SAndroid Build Coastguard Worker   base::TaskScheduler::GetInstance()->Start(
147*635a8641SAndroid Build Coastguard Worker       {{kMaxBackgroundThreads, kSuggestedReclaimTime},
148*635a8641SAndroid Build Coastguard Worker        {kMaxBackgroundBlockingThreads, kSuggestedReclaimTime},
149*635a8641SAndroid Build Coastguard Worker        {max_foreground_threads, kSuggestedReclaimTime},
150*635a8641SAndroid Build Coastguard Worker        {num_parallel_jobs, kSuggestedReclaimTime}});
151*635a8641SAndroid Build Coastguard Worker }
152*635a8641SAndroid Build Coastguard Worker 
153*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
154*635a8641SAndroid Build Coastguard Worker // Self-pipe that makes it possible to do complex shutdown handling
155*635a8641SAndroid Build Coastguard Worker // outside of the signal handler.
156*635a8641SAndroid Build Coastguard Worker int g_shutdown_pipe[2] = { -1, -1 };
157*635a8641SAndroid Build Coastguard Worker 
ShutdownPipeSignalHandler(int signal)158*635a8641SAndroid Build Coastguard Worker void ShutdownPipeSignalHandler(int signal) {
159*635a8641SAndroid Build Coastguard Worker   HANDLE_EINTR(write(g_shutdown_pipe[1], "q", 1));
160*635a8641SAndroid Build Coastguard Worker }
161*635a8641SAndroid Build Coastguard Worker 
KillSpawnedTestProcesses()162*635a8641SAndroid Build Coastguard Worker void KillSpawnedTestProcesses() {
163*635a8641SAndroid Build Coastguard Worker   // Keep the lock until exiting the process to prevent further processes
164*635a8641SAndroid Build Coastguard Worker   // from being spawned.
165*635a8641SAndroid Build Coastguard Worker   AutoLock lock(*GetLiveProcessesLock());
166*635a8641SAndroid Build Coastguard Worker 
167*635a8641SAndroid Build Coastguard Worker   fprintf(stdout, "Sending SIGTERM to %" PRIuS " child processes... ",
168*635a8641SAndroid Build Coastguard Worker           GetLiveProcesses()->size());
169*635a8641SAndroid Build Coastguard Worker   fflush(stdout);
170*635a8641SAndroid Build Coastguard Worker 
171*635a8641SAndroid Build Coastguard Worker   for (const auto& pair : *GetLiveProcesses()) {
172*635a8641SAndroid Build Coastguard Worker     // Send the signal to entire process group.
173*635a8641SAndroid Build Coastguard Worker     kill((-1) * (pair.first), SIGTERM);
174*635a8641SAndroid Build Coastguard Worker   }
175*635a8641SAndroid Build Coastguard Worker 
176*635a8641SAndroid Build Coastguard Worker   fprintf(stdout,
177*635a8641SAndroid Build Coastguard Worker           "done.\nGiving processes a chance to terminate cleanly... ");
178*635a8641SAndroid Build Coastguard Worker   fflush(stdout);
179*635a8641SAndroid Build Coastguard Worker 
180*635a8641SAndroid Build Coastguard Worker   PlatformThread::Sleep(TimeDelta::FromMilliseconds(500));
181*635a8641SAndroid Build Coastguard Worker 
182*635a8641SAndroid Build Coastguard Worker   fprintf(stdout, "done.\n");
183*635a8641SAndroid Build Coastguard Worker   fflush(stdout);
184*635a8641SAndroid Build Coastguard Worker 
185*635a8641SAndroid Build Coastguard Worker   fprintf(stdout, "Sending SIGKILL to %" PRIuS " child processes... ",
186*635a8641SAndroid Build Coastguard Worker           GetLiveProcesses()->size());
187*635a8641SAndroid Build Coastguard Worker   fflush(stdout);
188*635a8641SAndroid Build Coastguard Worker 
189*635a8641SAndroid Build Coastguard Worker   for (const auto& pair : *GetLiveProcesses()) {
190*635a8641SAndroid Build Coastguard Worker     // Send the signal to entire process group.
191*635a8641SAndroid Build Coastguard Worker     kill((-1) * (pair.first), SIGKILL);
192*635a8641SAndroid Build Coastguard Worker   }
193*635a8641SAndroid Build Coastguard Worker 
194*635a8641SAndroid Build Coastguard Worker   fprintf(stdout, "done.\n");
195*635a8641SAndroid Build Coastguard Worker   fflush(stdout);
196*635a8641SAndroid Build Coastguard Worker }
197*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX)
198*635a8641SAndroid Build Coastguard Worker 
199*635a8641SAndroid Build Coastguard Worker // Parses the environment variable var as an Int32.  If it is unset, returns
200*635a8641SAndroid Build Coastguard Worker // true.  If it is set, unsets it then converts it to Int32 before
201*635a8641SAndroid Build Coastguard Worker // returning it in |result|.  Returns true on success.
TakeInt32FromEnvironment(const char * const var,int32_t * result)202*635a8641SAndroid Build Coastguard Worker bool TakeInt32FromEnvironment(const char* const var, int32_t* result) {
203*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<Environment> env(Environment::Create());
204*635a8641SAndroid Build Coastguard Worker   std::string str_val;
205*635a8641SAndroid Build Coastguard Worker 
206*635a8641SAndroid Build Coastguard Worker   if (!env->GetVar(var, &str_val))
207*635a8641SAndroid Build Coastguard Worker     return true;
208*635a8641SAndroid Build Coastguard Worker 
209*635a8641SAndroid Build Coastguard Worker   if (!env->UnSetVar(var)) {
210*635a8641SAndroid Build Coastguard Worker     LOG(ERROR) << "Invalid environment: we could not unset " << var << ".\n";
211*635a8641SAndroid Build Coastguard Worker     return false;
212*635a8641SAndroid Build Coastguard Worker   }
213*635a8641SAndroid Build Coastguard Worker 
214*635a8641SAndroid Build Coastguard Worker   if (!StringToInt(str_val, result)) {
215*635a8641SAndroid Build Coastguard Worker     LOG(ERROR) << "Invalid environment: " << var << " is not an integer.\n";
216*635a8641SAndroid Build Coastguard Worker     return false;
217*635a8641SAndroid Build Coastguard Worker   }
218*635a8641SAndroid Build Coastguard Worker 
219*635a8641SAndroid Build Coastguard Worker   return true;
220*635a8641SAndroid Build Coastguard Worker }
221*635a8641SAndroid Build Coastguard Worker 
222*635a8641SAndroid Build Coastguard Worker // Unsets the environment variable |name| and returns true on success.
223*635a8641SAndroid Build Coastguard Worker // Also returns true if the variable just doesn't exist.
UnsetEnvironmentVariableIfExists(const std::string & name)224*635a8641SAndroid Build Coastguard Worker bool UnsetEnvironmentVariableIfExists(const std::string& name) {
225*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<Environment> env(Environment::Create());
226*635a8641SAndroid Build Coastguard Worker   std::string str_val;
227*635a8641SAndroid Build Coastguard Worker   if (!env->GetVar(name, &str_val))
228*635a8641SAndroid Build Coastguard Worker     return true;
229*635a8641SAndroid Build Coastguard Worker   return env->UnSetVar(name);
230*635a8641SAndroid Build Coastguard Worker }
231*635a8641SAndroid Build Coastguard Worker 
232*635a8641SAndroid Build Coastguard Worker // Returns true if bot mode has been requested, i.e. defaults optimized
233*635a8641SAndroid Build Coastguard Worker // for continuous integration bots. This way developers don't have to remember
234*635a8641SAndroid Build Coastguard Worker // special command-line flags.
BotModeEnabled()235*635a8641SAndroid Build Coastguard Worker bool BotModeEnabled() {
236*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<Environment> env(Environment::Create());
237*635a8641SAndroid Build Coastguard Worker   return CommandLine::ForCurrentProcess()->HasSwitch(
238*635a8641SAndroid Build Coastguard Worker       switches::kTestLauncherBotMode) ||
239*635a8641SAndroid Build Coastguard Worker       env->HasVar("CHROMIUM_TEST_LAUNCHER_BOT_MODE");
240*635a8641SAndroid Build Coastguard Worker }
241*635a8641SAndroid Build Coastguard Worker 
242*635a8641SAndroid Build Coastguard Worker // Returns command line command line after gtest-specific processing
243*635a8641SAndroid Build Coastguard Worker // and applying |wrapper|.
PrepareCommandLineForGTest(const CommandLine & command_line,const std::string & wrapper)244*635a8641SAndroid Build Coastguard Worker CommandLine PrepareCommandLineForGTest(const CommandLine& command_line,
245*635a8641SAndroid Build Coastguard Worker                                        const std::string& wrapper) {
246*635a8641SAndroid Build Coastguard Worker   CommandLine new_command_line(command_line.GetProgram());
247*635a8641SAndroid Build Coastguard Worker   CommandLine::SwitchMap switches = command_line.GetSwitches();
248*635a8641SAndroid Build Coastguard Worker 
249*635a8641SAndroid Build Coastguard Worker   // Handled by the launcher process.
250*635a8641SAndroid Build Coastguard Worker   switches.erase(kGTestRepeatFlag);
251*635a8641SAndroid Build Coastguard Worker   switches.erase(kGTestShuffleFlag);
252*635a8641SAndroid Build Coastguard Worker   switches.erase(kGTestRandomSeedFlag);
253*635a8641SAndroid Build Coastguard Worker 
254*635a8641SAndroid Build Coastguard Worker   // Don't try to write the final XML report in child processes.
255*635a8641SAndroid Build Coastguard Worker   switches.erase(kGTestOutputFlag);
256*635a8641SAndroid Build Coastguard Worker 
257*635a8641SAndroid Build Coastguard Worker   for (CommandLine::SwitchMap::const_iterator iter = switches.begin();
258*635a8641SAndroid Build Coastguard Worker        iter != switches.end(); ++iter) {
259*635a8641SAndroid Build Coastguard Worker     new_command_line.AppendSwitchNative((*iter).first, (*iter).second);
260*635a8641SAndroid Build Coastguard Worker   }
261*635a8641SAndroid Build Coastguard Worker 
262*635a8641SAndroid Build Coastguard Worker   // Prepend wrapper after last CommandLine quasi-copy operation. CommandLine
263*635a8641SAndroid Build Coastguard Worker   // does not really support removing switches well, and trying to do that
264*635a8641SAndroid Build Coastguard Worker   // on a CommandLine with a wrapper is known to break.
265*635a8641SAndroid Build Coastguard Worker   // TODO(phajdan.jr): Give it a try to support CommandLine removing switches.
266*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
267*635a8641SAndroid Build Coastguard Worker   new_command_line.PrependWrapper(ASCIIToUTF16(wrapper));
268*635a8641SAndroid Build Coastguard Worker #else
269*635a8641SAndroid Build Coastguard Worker   new_command_line.PrependWrapper(wrapper);
270*635a8641SAndroid Build Coastguard Worker #endif
271*635a8641SAndroid Build Coastguard Worker 
272*635a8641SAndroid Build Coastguard Worker   return new_command_line;
273*635a8641SAndroid Build Coastguard Worker }
274*635a8641SAndroid Build Coastguard Worker 
275*635a8641SAndroid Build Coastguard Worker // Launches a child process using |command_line|. If the child process is still
276*635a8641SAndroid Build Coastguard Worker // running after |timeout|, it is terminated and |*was_timeout| is set to true.
277*635a8641SAndroid Build Coastguard Worker // Returns exit code of the process.
LaunchChildTestProcessWithOptions(const CommandLine & command_line,const LaunchOptions & options,int flags,TimeDelta timeout,ProcessLifetimeObserver * observer,bool * was_timeout)278*635a8641SAndroid Build Coastguard Worker int LaunchChildTestProcessWithOptions(const CommandLine& command_line,
279*635a8641SAndroid Build Coastguard Worker                                       const LaunchOptions& options,
280*635a8641SAndroid Build Coastguard Worker                                       int flags,
281*635a8641SAndroid Build Coastguard Worker                                       TimeDelta timeout,
282*635a8641SAndroid Build Coastguard Worker                                       ProcessLifetimeObserver* observer,
283*635a8641SAndroid Build Coastguard Worker                                       bool* was_timeout) {
284*635a8641SAndroid Build Coastguard Worker   TimeTicks start_time(TimeTicks::Now());
285*635a8641SAndroid Build Coastguard Worker 
286*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
287*635a8641SAndroid Build Coastguard Worker   // Make sure an option we rely on is present - see LaunchChildGTestProcess.
288*635a8641SAndroid Build Coastguard Worker   DCHECK(options.new_process_group);
289*635a8641SAndroid Build Coastguard Worker #endif
290*635a8641SAndroid Build Coastguard Worker 
291*635a8641SAndroid Build Coastguard Worker   LaunchOptions new_options(options);
292*635a8641SAndroid Build Coastguard Worker 
293*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
294*635a8641SAndroid Build Coastguard Worker   DCHECK(!new_options.job_handle);
295*635a8641SAndroid Build Coastguard Worker 
296*635a8641SAndroid Build Coastguard Worker   win::ScopedHandle job_handle;
297*635a8641SAndroid Build Coastguard Worker   if (flags & TestLauncher::USE_JOB_OBJECTS) {
298*635a8641SAndroid Build Coastguard Worker     job_handle.Set(CreateJobObject(NULL, NULL));
299*635a8641SAndroid Build Coastguard Worker     if (!job_handle.IsValid()) {
300*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Could not create JobObject.";
301*635a8641SAndroid Build Coastguard Worker       return -1;
302*635a8641SAndroid Build Coastguard Worker     }
303*635a8641SAndroid Build Coastguard Worker 
304*635a8641SAndroid Build Coastguard Worker     DWORD job_flags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
305*635a8641SAndroid Build Coastguard Worker 
306*635a8641SAndroid Build Coastguard Worker     // Allow break-away from job since sandbox and few other places rely on it
307*635a8641SAndroid Build Coastguard Worker     // on Windows versions prior to Windows 8 (which supports nested jobs).
308*635a8641SAndroid Build Coastguard Worker     if (win::GetVersion() < win::VERSION_WIN8 &&
309*635a8641SAndroid Build Coastguard Worker         flags & TestLauncher::ALLOW_BREAKAWAY_FROM_JOB) {
310*635a8641SAndroid Build Coastguard Worker       job_flags |= JOB_OBJECT_LIMIT_BREAKAWAY_OK;
311*635a8641SAndroid Build Coastguard Worker     }
312*635a8641SAndroid Build Coastguard Worker 
313*635a8641SAndroid Build Coastguard Worker     if (!SetJobObjectLimitFlags(job_handle.Get(), job_flags)) {
314*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Could not SetJobObjectLimitFlags.";
315*635a8641SAndroid Build Coastguard Worker       return -1;
316*635a8641SAndroid Build Coastguard Worker     }
317*635a8641SAndroid Build Coastguard Worker 
318*635a8641SAndroid Build Coastguard Worker     new_options.job_handle = job_handle.Get();
319*635a8641SAndroid Build Coastguard Worker   }
320*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA)
321*635a8641SAndroid Build Coastguard Worker   DCHECK(!new_options.job_handle);
322*635a8641SAndroid Build Coastguard Worker 
323*635a8641SAndroid Build Coastguard Worker   zx::job job_handle;
324*635a8641SAndroid Build Coastguard Worker   zx_status_t result = zx::job::create(*GetDefaultJob(), 0, &job_handle);
325*635a8641SAndroid Build Coastguard Worker   ZX_CHECK(ZX_OK == result, result) << "zx_job_create";
326*635a8641SAndroid Build Coastguard Worker   new_options.job_handle = job_handle.get();
327*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_FUCHSIA)
328*635a8641SAndroid Build Coastguard Worker 
329*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX)
330*635a8641SAndroid Build Coastguard Worker   // To prevent accidental privilege sharing to an untrusted child, processes
331*635a8641SAndroid Build Coastguard Worker   // are started with PR_SET_NO_NEW_PRIVS. Do not set that here, since this
332*635a8641SAndroid Build Coastguard Worker   // new child will be privileged and trusted.
333*635a8641SAndroid Build Coastguard Worker   new_options.allow_new_privs = true;
334*635a8641SAndroid Build Coastguard Worker #endif
335*635a8641SAndroid Build Coastguard Worker 
336*635a8641SAndroid Build Coastguard Worker   Process process;
337*635a8641SAndroid Build Coastguard Worker 
338*635a8641SAndroid Build Coastguard Worker   {
339*635a8641SAndroid Build Coastguard Worker     // Note how we grab the lock before the process possibly gets created.
340*635a8641SAndroid Build Coastguard Worker     // This ensures that when the lock is held, ALL the processes are registered
341*635a8641SAndroid Build Coastguard Worker     // in the set.
342*635a8641SAndroid Build Coastguard Worker     AutoLock lock(*GetLiveProcessesLock());
343*635a8641SAndroid Build Coastguard Worker 
344*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
345*635a8641SAndroid Build Coastguard Worker     // Allow the handle used to capture stdio and stdout to be inherited by the
346*635a8641SAndroid Build Coastguard Worker     // child. Note that this is done under GetLiveProcessesLock() to ensure that
347*635a8641SAndroid Build Coastguard Worker     // only the desired child receives the handle.
348*635a8641SAndroid Build Coastguard Worker     if (new_options.stdout_handle) {
349*635a8641SAndroid Build Coastguard Worker       ::SetHandleInformation(new_options.stdout_handle, HANDLE_FLAG_INHERIT,
350*635a8641SAndroid Build Coastguard Worker                              HANDLE_FLAG_INHERIT);
351*635a8641SAndroid Build Coastguard Worker     }
352*635a8641SAndroid Build Coastguard Worker #endif
353*635a8641SAndroid Build Coastguard Worker 
354*635a8641SAndroid Build Coastguard Worker     process = LaunchProcess(command_line, new_options);
355*635a8641SAndroid Build Coastguard Worker 
356*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
357*635a8641SAndroid Build Coastguard Worker     // Revoke inheritance so that the handle isn't leaked into other children.
358*635a8641SAndroid Build Coastguard Worker     // Note that this is done under GetLiveProcessesLock() to ensure that only
359*635a8641SAndroid Build Coastguard Worker     // the desired child receives the handle.
360*635a8641SAndroid Build Coastguard Worker     if (new_options.stdout_handle)
361*635a8641SAndroid Build Coastguard Worker       ::SetHandleInformation(new_options.stdout_handle, HANDLE_FLAG_INHERIT, 0);
362*635a8641SAndroid Build Coastguard Worker #endif
363*635a8641SAndroid Build Coastguard Worker 
364*635a8641SAndroid Build Coastguard Worker     if (!process.IsValid())
365*635a8641SAndroid Build Coastguard Worker       return -1;
366*635a8641SAndroid Build Coastguard Worker 
367*635a8641SAndroid Build Coastguard Worker     // TODO(rvargas) crbug.com/417532: Don't store process handles.
368*635a8641SAndroid Build Coastguard Worker     GetLiveProcesses()->insert(std::make_pair(process.Handle(), command_line));
369*635a8641SAndroid Build Coastguard Worker   }
370*635a8641SAndroid Build Coastguard Worker 
371*635a8641SAndroid Build Coastguard Worker   if (observer)
372*635a8641SAndroid Build Coastguard Worker     observer->OnLaunched(process.Handle(), process.Pid());
373*635a8641SAndroid Build Coastguard Worker 
374*635a8641SAndroid Build Coastguard Worker   int exit_code = 0;
375*635a8641SAndroid Build Coastguard Worker   bool did_exit = false;
376*635a8641SAndroid Build Coastguard Worker 
377*635a8641SAndroid Build Coastguard Worker   {
378*635a8641SAndroid Build Coastguard Worker     base::ScopedAllowBaseSyncPrimitivesForTesting allow_base_sync_primitives;
379*635a8641SAndroid Build Coastguard Worker     did_exit = process.WaitForExitWithTimeout(timeout, &exit_code);
380*635a8641SAndroid Build Coastguard Worker   }
381*635a8641SAndroid Build Coastguard Worker 
382*635a8641SAndroid Build Coastguard Worker   if (!did_exit) {
383*635a8641SAndroid Build Coastguard Worker     if (observer)
384*635a8641SAndroid Build Coastguard Worker       observer->OnTimedOut(command_line);
385*635a8641SAndroid Build Coastguard Worker 
386*635a8641SAndroid Build Coastguard Worker     *was_timeout = true;
387*635a8641SAndroid Build Coastguard Worker     exit_code = -1;  // Set a non-zero exit code to signal a failure.
388*635a8641SAndroid Build Coastguard Worker 
389*635a8641SAndroid Build Coastguard Worker     {
390*635a8641SAndroid Build Coastguard Worker       base::ScopedAllowBaseSyncPrimitivesForTesting allow_base_sync_primitives;
391*635a8641SAndroid Build Coastguard Worker       // Ensure that the process terminates.
392*635a8641SAndroid Build Coastguard Worker       process.Terminate(-1, true);
393*635a8641SAndroid Build Coastguard Worker     }
394*635a8641SAndroid Build Coastguard Worker   }
395*635a8641SAndroid Build Coastguard Worker 
396*635a8641SAndroid Build Coastguard Worker   {
397*635a8641SAndroid Build Coastguard Worker     // Note how we grab the log before issuing a possibly broad process kill.
398*635a8641SAndroid Build Coastguard Worker     // Other code parts that grab the log kill processes, so avoid trying
399*635a8641SAndroid Build Coastguard Worker     // to do that twice and trigger all kinds of log messages.
400*635a8641SAndroid Build Coastguard Worker     AutoLock lock(*GetLiveProcessesLock());
401*635a8641SAndroid Build Coastguard Worker 
402*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
403*635a8641SAndroid Build Coastguard Worker     zx_status_t status = job_handle.kill();
404*635a8641SAndroid Build Coastguard Worker     ZX_CHECK(status == ZX_OK, status);
405*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX)
406*635a8641SAndroid Build Coastguard Worker     if (exit_code != 0) {
407*635a8641SAndroid Build Coastguard Worker       // On POSIX, in case the test does not exit cleanly, either due to a crash
408*635a8641SAndroid Build Coastguard Worker       // or due to it timing out, we need to clean up any child processes that
409*635a8641SAndroid Build Coastguard Worker       // it might have created. On Windows, child processes are automatically
410*635a8641SAndroid Build Coastguard Worker       // cleaned up using JobObjects.
411*635a8641SAndroid Build Coastguard Worker       KillProcessGroup(process.Handle());
412*635a8641SAndroid Build Coastguard Worker     }
413*635a8641SAndroid Build Coastguard Worker #endif
414*635a8641SAndroid Build Coastguard Worker 
415*635a8641SAndroid Build Coastguard Worker     GetLiveProcesses()->erase(process.Handle());
416*635a8641SAndroid Build Coastguard Worker   }
417*635a8641SAndroid Build Coastguard Worker 
418*635a8641SAndroid Build Coastguard Worker   GetTestLauncherTracer()->RecordProcessExecution(
419*635a8641SAndroid Build Coastguard Worker       start_time, TimeTicks::Now() - start_time);
420*635a8641SAndroid Build Coastguard Worker 
421*635a8641SAndroid Build Coastguard Worker   return exit_code;
422*635a8641SAndroid Build Coastguard Worker }
423*635a8641SAndroid Build Coastguard Worker 
DoLaunchChildTestProcess(const CommandLine & command_line,TimeDelta timeout,const TestLauncher::LaunchOptions & test_launch_options,bool redirect_stdio,SingleThreadTaskRunner * task_runner,std::unique_ptr<ProcessLifetimeObserver> observer)424*635a8641SAndroid Build Coastguard Worker void DoLaunchChildTestProcess(
425*635a8641SAndroid Build Coastguard Worker     const CommandLine& command_line,
426*635a8641SAndroid Build Coastguard Worker     TimeDelta timeout,
427*635a8641SAndroid Build Coastguard Worker     const TestLauncher::LaunchOptions& test_launch_options,
428*635a8641SAndroid Build Coastguard Worker     bool redirect_stdio,
429*635a8641SAndroid Build Coastguard Worker     SingleThreadTaskRunner* task_runner,
430*635a8641SAndroid Build Coastguard Worker     std::unique_ptr<ProcessLifetimeObserver> observer) {
431*635a8641SAndroid Build Coastguard Worker   TimeTicks start_time = TimeTicks::Now();
432*635a8641SAndroid Build Coastguard Worker 
433*635a8641SAndroid Build Coastguard Worker   ScopedFILE output_file;
434*635a8641SAndroid Build Coastguard Worker   FilePath output_filename;
435*635a8641SAndroid Build Coastguard Worker   if (redirect_stdio) {
436*635a8641SAndroid Build Coastguard Worker     FILE* raw_output_file = CreateAndOpenTemporaryFile(&output_filename);
437*635a8641SAndroid Build Coastguard Worker     output_file.reset(raw_output_file);
438*635a8641SAndroid Build Coastguard Worker     CHECK(output_file);
439*635a8641SAndroid Build Coastguard Worker   }
440*635a8641SAndroid Build Coastguard Worker 
441*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
442*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
443*635a8641SAndroid Build Coastguard Worker 
444*635a8641SAndroid Build Coastguard Worker   options.inherit_mode = test_launch_options.inherit_mode;
445*635a8641SAndroid Build Coastguard Worker   options.handles_to_inherit = test_launch_options.handles_to_inherit;
446*635a8641SAndroid Build Coastguard Worker   if (redirect_stdio) {
447*635a8641SAndroid Build Coastguard Worker     HANDLE handle =
448*635a8641SAndroid Build Coastguard Worker         reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(output_file.get())));
449*635a8641SAndroid Build Coastguard Worker     CHECK_NE(INVALID_HANDLE_VALUE, handle);
450*635a8641SAndroid Build Coastguard Worker     options.stdin_handle = INVALID_HANDLE_VALUE;
451*635a8641SAndroid Build Coastguard Worker     options.stdout_handle = handle;
452*635a8641SAndroid Build Coastguard Worker     options.stderr_handle = handle;
453*635a8641SAndroid Build Coastguard Worker     // See LaunchOptions.stdout_handle comments for why this compares against
454*635a8641SAndroid Build Coastguard Worker     // FILE_TYPE_CHAR.
455*635a8641SAndroid Build Coastguard Worker     if (options.inherit_mode == base::LaunchOptions::Inherit::kSpecific &&
456*635a8641SAndroid Build Coastguard Worker         GetFileType(handle) != FILE_TYPE_CHAR) {
457*635a8641SAndroid Build Coastguard Worker       options.handles_to_inherit.push_back(handle);
458*635a8641SAndroid Build Coastguard Worker     }
459*635a8641SAndroid Build Coastguard Worker   }
460*635a8641SAndroid Build Coastguard Worker 
461*635a8641SAndroid Build Coastguard Worker #else  // if !defined(OS_WIN)
462*635a8641SAndroid Build Coastguard Worker 
463*635a8641SAndroid Build Coastguard Worker   options.fds_to_remap = test_launch_options.fds_to_remap;
464*635a8641SAndroid Build Coastguard Worker   if (redirect_stdio) {
465*635a8641SAndroid Build Coastguard Worker     int output_file_fd = fileno(output_file.get());
466*635a8641SAndroid Build Coastguard Worker     CHECK_LE(0, output_file_fd);
467*635a8641SAndroid Build Coastguard Worker     options.fds_to_remap.push_back(
468*635a8641SAndroid Build Coastguard Worker         std::make_pair(output_file_fd, STDOUT_FILENO));
469*635a8641SAndroid Build Coastguard Worker     options.fds_to_remap.push_back(
470*635a8641SAndroid Build Coastguard Worker         std::make_pair(output_file_fd, STDERR_FILENO));
471*635a8641SAndroid Build Coastguard Worker   }
472*635a8641SAndroid Build Coastguard Worker 
473*635a8641SAndroid Build Coastguard Worker #if !defined(OS_FUCHSIA)
474*635a8641SAndroid Build Coastguard Worker   options.new_process_group = true;
475*635a8641SAndroid Build Coastguard Worker #endif
476*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX)
477*635a8641SAndroid Build Coastguard Worker   options.kill_on_parent_death = true;
478*635a8641SAndroid Build Coastguard Worker #endif
479*635a8641SAndroid Build Coastguard Worker 
480*635a8641SAndroid Build Coastguard Worker #endif  // !defined(OS_WIN)
481*635a8641SAndroid Build Coastguard Worker 
482*635a8641SAndroid Build Coastguard Worker   bool was_timeout = false;
483*635a8641SAndroid Build Coastguard Worker   int exit_code = LaunchChildTestProcessWithOptions(
484*635a8641SAndroid Build Coastguard Worker       command_line, options, test_launch_options.flags, timeout, observer.get(),
485*635a8641SAndroid Build Coastguard Worker       &was_timeout);
486*635a8641SAndroid Build Coastguard Worker 
487*635a8641SAndroid Build Coastguard Worker   std::string output_file_contents;
488*635a8641SAndroid Build Coastguard Worker   if (redirect_stdio) {
489*635a8641SAndroid Build Coastguard Worker     fflush(output_file.get());
490*635a8641SAndroid Build Coastguard Worker     output_file.reset();
491*635a8641SAndroid Build Coastguard Worker     // Reading the file can sometimes fail when the process was killed midflight
492*635a8641SAndroid Build Coastguard Worker     // (e.g. on test suite timeout): https://crbug.com/826408. Attempt to read
493*635a8641SAndroid Build Coastguard Worker     // the output file anyways, but do not crash on failure in this case.
494*635a8641SAndroid Build Coastguard Worker     CHECK(ReadFileToString(output_filename, &output_file_contents) ||
495*635a8641SAndroid Build Coastguard Worker           exit_code != 0);
496*635a8641SAndroid Build Coastguard Worker 
497*635a8641SAndroid Build Coastguard Worker     if (!DeleteFile(output_filename, false)) {
498*635a8641SAndroid Build Coastguard Worker       // This needs to be non-fatal at least for Windows.
499*635a8641SAndroid Build Coastguard Worker       LOG(WARNING) << "Failed to delete " << output_filename.AsUTF8Unsafe();
500*635a8641SAndroid Build Coastguard Worker     }
501*635a8641SAndroid Build Coastguard Worker   }
502*635a8641SAndroid Build Coastguard Worker 
503*635a8641SAndroid Build Coastguard Worker   // Invoke OnCompleted on the thread it was originating from, not on a worker
504*635a8641SAndroid Build Coastguard Worker   // pool thread.
505*635a8641SAndroid Build Coastguard Worker   task_runner->PostTask(
506*635a8641SAndroid Build Coastguard Worker       FROM_HERE,
507*635a8641SAndroid Build Coastguard Worker       BindOnce(&ProcessLifetimeObserver::OnCompleted, std::move(observer),
508*635a8641SAndroid Build Coastguard Worker                exit_code, TimeTicks::Now() - start_time, was_timeout,
509*635a8641SAndroid Build Coastguard Worker                output_file_contents));
510*635a8641SAndroid Build Coastguard Worker }
511*635a8641SAndroid Build Coastguard Worker 
512*635a8641SAndroid Build Coastguard Worker }  // namespace
513*635a8641SAndroid Build Coastguard Worker 
514*635a8641SAndroid Build Coastguard Worker const char kGTestBreakOnFailure[] = "gtest_break_on_failure";
515*635a8641SAndroid Build Coastguard Worker const char kGTestFilterFlag[] = "gtest_filter";
516*635a8641SAndroid Build Coastguard Worker const char kGTestFlagfileFlag[] = "gtest_flagfile";
517*635a8641SAndroid Build Coastguard Worker const char kGTestHelpFlag[]   = "gtest_help";
518*635a8641SAndroid Build Coastguard Worker const char kGTestListTestsFlag[] = "gtest_list_tests";
519*635a8641SAndroid Build Coastguard Worker const char kGTestRepeatFlag[] = "gtest_repeat";
520*635a8641SAndroid Build Coastguard Worker const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests";
521*635a8641SAndroid Build Coastguard Worker const char kGTestOutputFlag[] = "gtest_output";
522*635a8641SAndroid Build Coastguard Worker const char kGTestShuffleFlag[] = "gtest_shuffle";
523*635a8641SAndroid Build Coastguard Worker const char kGTestRandomSeedFlag[] = "gtest_random_seed";
524*635a8641SAndroid Build Coastguard Worker 
525*635a8641SAndroid Build Coastguard Worker TestLauncherDelegate::~TestLauncherDelegate() = default;
526*635a8641SAndroid Build Coastguard Worker 
527*635a8641SAndroid Build Coastguard Worker TestLauncher::LaunchOptions::LaunchOptions() = default;
528*635a8641SAndroid Build Coastguard Worker TestLauncher::LaunchOptions::LaunchOptions(const LaunchOptions& other) =
529*635a8641SAndroid Build Coastguard Worker     default;
530*635a8641SAndroid Build Coastguard Worker TestLauncher::LaunchOptions::~LaunchOptions() = default;
531*635a8641SAndroid Build Coastguard Worker 
TestLauncher(TestLauncherDelegate * launcher_delegate,size_t parallel_jobs)532*635a8641SAndroid Build Coastguard Worker TestLauncher::TestLauncher(TestLauncherDelegate* launcher_delegate,
533*635a8641SAndroid Build Coastguard Worker                            size_t parallel_jobs)
534*635a8641SAndroid Build Coastguard Worker     : launcher_delegate_(launcher_delegate),
535*635a8641SAndroid Build Coastguard Worker       total_shards_(1),
536*635a8641SAndroid Build Coastguard Worker       shard_index_(0),
537*635a8641SAndroid Build Coastguard Worker       cycles_(1),
538*635a8641SAndroid Build Coastguard Worker       test_found_count_(0),
539*635a8641SAndroid Build Coastguard Worker       test_started_count_(0),
540*635a8641SAndroid Build Coastguard Worker       test_finished_count_(0),
541*635a8641SAndroid Build Coastguard Worker       test_success_count_(0),
542*635a8641SAndroid Build Coastguard Worker       test_broken_count_(0),
543*635a8641SAndroid Build Coastguard Worker       retry_count_(0),
544*635a8641SAndroid Build Coastguard Worker       retry_limit_(0),
545*635a8641SAndroid Build Coastguard Worker       force_run_broken_tests_(false),
546*635a8641SAndroid Build Coastguard Worker       run_result_(true),
547*635a8641SAndroid Build Coastguard Worker       shuffle_(false),
548*635a8641SAndroid Build Coastguard Worker       shuffle_seed_(0),
549*635a8641SAndroid Build Coastguard Worker       watchdog_timer_(FROM_HERE,
550*635a8641SAndroid Build Coastguard Worker                       kOutputTimeout,
551*635a8641SAndroid Build Coastguard Worker                       this,
552*635a8641SAndroid Build Coastguard Worker                       &TestLauncher::OnOutputTimeout),
553*635a8641SAndroid Build Coastguard Worker       parallel_jobs_(parallel_jobs) {}
554*635a8641SAndroid Build Coastguard Worker 
~TestLauncher()555*635a8641SAndroid Build Coastguard Worker TestLauncher::~TestLauncher() {
556*635a8641SAndroid Build Coastguard Worker   if (base::TaskScheduler::GetInstance()) {
557*635a8641SAndroid Build Coastguard Worker     base::TaskScheduler::GetInstance()->Shutdown();
558*635a8641SAndroid Build Coastguard Worker   }
559*635a8641SAndroid Build Coastguard Worker }
560*635a8641SAndroid Build Coastguard Worker 
Run()561*635a8641SAndroid Build Coastguard Worker bool TestLauncher::Run() {
562*635a8641SAndroid Build Coastguard Worker   if (!Init())
563*635a8641SAndroid Build Coastguard Worker     return false;
564*635a8641SAndroid Build Coastguard Worker 
565*635a8641SAndroid Build Coastguard Worker   // Value of |cycles_| changes after each iteration. Keep track of the
566*635a8641SAndroid Build Coastguard Worker   // original value.
567*635a8641SAndroid Build Coastguard Worker   int requested_cycles = cycles_;
568*635a8641SAndroid Build Coastguard Worker 
569*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
570*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(0, pipe(g_shutdown_pipe));
571*635a8641SAndroid Build Coastguard Worker 
572*635a8641SAndroid Build Coastguard Worker   struct sigaction action;
573*635a8641SAndroid Build Coastguard Worker   memset(&action, 0, sizeof(action));
574*635a8641SAndroid Build Coastguard Worker   sigemptyset(&action.sa_mask);
575*635a8641SAndroid Build Coastguard Worker   action.sa_handler = &ShutdownPipeSignalHandler;
576*635a8641SAndroid Build Coastguard Worker 
577*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(0, sigaction(SIGINT, &action, nullptr));
578*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(0, sigaction(SIGQUIT, &action, nullptr));
579*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(0, sigaction(SIGTERM, &action, nullptr));
580*635a8641SAndroid Build Coastguard Worker 
581*635a8641SAndroid Build Coastguard Worker   auto controller = base::FileDescriptorWatcher::WatchReadable(
582*635a8641SAndroid Build Coastguard Worker       g_shutdown_pipe[0],
583*635a8641SAndroid Build Coastguard Worker       base::Bind(&TestLauncher::OnShutdownPipeReadable, Unretained(this)));
584*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX)
585*635a8641SAndroid Build Coastguard Worker 
586*635a8641SAndroid Build Coastguard Worker   // Start the watchdog timer.
587*635a8641SAndroid Build Coastguard Worker   watchdog_timer_.Reset();
588*635a8641SAndroid Build Coastguard Worker 
589*635a8641SAndroid Build Coastguard Worker   ThreadTaskRunnerHandle::Get()->PostTask(
590*635a8641SAndroid Build Coastguard Worker       FROM_HERE, BindOnce(&TestLauncher::RunTestIteration, Unretained(this)));
591*635a8641SAndroid Build Coastguard Worker 
592*635a8641SAndroid Build Coastguard Worker   RunLoop().Run();
593*635a8641SAndroid Build Coastguard Worker 
594*635a8641SAndroid Build Coastguard Worker   if (requested_cycles != 1)
595*635a8641SAndroid Build Coastguard Worker     results_tracker_.PrintSummaryOfAllIterations();
596*635a8641SAndroid Build Coastguard Worker 
597*635a8641SAndroid Build Coastguard Worker   MaybeSaveSummaryAsJSON(std::vector<std::string>());
598*635a8641SAndroid Build Coastguard Worker 
599*635a8641SAndroid Build Coastguard Worker   return run_result_;
600*635a8641SAndroid Build Coastguard Worker }
601*635a8641SAndroid Build Coastguard Worker 
LaunchChildGTestProcess(const CommandLine & command_line,const std::string & wrapper,TimeDelta timeout,const LaunchOptions & options,std::unique_ptr<ProcessLifetimeObserver> observer)602*635a8641SAndroid Build Coastguard Worker void TestLauncher::LaunchChildGTestProcess(
603*635a8641SAndroid Build Coastguard Worker     const CommandLine& command_line,
604*635a8641SAndroid Build Coastguard Worker     const std::string& wrapper,
605*635a8641SAndroid Build Coastguard Worker     TimeDelta timeout,
606*635a8641SAndroid Build Coastguard Worker     const LaunchOptions& options,
607*635a8641SAndroid Build Coastguard Worker     std::unique_ptr<ProcessLifetimeObserver> observer) {
608*635a8641SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
609*635a8641SAndroid Build Coastguard Worker 
610*635a8641SAndroid Build Coastguard Worker   // Record the exact command line used to launch the child.
611*635a8641SAndroid Build Coastguard Worker   CommandLine new_command_line(
612*635a8641SAndroid Build Coastguard Worker       PrepareCommandLineForGTest(command_line, wrapper));
613*635a8641SAndroid Build Coastguard Worker 
614*635a8641SAndroid Build Coastguard Worker   // When running in parallel mode we need to redirect stdio to avoid mixed-up
615*635a8641SAndroid Build Coastguard Worker   // output. We also always redirect on the bots to get the test output into
616*635a8641SAndroid Build Coastguard Worker   // JSON summary.
617*635a8641SAndroid Build Coastguard Worker   bool redirect_stdio = (parallel_jobs_ > 1) || BotModeEnabled();
618*635a8641SAndroid Build Coastguard Worker 
619*635a8641SAndroid Build Coastguard Worker   PostTaskWithTraits(
620*635a8641SAndroid Build Coastguard Worker       FROM_HERE, {MayBlock(), TaskShutdownBehavior::BLOCK_SHUTDOWN},
621*635a8641SAndroid Build Coastguard Worker       BindOnce(&DoLaunchChildTestProcess, new_command_line, timeout, options,
622*635a8641SAndroid Build Coastguard Worker                redirect_stdio, RetainedRef(ThreadTaskRunnerHandle::Get()),
623*635a8641SAndroid Build Coastguard Worker                std::move(observer)));
624*635a8641SAndroid Build Coastguard Worker }
625*635a8641SAndroid Build Coastguard Worker 
OnTestFinished(const TestResult & original_result)626*635a8641SAndroid Build Coastguard Worker void TestLauncher::OnTestFinished(const TestResult& original_result) {
627*635a8641SAndroid Build Coastguard Worker   ++test_finished_count_;
628*635a8641SAndroid Build Coastguard Worker 
629*635a8641SAndroid Build Coastguard Worker   TestResult result(original_result);
630*635a8641SAndroid Build Coastguard Worker 
631*635a8641SAndroid Build Coastguard Worker   if (result.output_snippet.length() > kOutputSnippetBytesLimit) {
632*635a8641SAndroid Build Coastguard Worker     if (result.status == TestResult::TEST_SUCCESS)
633*635a8641SAndroid Build Coastguard Worker       result.status = TestResult::TEST_EXCESSIVE_OUTPUT;
634*635a8641SAndroid Build Coastguard Worker 
635*635a8641SAndroid Build Coastguard Worker     // Keep the top and bottom of the log and truncate the middle part.
636*635a8641SAndroid Build Coastguard Worker     result.output_snippet =
637*635a8641SAndroid Build Coastguard Worker         result.output_snippet.substr(0, kOutputSnippetBytesLimit / 2) + "\n" +
638*635a8641SAndroid Build Coastguard Worker         StringPrintf("<truncated (%" PRIuS " bytes)>\n",
639*635a8641SAndroid Build Coastguard Worker                      result.output_snippet.length()) +
640*635a8641SAndroid Build Coastguard Worker         result.output_snippet.substr(result.output_snippet.length() -
641*635a8641SAndroid Build Coastguard Worker                                      kOutputSnippetBytesLimit / 2) +
642*635a8641SAndroid Build Coastguard Worker         "\n";
643*635a8641SAndroid Build Coastguard Worker   }
644*635a8641SAndroid Build Coastguard Worker 
645*635a8641SAndroid Build Coastguard Worker   bool print_snippet = false;
646*635a8641SAndroid Build Coastguard Worker   std::string print_test_stdio("auto");
647*635a8641SAndroid Build Coastguard Worker   if (CommandLine::ForCurrentProcess()->HasSwitch(
648*635a8641SAndroid Build Coastguard Worker           switches::kTestLauncherPrintTestStdio)) {
649*635a8641SAndroid Build Coastguard Worker     print_test_stdio = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
650*635a8641SAndroid Build Coastguard Worker         switches::kTestLauncherPrintTestStdio);
651*635a8641SAndroid Build Coastguard Worker   }
652*635a8641SAndroid Build Coastguard Worker   if (print_test_stdio == "auto") {
653*635a8641SAndroid Build Coastguard Worker     print_snippet = (result.status != TestResult::TEST_SUCCESS);
654*635a8641SAndroid Build Coastguard Worker   } else if (print_test_stdio == "always") {
655*635a8641SAndroid Build Coastguard Worker     print_snippet = true;
656*635a8641SAndroid Build Coastguard Worker   } else if (print_test_stdio == "never") {
657*635a8641SAndroid Build Coastguard Worker     print_snippet = false;
658*635a8641SAndroid Build Coastguard Worker   } else {
659*635a8641SAndroid Build Coastguard Worker     LOG(WARNING) << "Invalid value of " << switches::kTestLauncherPrintTestStdio
660*635a8641SAndroid Build Coastguard Worker                  << ": " << print_test_stdio;
661*635a8641SAndroid Build Coastguard Worker   }
662*635a8641SAndroid Build Coastguard Worker   if (print_snippet) {
663*635a8641SAndroid Build Coastguard Worker     std::vector<base::StringPiece> snippet_lines =
664*635a8641SAndroid Build Coastguard Worker         SplitStringPiece(result.output_snippet, "\n", base::KEEP_WHITESPACE,
665*635a8641SAndroid Build Coastguard Worker                          base::SPLIT_WANT_ALL);
666*635a8641SAndroid Build Coastguard Worker     if (snippet_lines.size() > kOutputSnippetLinesLimit) {
667*635a8641SAndroid Build Coastguard Worker       size_t truncated_size = snippet_lines.size() - kOutputSnippetLinesLimit;
668*635a8641SAndroid Build Coastguard Worker       snippet_lines.erase(
669*635a8641SAndroid Build Coastguard Worker           snippet_lines.begin(),
670*635a8641SAndroid Build Coastguard Worker           snippet_lines.begin() + truncated_size);
671*635a8641SAndroid Build Coastguard Worker       snippet_lines.insert(snippet_lines.begin(), "<truncated>");
672*635a8641SAndroid Build Coastguard Worker     }
673*635a8641SAndroid Build Coastguard Worker     fprintf(stdout, "%s", base::JoinString(snippet_lines, "\n").c_str());
674*635a8641SAndroid Build Coastguard Worker     fflush(stdout);
675*635a8641SAndroid Build Coastguard Worker   }
676*635a8641SAndroid Build Coastguard Worker 
677*635a8641SAndroid Build Coastguard Worker   if (result.status == TestResult::TEST_SUCCESS) {
678*635a8641SAndroid Build Coastguard Worker     ++test_success_count_;
679*635a8641SAndroid Build Coastguard Worker   } else {
680*635a8641SAndroid Build Coastguard Worker     tests_to_retry_.insert(result.full_name);
681*635a8641SAndroid Build Coastguard Worker   }
682*635a8641SAndroid Build Coastguard Worker 
683*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddTestResult(result);
684*635a8641SAndroid Build Coastguard Worker 
685*635a8641SAndroid Build Coastguard Worker   // TODO(phajdan.jr): Align counter (padding).
686*635a8641SAndroid Build Coastguard Worker   std::string status_line(
687*635a8641SAndroid Build Coastguard Worker       StringPrintf("[%" PRIuS "/%" PRIuS "] %s ",
688*635a8641SAndroid Build Coastguard Worker                    test_finished_count_,
689*635a8641SAndroid Build Coastguard Worker                    test_started_count_,
690*635a8641SAndroid Build Coastguard Worker                    result.full_name.c_str()));
691*635a8641SAndroid Build Coastguard Worker   if (result.completed()) {
692*635a8641SAndroid Build Coastguard Worker     status_line.append(StringPrintf("(%" PRId64 " ms)",
693*635a8641SAndroid Build Coastguard Worker                                     result.elapsed_time.InMilliseconds()));
694*635a8641SAndroid Build Coastguard Worker   } else if (result.status == TestResult::TEST_TIMEOUT) {
695*635a8641SAndroid Build Coastguard Worker     status_line.append("(TIMED OUT)");
696*635a8641SAndroid Build Coastguard Worker   } else if (result.status == TestResult::TEST_CRASH) {
697*635a8641SAndroid Build Coastguard Worker     status_line.append("(CRASHED)");
698*635a8641SAndroid Build Coastguard Worker   } else if (result.status == TestResult::TEST_SKIPPED) {
699*635a8641SAndroid Build Coastguard Worker     status_line.append("(SKIPPED)");
700*635a8641SAndroid Build Coastguard Worker   } else if (result.status == TestResult::TEST_UNKNOWN) {
701*635a8641SAndroid Build Coastguard Worker     status_line.append("(UNKNOWN)");
702*635a8641SAndroid Build Coastguard Worker   } else {
703*635a8641SAndroid Build Coastguard Worker     // Fail very loudly so it's not ignored.
704*635a8641SAndroid Build Coastguard Worker     CHECK(false) << "Unhandled test result status: " << result.status;
705*635a8641SAndroid Build Coastguard Worker   }
706*635a8641SAndroid Build Coastguard Worker   fprintf(stdout, "%s\n", status_line.c_str());
707*635a8641SAndroid Build Coastguard Worker   fflush(stdout);
708*635a8641SAndroid Build Coastguard Worker 
709*635a8641SAndroid Build Coastguard Worker   // We just printed a status line, reset the watchdog timer.
710*635a8641SAndroid Build Coastguard Worker   watchdog_timer_.Reset();
711*635a8641SAndroid Build Coastguard Worker 
712*635a8641SAndroid Build Coastguard Worker   // Do not waste time on timeouts. We include tests with unknown results here
713*635a8641SAndroid Build Coastguard Worker   // because sometimes (e.g. hang in between unit tests) that's how a timeout
714*635a8641SAndroid Build Coastguard Worker   // gets reported.
715*635a8641SAndroid Build Coastguard Worker   if (result.status == TestResult::TEST_TIMEOUT ||
716*635a8641SAndroid Build Coastguard Worker       result.status == TestResult::TEST_UNKNOWN) {
717*635a8641SAndroid Build Coastguard Worker     test_broken_count_++;
718*635a8641SAndroid Build Coastguard Worker   }
719*635a8641SAndroid Build Coastguard Worker   size_t broken_threshold =
720*635a8641SAndroid Build Coastguard Worker       std::max(static_cast<size_t>(20), test_found_count_ / 10);
721*635a8641SAndroid Build Coastguard Worker   if (!force_run_broken_tests_ && test_broken_count_ >= broken_threshold) {
722*635a8641SAndroid Build Coastguard Worker     fprintf(stdout, "Too many badly broken tests (%" PRIuS "), exiting now.\n",
723*635a8641SAndroid Build Coastguard Worker             test_broken_count_);
724*635a8641SAndroid Build Coastguard Worker     fflush(stdout);
725*635a8641SAndroid Build Coastguard Worker 
726*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
727*635a8641SAndroid Build Coastguard Worker     KillSpawnedTestProcesses();
728*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX)
729*635a8641SAndroid Build Coastguard Worker 
730*635a8641SAndroid Build Coastguard Worker     MaybeSaveSummaryAsJSON({"BROKEN_TEST_EARLY_EXIT", kUnreliableResultsTag});
731*635a8641SAndroid Build Coastguard Worker 
732*635a8641SAndroid Build Coastguard Worker     exit(1);
733*635a8641SAndroid Build Coastguard Worker   }
734*635a8641SAndroid Build Coastguard Worker 
735*635a8641SAndroid Build Coastguard Worker   if (test_finished_count_ != test_started_count_)
736*635a8641SAndroid Build Coastguard Worker     return;
737*635a8641SAndroid Build Coastguard Worker 
738*635a8641SAndroid Build Coastguard Worker   if (tests_to_retry_.empty() || retry_count_ >= retry_limit_) {
739*635a8641SAndroid Build Coastguard Worker     OnTestIterationFinished();
740*635a8641SAndroid Build Coastguard Worker     return;
741*635a8641SAndroid Build Coastguard Worker   }
742*635a8641SAndroid Build Coastguard Worker 
743*635a8641SAndroid Build Coastguard Worker   if (!force_run_broken_tests_ && tests_to_retry_.size() >= broken_threshold) {
744*635a8641SAndroid Build Coastguard Worker     fprintf(stdout,
745*635a8641SAndroid Build Coastguard Worker             "Too many failing tests (%" PRIuS "), skipping retries.\n",
746*635a8641SAndroid Build Coastguard Worker             tests_to_retry_.size());
747*635a8641SAndroid Build Coastguard Worker     fflush(stdout);
748*635a8641SAndroid Build Coastguard Worker 
749*635a8641SAndroid Build Coastguard Worker     results_tracker_.AddGlobalTag("BROKEN_TEST_SKIPPED_RETRIES");
750*635a8641SAndroid Build Coastguard Worker     results_tracker_.AddGlobalTag(kUnreliableResultsTag);
751*635a8641SAndroid Build Coastguard Worker 
752*635a8641SAndroid Build Coastguard Worker     OnTestIterationFinished();
753*635a8641SAndroid Build Coastguard Worker     return;
754*635a8641SAndroid Build Coastguard Worker   }
755*635a8641SAndroid Build Coastguard Worker 
756*635a8641SAndroid Build Coastguard Worker   retry_count_++;
757*635a8641SAndroid Build Coastguard Worker 
758*635a8641SAndroid Build Coastguard Worker   std::vector<std::string> test_names(tests_to_retry_.begin(),
759*635a8641SAndroid Build Coastguard Worker                                       tests_to_retry_.end());
760*635a8641SAndroid Build Coastguard Worker 
761*635a8641SAndroid Build Coastguard Worker   tests_to_retry_.clear();
762*635a8641SAndroid Build Coastguard Worker 
763*635a8641SAndroid Build Coastguard Worker   size_t retry_started_count = launcher_delegate_->RetryTests(this, test_names);
764*635a8641SAndroid Build Coastguard Worker   if (retry_started_count == 0) {
765*635a8641SAndroid Build Coastguard Worker     // Signal failure, but continue to run all requested test iterations.
766*635a8641SAndroid Build Coastguard Worker     // With the summary of all iterations at the end this is a good default.
767*635a8641SAndroid Build Coastguard Worker     run_result_ = false;
768*635a8641SAndroid Build Coastguard Worker 
769*635a8641SAndroid Build Coastguard Worker     OnTestIterationFinished();
770*635a8641SAndroid Build Coastguard Worker     return;
771*635a8641SAndroid Build Coastguard Worker   }
772*635a8641SAndroid Build Coastguard Worker 
773*635a8641SAndroid Build Coastguard Worker   fprintf(stdout, "Retrying %" PRIuS " test%s (retry #%" PRIuS ")\n",
774*635a8641SAndroid Build Coastguard Worker           retry_started_count,
775*635a8641SAndroid Build Coastguard Worker           retry_started_count > 1 ? "s" : "",
776*635a8641SAndroid Build Coastguard Worker           retry_count_);
777*635a8641SAndroid Build Coastguard Worker   fflush(stdout);
778*635a8641SAndroid Build Coastguard Worker 
779*635a8641SAndroid Build Coastguard Worker   test_started_count_ += retry_started_count;
780*635a8641SAndroid Build Coastguard Worker }
781*635a8641SAndroid Build Coastguard Worker 
782*635a8641SAndroid Build Coastguard Worker // Helper used to parse test filter files. Syntax is documented in
783*635a8641SAndroid Build Coastguard Worker // //testing/buildbot/filters/README.md .
LoadFilterFile(const FilePath & file_path,std::vector<std::string> * positive_filter,std::vector<std::string> * negative_filter)784*635a8641SAndroid Build Coastguard Worker bool LoadFilterFile(const FilePath& file_path,
785*635a8641SAndroid Build Coastguard Worker                     std::vector<std::string>* positive_filter,
786*635a8641SAndroid Build Coastguard Worker                     std::vector<std::string>* negative_filter) {
787*635a8641SAndroid Build Coastguard Worker   std::string file_content;
788*635a8641SAndroid Build Coastguard Worker   if (!ReadFileToString(file_path, &file_content)) {
789*635a8641SAndroid Build Coastguard Worker     LOG(ERROR) << "Failed to read the filter file.";
790*635a8641SAndroid Build Coastguard Worker     return false;
791*635a8641SAndroid Build Coastguard Worker   }
792*635a8641SAndroid Build Coastguard Worker 
793*635a8641SAndroid Build Coastguard Worker   std::vector<std::string> filter_lines = SplitString(
794*635a8641SAndroid Build Coastguard Worker       file_content, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
795*635a8641SAndroid Build Coastguard Worker   int line_num = 0;
796*635a8641SAndroid Build Coastguard Worker   for (const std::string& filter_line : filter_lines) {
797*635a8641SAndroid Build Coastguard Worker     line_num++;
798*635a8641SAndroid Build Coastguard Worker 
799*635a8641SAndroid Build Coastguard Worker     size_t hash_pos = filter_line.find('#');
800*635a8641SAndroid Build Coastguard Worker 
801*635a8641SAndroid Build Coastguard Worker     // In case when # symbol is not in the beginning of the line and is not
802*635a8641SAndroid Build Coastguard Worker     // proceeded with a space then it's likely that the comment was
803*635a8641SAndroid Build Coastguard Worker     // unintentional.
804*635a8641SAndroid Build Coastguard Worker     if (hash_pos != std::string::npos && hash_pos > 0 &&
805*635a8641SAndroid Build Coastguard Worker         filter_line[hash_pos - 1] != ' ') {
806*635a8641SAndroid Build Coastguard Worker       LOG(WARNING) << "Content of line " << line_num << " in " << file_path
807*635a8641SAndroid Build Coastguard Worker                    << " after # is treated as a comment, " << filter_line;
808*635a8641SAndroid Build Coastguard Worker     }
809*635a8641SAndroid Build Coastguard Worker 
810*635a8641SAndroid Build Coastguard Worker     // Strip comments and whitespace from each line.
811*635a8641SAndroid Build Coastguard Worker     std::string trimmed_line =
812*635a8641SAndroid Build Coastguard Worker         TrimWhitespaceASCII(filter_line.substr(0, hash_pos), TRIM_ALL)
813*635a8641SAndroid Build Coastguard Worker             .as_string();
814*635a8641SAndroid Build Coastguard Worker 
815*635a8641SAndroid Build Coastguard Worker     if (trimmed_line.substr(0, 2) == "//") {
816*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Line " << line_num << " in " << file_path
817*635a8641SAndroid Build Coastguard Worker                  << " starts with //, use # for comments.";
818*635a8641SAndroid Build Coastguard Worker       return false;
819*635a8641SAndroid Build Coastguard Worker     }
820*635a8641SAndroid Build Coastguard Worker 
821*635a8641SAndroid Build Coastguard Worker     // Treat a line starting with '//' as a comment.
822*635a8641SAndroid Build Coastguard Worker     if (trimmed_line.empty())
823*635a8641SAndroid Build Coastguard Worker       continue;
824*635a8641SAndroid Build Coastguard Worker 
825*635a8641SAndroid Build Coastguard Worker     if (trimmed_line[0] == '-')
826*635a8641SAndroid Build Coastguard Worker       negative_filter->push_back(trimmed_line.substr(1));
827*635a8641SAndroid Build Coastguard Worker     else
828*635a8641SAndroid Build Coastguard Worker       positive_filter->push_back(trimmed_line);
829*635a8641SAndroid Build Coastguard Worker   }
830*635a8641SAndroid Build Coastguard Worker 
831*635a8641SAndroid Build Coastguard Worker   return true;
832*635a8641SAndroid Build Coastguard Worker }
833*635a8641SAndroid Build Coastguard Worker 
Init()834*635a8641SAndroid Build Coastguard Worker bool TestLauncher::Init() {
835*635a8641SAndroid Build Coastguard Worker   const CommandLine* command_line = CommandLine::ForCurrentProcess();
836*635a8641SAndroid Build Coastguard Worker 
837*635a8641SAndroid Build Coastguard Worker   // Initialize sharding. Command line takes precedence over legacy environment
838*635a8641SAndroid Build Coastguard Worker   // variables.
839*635a8641SAndroid Build Coastguard Worker   if (command_line->HasSwitch(switches::kTestLauncherTotalShards) &&
840*635a8641SAndroid Build Coastguard Worker       command_line->HasSwitch(switches::kTestLauncherShardIndex)) {
841*635a8641SAndroid Build Coastguard Worker     if (!StringToInt(
842*635a8641SAndroid Build Coastguard Worker             command_line->GetSwitchValueASCII(
843*635a8641SAndroid Build Coastguard Worker                 switches::kTestLauncherTotalShards),
844*635a8641SAndroid Build Coastguard Worker             &total_shards_)) {
845*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Invalid value for " << switches::kTestLauncherTotalShards;
846*635a8641SAndroid Build Coastguard Worker       return false;
847*635a8641SAndroid Build Coastguard Worker     }
848*635a8641SAndroid Build Coastguard Worker     if (!StringToInt(
849*635a8641SAndroid Build Coastguard Worker             command_line->GetSwitchValueASCII(
850*635a8641SAndroid Build Coastguard Worker                 switches::kTestLauncherShardIndex),
851*635a8641SAndroid Build Coastguard Worker             &shard_index_)) {
852*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Invalid value for " << switches::kTestLauncherShardIndex;
853*635a8641SAndroid Build Coastguard Worker       return false;
854*635a8641SAndroid Build Coastguard Worker     }
855*635a8641SAndroid Build Coastguard Worker     fprintf(stdout,
856*635a8641SAndroid Build Coastguard Worker             "Using sharding settings from command line. This is shard %d/%d\n",
857*635a8641SAndroid Build Coastguard Worker             shard_index_, total_shards_);
858*635a8641SAndroid Build Coastguard Worker     fflush(stdout);
859*635a8641SAndroid Build Coastguard Worker   } else {
860*635a8641SAndroid Build Coastguard Worker     if (!TakeInt32FromEnvironment(kTestTotalShards, &total_shards_))
861*635a8641SAndroid Build Coastguard Worker       return false;
862*635a8641SAndroid Build Coastguard Worker     if (!TakeInt32FromEnvironment(kTestShardIndex, &shard_index_))
863*635a8641SAndroid Build Coastguard Worker       return false;
864*635a8641SAndroid Build Coastguard Worker     fprintf(stdout,
865*635a8641SAndroid Build Coastguard Worker             "Using sharding settings from environment. This is shard %d/%d\n",
866*635a8641SAndroid Build Coastguard Worker             shard_index_, total_shards_);
867*635a8641SAndroid Build Coastguard Worker     fflush(stdout);
868*635a8641SAndroid Build Coastguard Worker   }
869*635a8641SAndroid Build Coastguard Worker   if (shard_index_ < 0 ||
870*635a8641SAndroid Build Coastguard Worker       total_shards_ < 0 ||
871*635a8641SAndroid Build Coastguard Worker       shard_index_ >= total_shards_) {
872*635a8641SAndroid Build Coastguard Worker     LOG(ERROR) << "Invalid sharding settings: we require 0 <= "
873*635a8641SAndroid Build Coastguard Worker                << kTestShardIndex << " < " << kTestTotalShards
874*635a8641SAndroid Build Coastguard Worker                << ", but you have " << kTestShardIndex << "=" << shard_index_
875*635a8641SAndroid Build Coastguard Worker                << ", " << kTestTotalShards << "=" << total_shards_ << ".\n";
876*635a8641SAndroid Build Coastguard Worker     return false;
877*635a8641SAndroid Build Coastguard Worker   }
878*635a8641SAndroid Build Coastguard Worker 
879*635a8641SAndroid Build Coastguard Worker   // Make sure we don't pass any sharding-related environment to the child
880*635a8641SAndroid Build Coastguard Worker   // processes. This test launcher implements the sharding completely.
881*635a8641SAndroid Build Coastguard Worker   CHECK(UnsetEnvironmentVariableIfExists("GTEST_TOTAL_SHARDS"));
882*635a8641SAndroid Build Coastguard Worker   CHECK(UnsetEnvironmentVariableIfExists("GTEST_SHARD_INDEX"));
883*635a8641SAndroid Build Coastguard Worker 
884*635a8641SAndroid Build Coastguard Worker   if (command_line->HasSwitch(kGTestRepeatFlag) &&
885*635a8641SAndroid Build Coastguard Worker       !StringToInt(command_line->GetSwitchValueASCII(kGTestRepeatFlag),
886*635a8641SAndroid Build Coastguard Worker                    &cycles_)) {
887*635a8641SAndroid Build Coastguard Worker     LOG(ERROR) << "Invalid value for " << kGTestRepeatFlag;
888*635a8641SAndroid Build Coastguard Worker     return false;
889*635a8641SAndroid Build Coastguard Worker   }
890*635a8641SAndroid Build Coastguard Worker 
891*635a8641SAndroid Build Coastguard Worker   if (command_line->HasSwitch(switches::kTestLauncherRetryLimit)) {
892*635a8641SAndroid Build Coastguard Worker     int retry_limit = -1;
893*635a8641SAndroid Build Coastguard Worker     if (!StringToInt(command_line->GetSwitchValueASCII(
894*635a8641SAndroid Build Coastguard Worker                          switches::kTestLauncherRetryLimit), &retry_limit) ||
895*635a8641SAndroid Build Coastguard Worker         retry_limit < 0) {
896*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Invalid value for " << switches::kTestLauncherRetryLimit;
897*635a8641SAndroid Build Coastguard Worker       return false;
898*635a8641SAndroid Build Coastguard Worker     }
899*635a8641SAndroid Build Coastguard Worker 
900*635a8641SAndroid Build Coastguard Worker     retry_limit_ = retry_limit;
901*635a8641SAndroid Build Coastguard Worker   } else if (!command_line->HasSwitch(kGTestFilterFlag) || BotModeEnabled()) {
902*635a8641SAndroid Build Coastguard Worker     // Retry failures 3 times by default if we are running all of the tests or
903*635a8641SAndroid Build Coastguard Worker     // in bot mode.
904*635a8641SAndroid Build Coastguard Worker     retry_limit_ = 3;
905*635a8641SAndroid Build Coastguard Worker   }
906*635a8641SAndroid Build Coastguard Worker 
907*635a8641SAndroid Build Coastguard Worker   if (command_line->HasSwitch(switches::kTestLauncherForceRunBrokenTests))
908*635a8641SAndroid Build Coastguard Worker     force_run_broken_tests_ = true;
909*635a8641SAndroid Build Coastguard Worker 
910*635a8641SAndroid Build Coastguard Worker   // Some of the TestLauncherDelegate implementations don't call into gtest
911*635a8641SAndroid Build Coastguard Worker   // until they've already split into test-specific processes. This results
912*635a8641SAndroid Build Coastguard Worker   // in gtest's native shuffle implementation attempting to shuffle one test.
913*635a8641SAndroid Build Coastguard Worker   // Shuffling the list of tests in the test launcher (before the delegate
914*635a8641SAndroid Build Coastguard Worker   // gets involved) ensures that the entire shard is shuffled.
915*635a8641SAndroid Build Coastguard Worker   if (command_line->HasSwitch(kGTestShuffleFlag)) {
916*635a8641SAndroid Build Coastguard Worker     shuffle_ = true;
917*635a8641SAndroid Build Coastguard Worker 
918*635a8641SAndroid Build Coastguard Worker     if (command_line->HasSwitch(kGTestRandomSeedFlag)) {
919*635a8641SAndroid Build Coastguard Worker       const std::string custom_seed_str =
920*635a8641SAndroid Build Coastguard Worker           command_line->GetSwitchValueASCII(kGTestRandomSeedFlag);
921*635a8641SAndroid Build Coastguard Worker       uint32_t custom_seed = 0;
922*635a8641SAndroid Build Coastguard Worker       if (!StringToUint(custom_seed_str, &custom_seed)) {
923*635a8641SAndroid Build Coastguard Worker         LOG(ERROR) << "Unable to parse seed \"" << custom_seed_str << "\".";
924*635a8641SAndroid Build Coastguard Worker         return false;
925*635a8641SAndroid Build Coastguard Worker       }
926*635a8641SAndroid Build Coastguard Worker       if (custom_seed >= kRandomSeedUpperBound) {
927*635a8641SAndroid Build Coastguard Worker         LOG(ERROR) << "Seed " << custom_seed << " outside of expected range "
928*635a8641SAndroid Build Coastguard Worker                    << "[0, " << kRandomSeedUpperBound << ")";
929*635a8641SAndroid Build Coastguard Worker         return false;
930*635a8641SAndroid Build Coastguard Worker       }
931*635a8641SAndroid Build Coastguard Worker       shuffle_seed_ = custom_seed;
932*635a8641SAndroid Build Coastguard Worker     } else {
933*635a8641SAndroid Build Coastguard Worker       std::uniform_int_distribution<uint32_t> dist(0, kRandomSeedUpperBound);
934*635a8641SAndroid Build Coastguard Worker       std::random_device random_dev;
935*635a8641SAndroid Build Coastguard Worker       shuffle_seed_ = dist(random_dev);
936*635a8641SAndroid Build Coastguard Worker     }
937*635a8641SAndroid Build Coastguard Worker   } else if (command_line->HasSwitch(kGTestRandomSeedFlag)) {
938*635a8641SAndroid Build Coastguard Worker     LOG(ERROR) << kGTestRandomSeedFlag << " requires " << kGTestShuffleFlag;
939*635a8641SAndroid Build Coastguard Worker     return false;
940*635a8641SAndroid Build Coastguard Worker   }
941*635a8641SAndroid Build Coastguard Worker 
942*635a8641SAndroid Build Coastguard Worker   fprintf(stdout, "Using %" PRIuS " parallel jobs.\n", parallel_jobs_);
943*635a8641SAndroid Build Coastguard Worker   fflush(stdout);
944*635a8641SAndroid Build Coastguard Worker 
945*635a8641SAndroid Build Coastguard Worker   CreateAndStartTaskScheduler(static_cast<int>(parallel_jobs_));
946*635a8641SAndroid Build Coastguard Worker 
947*635a8641SAndroid Build Coastguard Worker   std::vector<std::string> positive_file_filter;
948*635a8641SAndroid Build Coastguard Worker   std::vector<std::string> positive_gtest_filter;
949*635a8641SAndroid Build Coastguard Worker 
950*635a8641SAndroid Build Coastguard Worker   if (command_line->HasSwitch(switches::kTestLauncherFilterFile)) {
951*635a8641SAndroid Build Coastguard Worker     base::FilePath filter_file_path = base::MakeAbsoluteFilePath(
952*635a8641SAndroid Build Coastguard Worker         command_line->GetSwitchValuePath(switches::kTestLauncherFilterFile));
953*635a8641SAndroid Build Coastguard Worker     if (!LoadFilterFile(filter_file_path, &positive_file_filter,
954*635a8641SAndroid Build Coastguard Worker                         &negative_test_filter_))
955*635a8641SAndroid Build Coastguard Worker       return false;
956*635a8641SAndroid Build Coastguard Worker   }
957*635a8641SAndroid Build Coastguard Worker 
958*635a8641SAndroid Build Coastguard Worker   // Split --gtest_filter at '-', if there is one, to separate into
959*635a8641SAndroid Build Coastguard Worker   // positive filter and negative filter portions.
960*635a8641SAndroid Build Coastguard Worker   std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag);
961*635a8641SAndroid Build Coastguard Worker   size_t dash_pos = filter.find('-');
962*635a8641SAndroid Build Coastguard Worker   if (dash_pos == std::string::npos) {
963*635a8641SAndroid Build Coastguard Worker     positive_gtest_filter =
964*635a8641SAndroid Build Coastguard Worker         SplitString(filter, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
965*635a8641SAndroid Build Coastguard Worker   } else {
966*635a8641SAndroid Build Coastguard Worker     // Everything up to the dash.
967*635a8641SAndroid Build Coastguard Worker     positive_gtest_filter =
968*635a8641SAndroid Build Coastguard Worker         SplitString(filter.substr(0, dash_pos), ":", base::TRIM_WHITESPACE,
969*635a8641SAndroid Build Coastguard Worker                     base::SPLIT_WANT_ALL);
970*635a8641SAndroid Build Coastguard Worker 
971*635a8641SAndroid Build Coastguard Worker     // Everything after the dash.
972*635a8641SAndroid Build Coastguard Worker     for (std::string pattern :
973*635a8641SAndroid Build Coastguard Worker          SplitString(filter.substr(dash_pos + 1), ":", base::TRIM_WHITESPACE,
974*635a8641SAndroid Build Coastguard Worker                      base::SPLIT_WANT_ALL)) {
975*635a8641SAndroid Build Coastguard Worker       negative_test_filter_.push_back(pattern);
976*635a8641SAndroid Build Coastguard Worker     }
977*635a8641SAndroid Build Coastguard Worker   }
978*635a8641SAndroid Build Coastguard Worker 
979*635a8641SAndroid Build Coastguard Worker   if (!launcher_delegate_->GetTests(&tests_)) {
980*635a8641SAndroid Build Coastguard Worker     LOG(ERROR) << "Failed to get list of tests.";
981*635a8641SAndroid Build Coastguard Worker     return false;
982*635a8641SAndroid Build Coastguard Worker   }
983*635a8641SAndroid Build Coastguard Worker 
984*635a8641SAndroid Build Coastguard Worker   CombinePositiveTestFilters(std::move(positive_gtest_filter),
985*635a8641SAndroid Build Coastguard Worker                              std::move(positive_file_filter));
986*635a8641SAndroid Build Coastguard Worker 
987*635a8641SAndroid Build Coastguard Worker   if (!results_tracker_.Init(*command_line)) {
988*635a8641SAndroid Build Coastguard Worker     LOG(ERROR) << "Failed to initialize test results tracker.";
989*635a8641SAndroid Build Coastguard Worker     return 1;
990*635a8641SAndroid Build Coastguard Worker   }
991*635a8641SAndroid Build Coastguard Worker 
992*635a8641SAndroid Build Coastguard Worker #if defined(NDEBUG)
993*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("MODE_RELEASE");
994*635a8641SAndroid Build Coastguard Worker #else
995*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("MODE_DEBUG");
996*635a8641SAndroid Build Coastguard Worker #endif
997*635a8641SAndroid Build Coastguard Worker 
998*635a8641SAndroid Build Coastguard Worker   // Operating systems (sorted alphabetically).
999*635a8641SAndroid Build Coastguard Worker   // Note that they can deliberately overlap, e.g. OS_LINUX is a subset
1000*635a8641SAndroid Build Coastguard Worker   // of OS_POSIX.
1001*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
1002*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("OS_ANDROID");
1003*635a8641SAndroid Build Coastguard Worker #endif
1004*635a8641SAndroid Build Coastguard Worker 
1005*635a8641SAndroid Build Coastguard Worker #if defined(OS_BSD)
1006*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("OS_BSD");
1007*635a8641SAndroid Build Coastguard Worker #endif
1008*635a8641SAndroid Build Coastguard Worker 
1009*635a8641SAndroid Build Coastguard Worker #if defined(OS_FREEBSD)
1010*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("OS_FREEBSD");
1011*635a8641SAndroid Build Coastguard Worker #endif
1012*635a8641SAndroid Build Coastguard Worker 
1013*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
1014*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("OS_FUCHSIA");
1015*635a8641SAndroid Build Coastguard Worker #endif
1016*635a8641SAndroid Build Coastguard Worker 
1017*635a8641SAndroid Build Coastguard Worker #if defined(OS_IOS)
1018*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("OS_IOS");
1019*635a8641SAndroid Build Coastguard Worker #endif
1020*635a8641SAndroid Build Coastguard Worker 
1021*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX)
1022*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("OS_LINUX");
1023*635a8641SAndroid Build Coastguard Worker #endif
1024*635a8641SAndroid Build Coastguard Worker 
1025*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
1026*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("OS_MACOSX");
1027*635a8641SAndroid Build Coastguard Worker #endif
1028*635a8641SAndroid Build Coastguard Worker 
1029*635a8641SAndroid Build Coastguard Worker #if defined(OS_NACL)
1030*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("OS_NACL");
1031*635a8641SAndroid Build Coastguard Worker #endif
1032*635a8641SAndroid Build Coastguard Worker 
1033*635a8641SAndroid Build Coastguard Worker #if defined(OS_OPENBSD)
1034*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("OS_OPENBSD");
1035*635a8641SAndroid Build Coastguard Worker #endif
1036*635a8641SAndroid Build Coastguard Worker 
1037*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
1038*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("OS_POSIX");
1039*635a8641SAndroid Build Coastguard Worker #endif
1040*635a8641SAndroid Build Coastguard Worker 
1041*635a8641SAndroid Build Coastguard Worker #if defined(OS_SOLARIS)
1042*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("OS_SOLARIS");
1043*635a8641SAndroid Build Coastguard Worker #endif
1044*635a8641SAndroid Build Coastguard Worker 
1045*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
1046*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("OS_WIN");
1047*635a8641SAndroid Build Coastguard Worker #endif
1048*635a8641SAndroid Build Coastguard Worker 
1049*635a8641SAndroid Build Coastguard Worker   // CPU-related tags.
1050*635a8641SAndroid Build Coastguard Worker #if defined(ARCH_CPU_32_BITS)
1051*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("CPU_32_BITS");
1052*635a8641SAndroid Build Coastguard Worker #endif
1053*635a8641SAndroid Build Coastguard Worker 
1054*635a8641SAndroid Build Coastguard Worker #if defined(ARCH_CPU_64_BITS)
1055*635a8641SAndroid Build Coastguard Worker   results_tracker_.AddGlobalTag("CPU_64_BITS");
1056*635a8641SAndroid Build Coastguard Worker #endif
1057*635a8641SAndroid Build Coastguard Worker 
1058*635a8641SAndroid Build Coastguard Worker   return true;
1059*635a8641SAndroid Build Coastguard Worker }
1060*635a8641SAndroid Build Coastguard Worker 
CombinePositiveTestFilters(std::vector<std::string> filter_a,std::vector<std::string> filter_b)1061*635a8641SAndroid Build Coastguard Worker void TestLauncher::CombinePositiveTestFilters(
1062*635a8641SAndroid Build Coastguard Worker     std::vector<std::string> filter_a,
1063*635a8641SAndroid Build Coastguard Worker     std::vector<std::string> filter_b) {
1064*635a8641SAndroid Build Coastguard Worker   has_at_least_one_positive_filter_ = !filter_a.empty() || !filter_b.empty();
1065*635a8641SAndroid Build Coastguard Worker   if (!has_at_least_one_positive_filter_) {
1066*635a8641SAndroid Build Coastguard Worker     return;
1067*635a8641SAndroid Build Coastguard Worker   }
1068*635a8641SAndroid Build Coastguard Worker   // If two positive filters are present, only run tests that match a pattern
1069*635a8641SAndroid Build Coastguard Worker   // in both filters.
1070*635a8641SAndroid Build Coastguard Worker   if (!filter_a.empty() && !filter_b.empty()) {
1071*635a8641SAndroid Build Coastguard Worker     for (size_t i = 0; i < tests_.size(); i++) {
1072*635a8641SAndroid Build Coastguard Worker       std::string test_name =
1073*635a8641SAndroid Build Coastguard Worker           FormatFullTestName(tests_[i].test_case_name, tests_[i].test_name);
1074*635a8641SAndroid Build Coastguard Worker       bool found_a = false;
1075*635a8641SAndroid Build Coastguard Worker       bool found_b = false;
1076*635a8641SAndroid Build Coastguard Worker       for (size_t k = 0; k < filter_a.size(); ++k) {
1077*635a8641SAndroid Build Coastguard Worker         found_a = found_a || MatchPattern(test_name, filter_a[k]);
1078*635a8641SAndroid Build Coastguard Worker       }
1079*635a8641SAndroid Build Coastguard Worker       for (size_t k = 0; k < filter_b.size(); ++k) {
1080*635a8641SAndroid Build Coastguard Worker         found_b = found_b || MatchPattern(test_name, filter_b[k]);
1081*635a8641SAndroid Build Coastguard Worker       }
1082*635a8641SAndroid Build Coastguard Worker       if (found_a && found_b) {
1083*635a8641SAndroid Build Coastguard Worker         positive_test_filter_.push_back(test_name);
1084*635a8641SAndroid Build Coastguard Worker       }
1085*635a8641SAndroid Build Coastguard Worker     }
1086*635a8641SAndroid Build Coastguard Worker   } else if (!filter_a.empty()) {
1087*635a8641SAndroid Build Coastguard Worker     positive_test_filter_ = std::move(filter_a);
1088*635a8641SAndroid Build Coastguard Worker   } else {
1089*635a8641SAndroid Build Coastguard Worker     positive_test_filter_ = std::move(filter_b);
1090*635a8641SAndroid Build Coastguard Worker   }
1091*635a8641SAndroid Build Coastguard Worker }
1092*635a8641SAndroid Build Coastguard Worker 
RunTests()1093*635a8641SAndroid Build Coastguard Worker void TestLauncher::RunTests() {
1094*635a8641SAndroid Build Coastguard Worker   std::vector<std::string> test_names;
1095*635a8641SAndroid Build Coastguard Worker   const CommandLine* command_line = CommandLine::ForCurrentProcess();
1096*635a8641SAndroid Build Coastguard Worker   for (const TestIdentifier& test_id : tests_) {
1097*635a8641SAndroid Build Coastguard Worker     std::string test_name =
1098*635a8641SAndroid Build Coastguard Worker         FormatFullTestName(test_id.test_case_name, test_id.test_name);
1099*635a8641SAndroid Build Coastguard Worker 
1100*635a8641SAndroid Build Coastguard Worker     results_tracker_.AddTest(test_name);
1101*635a8641SAndroid Build Coastguard Worker 
1102*635a8641SAndroid Build Coastguard Worker     if (test_name.find("DISABLED") != std::string::npos) {
1103*635a8641SAndroid Build Coastguard Worker       results_tracker_.AddDisabledTest(test_name);
1104*635a8641SAndroid Build Coastguard Worker 
1105*635a8641SAndroid Build Coastguard Worker       // Skip disabled tests unless explicitly requested.
1106*635a8641SAndroid Build Coastguard Worker       if (!command_line->HasSwitch(kGTestRunDisabledTestsFlag))
1107*635a8641SAndroid Build Coastguard Worker         continue;
1108*635a8641SAndroid Build Coastguard Worker     }
1109*635a8641SAndroid Build Coastguard Worker 
1110*635a8641SAndroid Build Coastguard Worker     if (!launcher_delegate_->ShouldRunTest(test_id.test_case_name,
1111*635a8641SAndroid Build Coastguard Worker                                            test_id.test_name)) {
1112*635a8641SAndroid Build Coastguard Worker       continue;
1113*635a8641SAndroid Build Coastguard Worker     }
1114*635a8641SAndroid Build Coastguard Worker 
1115*635a8641SAndroid Build Coastguard Worker     // Count tests in the binary, before we apply filter and sharding.
1116*635a8641SAndroid Build Coastguard Worker     test_found_count_++;
1117*635a8641SAndroid Build Coastguard Worker 
1118*635a8641SAndroid Build Coastguard Worker     std::string test_name_no_disabled =
1119*635a8641SAndroid Build Coastguard Worker         TestNameWithoutDisabledPrefix(test_name);
1120*635a8641SAndroid Build Coastguard Worker 
1121*635a8641SAndroid Build Coastguard Worker     // Skip the test that doesn't match the filter (if given).
1122*635a8641SAndroid Build Coastguard Worker     if (has_at_least_one_positive_filter_) {
1123*635a8641SAndroid Build Coastguard Worker       bool found = false;
1124*635a8641SAndroid Build Coastguard Worker       for (auto filter : positive_test_filter_) {
1125*635a8641SAndroid Build Coastguard Worker         if (MatchPattern(test_name, filter) ||
1126*635a8641SAndroid Build Coastguard Worker             MatchPattern(test_name_no_disabled, filter)) {
1127*635a8641SAndroid Build Coastguard Worker           found = true;
1128*635a8641SAndroid Build Coastguard Worker           break;
1129*635a8641SAndroid Build Coastguard Worker         }
1130*635a8641SAndroid Build Coastguard Worker       }
1131*635a8641SAndroid Build Coastguard Worker 
1132*635a8641SAndroid Build Coastguard Worker       if (!found)
1133*635a8641SAndroid Build Coastguard Worker         continue;
1134*635a8641SAndroid Build Coastguard Worker     }
1135*635a8641SAndroid Build Coastguard Worker     if (!negative_test_filter_.empty()) {
1136*635a8641SAndroid Build Coastguard Worker       bool excluded = false;
1137*635a8641SAndroid Build Coastguard Worker       for (auto filter : negative_test_filter_) {
1138*635a8641SAndroid Build Coastguard Worker         if (MatchPattern(test_name, filter) ||
1139*635a8641SAndroid Build Coastguard Worker             MatchPattern(test_name_no_disabled, filter)) {
1140*635a8641SAndroid Build Coastguard Worker           excluded = true;
1141*635a8641SAndroid Build Coastguard Worker           break;
1142*635a8641SAndroid Build Coastguard Worker         }
1143*635a8641SAndroid Build Coastguard Worker       }
1144*635a8641SAndroid Build Coastguard Worker 
1145*635a8641SAndroid Build Coastguard Worker       if (excluded)
1146*635a8641SAndroid Build Coastguard Worker         continue;
1147*635a8641SAndroid Build Coastguard Worker     }
1148*635a8641SAndroid Build Coastguard Worker 
1149*635a8641SAndroid Build Coastguard Worker     if (Hash(test_name) % total_shards_ != static_cast<uint32_t>(shard_index_))
1150*635a8641SAndroid Build Coastguard Worker       continue;
1151*635a8641SAndroid Build Coastguard Worker 
1152*635a8641SAndroid Build Coastguard Worker     // Report test locations after applying all filters, so that we report test
1153*635a8641SAndroid Build Coastguard Worker     // locations only for those tests that were run as part of this shard.
1154*635a8641SAndroid Build Coastguard Worker     results_tracker_.AddTestLocation(test_name, test_id.file, test_id.line);
1155*635a8641SAndroid Build Coastguard Worker 
1156*635a8641SAndroid Build Coastguard Worker     test_names.push_back(test_name);
1157*635a8641SAndroid Build Coastguard Worker   }
1158*635a8641SAndroid Build Coastguard Worker 
1159*635a8641SAndroid Build Coastguard Worker   if (shuffle_) {
1160*635a8641SAndroid Build Coastguard Worker     std::mt19937 randomizer;
1161*635a8641SAndroid Build Coastguard Worker     randomizer.seed(shuffle_seed_);
1162*635a8641SAndroid Build Coastguard Worker     std::shuffle(test_names.begin(), test_names.end(), randomizer);
1163*635a8641SAndroid Build Coastguard Worker 
1164*635a8641SAndroid Build Coastguard Worker     fprintf(stdout, "Randomizing with seed %u\n", shuffle_seed_);
1165*635a8641SAndroid Build Coastguard Worker     fflush(stdout);
1166*635a8641SAndroid Build Coastguard Worker   }
1167*635a8641SAndroid Build Coastguard Worker 
1168*635a8641SAndroid Build Coastguard Worker   // Save an early test summary in case the launcher crashes or gets killed.
1169*635a8641SAndroid Build Coastguard Worker   MaybeSaveSummaryAsJSON({"EARLY_SUMMARY", kUnreliableResultsTag});
1170*635a8641SAndroid Build Coastguard Worker 
1171*635a8641SAndroid Build Coastguard Worker   test_started_count_ = launcher_delegate_->RunTests(this, test_names);
1172*635a8641SAndroid Build Coastguard Worker 
1173*635a8641SAndroid Build Coastguard Worker   if (test_started_count_ == 0) {
1174*635a8641SAndroid Build Coastguard Worker     fprintf(stdout, "0 tests run\n");
1175*635a8641SAndroid Build Coastguard Worker     fflush(stdout);
1176*635a8641SAndroid Build Coastguard Worker 
1177*635a8641SAndroid Build Coastguard Worker     // No tests have actually been started, so kick off the next iteration.
1178*635a8641SAndroid Build Coastguard Worker     ThreadTaskRunnerHandle::Get()->PostTask(
1179*635a8641SAndroid Build Coastguard Worker         FROM_HERE, BindOnce(&TestLauncher::RunTestIteration, Unretained(this)));
1180*635a8641SAndroid Build Coastguard Worker   }
1181*635a8641SAndroid Build Coastguard Worker }
1182*635a8641SAndroid Build Coastguard Worker 
RunTestIteration()1183*635a8641SAndroid Build Coastguard Worker void TestLauncher::RunTestIteration() {
1184*635a8641SAndroid Build Coastguard Worker   const bool stop_on_failure =
1185*635a8641SAndroid Build Coastguard Worker       CommandLine::ForCurrentProcess()->HasSwitch(kGTestBreakOnFailure);
1186*635a8641SAndroid Build Coastguard Worker   if (cycles_ == 0 ||
1187*635a8641SAndroid Build Coastguard Worker       (stop_on_failure && test_success_count_ != test_finished_count_)) {
1188*635a8641SAndroid Build Coastguard Worker     RunLoop::QuitCurrentWhenIdleDeprecated();
1189*635a8641SAndroid Build Coastguard Worker     return;
1190*635a8641SAndroid Build Coastguard Worker   }
1191*635a8641SAndroid Build Coastguard Worker 
1192*635a8641SAndroid Build Coastguard Worker   // Special value "-1" means "repeat indefinitely".
1193*635a8641SAndroid Build Coastguard Worker   cycles_ = (cycles_ == -1) ? cycles_ : cycles_ - 1;
1194*635a8641SAndroid Build Coastguard Worker 
1195*635a8641SAndroid Build Coastguard Worker   test_found_count_ = 0;
1196*635a8641SAndroid Build Coastguard Worker   test_started_count_ = 0;
1197*635a8641SAndroid Build Coastguard Worker   test_finished_count_ = 0;
1198*635a8641SAndroid Build Coastguard Worker   test_success_count_ = 0;
1199*635a8641SAndroid Build Coastguard Worker   test_broken_count_ = 0;
1200*635a8641SAndroid Build Coastguard Worker   retry_count_ = 0;
1201*635a8641SAndroid Build Coastguard Worker   tests_to_retry_.clear();
1202*635a8641SAndroid Build Coastguard Worker   results_tracker_.OnTestIterationStarting();
1203*635a8641SAndroid Build Coastguard Worker 
1204*635a8641SAndroid Build Coastguard Worker   ThreadTaskRunnerHandle::Get()->PostTask(
1205*635a8641SAndroid Build Coastguard Worker       FROM_HERE, BindOnce(&TestLauncher::RunTests, Unretained(this)));
1206*635a8641SAndroid Build Coastguard Worker }
1207*635a8641SAndroid Build Coastguard Worker 
1208*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
1209*635a8641SAndroid Build Coastguard Worker // I/O watcher for the reading end of the self-pipe above.
1210*635a8641SAndroid Build Coastguard Worker // Terminates any launched child processes and exits the process.
OnShutdownPipeReadable()1211*635a8641SAndroid Build Coastguard Worker void TestLauncher::OnShutdownPipeReadable() {
1212*635a8641SAndroid Build Coastguard Worker   fprintf(stdout, "\nCaught signal. Killing spawned test processes...\n");
1213*635a8641SAndroid Build Coastguard Worker   fflush(stdout);
1214*635a8641SAndroid Build Coastguard Worker 
1215*635a8641SAndroid Build Coastguard Worker   KillSpawnedTestProcesses();
1216*635a8641SAndroid Build Coastguard Worker 
1217*635a8641SAndroid Build Coastguard Worker   MaybeSaveSummaryAsJSON({"CAUGHT_TERMINATION_SIGNAL", kUnreliableResultsTag});
1218*635a8641SAndroid Build Coastguard Worker 
1219*635a8641SAndroid Build Coastguard Worker   // The signal would normally kill the process, so exit now.
1220*635a8641SAndroid Build Coastguard Worker   _exit(1);
1221*635a8641SAndroid Build Coastguard Worker }
1222*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX)
1223*635a8641SAndroid Build Coastguard Worker 
MaybeSaveSummaryAsJSON(const std::vector<std::string> & additional_tags)1224*635a8641SAndroid Build Coastguard Worker void TestLauncher::MaybeSaveSummaryAsJSON(
1225*635a8641SAndroid Build Coastguard Worker     const std::vector<std::string>& additional_tags) {
1226*635a8641SAndroid Build Coastguard Worker   const CommandLine* command_line = CommandLine::ForCurrentProcess();
1227*635a8641SAndroid Build Coastguard Worker   if (command_line->HasSwitch(switches::kTestLauncherSummaryOutput)) {
1228*635a8641SAndroid Build Coastguard Worker     FilePath summary_path(command_line->GetSwitchValuePath(
1229*635a8641SAndroid Build Coastguard Worker                               switches::kTestLauncherSummaryOutput));
1230*635a8641SAndroid Build Coastguard Worker     if (!results_tracker_.SaveSummaryAsJSON(summary_path, additional_tags)) {
1231*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Failed to save test launcher output summary.";
1232*635a8641SAndroid Build Coastguard Worker     }
1233*635a8641SAndroid Build Coastguard Worker   }
1234*635a8641SAndroid Build Coastguard Worker   if (command_line->HasSwitch(switches::kTestLauncherTrace)) {
1235*635a8641SAndroid Build Coastguard Worker     FilePath trace_path(
1236*635a8641SAndroid Build Coastguard Worker         command_line->GetSwitchValuePath(switches::kTestLauncherTrace));
1237*635a8641SAndroid Build Coastguard Worker     if (!GetTestLauncherTracer()->Dump(trace_path)) {
1238*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Failed to save test launcher trace.";
1239*635a8641SAndroid Build Coastguard Worker     }
1240*635a8641SAndroid Build Coastguard Worker   }
1241*635a8641SAndroid Build Coastguard Worker }
1242*635a8641SAndroid Build Coastguard Worker 
OnTestIterationFinished()1243*635a8641SAndroid Build Coastguard Worker void TestLauncher::OnTestIterationFinished() {
1244*635a8641SAndroid Build Coastguard Worker   TestResultsTracker::TestStatusMap tests_by_status(
1245*635a8641SAndroid Build Coastguard Worker       results_tracker_.GetTestStatusMapForCurrentIteration());
1246*635a8641SAndroid Build Coastguard Worker   if (!tests_by_status[TestResult::TEST_UNKNOWN].empty())
1247*635a8641SAndroid Build Coastguard Worker     results_tracker_.AddGlobalTag(kUnreliableResultsTag);
1248*635a8641SAndroid Build Coastguard Worker 
1249*635a8641SAndroid Build Coastguard Worker   // When we retry tests, success is determined by having nothing more
1250*635a8641SAndroid Build Coastguard Worker   // to retry (everything eventually passed), as opposed to having
1251*635a8641SAndroid Build Coastguard Worker   // no failures at all.
1252*635a8641SAndroid Build Coastguard Worker   if (tests_to_retry_.empty()) {
1253*635a8641SAndroid Build Coastguard Worker     fprintf(stdout, "SUCCESS: all tests passed.\n");
1254*635a8641SAndroid Build Coastguard Worker     fflush(stdout);
1255*635a8641SAndroid Build Coastguard Worker   } else {
1256*635a8641SAndroid Build Coastguard Worker     // Signal failure, but continue to run all requested test iterations.
1257*635a8641SAndroid Build Coastguard Worker     // With the summary of all iterations at the end this is a good default.
1258*635a8641SAndroid Build Coastguard Worker     run_result_ = false;
1259*635a8641SAndroid Build Coastguard Worker   }
1260*635a8641SAndroid Build Coastguard Worker 
1261*635a8641SAndroid Build Coastguard Worker   results_tracker_.PrintSummaryOfCurrentIteration();
1262*635a8641SAndroid Build Coastguard Worker 
1263*635a8641SAndroid Build Coastguard Worker   // Kick off the next iteration.
1264*635a8641SAndroid Build Coastguard Worker   ThreadTaskRunnerHandle::Get()->PostTask(
1265*635a8641SAndroid Build Coastguard Worker       FROM_HERE, BindOnce(&TestLauncher::RunTestIteration, Unretained(this)));
1266*635a8641SAndroid Build Coastguard Worker }
1267*635a8641SAndroid Build Coastguard Worker 
OnOutputTimeout()1268*635a8641SAndroid Build Coastguard Worker void TestLauncher::OnOutputTimeout() {
1269*635a8641SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
1270*635a8641SAndroid Build Coastguard Worker 
1271*635a8641SAndroid Build Coastguard Worker   AutoLock lock(*GetLiveProcessesLock());
1272*635a8641SAndroid Build Coastguard Worker 
1273*635a8641SAndroid Build Coastguard Worker   fprintf(stdout, "Still waiting for the following processes to finish:\n");
1274*635a8641SAndroid Build Coastguard Worker 
1275*635a8641SAndroid Build Coastguard Worker   for (const auto& pair : *GetLiveProcesses()) {
1276*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
1277*635a8641SAndroid Build Coastguard Worker     fwprintf(stdout, L"\t%s\n", pair.second.GetCommandLineString().c_str());
1278*635a8641SAndroid Build Coastguard Worker #else
1279*635a8641SAndroid Build Coastguard Worker     fprintf(stdout, "\t%s\n", pair.second.GetCommandLineString().c_str());
1280*635a8641SAndroid Build Coastguard Worker #endif
1281*635a8641SAndroid Build Coastguard Worker   }
1282*635a8641SAndroid Build Coastguard Worker 
1283*635a8641SAndroid Build Coastguard Worker   fflush(stdout);
1284*635a8641SAndroid Build Coastguard Worker 
1285*635a8641SAndroid Build Coastguard Worker   // Arm the timer again - otherwise it would fire only once.
1286*635a8641SAndroid Build Coastguard Worker   watchdog_timer_.Reset();
1287*635a8641SAndroid Build Coastguard Worker }
1288*635a8641SAndroid Build Coastguard Worker 
NumParallelJobs()1289*635a8641SAndroid Build Coastguard Worker size_t NumParallelJobs() {
1290*635a8641SAndroid Build Coastguard Worker   const CommandLine* command_line = CommandLine::ForCurrentProcess();
1291*635a8641SAndroid Build Coastguard Worker   if (command_line->HasSwitch(switches::kTestLauncherJobs)) {
1292*635a8641SAndroid Build Coastguard Worker     // If the number of test launcher jobs was specified, return that number.
1293*635a8641SAndroid Build Coastguard Worker     size_t jobs = 0U;
1294*635a8641SAndroid Build Coastguard Worker 
1295*635a8641SAndroid Build Coastguard Worker     if (!StringToSizeT(
1296*635a8641SAndroid Build Coastguard Worker             command_line->GetSwitchValueASCII(switches::kTestLauncherJobs),
1297*635a8641SAndroid Build Coastguard Worker             &jobs) ||
1298*635a8641SAndroid Build Coastguard Worker         !jobs) {
1299*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Invalid value for " << switches::kTestLauncherJobs;
1300*635a8641SAndroid Build Coastguard Worker       return 0U;
1301*635a8641SAndroid Build Coastguard Worker     }
1302*635a8641SAndroid Build Coastguard Worker     return jobs;
1303*635a8641SAndroid Build Coastguard Worker   }
1304*635a8641SAndroid Build Coastguard Worker   if (command_line->HasSwitch(kGTestFilterFlag) && !BotModeEnabled()) {
1305*635a8641SAndroid Build Coastguard Worker     // Do not run jobs in parallel by default if we are running a subset of
1306*635a8641SAndroid Build Coastguard Worker     // the tests and if bot mode is off.
1307*635a8641SAndroid Build Coastguard Worker     return 1U;
1308*635a8641SAndroid Build Coastguard Worker   }
1309*635a8641SAndroid Build Coastguard Worker 
1310*635a8641SAndroid Build Coastguard Worker   // Default to the number of processor cores.
1311*635a8641SAndroid Build Coastguard Worker   return base::checked_cast<size_t>(SysInfo::NumberOfProcessors());
1312*635a8641SAndroid Build Coastguard Worker }
1313*635a8641SAndroid Build Coastguard Worker 
GetTestOutputSnippet(const TestResult & result,const std::string & full_output)1314*635a8641SAndroid Build Coastguard Worker std::string GetTestOutputSnippet(const TestResult& result,
1315*635a8641SAndroid Build Coastguard Worker                                  const std::string& full_output) {
1316*635a8641SAndroid Build Coastguard Worker   size_t run_pos = full_output.find(std::string("[ RUN      ] ") +
1317*635a8641SAndroid Build Coastguard Worker                                     result.full_name);
1318*635a8641SAndroid Build Coastguard Worker   if (run_pos == std::string::npos)
1319*635a8641SAndroid Build Coastguard Worker     return std::string();
1320*635a8641SAndroid Build Coastguard Worker 
1321*635a8641SAndroid Build Coastguard Worker   size_t end_pos = full_output.find(std::string("[  FAILED  ] ") +
1322*635a8641SAndroid Build Coastguard Worker                                     result.full_name,
1323*635a8641SAndroid Build Coastguard Worker                                     run_pos);
1324*635a8641SAndroid Build Coastguard Worker   // Only clip the snippet to the "OK" message if the test really
1325*635a8641SAndroid Build Coastguard Worker   // succeeded. It still might have e.g. crashed after printing it.
1326*635a8641SAndroid Build Coastguard Worker   if (end_pos == std::string::npos &&
1327*635a8641SAndroid Build Coastguard Worker       result.status == TestResult::TEST_SUCCESS) {
1328*635a8641SAndroid Build Coastguard Worker     end_pos = full_output.find(std::string("[       OK ] ") +
1329*635a8641SAndroid Build Coastguard Worker                                result.full_name,
1330*635a8641SAndroid Build Coastguard Worker                                run_pos);
1331*635a8641SAndroid Build Coastguard Worker   }
1332*635a8641SAndroid Build Coastguard Worker   if (end_pos != std::string::npos) {
1333*635a8641SAndroid Build Coastguard Worker     size_t newline_pos = full_output.find("\n", end_pos);
1334*635a8641SAndroid Build Coastguard Worker     if (newline_pos != std::string::npos)
1335*635a8641SAndroid Build Coastguard Worker       end_pos = newline_pos + 1;
1336*635a8641SAndroid Build Coastguard Worker   }
1337*635a8641SAndroid Build Coastguard Worker 
1338*635a8641SAndroid Build Coastguard Worker   std::string snippet(full_output.substr(run_pos));
1339*635a8641SAndroid Build Coastguard Worker   if (end_pos != std::string::npos)
1340*635a8641SAndroid Build Coastguard Worker     snippet = full_output.substr(run_pos, end_pos - run_pos);
1341*635a8641SAndroid Build Coastguard Worker 
1342*635a8641SAndroid Build Coastguard Worker   return snippet;
1343*635a8641SAndroid Build Coastguard Worker }
1344*635a8641SAndroid Build Coastguard Worker 
1345*635a8641SAndroid Build Coastguard Worker }  // namespace base
1346