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

Side by Side Diff: chrome/browser/unload_browsertest.cc

Issue 11016023: Quickly close tabs/window with long-running unload handlers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Patch for landing Created 7 years, 6 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #if defined(OS_POSIX) 5 #if defined(OS_POSIX)
6 #include <signal.h> 6 #include <signal.h>
7 #endif 7 #endif
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 405
406 content::WindowedNotificationObserver tab_close_observer( 406 content::WindowedNotificationObserver tab_close_observer(
407 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 407 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
408 content::NotificationService::AllSources()); 408 content::NotificationService::AllSources());
409 chrome::CloseTab(browser()); 409 chrome::CloseTab(browser());
410 tab_close_observer.Wait(); 410 tab_close_observer.Wait();
411 411
412 CheckTitle("only_one_unload"); 412 CheckTitle("only_one_unload");
413 } 413 }
414 414
415
416 class FastUnloadTest : public UnloadTest {
417 public:
418 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
419 ASSERT_TRUE(test_server()->Start());
420 }
421
422 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
423 test_server()->Stop();
424 }
425
426 GURL GetUrl(const std::string& name) {
427 return GURL(test_server()->GetURL(
428 "files/fast_tab_close/" + name + ".html"));
429 }
430
431 void NavigateToPage(const char* name) {
432 ui_test_utils::NavigateToURL(browser(), GetUrl(name));
433 CheckTitle(name);
434 }
435
436 void NavigateToPageInNewTab(const char* name) {
437 ui_test_utils::NavigateToURLWithDisposition(
438 browser(), GetUrl(name), NEW_FOREGROUND_TAB,
439 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
440 CheckTitle(name);
441 }
442
443 std::string GetCookies(const char* name) {
444 content::WebContents* contents =
445 browser()->tab_strip_model()->GetActiveWebContents();
446 return content::GetCookies(contents->GetBrowserContext(), GetUrl(name));
447 }
448 };
449
450 class FastTabCloseTabStripModelObserver : public TabStripModelObserver {
451 public:
452 FastTabCloseTabStripModelObserver(TabStripModel* model,
453 base::RunLoop* run_loop)
454 : model_(model),
455 run_loop_(run_loop) {
456 model_->AddObserver(this);
457 }
458
459 virtual ~FastTabCloseTabStripModelObserver() {
460 model_->RemoveObserver(this);
461 }
462
463 // TabStripModelObserver:
464 virtual void TabDetachedAt(content::WebContents* contents,
465 int index) OVERRIDE {
466 run_loop_->Quit();
467 }
468
469 private:
470 TabStripModel* const model_;
471 base::RunLoop* const run_loop_;
472 };
473
474
475 // Test that fast-tab-close works when closing a tab with an unload handler
476 // (http://crbug.com/142458).
477 IN_PROC_BROWSER_TEST_F(FastUnloadTest, UnloadHidden) {
478 NavigateToPage("no_listeners");
479 NavigateToPageInNewTab("unload_sets_cookie");
480 EXPECT_EQ("", GetCookies("no_listeners"));
481
482 {
483 base::RunLoop run_loop;
484 FastTabCloseTabStripModelObserver observer(
485 browser()->tab_strip_model(), &run_loop);
486 chrome::CloseTab(browser());
487 run_loop.Run();
488 }
489
490 // Check that the browser only has the original tab.
491 CheckTitle("no_listeners");
492 EXPECT_EQ(1, browser()->tab_strip_model()->count());
493
494 // Show that the web contents to go away after the was removed.
495 // Without unload-detached, this times-out because it happens earlier.
496 content::WindowedNotificationObserver contents_destroyed_observer(
497 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
498 content::NotificationService::AllSources());
499 contents_destroyed_observer.Wait();
500
501 // Browser still has the same tab.
502 CheckTitle("no_listeners");
503 EXPECT_EQ(1, browser()->tab_strip_model()->count());
504 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners"));
505 }
506
507 // Test that fast-tab-close does not break a solo tab.
508 IN_PROC_BROWSER_TEST_F(FastUnloadTest, PRE_ClosingLastTabFinishesUnload) {
509 // The unload handler sleeps before setting the cookie to catch cases when
510 // unload handlers are not allowed to run to completion. (For example,
511 // using the detached handler for the tab and then closing the browser.)
512 NavigateToPage("unload_sleep_before_cookie");
513 EXPECT_EQ(1, browser()->tab_strip_model()->count());
514 EXPECT_EQ("", GetCookies("unload_sleep_before_cookie"));
515
516 content::WindowedNotificationObserver window_observer(
517 chrome::NOTIFICATION_BROWSER_CLOSED,
518 content::NotificationService::AllSources());
519 chrome::CloseTab(browser());
520 window_observer.Wait();
521 }
522 IN_PROC_BROWSER_TEST_F(FastUnloadTest, ClosingLastTabFinishesUnload) {
523 // Check for cookie set in unload handler of PRE_ test.
524 NavigateToPage("no_listeners");
525 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners"));
526 }
527
528 // Test that fast-tab-close does not break window close.
529 IN_PROC_BROWSER_TEST_F(FastUnloadTest, PRE_WindowCloseFinishesUnload) {
530 NavigateToPage("no_listeners");
531
532 // The unload handler sleeps before setting the cookie to catch cases when
533 // unload handlers are not allowed to run to completion. Without the sleep,
534 // the cookie can get set even if the browser does not wait for
535 // the unload handler to finish.
536 NavigateToPageInNewTab("unload_sleep_before_cookie");
537 EXPECT_EQ(2, browser()->tab_strip_model()->count());
538 EXPECT_EQ("", GetCookies("no_listeners"));
539
540 content::WindowedNotificationObserver window_observer(
541 chrome::NOTIFICATION_BROWSER_CLOSED,
542 content::NotificationService::AllSources());
543 chrome::CloseWindow(browser());
544 window_observer.Wait();
545 }
546 IN_PROC_BROWSER_TEST_F(FastUnloadTest, WindowCloseFinishesUnload) {
547 // Check for cookie set in unload during PRE_ test.
548 NavigateToPage("no_listeners");
549 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners"));
550 }
551
552 // Test that a tab crash during unload does not break window close.
553 //
554 // Hits assertion on Linux and Mac:
555 // [FATAL:profile_destroyer.cc(46)] Check failed:
556 // hosts.empty() ||
557 // profile->IsOffTheRecord() ||
558 // content::RenderProcessHost::run_renderer_in_process().
559 // More details: The renderer process host matches the closed, crashed tab.
560 // The |UnloadController| receives |NOTIFICATION_WEB_CONTENTS_DISCONNECTED|
561 // and proceeds with the close.
562 IN_PROC_BROWSER_TEST_F(FastUnloadTest, DISABLED_WindowCloseAfterUnloadCrash) {
563 NavigateToPage("no_listeners");
564 NavigateToPageInNewTab("unload_sets_cookie");
565 content::WebContents* unload_contents =
566 browser()->tab_strip_model()->GetActiveWebContents();
567 EXPECT_EQ("", GetCookies("no_listeners"));
568
569 {
570 base::RunLoop run_loop;
571 FastTabCloseTabStripModelObserver observer(
572 browser()->tab_strip_model(), &run_loop);
573 chrome::CloseTab(browser());
574 run_loop.Run();
575 }
576
577 // Check that the browser only has the original tab.
578 CheckTitle("no_listeners");
579 EXPECT_EQ(1, browser()->tab_strip_model()->count());
580
581 CrashTab(unload_contents);
582
583 // Check that the browser only has the original tab.
584 CheckTitle("no_listeners");
585 EXPECT_EQ(1, browser()->tab_strip_model()->count());
586
587 content::WindowedNotificationObserver window_observer(
588 chrome::NOTIFICATION_BROWSER_CLOSED,
589 content::NotificationService::AllSources());
590 chrome::CloseWindow(browser());
591 window_observer.Wait();
592 }
593
594 // Times out on Windows and Linux.
595 #if defined(OS_WIN) || defined(OS_LINUX)
596 #define MAYBE_WindowCloseAfterBeforeUnloadCrash \
597 DISABLED_WindowCloseAfterBeforeUnloadCrash
598 #else
599 #define MAYBE_WindowCloseAfterBeforeUnloadCrash \
600 WindowCloseAfterBeforeUnloadCrash
601 #endif
602 IN_PROC_BROWSER_TEST_F(FastUnloadTest,
603 MAYBE_WindowCloseAfterBeforeUnloadCrash) {
604 // Tests makes no sense in single-process mode since the renderer is hung.
605 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess))
606 return;
607
608 NavigateToDataURL(BEFORE_UNLOAD_HTML, "beforeunload");
609 content::WebContents* beforeunload_contents =
610 browser()->tab_strip_model()->GetActiveWebContents();
611
612 content::WindowedNotificationObserver window_observer(
613 chrome::NOTIFICATION_BROWSER_CLOSED,
614 content::NotificationService::AllSources());
615 chrome::CloseWindow(browser());
616 CrashTab(beforeunload_contents);
617 window_observer.Wait();
618 }
619
415 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs 620 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs
416 // and multiple windows. 621 // and multiple windows.
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/frame/browser_view.cc ('k') | chrome/test/data/fast_tab_close/no_listeners.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698