| Index: base/test/test_launcher.cc
|
| diff --git a/base/test/test_launcher.cc b/base/test/test_launcher.cc
|
| index 7248b9c734350121b2221a8697c7bcf6a40be30f..0da8cec21cc1becda1969c9482ae3768448da666 100644
|
| --- a/base/test/test_launcher.cc
|
| +++ b/base/test/test_launcher.cc
|
| @@ -13,6 +13,7 @@
|
| #include "base/format_macros.h"
|
| #include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| +#include "base/process_util.h"
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/test/test_timeouts.h"
|
| #include "base/time.h"
|
| @@ -348,6 +349,64 @@ TestResult::TestResult() {
|
| TestLauncherDelegate::~TestLauncherDelegate() {
|
| }
|
|
|
| +int LaunchChildGTestProcess(const CommandLine& command_line,
|
| + base::TimeDelta timeout,
|
| + bool* was_timeout) {
|
| + CommandLine new_command_line(command_line.GetProgram());
|
| + CommandLine::SwitchMap switches = command_line.GetSwitches();
|
| +
|
| + // Strip out gtest_output flag because otherwise we would overwrite results
|
| + // of the other tests.
|
| + switches.erase(kGTestOutputFlag);
|
| +
|
| + // Strip out gtest_repeat flag - this is handled by the launcher process.
|
| + switches.erase(kGTestRepeatFlag);
|
| +
|
| + for (CommandLine::SwitchMap::const_iterator iter = switches.begin();
|
| + iter != switches.end(); ++iter) {
|
| + new_command_line.AppendSwitchNative((*iter).first, (*iter).second);
|
| + }
|
| +
|
| + base::ProcessHandle process_handle;
|
| + base::LaunchOptions options;
|
| +
|
| +#if defined(OS_POSIX)
|
| + // On POSIX, we launch the test in a new process group with pgid equal to
|
| + // its pid. Any child processes that the test may create will inherit the
|
| + // same pgid. This way, if the test is abruptly terminated, we can clean up
|
| + // any orphaned child processes it may have left behind.
|
| + options.new_process_group = true;
|
| +#endif
|
| +
|
| + if (!base::LaunchProcess(new_command_line, options, &process_handle))
|
| + return -1;
|
| +
|
| + int exit_code = 0;
|
| + if (!base::WaitForExitCodeWithTimeout(process_handle,
|
| + &exit_code,
|
| + timeout)) {
|
| + *was_timeout = true;
|
| + exit_code = -1; // Set a non-zero exit code to signal a failure.
|
| +
|
| + // Ensure that the process terminates.
|
| + base::KillProcess(process_handle, -1, true);
|
| + }
|
| +
|
| +#if defined(OS_POSIX)
|
| + if (exit_code != 0) {
|
| + // On POSIX, in case the test does not exit cleanly, either due to a crash
|
| + // or due to it timing out, we need to clean up any child processes that
|
| + // it might have created. On Windows, child processes are automatically
|
| + // cleaned up using JobObjects.
|
| + base::KillProcessGroup(process_handle);
|
| + }
|
| +#endif
|
| +
|
| + base::CloseProcessHandle(process_handle);
|
| +
|
| + return exit_code;
|
| +}
|
| +
|
| int LaunchTests(TestLauncherDelegate* launcher_delegate,
|
| int argc,
|
| char** argv) {
|
|
|