OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/test/automation/proxy_launcher.h" | 5 #include "chrome/test/automation/proxy_launcher.h" |
6 | 6 |
7 #include "app/sql/connection.h" | 7 #include "app/sql/connection.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
10 #include "base/string_split.h" | 10 #include "base/string_split.h" |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 return LaunchBrowserHelper(state, true, NULL); | 199 return LaunchBrowserHelper(state, true, NULL); |
200 } | 200 } |
201 #endif | 201 #endif |
202 | 202 |
203 void ProxyLauncher::QuitBrowser() { | 203 void ProxyLauncher::QuitBrowser() { |
204 if (SESSION_ENDING == shutdown_type_) { | 204 if (SESSION_ENDING == shutdown_type_) { |
205 TerminateBrowser(); | 205 TerminateBrowser(); |
206 return; | 206 return; |
207 } | 207 } |
208 | 208 |
209 base::TimeTicks quit_start = base::TimeTicks::Now(); | |
210 | |
211 // There's nothing to do here if the browser is not running. | 209 // There's nothing to do here if the browser is not running. |
212 // WARNING: There is a race condition here where the browser may shut down | 210 // WARNING: There is a race condition here where the browser may shut down |
213 // after this check but before some later automation call. Your test should | 211 // after this check but before some later automation call. Your test should |
214 // use WaitForBrowserProcessToQuit() if it intentionally | 212 // use WaitForBrowserProcessToQuit() if it intentionally |
215 // causes the browser to shut down. | 213 // causes the browser to shut down. |
216 if (IsBrowserRunning()) { | 214 if (IsBrowserRunning()) { |
| 215 base::TimeTicks quit_start = base::TimeTicks::Now(); |
217 EXPECT_TRUE(automation()->SetFilteredInet(false)); | 216 EXPECT_TRUE(automation()->SetFilteredInet(false)); |
218 | 217 |
219 if (WINDOW_CLOSE == shutdown_type_) { | 218 if (WINDOW_CLOSE == shutdown_type_) { |
220 int window_count = 0; | 219 int window_count = 0; |
221 EXPECT_TRUE(automation()->GetBrowserWindowCount(&window_count)); | 220 EXPECT_TRUE(automation()->GetBrowserWindowCount(&window_count)); |
222 | 221 |
223 // Synchronously close all but the last browser window. Closing them | 222 // Synchronously close all but the last browser window. Closing them |
224 // one-by-one may help with stability. | 223 // one-by-one may help with stability. |
225 while (window_count > 1) { | 224 while (window_count > 1) { |
226 scoped_refptr<BrowserProxy> browser_proxy = | 225 scoped_refptr<BrowserProxy> browser_proxy = |
(...skipping 20 matching lines...) Expand all Loading... |
247 } else if (USER_QUIT == shutdown_type_) { | 246 } else if (USER_QUIT == shutdown_type_) { |
248 scoped_refptr<BrowserProxy> browser_proxy = | 247 scoped_refptr<BrowserProxy> browser_proxy = |
249 automation()->GetBrowserWindow(0); | 248 automation()->GetBrowserWindow(0); |
250 EXPECT_TRUE(browser_proxy.get()); | 249 EXPECT_TRUE(browser_proxy.get()); |
251 if (browser_proxy.get()) { | 250 if (browser_proxy.get()) { |
252 EXPECT_TRUE(browser_proxy->RunCommandAsync(IDC_EXIT)); | 251 EXPECT_TRUE(browser_proxy->RunCommandAsync(IDC_EXIT)); |
253 } | 252 } |
254 } else { | 253 } else { |
255 NOTREACHED() << "Invalid shutdown type " << shutdown_type_; | 254 NOTREACHED() << "Invalid shutdown type " << shutdown_type_; |
256 } | 255 } |
| 256 |
| 257 // Now, drop the automation IPC channel so that the automation provider in |
| 258 // the browser notices and drops its reference to the browser process. |
| 259 automation()->Disconnect(); |
| 260 |
| 261 // Wait for the browser process to quit. It should quit once all tabs have |
| 262 // been closed. |
| 263 if (!WaitForBrowserProcessToQuit( |
| 264 TestTimeouts::wait_for_terminate_timeout_ms())) { |
| 265 // We need to force the browser to quit because it didn't quit fast |
| 266 // enough. Take no chance and kill every chrome processes. |
| 267 CleanupAppProcesses(); |
| 268 } |
| 269 browser_quit_time_ = base::TimeTicks::Now() - quit_start; |
257 } | 270 } |
258 | 271 |
259 // Now, drop the automation IPC channel so that the automation provider in | |
260 // the browser notices and drops its reference to the browser process. | |
261 automation()->Disconnect(); | |
262 | |
263 // Wait for the browser process to quit. It should quit once all tabs have | |
264 // been closed. | |
265 int exit_code = -1; | |
266 if (WaitForBrowserProcessToQuit( | |
267 TestTimeouts::wait_for_terminate_timeout_ms(), &exit_code)) { | |
268 EXPECT_EQ(0, exit_code); // Expect a clean shutdown. | |
269 } else { | |
270 // We need to force the browser to quit because it didn't quit fast | |
271 // enough. Take no chance and kill every chrome processes. | |
272 CleanupAppProcesses(); | |
273 } | |
274 browser_quit_time_ = base::TimeTicks::Now() - quit_start; | |
275 | |
276 // Don't forget to close the handle | 272 // Don't forget to close the handle |
277 base::CloseProcessHandle(process_); | 273 base::CloseProcessHandle(process_); |
278 process_ = base::kNullProcessHandle; | 274 process_ = base::kNullProcessHandle; |
279 process_id_ = -1; | 275 process_id_ = -1; |
280 } | 276 } |
281 | 277 |
282 void ProxyLauncher::TerminateBrowser() { | 278 void ProxyLauncher::TerminateBrowser() { |
283 base::TimeTicks quit_start = base::TimeTicks::Now(); | |
284 | |
285 if (IsBrowserRunning()) { | 279 if (IsBrowserRunning()) { |
| 280 base::TimeTicks quit_start = base::TimeTicks::Now(); |
286 EXPECT_TRUE(automation()->SetFilteredInet(false)); | 281 EXPECT_TRUE(automation()->SetFilteredInet(false)); |
287 #if defined(OS_WIN) | 282 #if defined(OS_WIN) |
288 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); | 283 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); |
289 ASSERT_TRUE(browser.get()); | 284 ASSERT_TRUE(browser.get()); |
290 ASSERT_TRUE(browser->TerminateSession()); | 285 ASSERT_TRUE(browser->TerminateSession()); |
291 #endif // defined(OS_WIN) | 286 #endif // defined(OS_WIN) |
292 | 287 |
293 // Now, drop the automation IPC channel so that the automation provider in | 288 // Now, drop the automation IPC channel so that the automation provider in |
294 // the browser notices and drops its reference to the browser process. | 289 // the browser notices and drops its reference to the browser process. |
295 automation()->Disconnect(); | 290 automation()->Disconnect(); |
296 | 291 |
297 #if defined(OS_POSIX) | 292 #if defined(OS_POSIX) |
298 EXPECT_EQ(kill(process_, SIGTERM), 0); | 293 EXPECT_EQ(kill(process_, SIGTERM), 0); |
299 #endif // OS_POSIX | 294 #endif // OS_POSIX |
| 295 |
| 296 if (!WaitForBrowserProcessToQuit( |
| 297 TestTimeouts::wait_for_terminate_timeout_ms())) { |
| 298 // We need to force the browser to quit because it didn't quit fast |
| 299 // enough. Take no chance and kill every chrome processes. |
| 300 CleanupAppProcesses(); |
| 301 } |
| 302 browser_quit_time_ = base::TimeTicks::Now() - quit_start; |
300 } | 303 } |
301 | 304 |
302 int exit_code = 0; | |
303 if (WaitForBrowserProcessToQuit( | |
304 TestTimeouts::wait_for_terminate_timeout_ms(), &exit_code)) { | |
305 EXPECT_EQ(0, exit_code); // Expect a clean shutdown. | |
306 } else { | |
307 // We need to force the browser to quit because it didn't quit fast | |
308 // enough. Take no chance and kill every chrome processes. | |
309 CleanupAppProcesses(); | |
310 } | |
311 browser_quit_time_ = base::TimeTicks::Now() - quit_start; | |
312 | |
313 // Don't forget to close the handle | 305 // Don't forget to close the handle |
314 base::CloseProcessHandle(process_); | 306 base::CloseProcessHandle(process_); |
315 process_ = base::kNullProcessHandle; | 307 process_ = base::kNullProcessHandle; |
316 process_id_ = -1; | 308 process_id_ = -1; |
317 } | 309 } |
318 | 310 |
319 void ProxyLauncher::AssertAppNotRunning(const std::wstring& error_message) { | 311 void ProxyLauncher::AssertAppNotRunning(const std::wstring& error_message) { |
320 std::wstring final_error_message(error_message); | 312 std::wstring final_error_message(error_message); |
321 | 313 |
322 ChromeProcessList processes = GetRunningChromeProcesses(process_id_); | 314 ChromeProcessList processes = GetRunningChromeProcesses(process_id_); |
323 if (!processes.empty()) { | 315 if (!processes.empty()) { |
324 final_error_message += L" Leftover PIDs: ["; | 316 final_error_message += L" Leftover PIDs: ["; |
325 for (ChromeProcessList::const_iterator it = processes.begin(); | 317 for (ChromeProcessList::const_iterator it = processes.begin(); |
326 it != processes.end(); ++it) { | 318 it != processes.end(); ++it) { |
327 final_error_message += StringPrintf(L" %d", *it); | 319 final_error_message += StringPrintf(L" %d", *it); |
328 } | 320 } |
329 final_error_message += L" ]"; | 321 final_error_message += L" ]"; |
330 } | 322 } |
331 ASSERT_TRUE(processes.empty()) << final_error_message; | 323 ASSERT_TRUE(processes.empty()) << final_error_message; |
332 } | 324 } |
333 | 325 |
334 void ProxyLauncher::CleanupAppProcesses() { | 326 void ProxyLauncher::CleanupAppProcesses() { |
335 TerminateAllChromeProcesses(process_id_); | 327 TerminateAllChromeProcesses(process_id_); |
336 } | 328 } |
337 | 329 |
338 bool ProxyLauncher::WaitForBrowserProcessToQuit(int timeout, int* exit_code) { | 330 bool ProxyLauncher::WaitForBrowserProcessToQuit(int timeout) { |
339 #ifdef WAIT_FOR_DEBUGGER_ON_OPEN | 331 #ifdef WAIT_FOR_DEBUGGER_ON_OPEN |
340 timeout = 500000; | 332 timeout = 500000; |
341 #endif | 333 #endif |
342 return base::WaitForExitCodeWithTimeout(process_, exit_code, timeout); | 334 return base::WaitForSingleProcess(process_, timeout); |
343 } | 335 } |
344 | 336 |
345 bool ProxyLauncher::IsBrowserRunning() { | 337 bool ProxyLauncher::IsBrowserRunning() { |
346 // Send a simple message to the browser. If it comes back, the browser | 338 return CrashAwareSleep(0); |
347 // must be alive. | 339 } |
348 int window_count; | 340 |
349 return automation_proxy_->GetBrowserWindowCount(&window_count); | 341 bool ProxyLauncher::CrashAwareSleep(int timeout_ms) { |
| 342 return base::CrashAwareSleep(process_, timeout_ms); |
350 } | 343 } |
351 | 344 |
352 void ProxyLauncher::PrepareTestCommandline(CommandLine* command_line, | 345 void ProxyLauncher::PrepareTestCommandline(CommandLine* command_line, |
353 bool include_testing_id) { | 346 bool include_testing_id) { |
354 // Propagate commandline settings from test_launcher_utils. | 347 // Propagate commandline settings from test_launcher_utils. |
355 test_launcher_utils::PrepareBrowserCommandLineForTests(command_line); | 348 test_launcher_utils::PrepareBrowserCommandLineForTests(command_line); |
356 | 349 |
357 // Add any explicit command line flags passed to the process. | 350 // Add any explicit command line flags passed to the process. |
358 CommandLine::StringType extra_chrome_flags = | 351 CommandLine::StringType extra_chrome_flags = |
359 CommandLine::ForCurrentProcess()->GetSwitchValueNative( | 352 CommandLine::ForCurrentProcess()->GetSwitchValueNative( |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 LaunchBrowserAndServer(state, wait_for_initial_loads); | 575 LaunchBrowserAndServer(state, wait_for_initial_loads); |
583 } | 576 } |
584 | 577 |
585 void AnonymousProxyLauncher::TerminateConnection() { | 578 void AnonymousProxyLauncher::TerminateConnection() { |
586 CloseBrowserAndServer(); | 579 CloseBrowserAndServer(); |
587 } | 580 } |
588 | 581 |
589 std::string AnonymousProxyLauncher::PrefixedChannelID() const { | 582 std::string AnonymousProxyLauncher::PrefixedChannelID() const { |
590 return channel_id_; | 583 return channel_id_; |
591 } | 584 } |
OLD | NEW |