Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1996)

Side by Side Diff: chrome/test/automation/proxy_launcher.cc

Issue 6689014: GTTF: Detect browser crashes on shutdown in UI tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698