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

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

Issue 6625066: Add pending preloads indexed by routing id. Start preloading once we navigate. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 9 years, 9 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
« no previous file with comments | « no previous file | chrome/browser/prerender/prerender_contents.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/command_line.h" 5 #include "base/command_line.h"
6 #include "base/path_service.h" 6 #include "base/path_service.h"
7 #include "chrome/browser/prerender/prerender_contents.h" 7 #include "chrome/browser/prerender/prerender_contents.h"
8 #include "chrome/browser/prerender/prerender_manager.h" 8 #include "chrome/browser/prerender/prerender_manager.h"
9 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/ui/browser.h" 10 #include "chrome/browser/ui/browser.h"
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 }; 78 };
79 79
80 // PrerenderManager that uses TestPrerenderContents. 80 // PrerenderManager that uses TestPrerenderContents.
81 class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory { 81 class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory {
82 public: 82 public:
83 explicit WaitForLoadPrerenderContentsFactory( 83 explicit WaitForLoadPrerenderContentsFactory(
84 FinalStatus expected_final_status) 84 FinalStatus expected_final_status)
85 : expected_final_status_(expected_final_status) { 85 : expected_final_status_(expected_final_status) {
86 } 86 }
87 87
88 void set_expected_final_status(FinalStatus expected_final_status) {
89 expected_final_status_ = expected_final_status;
90 }
91
92 void set_expected_final_status_for_url(const GURL& url,
93 FinalStatus expected_final_status) {
94 DCHECK(expected_final_status_map_.find(url) ==
95 expected_final_status_map_.end());
96 expected_final_status_map_[url] = expected_final_status;
97 }
98
88 virtual PrerenderContents* CreatePrerenderContents( 99 virtual PrerenderContents* CreatePrerenderContents(
89 PrerenderManager* prerender_manager, Profile* profile, const GURL& url, 100 PrerenderManager* prerender_manager, Profile* profile, const GURL& url,
90 const std::vector<GURL>& alias_urls, const GURL& referrer) { 101 const std::vector<GURL>& alias_urls, const GURL& referrer) {
102 FinalStatus expected_final_status = expected_final_status_;
103 std::map<GURL, FinalStatus>::iterator it =
104 expected_final_status_map_.find(url);
105 if (it != expected_final_status_map_.end()) {
106 expected_final_status = it->second;
107 expected_final_status_map_.erase(it);
108 }
91 return new TestPrerenderContents(prerender_manager, profile, url, 109 return new TestPrerenderContents(prerender_manager, profile, url,
92 alias_urls, referrer, 110 alias_urls, referrer,
93 expected_final_status_); 111 expected_final_status);
94 } 112 }
95 113
96 private: 114 private:
97 FinalStatus expected_final_status_; 115 FinalStatus expected_final_status_;
116 std::map<GURL, FinalStatus> expected_final_status_map_;
98 }; 117 };
99 118
100 } // namespace 119 } // namespace
101 120
102 class PrerenderBrowserTest : public InProcessBrowserTest { 121 class PrerenderBrowserTest : public InProcessBrowserTest {
103 public: 122 public:
104 PrerenderBrowserTest() : use_https_src_server_(false), 123 PrerenderBrowserTest()
105 on_iteration_succeeded_(true) { 124 : prc_factory_(NULL),
125 use_https_src_server_(false),
126 on_iteration_succeeded_(true) {
106 EnableDOMAutomation(); 127 EnableDOMAutomation();
107 } 128 }
108 129
109 virtual void SetUpCommandLine(CommandLine* command_line) { 130 virtual void SetUpCommandLine(CommandLine* command_line) {
110 command_line->AppendSwitchASCII(switches::kPrerender, 131 command_line->AppendSwitchASCII(switches::kPrerender,
111 switches::kPrerenderSwitchValueEnabled); 132 switches::kPrerenderSwitchValueEnabled);
112 #if defined(OS_MACOSX) 133 #if defined(OS_MACOSX)
113 // The plugins directory isn't read by default on the Mac, so it needs to be 134 // The plugins directory isn't read by default on the Mac, so it needs to be
114 // explicitly registered. 135 // explicitly registered.
115 FilePath app_dir; 136 FilePath app_dir;
116 PathService::Get(chrome::DIR_APP, &app_dir); 137 PathService::Get(chrome::DIR_APP, &app_dir);
117 command_line->AppendSwitchPath( 138 command_line->AppendSwitchPath(
118 switches::kExtraPluginDir, 139 switches::kExtraPluginDir,
119 app_dir.Append(FILE_PATH_LITERAL("plugins"))); 140 app_dir.Append(FILE_PATH_LITERAL("plugins")));
120 #endif 141 #endif
121 } 142 }
122 143
123 void PrerenderTestURL(const std::string& html_file, 144 void PrerenderTestURL(const std::string& html_file,
124 FinalStatus expected_final_status, 145 FinalStatus expected_final_status,
125 int total_navigations) { 146 int total_navigations) {
126 ASSERT_TRUE(test_server()->Start()); 147 ASSERT_TRUE(test_server()->Start());
127 std::string dest_path = "files/prerender/"; 148 dest_url_ = UrlForHtmlFile(html_file);
128 dest_path.append(html_file);
129 dest_url_ = test_server()->GetURL(dest_path);
130 149
131 std::vector<net::TestServer::StringPair> replacement_text; 150 std::vector<net::TestServer::StringPair> replacement_text;
132 replacement_text.push_back( 151 replacement_text.push_back(
133 make_pair("REPLACE_WITH_PREFETCH_URL", dest_url_.spec())); 152 make_pair("REPLACE_WITH_PREFETCH_URL", dest_url_.spec()));
134 std::string replacement_path; 153 std::string replacement_path;
135 ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements( 154 ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
136 "files/prerender/prerender_loader.html", 155 "files/prerender/prerender_loader.html",
137 replacement_text, 156 replacement_text,
138 &replacement_path)); 157 &replacement_path));
139 158
140 net::TestServer* src_server = test_server(); 159 net::TestServer* src_server = test_server();
141 scoped_ptr<net::TestServer> https_src_server; 160 scoped_ptr<net::TestServer> https_src_server;
142 if (use_https_src_server_) { 161 if (use_https_src_server_) {
143 https_src_server.reset( 162 https_src_server.reset(
144 new net::TestServer(net::TestServer::TYPE_HTTPS, 163 new net::TestServer(net::TestServer::TYPE_HTTPS,
145 FilePath(FILE_PATH_LITERAL("chrome/test/data")))); 164 FilePath(FILE_PATH_LITERAL("chrome/test/data"))));
146 ASSERT_TRUE(https_src_server->Start()); 165 ASSERT_TRUE(https_src_server->Start());
147 src_server = https_src_server.get(); 166 src_server = https_src_server.get();
148 } 167 }
149 GURL src_url = src_server->GetURL(replacement_path); 168 GURL src_url = src_server->GetURL(replacement_path);
150 169
151 Profile* profile = browser()->GetSelectedTabContents()->profile();
152 PrerenderManager* prerender_manager = profile->GetPrerenderManager();
153 ASSERT_TRUE(prerender_manager);
154
155 // This is needed to exit the event loop once the prerendered page has 170 // This is needed to exit the event loop once the prerendered page has
156 // stopped loading or was cancelled. 171 // stopped loading or was cancelled.
157 prerender_manager->SetPrerenderContentsFactory( 172 ASSERT_TRUE(prerender_manager());
158 new WaitForLoadPrerenderContentsFactory(expected_final_status)); 173 ASSERT_TRUE(prc_factory_ == NULL);
174 prc_factory_ =
175 new WaitForLoadPrerenderContentsFactory(expected_final_status);
176 prerender_manager()->SetPrerenderContentsFactory(prc_factory_);
159 177
160 // ui_test_utils::NavigateToURL uses its own observer and message loop. 178 // ui_test_utils::NavigateToURL uses its own observer and message loop.
161 // Since the test needs to wait until the prerendered page has stopped 179 // Since the test needs to wait until the prerendered page has stopped
162 // loading, rathather than the page directly navigated to, need to 180 // loading, rathather than the page directly navigated to, need to
163 // handle browser navigation directly. 181 // handle browser navigation directly.
164 browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED); 182 browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
165 183
166 TestPrerenderContents* prerender_contents = NULL; 184 TestPrerenderContents* prerender_contents = NULL;
167 int navigations = 0; 185 int navigations = 0;
168 while (true) { 186 while (true) {
169 ui_test_utils::RunMessageLoop(); 187 ui_test_utils::RunMessageLoop();
170 ++navigations; 188 ++navigations;
171 EXPECT_TRUE(on_iteration_succeeded_); 189 EXPECT_TRUE(on_iteration_succeeded_);
172 190
173 prerender_contents = 191 prerender_contents =
174 static_cast<TestPrerenderContents*>( 192 static_cast<TestPrerenderContents*>(
175 prerender_manager->FindEntry(dest_url_)); 193 prerender_manager()->FindEntry(dest_url_));
176 if (prerender_contents == NULL || 194 if (prerender_contents == NULL ||
177 !prerender_contents->did_finish_loading() || 195 !prerender_contents->did_finish_loading() ||
178 navigations >= total_navigations) { 196 navigations >= total_navigations) {
179 EXPECT_EQ(navigations, total_navigations); 197 EXPECT_EQ(navigations, total_navigations);
180 break; 198 break;
181 } 199 }
182 prerender_contents->set_did_finish_loading(false); 200 prerender_contents->set_did_finish_loading(false);
183 MessageLoopForUI::current()->PostTask( 201 MessageLoopForUI::current()->PostTask(
184 FROM_HERE, 202 FROM_HERE,
185 NewRunnableMethod(this, 203 NewRunnableMethod(this,
(...skipping 19 matching lines...) Expand all
205 // In the failure case, we should have removed dest_url_ from the 223 // In the failure case, we should have removed dest_url_ from the
206 // prerender_manager. 224 // prerender_manager.
207 EXPECT_TRUE(prerender_contents == NULL); 225 EXPECT_TRUE(prerender_contents == NULL);
208 break; 226 break;
209 } 227 }
210 } 228 }
211 229
212 void NavigateToDestURL() const { 230 void NavigateToDestURL() const {
213 ui_test_utils::NavigateToURL(browser(), dest_url_); 231 ui_test_utils::NavigateToURL(browser(), dest_url_);
214 232
215 Profile* profile = browser()->GetSelectedTabContents()->profile();
216 PrerenderManager* prerender_manager = profile->GetPrerenderManager();
217 ASSERT_TRUE(prerender_manager);
218
219 // Make sure the PrerenderContents found earlier was used or removed 233 // Make sure the PrerenderContents found earlier was used or removed
220 EXPECT_TRUE(prerender_manager->FindEntry(dest_url_) == NULL); 234 EXPECT_TRUE(prerender_manager()->FindEntry(dest_url_) == NULL);
221 235
222 // Check if page behaved as expected when actually displayed. 236 // Check if page behaved as expected when actually displayed.
223 bool display_test_result = false; 237 bool display_test_result = false;
224 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( 238 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
225 browser()->GetSelectedTabContents()->render_view_host(), L"", 239 browser()->GetSelectedTabContents()->render_view_host(), L"",
226 L"window.domAutomationController.send(DidDisplayPass())", 240 L"window.domAutomationController.send(DidDisplayPass())",
227 &display_test_result)); 241 &display_test_result));
228 EXPECT_TRUE(display_test_result); 242 EXPECT_TRUE(display_test_result);
229 } 243 }
230 244
245 bool UrlIsInPrerenderManager(const std::string& html_file) {
246 GURL dest_url = UrlForHtmlFile(html_file);
247
248 return (prerender_manager()->FindEntry(dest_url) != NULL);
249 }
250
251 bool UrlIsPendingInPrerenderManager(const std::string& html_file) {
252 GURL dest_url = UrlForHtmlFile(html_file);
253
254 return (prerender_manager()->FindPendingEntry(dest_url) != NULL);
255 }
256
231 void set_use_https_src(bool use_https_src_server) { 257 void set_use_https_src(bool use_https_src_server) {
232 use_https_src_server_ = use_https_src_server; 258 use_https_src_server_ = use_https_src_server;
233 } 259 }
234 260
261 void SetExpectedFinalStatus(FinalStatus expected_final_status) {
262 DCHECK(prerender_manager()->prerender_contents_factory_.get() ==
263 prc_factory_);
264 prc_factory_->set_expected_final_status(expected_final_status);
265 }
266
267 void SetExpectedFinalStatusForUrl(const std::string& html_file,
268 FinalStatus expected_final_status) {
269 GURL url = UrlForHtmlFile(html_file);
270 DCHECK(prerender_manager()->prerender_contents_factory_.get() ==
271 prc_factory_);
272 prc_factory_->set_expected_final_status_for_url(url, expected_final_status);
273 }
274
275 void set_rate_limit_enabled(bool enabled) {
276 prerender_manager()->rate_limit_enabled_ = enabled;
277 }
278
235 private: 279 private:
280 PrerenderManager* prerender_manager() const {
281 Profile* profile = browser()->GetSelectedTabContents()->profile();
282 PrerenderManager* prerender_manager = profile->GetPrerenderManager();
283 return prerender_manager;
284 }
285
286 // Non-const as test_server()->GetURL() is not const
287 GURL UrlForHtmlFile(const std::string& html_file) {
288 std::string dest_path = "files/prerender/";
289 dest_path.append(html_file);
290 return test_server()->GetURL(dest_path);
291 }
292
236 void CallOnIteration(RenderViewHost* rvh) { 293 void CallOnIteration(RenderViewHost* rvh) {
237 on_iteration_succeeded_ = ui_test_utils::ExecuteJavaScript( 294 on_iteration_succeeded_ = ui_test_utils::ExecuteJavaScript(
238 rvh, 295 rvh,
239 L"", 296 L"",
240 L"if (typeof(OnIteration) != 'undefined') {OnIteration();}"); 297 L"if (typeof(OnIteration) != 'undefined') {OnIteration();}");
241 } 298 }
242 299
300 WaitForLoadPrerenderContentsFactory* prc_factory_;
243 GURL dest_url_; 301 GURL dest_url_;
244 bool use_https_src_server_; 302 bool use_https_src_server_;
245 bool on_iteration_succeeded_; 303 bool on_iteration_succeeded_;
246 }; 304 };
247 305
248 // Checks that a page is correctly prerendered in the case of a 306 // Checks that a page is correctly prerendered in the case of a
249 // <link rel=prefetch> tag and then loaded into a tab in response to a 307 // <link rel=prefetch> tag and then loaded into a tab in response to a
250 // navigation. 308 // navigation.
251 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) { 309 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) {
252 PrerenderTestURL("prerender_page.html", 310 PrerenderTestURL("prerender_page.html",
253 FINAL_STATUS_USED, 1); 311 FINAL_STATUS_USED, 1);
254 NavigateToDestURL(); 312 NavigateToDestURL();
255 } 313 }
256 314
257 // Checks that the prerendering of a page is canceled correctly when a 315 // Checks that the prerendering of a page is canceled correctly when a
258 // Javascript alert is called. 316 // Javascript alert is called.
259 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) { 317 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) {
260 PrerenderTestURL( 318 PrerenderTestURL("prerender_alert_before_onload.html",
261 "prerender_alert_before_onload.html", 319 FINAL_STATUS_JAVASCRIPT_ALERT, 1);
262 FINAL_STATUS_JAVASCRIPT_ALERT, 1);
263 } 320 }
264 321
265 // Checks that the prerendering of a page is canceled correctly when a 322 // Checks that the prerendering of a page is canceled correctly when a
266 // Javascript alert is called. 323 // Javascript alert is called.
267 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) { 324 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) {
268 PrerenderTestURL( 325 PrerenderTestURL("prerender_alert_after_onload.html",
269 "prerender_alert_after_onload.html", 326 FINAL_STATUS_JAVASCRIPT_ALERT, 1);
270 FINAL_STATUS_JAVASCRIPT_ALERT, 1);
271 } 327 }
272 328
273 // Checks that plugins are not loaded while a page is being preloaded, but 329 // Checks that plugins are not loaded while a page is being preloaded, but
274 // are loaded when the page is displayed. 330 // are loaded when the page is displayed.
275 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDelayLoadPlugin) { 331 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDelayLoadPlugin) {
276 PrerenderTestURL("plugin_delay_load.html", 332 PrerenderTestURL("plugin_delay_load.html",
277 FINAL_STATUS_USED, 1); 333 FINAL_STATUS_USED, 1);
278 NavigateToDestURL(); 334 NavigateToDestURL();
279 } 335 }
280 336
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 } 420 }
365 421
366 // Checks that renderers using excessive memory will be terminated. 422 // Checks that renderers using excessive memory will be terminated.
367 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExcessiveMemory) { 423 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExcessiveMemory) {
368 PrerenderTestURL("prerender_excessive_memory.html", 424 PrerenderTestURL("prerender_excessive_memory.html",
369 FINAL_STATUS_MEMORY_LIMIT_EXCEEDED, 1); 425 FINAL_STATUS_MEMORY_LIMIT_EXCEEDED, 1);
370 } 426 }
371 427
372 // Checks that we don't prerender in an infinite loop. 428 // Checks that we don't prerender in an infinite loop.
373 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoop) { 429 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoop) {
374 PrerenderTestURL("prerender_infinite_a.html", FINAL_STATUS_USED, 1); 430 const char* const kHtmlFileA = "prerender_infinite_a.html";
431 const char* const kHtmlFileB = "prerender_infinite_b.html";
432
433 set_rate_limit_enabled(false);
434
435 PrerenderTestURL(kHtmlFileA, FINAL_STATUS_USED, 1);
436
437 // Next url should be in pending list but not an active entry.
438 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
439 EXPECT_TRUE(UrlIsPendingInPrerenderManager(kHtmlFileB));
440
441 // We are not going to navigate back to kHtmlFileA but we will start the
442 // preload so we need to set the final status to expect here before
443 // navigating.
444 SetExpectedFinalStatus(FINAL_STATUS_APP_TERMINATING);
445
375 NavigateToDestURL(); 446 NavigateToDestURL();
447
448 // Make sure the PrerenderContents for the next url is now in the manager
449 // and not pending.
450 EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB));
451 EXPECT_FALSE(UrlIsPendingInPrerenderManager(kHtmlFileB));
452
453 set_rate_limit_enabled(true);
454 }
455
456 // Checks that we don't prerender in an infinite loop and multiple links are
457 // handled correctly.
458 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoopMultiple) {
459 const char* const kHtmlFileA = "prerender_infinite_a_multiple.html";
460 const char* const kHtmlFileB = "prerender_infinite_b_multiple.html";
461 const char* const kHtmlFileC = "prerender_infinite_c_multiple.html";
462
463 set_rate_limit_enabled(false);
464
465 PrerenderTestURL(kHtmlFileA, FINAL_STATUS_USED, 1);
466
467 // Next url should be in pending list but not an active entry.
468 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
469 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC));
470 EXPECT_TRUE(UrlIsPendingInPrerenderManager(kHtmlFileB));
471 EXPECT_TRUE(UrlIsPendingInPrerenderManager(kHtmlFileC));
472
473 // We are not going to navigate back to kHtmlFileA but we will start the
474 // preload so we need to set the final status to expect here before
475 // navigating.
476 SetExpectedFinalStatusForUrl(kHtmlFileB, FINAL_STATUS_EVICTED);
477 SetExpectedFinalStatusForUrl(kHtmlFileC, FINAL_STATUS_APP_TERMINATING);
478
479 NavigateToDestURL();
480
481 // Make sure the PrerenderContents for the next urls are now in the manager
482 // and not pending. url_c was the last seen so should be the active
483 // entry.
484 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
485 EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileC));
486 EXPECT_FALSE(UrlIsPendingInPrerenderManager(kHtmlFileB));
487 EXPECT_FALSE(UrlIsPendingInPrerenderManager(kHtmlFileC));
488
489 set_rate_limit_enabled(true);
376 } 490 }
377 491
378 } // namespace prerender 492 } // namespace prerender
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/prerender/prerender_contents.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698