| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/test/parallel_test_launcher.h" | 5 #include "base/test/parallel_test_launcher.h" |
| 6 | 6 |
| 7 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 10 #include <sys/types.h> | 10 #include <sys/types.h> |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 // the purpose of this timeout, which is 1) to avoid buildbot "no output for | 38 // the purpose of this timeout, which is 1) to avoid buildbot "no output for |
| 39 // X seconds" timeout killing the process 2) help communicate status of | 39 // X seconds" timeout killing the process 2) help communicate status of |
| 40 // the test launcher to people looking at the output (no output for a long | 40 // the test launcher to people looking at the output (no output for a long |
| 41 // time is mysterious and gives no info about what is happening) 3) help | 41 // time is mysterious and gives no info about what is happening) 3) help |
| 42 // debugging in case the process hangs anyway. | 42 // debugging in case the process hangs anyway. |
| 43 const int kOutputTimeoutSeconds = 15; | 43 const int kOutputTimeoutSeconds = 15; |
| 44 | 44 |
| 45 void RunCallback( | 45 void RunCallback( |
| 46 const ParallelTestLauncher::LaunchChildGTestProcessCallback& callback, | 46 const ParallelTestLauncher::LaunchChildGTestProcessCallback& callback, |
| 47 int exit_code, | 47 int exit_code, |
| 48 const TimeDelta& elapsed_time, |
| 48 bool was_timeout, | 49 bool was_timeout, |
| 49 const std::string& output) { | 50 const std::string& output) { |
| 50 callback.Run(exit_code, was_timeout, output); | 51 callback.Run(exit_code, elapsed_time, was_timeout, output); |
| 51 } | 52 } |
| 52 | 53 |
| 53 void DoLaunchChildTestProcess( | 54 void DoLaunchChildTestProcess( |
| 54 const CommandLine& command_line, | 55 const CommandLine& command_line, |
| 55 base::TimeDelta timeout, | 56 base::TimeDelta timeout, |
| 56 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 57 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 57 const ParallelTestLauncher::LaunchChildGTestProcessCallback& callback) { | 58 const ParallelTestLauncher::LaunchChildGTestProcessCallback& callback) { |
| 59 TimeTicks start_time = TimeTicks::Now(); |
| 60 |
| 58 // Redirect child process output to a file. | 61 // Redirect child process output to a file. |
| 59 base::FilePath output_file; | 62 base::FilePath output_file; |
| 60 CHECK(file_util::CreateTemporaryFile(&output_file)); | 63 CHECK(file_util::CreateTemporaryFile(&output_file)); |
| 61 | 64 |
| 62 LaunchOptions options; | 65 LaunchOptions options; |
| 63 #if defined(OS_WIN) | 66 #if defined(OS_WIN) |
| 64 // Make the file handle inheritable by the child. | 67 // Make the file handle inheritable by the child. |
| 65 SECURITY_ATTRIBUTES sa_attr; | 68 SECURITY_ATTRIBUTES sa_attr; |
| 66 sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES); | 69 sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES); |
| 67 sa_attr.lpSecurityDescriptor = NULL; | 70 sa_attr.lpSecurityDescriptor = NULL; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 | 112 |
| 110 CHECK(base::DeleteFile(output_file, false)); | 113 CHECK(base::DeleteFile(output_file, false)); |
| 111 | 114 |
| 112 // Run target callback on the thread it was originating from, not on | 115 // Run target callback on the thread it was originating from, not on |
| 113 // a worker pool thread. | 116 // a worker pool thread. |
| 114 message_loop_proxy->PostTask( | 117 message_loop_proxy->PostTask( |
| 115 FROM_HERE, | 118 FROM_HERE, |
| 116 Bind(&RunCallback, | 119 Bind(&RunCallback, |
| 117 callback, | 120 callback, |
| 118 exit_code, | 121 exit_code, |
| 122 TimeTicks::Now() - start_time, |
| 119 was_timeout, | 123 was_timeout, |
| 120 output_file_contents)); | 124 output_file_contents)); |
| 121 } | 125 } |
| 122 | 126 |
| 123 } // namespace | 127 } // namespace |
| 124 | 128 |
| 125 ParallelTestLauncher::ParallelTestLauncher(size_t jobs) | 129 ParallelTestLauncher::ParallelTestLauncher(size_t jobs) |
| 126 : timer_(FROM_HERE, | 130 : timer_(FROM_HERE, |
| 127 TimeDelta::FromSeconds(kOutputTimeoutSeconds), | 131 TimeDelta::FromSeconds(kOutputTimeoutSeconds), |
| 128 this, | 132 this, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 140 worker_pool_owner_->pool()->Shutdown(); | 144 worker_pool_owner_->pool()->Shutdown(); |
| 141 } | 145 } |
| 142 | 146 |
| 143 void ParallelTestLauncher::LaunchChildGTestProcess( | 147 void ParallelTestLauncher::LaunchChildGTestProcess( |
| 144 const CommandLine& command_line, | 148 const CommandLine& command_line, |
| 145 const std::string& wrapper, | 149 const std::string& wrapper, |
| 146 base::TimeDelta timeout, | 150 base::TimeDelta timeout, |
| 147 const LaunchChildGTestProcessCallback& callback) { | 151 const LaunchChildGTestProcessCallback& callback) { |
| 148 DCHECK(thread_checker_.CalledOnValidThread()); | 152 DCHECK(thread_checker_.CalledOnValidThread()); |
| 149 | 153 |
| 154 LaunchSequencedChildGTestProcess( |
| 155 worker_pool_owner_->pool()->GetSequenceToken(), |
| 156 command_line, |
| 157 wrapper, |
| 158 timeout, |
| 159 callback); |
| 160 } |
| 161 |
| 162 void ParallelTestLauncher::LaunchNamedSequencedChildGTestProcess( |
| 163 const std::string& token_name, |
| 164 const CommandLine& command_line, |
| 165 const std::string& wrapper, |
| 166 base::TimeDelta timeout, |
| 167 const LaunchChildGTestProcessCallback& callback) { |
| 168 DCHECK(thread_checker_.CalledOnValidThread()); |
| 169 |
| 170 LaunchSequencedChildGTestProcess( |
| 171 worker_pool_owner_->pool()->GetNamedSequenceToken(token_name), |
| 172 command_line, |
| 173 wrapper, |
| 174 timeout, |
| 175 callback); |
| 176 } |
| 177 |
| 178 void ParallelTestLauncher::ResetOutputWatchdog() { |
| 179 DCHECK(thread_checker_.CalledOnValidThread()); |
| 180 timer_.Reset(); |
| 181 } |
| 182 |
| 183 void ParallelTestLauncher::LaunchSequencedChildGTestProcess( |
| 184 SequencedWorkerPool::SequenceToken sequence_token, |
| 185 const CommandLine& command_line, |
| 186 const std::string& wrapper, |
| 187 base::TimeDelta timeout, |
| 188 const LaunchChildGTestProcessCallback& callback) { |
| 189 DCHECK(thread_checker_.CalledOnValidThread()); |
| 190 |
| 150 // Record the exact command line used to launch the child. | 191 // Record the exact command line used to launch the child. |
| 151 CommandLine new_command_line( | 192 CommandLine new_command_line( |
| 152 PrepareCommandLineForGTest(command_line, wrapper)); | 193 PrepareCommandLineForGTest(command_line, wrapper)); |
| 153 launch_sequence_number_++; | 194 launch_sequence_number_++; |
| 154 running_processes_map_.insert( | 195 running_processes_map_.insert( |
| 155 std::make_pair(launch_sequence_number_, new_command_line)); | 196 std::make_pair(launch_sequence_number_, new_command_line)); |
| 156 | 197 |
| 157 worker_pool_owner_->pool()->PostWorkerTask( | 198 worker_pool_owner_->pool()->PostSequencedWorkerTask( |
| 199 sequence_token, |
| 158 FROM_HERE, | 200 FROM_HERE, |
| 159 Bind(&DoLaunchChildTestProcess, | 201 Bind(&DoLaunchChildTestProcess, |
| 160 new_command_line, | 202 new_command_line, |
| 161 timeout, | 203 timeout, |
| 162 MessageLoopProxy::current(), | 204 MessageLoopProxy::current(), |
| 163 Bind(&ParallelTestLauncher::OnLaunchTestProcessFinished, | 205 Bind(&ParallelTestLauncher::OnLaunchTestProcessFinished, |
| 164 Unretained(this), | 206 Unretained(this), |
| 165 launch_sequence_number_, | 207 launch_sequence_number_, |
| 166 callback))); | 208 callback))); |
| 167 } | 209 } |
| 168 | 210 |
| 169 void ParallelTestLauncher::ResetOutputWatchdog() { | |
| 170 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 171 timer_.Reset(); | |
| 172 } | |
| 173 | |
| 174 void ParallelTestLauncher::OnLaunchTestProcessFinished( | 211 void ParallelTestLauncher::OnLaunchTestProcessFinished( |
| 175 size_t sequence_number, | 212 size_t sequence_number, |
| 176 const LaunchChildGTestProcessCallback& callback, | 213 const LaunchChildGTestProcessCallback& callback, |
| 177 int exit_code, | 214 int exit_code, |
| 215 const TimeDelta& elapsed_time, |
| 178 bool was_timeout, | 216 bool was_timeout, |
| 179 const std::string& output) { | 217 const std::string& output) { |
| 180 DCHECK(thread_checker_.CalledOnValidThread()); | 218 DCHECK(thread_checker_.CalledOnValidThread()); |
| 181 running_processes_map_.erase(sequence_number); | 219 running_processes_map_.erase(sequence_number); |
| 182 callback.Run(exit_code, was_timeout, output); | 220 callback.Run(exit_code, elapsed_time, was_timeout, output); |
| 183 } | 221 } |
| 184 | 222 |
| 185 void ParallelTestLauncher::OnOutputTimeout() { | 223 void ParallelTestLauncher::OnOutputTimeout() { |
| 186 DCHECK(thread_checker_.CalledOnValidThread()); | 224 DCHECK(thread_checker_.CalledOnValidThread()); |
| 187 | 225 |
| 188 fprintf(stdout, "Still waiting for the following processes to finish:\n"); | 226 fprintf(stdout, "Still waiting for the following processes to finish:\n"); |
| 189 | 227 |
| 190 for (RunningProcessesMap::const_iterator i = running_processes_map_.begin(); | 228 for (RunningProcessesMap::const_iterator i = running_processes_map_.begin(); |
| 191 i != running_processes_map_.end(); | 229 i != running_processes_map_.end(); |
| 192 ++i) { | 230 ++i) { |
| 193 #if defined(OS_WIN) | 231 #if defined(OS_WIN) |
| 194 fwprintf(stdout, L"\t%s\n", i->second.GetCommandLineString().c_str()); | 232 fwprintf(stdout, L"\t%s\n", i->second.GetCommandLineString().c_str()); |
| 195 #else | 233 #else |
| 196 fprintf(stdout, "\t%s\n", i->second.GetCommandLineString().c_str()); | 234 fprintf(stdout, "\t%s\n", i->second.GetCommandLineString().c_str()); |
| 197 #endif | 235 #endif |
| 198 } | 236 } |
| 199 | 237 |
| 200 fflush(stdout); | 238 fflush(stdout); |
| 201 | 239 |
| 202 // Arm the timer again - otherwise it would fire only once. | 240 // Arm the timer again - otherwise it would fire only once. |
| 203 timer_.Reset(); | 241 timer_.Reset(); |
| 204 } | 242 } |
| 205 | 243 |
| 206 } // namespace base | 244 } // namespace base |
| OLD | NEW |