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

Side by Side Diff: chrome/browser/prerender/prerender_browsertest.cc

Issue 7693029: Deflake PrerenderExcessiveMemory, fix race (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Oops Created 9 years, 3 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 <deque> 5 #include <deque>
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/path_service.h" 8 #include "base/path_service.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/test/test_timeouts.h" 10 #include "base/test/test_timeouts.h"
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 95
96 // PrerenderContents that stops the UI message loop on DidStopLoading(). 96 // PrerenderContents that stops the UI message loop on DidStopLoading().
97 class TestPrerenderContents : public PrerenderContents { 97 class TestPrerenderContents : public PrerenderContents {
98 public: 98 public:
99 TestPrerenderContents( 99 TestPrerenderContents(
100 PrerenderManager* prerender_manager, 100 PrerenderManager* prerender_manager,
101 PrerenderTracker* prerender_tracker, 101 PrerenderTracker* prerender_tracker,
102 Profile* profile, 102 Profile* profile,
103 const GURL& url, 103 const GURL& url,
104 const GURL& referrer, 104 const GURL& referrer,
105 int number_of_loads, 105 int expected_number_of_loads,
106 FinalStatus expected_final_status) 106 FinalStatus expected_final_status)
107 : PrerenderContents(prerender_manager, prerender_tracker, profile, 107 : PrerenderContents(prerender_manager, prerender_tracker, profile,
108 url, referrer, ORIGIN_LINK_REL_PRERENDER, 108 url, referrer, ORIGIN_LINK_REL_PRERENDER,
109 PrerenderManager::kNoExperiment), 109 PrerenderManager::kNoExperiment),
110 number_of_loads_(0), 110 number_of_loads_(0),
111 expected_number_of_loads_(number_of_loads), 111 expected_number_of_loads_(expected_number_of_loads),
112 expected_final_status_(expected_final_status), 112 expected_final_status_(expected_final_status),
113 new_render_view_host_(NULL), 113 new_render_view_host_(NULL),
114 was_hidden_(false), 114 was_hidden_(false),
115 was_shown_(false), 115 was_shown_(false),
116 should_be_shown_(expected_final_status == FINAL_STATUS_USED), 116 should_be_shown_(expected_final_status == FINAL_STATUS_USED),
117 quit_message_loop_on_destruction_(true) { 117 quit_message_loop_on_destruction_(true) {
118 if (expected_number_of_loads == 0)
119 MessageLoopForUI::current()->Quit();
118 } 120 }
119 121
120 virtual ~TestPrerenderContents() { 122 virtual ~TestPrerenderContents() {
121 EXPECT_EQ(expected_final_status_, final_status()) << 123 EXPECT_EQ(expected_final_status_, final_status()) <<
122 " when testing URL " << prerender_url().path() << 124 " when testing URL " << prerender_url().path() <<
123 " (Expected: " << NameFromFinalStatus(expected_final_status_) << 125 " (Expected: " << NameFromFinalStatus(expected_final_status_) <<
124 ", Actual: " << NameFromFinalStatus(final_status()) << ")"; 126 ", Actual: " << NameFromFinalStatus(final_status()) << ")";
125 // Prerendering RenderViewHosts should be hidden before the first 127 // Prerendering RenderViewHosts should be hidden before the first
126 // navigation, so this should be happen for every PrerenderContents for 128 // navigation, so this should be happen for every PrerenderContents for
127 // which a RenderViewHost is created, regardless of whether or not it's 129 // which a RenderViewHost is created, regardless of whether or not it's
128 // used. 130 // used.
129 if (new_render_view_host_) { 131 if (new_render_view_host_)
130 EXPECT_TRUE(was_hidden_); 132 EXPECT_TRUE(was_hidden_);
131 }
132 133
133 // A used PrerenderContents will only be destroyed when we swap out 134 // A used PrerenderContents will only be destroyed when we swap out
134 // TabContents, at the end of a navigation caused by a call to 135 // TabContents, at the end of a navigation caused by a call to
135 // NavigateToURLImpl(). 136 // NavigateToURLImpl().
136 if (final_status() == FINAL_STATUS_USED) 137 if (final_status() == FINAL_STATUS_USED)
137 EXPECT_TRUE(new_render_view_host_); 138 EXPECT_TRUE(new_render_view_host_);
138 139
139 EXPECT_EQ(should_be_shown_, was_shown_); 140 EXPECT_EQ(should_be_shown_, was_shown_);
140 141
141 // When the PrerenderContents is destroyed, quit the UI message loop. 142 // When the PrerenderContents is destroyed, quit the UI message loop.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 // even though it is used. 179 // even though it is used.
179 void set_should_be_shown(bool value) { should_be_shown_ = value; } 180 void set_should_be_shown(bool value) { should_be_shown_ = value; }
180 181
181 // Some of the ui_test_utils calls that we use assume that no one will quit 182 // Some of the ui_test_utils calls that we use assume that no one will quit
182 // the message loop that they run internally. So we dont quit the message 183 // the message loop that they run internally. So we dont quit the message
183 // loop in the destructor so as not to interfere. 184 // loop in the destructor so as not to interfere.
184 void set_quit_message_loop_on_destruction(bool value) { 185 void set_quit_message_loop_on_destruction(bool value) {
185 quit_message_loop_on_destruction_ = value; 186 quit_message_loop_on_destruction_ = value;
186 } 187 }
187 188
189 int number_of_loads() { return number_of_loads_; }
190
188 private: 191 private:
189 virtual void OnRenderViewHostCreated( 192 virtual void OnRenderViewHostCreated(
190 RenderViewHost* new_render_view_host) OVERRIDE { 193 RenderViewHost* new_render_view_host) OVERRIDE {
191 // Used to make sure the RenderViewHost is hidden and, if used, 194 // Used to make sure the RenderViewHost is hidden and, if used,
192 // subsequently shown. 195 // subsequently shown.
193 notification_registrar().Add( 196 notification_registrar().Add(
194 this, 197 this,
195 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, 198 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
196 Source<RenderWidgetHost>(new_render_view_host)); 199 Source<RenderWidgetHost>(new_render_view_host));
197 200
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 241
239 bool quit_message_loop_on_destruction_; 242 bool quit_message_loop_on_destruction_;
240 }; 243 };
241 244
242 // PrerenderManager that uses TestPrerenderContents. 245 // PrerenderManager that uses TestPrerenderContents.
243 class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory { 246 class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory {
244 public: 247 public:
245 WaitForLoadPrerenderContentsFactory( 248 WaitForLoadPrerenderContentsFactory(
246 int number_of_loads, 249 int number_of_loads,
247 const std::deque<FinalStatus>& expected_final_status_queue) 250 const std::deque<FinalStatus>& expected_final_status_queue)
248 : number_of_loads_(number_of_loads) { 251 : number_of_loads_(number_of_loads),
cbentzel 2011/08/29 12:26:18 Nit: should this change to expected_number_of_load
249 expected_final_status_queue_.resize(expected_final_status_queue.size()); 252 expected_final_status_queue_(expected_final_status_queue) {
250 std::copy(expected_final_status_queue.begin(),
251 expected_final_status_queue.end(),
252 expected_final_status_queue_.begin());
253 VLOG(1) << "Factory created with queue length " << 253 VLOG(1) << "Factory created with queue length " <<
254 expected_final_status_queue_.size(); 254 expected_final_status_queue_.size();
255 } 255 }
256 256
257 virtual PrerenderContents* CreatePrerenderContents( 257 virtual PrerenderContents* CreatePrerenderContents(
258 PrerenderManager* prerender_manager, 258 PrerenderManager* prerender_manager,
259 PrerenderTracker* prerender_tracker, 259 PrerenderTracker* prerender_tracker,
260 Profile* profile, 260 Profile* profile,
261 const GURL& url, 261 const GURL& url,
262 const GURL& referrer, 262 const GURL& referrer,
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED); 608 browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
609 609
610 ui_test_utils::RunMessageLoop(); 610 ui_test_utils::RunMessageLoop();
611 611
612 TestPrerenderContents* prerender_contents = GetPrerenderContents(); 612 TestPrerenderContents* prerender_contents = GetPrerenderContents();
613 613
614 if (ShouldRenderPrerenderedPageCorrectly(expected_final_status)) { 614 if (ShouldRenderPrerenderedPageCorrectly(expected_final_status)) {
615 ASSERT_TRUE(prerender_contents != NULL); 615 ASSERT_TRUE(prerender_contents != NULL);
616 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status()); 616 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status());
617 617
618 if (call_javascript_) { 618 if (call_javascript_ && total_navigations > 0) {
619 // Check if page behaves as expected while in prerendered state. 619 // Check if page behaves as expected while in prerendered state.
620 bool prerender_test_result = false; 620 bool prerender_test_result = false;
621 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( 621 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
622 prerender_contents->render_view_host_mutable(), L"", 622 prerender_contents->render_view_host_mutable(), L"",
623 L"window.domAutomationController.send(DidPrerenderPass())", 623 L"window.domAutomationController.send(DidPrerenderPass())",
624 &prerender_test_result)); 624 &prerender_test_result));
625 EXPECT_TRUE(prerender_test_result); 625 EXPECT_TRUE(prerender_test_result);
626 } 626 }
627 } else { 627 } else {
628 // In the failure case, we should have removed dest_url_ from the 628 // In the failure case, we should have removed |dest_url_| from the
629 // prerender_manager. 629 // prerender_manager.
630 EXPECT_TRUE(prerender_contents == NULL); 630 EXPECT_TRUE(prerender_contents == NULL);
631 } 631 }
632 } 632 }
633 633
634 void NavigateToURLImpl(const GURL& dest_url, 634 void NavigateToURLImpl(const GURL& dest_url,
635 WindowOpenDisposition disposition) const { 635 WindowOpenDisposition disposition) const {
636 // Make sure in navigating we have a URL to use in the PrerenderManager. 636 // Make sure in navigating we have a URL to use in the PrerenderManager.
637 ASSERT_TRUE(GetPrerenderContents() != NULL); 637 ASSERT_TRUE(GetPrerenderContents() != NULL);
638 638
639 // If opening the page in a background tab, it won't be shown when swapped 639 // If opening the page in a background tab, it won't be shown when swapped
640 // in. 640 // in.
641 if (disposition == NEW_BACKGROUND_TAB) 641 if (disposition == NEW_BACKGROUND_TAB)
642 GetPrerenderContents()->set_should_be_shown(false); 642 GetPrerenderContents()->set_should_be_shown(false);
643 643
644 // In the case of zero loads, need to wait for the page load to complete
645 // before running any Javascript.
646 scoped_ptr<ui_test_utils::WindowedNotificationObserver> page_load_observer;
647 TabContents* tab_contents =
648 GetPrerenderContents()->prerender_contents()->tab_contents();
649 if (GetPrerenderContents()->number_of_loads() == 0) {
650 page_load_observer.reset(
651 new ui_test_utils::WindowedNotificationObserver(
652 content::NOTIFICATION_LOAD_STOP,
653 Source<NavigationController>(&tab_contents->controller())));
654 }
655
644 // ui_test_utils::NavigateToURL waits until DidStopLoading is called on 656 // ui_test_utils::NavigateToURL waits until DidStopLoading is called on
645 // the current tab. As that tab is going to end up deleted, and may never 657 // the current tab. As that tab is going to end up deleted, and may never
646 // finish loading before that happens, exit the message loop on the deletion 658 // finish loading before that happens, exit the message loop on the deletion
647 // of the used prerender contents instead. 659 // of the used prerender contents instead.
648 // 660 //
649 // As PrerenderTestURL waits until the prerendered page has completely 661 // As PrerenderTestURL waits until the prerendered page has completely
650 // loaded, there is no race between loading |dest_url| and swapping the 662 // loaded, there is no race between loading |dest_url| and swapping the
651 // prerendered TabContents into the tab. 663 // prerendered TabContents into the tab.
652 ui_test_utils::NavigateToURLWithDisposition( 664 ui_test_utils::NavigateToURLWithDisposition(
653 browser(), dest_url, disposition, ui_test_utils::BROWSER_TEST_NONE); 665 browser(), dest_url, disposition, ui_test_utils::BROWSER_TEST_NONE);
654 ui_test_utils::RunMessageLoop(); 666 ui_test_utils::RunMessageLoop();
655 667
656 // Make sure the PrerenderContents found earlier was used or removed. 668 // Make sure the PrerenderContents found earlier was used or removed.
657 EXPECT_TRUE(GetPrerenderContents() == NULL); 669 EXPECT_TRUE(GetPrerenderContents() == NULL);
658 670
659 if (call_javascript_) { 671 if (call_javascript_) {
660 // Check if page behaved as expected when actually displayed. 672 if (page_load_observer.get())
661 673 page_load_observer->Wait();
662 // Locate the navigated TabContents.
663 TabContents* tab_contents = NULL;
664 switch (disposition) {
665 case CURRENT_TAB:
666 case NEW_FOREGROUND_TAB:
667 tab_contents = browser()->GetSelectedTabContents();
668 break;
669 case NEW_BACKGROUND_TAB:
670 tab_contents =
671 browser()->GetTabContentsAt(browser()->active_index() + 1);
672 break;
673 default:
674 ASSERT_TRUE(false) << "Unsupported creation disposition";
675 }
676 ASSERT_TRUE(tab_contents);
677 674
678 bool display_test_result = false; 675 bool display_test_result = false;
679 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( 676 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
680 tab_contents->render_view_host(), L"", 677 tab_contents->render_view_host(), L"",
681 L"window.domAutomationController.send(DidDisplayPass())", 678 L"window.domAutomationController.send(DidDisplayPass())",
682 &display_test_result)); 679 &display_test_result));
683 EXPECT_TRUE(display_test_result); 680 EXPECT_TRUE(display_test_result);
684 } 681 }
685 } 682 }
686 683
(...skipping 16 matching lines...) Expand all
703 } 700 }
704 701
705 // Checks that the visibility API works. 702 // Checks that the visibility API works.
706 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibility) { 703 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibility) {
707 PrerenderTestURL("files/prerender/prerender_visibility.html", 704 PrerenderTestURL("files/prerender/prerender_visibility.html",
708 FINAL_STATUS_USED, 705 FINAL_STATUS_USED,
709 1); 706 1);
710 NavigateToDestURL(); 707 NavigateToDestURL();
711 } 708 }
712 709
710 // Checks that the visibility API works when the prerender is quickly opened
711 // in a new tab before it stops loading.
712 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibilityQuickSwitch) {
713 PrerenderTestURL("files/prerender/prerender_visibility_quick.html",
714 FINAL_STATUS_USED, 0);
715 NavigateToDestURL();
716 }
717
713 // Checks that the visibility API works when opening a page in a new hidden 718 // Checks that the visibility API works when opening a page in a new hidden
714 // tab. 719 // tab.
715 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibilityBackgroundTab) { 720 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibilityBackgroundTab) {
716 PrerenderTestURL("files/prerender/prerender_visibility_hidden.html", 721 PrerenderTestURL("files/prerender/prerender_visibility_hidden.html",
717 FINAL_STATUS_USED, 722 FINAL_STATUS_USED,
718 1); 723 1);
719 NavigateToDestURLWithDisposition(NEW_BACKGROUND_TAB); 724 NavigateToDestURLWithDisposition(NEW_BACKGROUND_TAB);
720 } 725 }
721 726
727 // Checks that the visibility API works when opening a page in a new hidden
728 // tab, which is switched to before it stops loading.
729 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
730 PrerenderVisibilityBackgroundTabQuickSwitch) {
731 PrerenderTestURL("files/prerender/prerender_visibility_hidden_quick.html",
732 FINAL_STATUS_USED, 0);
733 NavigateToDestURLWithDisposition(NEW_BACKGROUND_TAB);
734 }
735
722 // Checks that the visibility API works when opening a page in a new foreground 736 // Checks that the visibility API works when opening a page in a new foreground
723 // tab. 737 // tab.
724 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibilityForegroundTab) { 738 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibilityForegroundTab) {
725 PrerenderTestURL("files/prerender/prerender_visibility.html", 739 PrerenderTestURL("files/prerender/prerender_visibility.html",
726 FINAL_STATUS_USED, 740 FINAL_STATUS_USED,
727 1); 741 1);
728 NavigateToDestURLWithDisposition(NEW_FOREGROUND_TAB); 742 NavigateToDestURLWithDisposition(NEW_FOREGROUND_TAB);
729 } 743 }
730 744
745 // Checks that the visibility API works when the prerender is quickly opened
746 // in a new tab foreground before it stops loading.
747 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
748 PrerenderVisibilityForegroundTabQuickSwitch) {
749 PrerenderTestURL("files/prerender/prerender_visibility_quick.html",
750 FINAL_STATUS_USED, 0);
751 NavigateToDestURL();
752 }
753
731 // Checks that the prerendering of a page is canceled correctly when a 754 // Checks that the prerendering of a page is canceled correctly when a
732 // Javascript alert is called. 755 // Javascript alert is called.
733 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) { 756 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) {
734 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html", 757 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
735 FINAL_STATUS_JAVASCRIPT_ALERT, 758 FINAL_STATUS_JAVASCRIPT_ALERT,
736 1); 759 1);
737 } 760 }
738 761
739 // Checks that the prerendering of a page is canceled correctly when a 762 // Checks that the prerendering of a page is canceled correctly when a
740 // Javascript alert is called. 763 // Javascript alert is called.
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after
1675 bool original_prerender_page = false; 1698 bool original_prerender_page = false;
1676 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( 1699 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
1677 browser()->GetSelectedTabContents()->render_view_host(), L"", 1700 browser()->GetSelectedTabContents()->render_view_host(), L"",
1678 L"window.domAutomationController.send(IsOriginalPrerenderPage())", 1701 L"window.domAutomationController.send(IsOriginalPrerenderPage())",
1679 &original_prerender_page)); 1702 &original_prerender_page));
1680 EXPECT_TRUE(original_prerender_page); 1703 EXPECT_TRUE(original_prerender_page);
1681 } 1704 }
1682 } 1705 }
1683 1706
1684 } // namespace prerender 1707 } // namespace prerender
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/prerender/prerender_contents.h » ('j') | chrome/browser/prerender/prerender_contents.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698