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