1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/updater/win/test/test_executables.h" 6 7 #include <memory> 8 9 #include "base/base_paths.h" 10 #include "base/command_line.h" 11 #include "base/logging.h" 12 #include "base/path_service.h" 13 #include "base/process/launch.h" 14 #include "base/strings/string_number_conversions.h" 15 #include "base/synchronization/waitable_event.h" 16 #include "base/win/win_util.h" 17 #include "chrome/updater/constants.h" 18 #include "chrome/updater/win/test/test_inheritable_event.h" 19 #include "chrome/updater/win/test/test_strings.h" 20 21 namespace updater { 22 23 // If you add another test executable here, also add it to the data_deps in 24 // the "test_executables" target of updater/win/test/BUILD.gn. 25 const base::char16 kTestProcessExecutableName[] = L"updater_test_process.exe"; 26 LongRunningProcess(base::CommandLine * cmd)27base::Process LongRunningProcess(base::CommandLine* cmd) { 28 base::FilePath exe_dir; 29 if (!base::PathService::Get(base::DIR_EXE, &exe_dir)) { 30 LOG(ERROR) << "Failed to get the executable path, unable to create always " 31 "running process"; 32 return base::Process(); 33 } 34 35 base::FilePath exe_path = exe_dir.Append(updater::kTestProcessExecutableName); 36 base::CommandLine command_line(exe_path); 37 38 // This will ensure this new process will run for one minute before dying. 39 command_line.AppendSwitchASCII(updater::kTestSleepMinutesSwitch, "1"); 40 41 auto init_done_event = updater::CreateInheritableEvent( 42 base::WaitableEvent::ResetPolicy::AUTOMATIC, 43 base::WaitableEvent::InitialState::NOT_SIGNALED); 44 command_line.AppendSwitchNative( 45 updater::kInitDoneNotifierSwitch, 46 base::NumberToString16( 47 base::win::HandleToUint32(init_done_event->handle()))); 48 49 if (cmd) 50 *cmd = command_line; 51 52 base::LaunchOptions launch_options; 53 launch_options.handles_to_inherit.push_back(init_done_event->handle()); 54 base::Process result = base::LaunchProcess(command_line, launch_options); 55 56 if (!init_done_event->TimedWait(base::TimeDelta::FromSeconds(10))) { 57 LOG(ERROR) << "Process did not signal"; 58 result.Terminate(/*exit_code=*/1, /*wait=*/false); 59 return base::Process(); 60 } 61 62 return result; 63 } 64 65 } // namespace updater 66