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 |