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

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: Added browser test for multiple referenced prerenders and responded to comments. 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
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 expected_final_status_map_[url] = expected_final_status;
cbentzel 2011/03/15 18:42:24 Should this DCHECK that it doesn't already exist?
dominich 2011/03/15 20:41:14 Done.
95 }
96
88 virtual PrerenderContents* CreatePrerenderContents( 97 virtual PrerenderContents* CreatePrerenderContents(
89 PrerenderManager* prerender_manager, Profile* profile, const GURL& url, 98 PrerenderManager* prerender_manager, Profile* profile, const GURL& url,
90 const std::vector<GURL>& alias_urls, const GURL& referrer) { 99 const std::vector<GURL>& alias_urls, const GURL& referrer) {
100 FinalStatus expected_final_status = expected_final_status_;
101 std::map<GURL, FinalStatus>::iterator it =
102 expected_final_status_map_.find(url);
103 if (it != expected_final_status_map_.end())
cbentzel 2011/03/15 18:42:24 Does this need to be erased if found, or can it st
dominich 2011/03/15 20:41:14 Done.
104 expected_final_status = it->second;
91 return new TestPrerenderContents(prerender_manager, profile, url, 105 return new TestPrerenderContents(prerender_manager, profile, url,
92 alias_urls, referrer, 106 alias_urls, referrer,
93 expected_final_status_); 107 expected_final_status);
94 } 108 }
95 109
96 private: 110 private:
97 FinalStatus expected_final_status_; 111 FinalStatus expected_final_status_;
112 std::map<GURL, FinalStatus> expected_final_status_map_;
98 }; 113 };
99 114
100 } // namespace 115 } // namespace
101 116
102 class PrerenderBrowserTest : public InProcessBrowserTest { 117 class PrerenderBrowserTest : public InProcessBrowserTest {
103 public: 118 public:
104 PrerenderBrowserTest() : use_https_src_server_(false) { 119 PrerenderBrowserTest() : use_https_src_server_(false) {
105 EnableDOMAutomation(); 120 EnableDOMAutomation();
106 } 121 }
107 122
108 virtual void SetUpCommandLine(CommandLine* command_line) { 123 virtual void SetUpCommandLine(CommandLine* command_line) {
109 command_line->AppendSwitchASCII(switches::kPrerender, 124 command_line->AppendSwitchASCII(switches::kPrerender,
110 switches::kPrerenderSwitchValueEnabled); 125 switches::kPrerenderSwitchValueEnabled);
111 #if defined(OS_MACOSX) 126 #if defined(OS_MACOSX)
112 // The plugins directory isn't read by default on the Mac, so it needs to be 127 // The plugins directory isn't read by default on the Mac, so it needs to be
113 // explicitly registered. 128 // explicitly registered.
114 FilePath app_dir; 129 FilePath app_dir;
115 PathService::Get(chrome::DIR_APP, &app_dir); 130 PathService::Get(chrome::DIR_APP, &app_dir);
116 command_line->AppendSwitchPath( 131 command_line->AppendSwitchPath(
117 switches::kExtraPluginDir, 132 switches::kExtraPluginDir,
118 app_dir.Append(FILE_PATH_LITERAL("plugins"))); 133 app_dir.Append(FILE_PATH_LITERAL("plugins")));
119 #endif 134 #endif
120 } 135 }
121 136
122 void PrerenderTestURL(const std::string& html_file, 137 void PrerenderTestURL(const std::string& html_file,
123 FinalStatus expected_final_status, 138 FinalStatus expected_final_status,
124 int total_navigations) { 139 int total_navigations) {
125 ASSERT_TRUE(test_server()->Start()); 140 ASSERT_TRUE(test_server()->Start());
126 std::string dest_path = "files/prerender/"; 141 dest_url_ = UrlForHtmlFile(html_file);
127 dest_path.append(html_file);
128 dest_url_ = test_server()->GetURL(dest_path);
129 142
130 std::vector<net::TestServer::StringPair> replacement_text; 143 std::vector<net::TestServer::StringPair> replacement_text;
131 replacement_text.push_back( 144 replacement_text.push_back(
132 make_pair("REPLACE_WITH_PREFETCH_URL", dest_url_.spec())); 145 make_pair("REPLACE_WITH_PREFETCH_URL", dest_url_.spec()));
133 std::string replacement_path; 146 std::string replacement_path;
134 ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements( 147 ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
135 "files/prerender/prerender_loader.html", 148 "files/prerender/prerender_loader.html",
136 replacement_text, 149 replacement_text,
137 &replacement_path)); 150 &replacement_path));
138 151
139 net::TestServer* src_server = test_server(); 152 net::TestServer* src_server = test_server();
140 scoped_ptr<net::TestServer> https_src_server; 153 scoped_ptr<net::TestServer> https_src_server;
141 if (use_https_src_server_) { 154 if (use_https_src_server_) {
142 https_src_server.reset( 155 https_src_server.reset(
143 new net::TestServer(net::TestServer::TYPE_HTTPS, 156 new net::TestServer(net::TestServer::TYPE_HTTPS,
144 FilePath(FILE_PATH_LITERAL("chrome/test/data")))); 157 FilePath(FILE_PATH_LITERAL("chrome/test/data"))));
145 ASSERT_TRUE(https_src_server->Start()); 158 ASSERT_TRUE(https_src_server->Start());
146 src_server = https_src_server.get(); 159 src_server = https_src_server.get();
147 } 160 }
148 GURL src_url = src_server->GetURL(replacement_path); 161 GURL src_url = src_server->GetURL(replacement_path);
149 162
150 Profile* profile = browser()->GetSelectedTabContents()->profile();
151 PrerenderManager* prerender_manager = profile->GetPrerenderManager();
152 ASSERT_TRUE(prerender_manager);
153
154 // This is needed to exit the event loop once the prerendered page has 163 // This is needed to exit the event loop once the prerendered page has
155 // stopped loading or was cancelled. 164 // stopped loading or was cancelled.
156 prerender_manager->SetPrerenderContentsFactory( 165 ASSERT_TRUE(prerender_manager());
166 prerender_manager()->SetPrerenderContentsFactory(
157 new WaitForLoadPrerenderContentsFactory(expected_final_status)); 167 new WaitForLoadPrerenderContentsFactory(expected_final_status));
158 168
159 // ui_test_utils::NavigateToURL uses its own observer and message loop. 169 // ui_test_utils::NavigateToURL uses its own observer and message loop.
160 // Since the test needs to wait until the prerendered page has stopped 170 // Since the test needs to wait until the prerendered page has stopped
161 // loading, rathather than the page directly navigated to, need to 171 // loading, rathather than the page directly navigated to, need to
162 // handle browser navigation directly. 172 // handle browser navigation directly.
163 browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED); 173 browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
164 174
165 TestPrerenderContents* prerender_contents = NULL; 175 TestPrerenderContents* prerender_contents = NULL;
166 int navigations = 0; 176 int navigations = 0;
167 while (true) { 177 while (true) {
168 ui_test_utils::RunMessageLoop(); 178 ui_test_utils::RunMessageLoop();
169 ++navigations; 179 ++navigations;
170 180
171 prerender_contents = 181 prerender_contents =
172 static_cast<TestPrerenderContents*>( 182 static_cast<TestPrerenderContents*>(
173 prerender_manager->FindEntry(dest_url_)); 183 prerender_manager()->FindEntry(dest_url_));
174 if (prerender_contents == NULL || 184 if (prerender_contents == NULL ||
175 !prerender_contents->did_finish_loading() || 185 !prerender_contents->did_finish_loading() ||
176 navigations >= total_navigations) { 186 navigations >= total_navigations) {
177 EXPECT_EQ(navigations, total_navigations); 187 EXPECT_EQ(navigations, total_navigations);
178 break; 188 break;
179 } 189 }
180 prerender_contents->set_did_finish_loading(false); 190 prerender_contents->set_did_finish_loading(false);
181 } 191 }
182 192
183 switch (expected_final_status) { 193 switch (expected_final_status) {
(...skipping 14 matching lines...) Expand all
198 // In the failure case, we should have removed dest_url_ from the 208 // In the failure case, we should have removed dest_url_ from the
199 // prerender_manager. 209 // prerender_manager.
200 EXPECT_TRUE(prerender_contents == NULL); 210 EXPECT_TRUE(prerender_contents == NULL);
201 break; 211 break;
202 } 212 }
203 } 213 }
204 214
205 void NavigateToDestURL() const { 215 void NavigateToDestURL() const {
206 ui_test_utils::NavigateToURL(browser(), dest_url_); 216 ui_test_utils::NavigateToURL(browser(), dest_url_);
207 217
208 Profile* profile = browser()->GetSelectedTabContents()->profile();
209 PrerenderManager* prerender_manager = profile->GetPrerenderManager();
210 ASSERT_TRUE(prerender_manager);
211
212 // Make sure the PrerenderContents found earlier was used or removed 218 // Make sure the PrerenderContents found earlier was used or removed
213 EXPECT_TRUE(prerender_manager->FindEntry(dest_url_) == NULL); 219 EXPECT_TRUE(prerender_manager()->FindEntry(dest_url_) == NULL);
214 220
215 // Check if page behaved as expected when actually displayed. 221 // Check if page behaved as expected when actually displayed.
216 bool display_test_result = false; 222 bool display_test_result = false;
217 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( 223 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
218 browser()->GetSelectedTabContents()->render_view_host(), L"", 224 browser()->GetSelectedTabContents()->render_view_host(), L"",
219 L"window.domAutomationController.send(DidDisplayPass())", 225 L"window.domAutomationController.send(DidDisplayPass())",
220 &display_test_result)); 226 &display_test_result));
221 EXPECT_TRUE(display_test_result); 227 EXPECT_TRUE(display_test_result);
222 } 228 }
223 229
230 bool UrlIsInPrerenderManager(const std::string& url) {
cbentzel 2011/03/15 18:42:24 const also, the name is misleading - the paramete
231 GURL dest_url = UrlForHtmlFile(url);
232
233 return (prerender_manager()->FindEntry(dest_url) != NULL);
234 }
235
236 bool UrlIsPendingInPrerenderManager(const std::string& url) {
237 GURL dest_url = UrlForHtmlFile(url);
238
239 for (PrerenderManager::PendingPrerenderList::iterator map_it =
cbentzel 2011/03/15 18:42:24 Add a FindPendingEntry() to PrerenderManager? Woul
dominich 2011/03/15 20:41:14 Done.
240 prerender_manager()->pending_prerender_list_.begin();
241 map_it != prerender_manager()->pending_prerender_list_.end();
242 ++map_it) {
243 for (std::vector<PrerenderManager::PendingContentsData>::iterator
244 content_it = map_it->second.begin();
245 content_it != map_it->second.end(); ++content_it) {
246 if (content_it->url_ == dest_url)
247 return true;
248 }
249 }
250
251 return false;
252 }
253
254 GURL UrlForHtmlFile(const std::string& html_file) {
cbentzel 2011/03/15 18:42:24 const, I think GetURL is const.
dominich 2011/03/15 20:41:14 Sadly not.
255 std::string dest_path = "files/prerender/";
256 dest_path.append(html_file);
257 return test_server()->GetURL(dest_path);
258 }
259
260 PrerenderManager* prerender_manager() const {
261 Profile* profile = browser()->GetSelectedTabContents()->profile();
262 PrerenderManager* prerender_manager = profile->GetPrerenderManager();
263 return prerender_manager;
264 }
265
224 void set_use_https_src(bool use_https_src_server) { 266 void set_use_https_src(bool use_https_src_server) {
225 use_https_src_server_ = use_https_src_server; 267 use_https_src_server_ = use_https_src_server;
226 } 268 }
227 269
270 void SetExpectedFinalStatus(FinalStatus expected_final_status) {
271 WaitForLoadPrerenderContentsFactory* prc_factory =
cbentzel 2011/03/15 18:42:24 I would just set a pointer to prc_factory in Prere
dominich 2011/03/15 20:41:14 Done.
272 static_cast<WaitForLoadPrerenderContentsFactory*>(
273 prerender_manager()->prerender_contents_factory_.get());
274 prc_factory->set_expected_final_status(expected_final_status);
275 }
276
277 void SetExpectedFinalStatusForUrl(const GURL& url,
cbentzel 2011/03/15 18:42:24 I would change this to take a const std::string& l
dominich 2011/03/15 20:41:14 Done.
278 FinalStatus expected_final_status) {
279 WaitForLoadPrerenderContentsFactory* prc_factory =
280 static_cast<WaitForLoadPrerenderContentsFactory*>(
281 prerender_manager()->prerender_contents_factory_.get());
282 prc_factory->set_expected_final_status_for_url(url, expected_final_status);
283 }
284
228 private: 285 private:
229 GURL dest_url_; 286 GURL dest_url_;
230 bool use_https_src_server_; 287 bool use_https_src_server_;
231 }; 288 };
232 289
233 // Checks that a page is correctly prerendered in the case of a 290 // Checks that a page is correctly prerendered in the case of a
234 // <link rel=prefetch> tag and then loaded into a tab in response to a 291 // <link rel=prefetch> tag and then loaded into a tab in response to a
235 // navigation. 292 // navigation.
236 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) { 293 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) {
237 PrerenderTestURL("prerender_page.html", 294 PrerenderTestURL("prerender_page.html",
238 FINAL_STATUS_USED, 1); 295 FINAL_STATUS_USED, 1);
239 NavigateToDestURL(); 296 NavigateToDestURL();
240 } 297 }
241 298
242 // Checks that the prerendering of a page is canceled correctly when a 299 // Checks that the prerendering of a page is canceled correctly when a
243 // Javascript alert is called. 300 // Javascript alert is called.
244 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) { 301 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) {
245 PrerenderTestURL( 302 PrerenderTestURL("prerender_alert_before_onload.html",
246 "prerender_alert_before_onload.html", 303 FINAL_STATUS_JAVASCRIPT_ALERT, 1);
247 FINAL_STATUS_JAVASCRIPT_ALERT, 1);
248 } 304 }
249 305
250 // Checks that the prerendering of a page is canceled correctly when a 306 // Checks that the prerendering of a page is canceled correctly when a
251 // Javascript alert is called. 307 // Javascript alert is called.
252 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) { 308 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) {
253 PrerenderTestURL( 309 PrerenderTestURL("prerender_alert_after_onload.html",
254 "prerender_alert_after_onload.html", 310 FINAL_STATUS_JAVASCRIPT_ALERT, 1);
255 FINAL_STATUS_JAVASCRIPT_ALERT, 1);
256 } 311 }
257 312
258 // Checks that plugins are not loaded while a page is being preloaded, but 313 // Checks that plugins are not loaded while a page is being preloaded, but
259 // are loaded when the page is displayed. 314 // are loaded when the page is displayed.
260 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDelayLoadPlugin) { 315 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDelayLoadPlugin) {
261 PrerenderTestURL("plugin_delay_load.html", 316 PrerenderTestURL("plugin_delay_load.html",
262 FINAL_STATUS_USED, 1); 317 FINAL_STATUS_USED, 1);
263 NavigateToDestURL(); 318 NavigateToDestURL();
264 } 319 }
265 320
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 FINAL_STATUS_HTTPS, 401 FINAL_STATUS_HTTPS,
347 2); 402 2);
348 } 403 }
349 404
350 // Checks that renderers using excessive memory will be terminated. 405 // Checks that renderers using excessive memory will be terminated.
351 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExcessiveMemory) { 406 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExcessiveMemory) {
352 PrerenderTestURL("prerender_excessive_memory.html", 407 PrerenderTestURL("prerender_excessive_memory.html",
353 FINAL_STATUS_MEMORY_LIMIT_EXCEEDED, 1); 408 FINAL_STATUS_MEMORY_LIMIT_EXCEEDED, 1);
354 } 409 }
355 410
411 // Checks that we don't prerender in an infinite loop.
412 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoop) {
413 const char* url_a = "prerender_infinite_a.html";
cbentzel 2011/03/15 18:42:24 Nit: const char* const kPathA
dominich 2011/03/15 20:41:14 Done.
414 const char* url_b = "prerender_infinite_b.html";
415
416 PrerenderTestURL(url_a, FINAL_STATUS_USED, 1);
417
418 // Next url should be in pending list but not an active entry.
419 EXPECT_FALSE(UrlIsInPrerenderManager(url_b));
420 EXPECT_TRUE(UrlIsPendingInPrerenderManager(url_b));
421
422 // We are not going to navigate back to url_a but we will start the preload so
423 // we need to set the final status to expect here before navigating.
424 SetExpectedFinalStatus(FINAL_STATUS_APP_TERMINATING);
425
426 NavigateToDestURL();
427
428 // Make sure the PrerenderContents for the next url is now in the manager
429 // and not pending.
430 EXPECT_TRUE(UrlIsInPrerenderManager(url_b));
431 EXPECT_FALSE(UrlIsPendingInPrerenderManager(url_b));
432 }
433
434 // Checks that we don't prerender in an infinite loop and multiple links are
435 // handled correctly.
436 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoopMultiple) {
437 const char* url_a = "prerender_infinite_a_multiple.html";
438 const char* url_b = "prerender_infinite_b_multiple.html";
439 const char* url_c = "prerender_infinite_c_multiple.html";
440
441 PrerenderTestURL(url_a, FINAL_STATUS_USED, 1);
442
443 // Next url should be in pending list but not an active entry.
444 EXPECT_FALSE(UrlIsInPrerenderManager(url_b));
445 EXPECT_FALSE(UrlIsInPrerenderManager(url_c));
446 EXPECT_TRUE(UrlIsPendingInPrerenderManager(url_b));
447 EXPECT_TRUE(UrlIsPendingInPrerenderManager(url_c));
448
449 // We are not going to navigate back to url_a but we will start the preload so
450 // we need to set the final status to expect here before navigating.
451 GURL gurl_b = UrlForHtmlFile(url_b);
452 GURL gurl_c = UrlForHtmlFile(url_c);
453 SetExpectedFinalStatusForUrl(gurl_b, FINAL_STATUS_EVICTED);
454 SetExpectedFinalStatusForUrl(gurl_c, FINAL_STATUS_APP_TERMINATING);
455
456 NavigateToDestURL();
457
458 // Make sure the PrerenderContents for the next urls are now in the manager
459 // and not pending. url_c was the last seen so should be the active
460 // entry.
461 EXPECT_FALSE(UrlIsInPrerenderManager(url_b));
462 EXPECT_TRUE(UrlIsInPrerenderManager(url_c));
463 EXPECT_FALSE(UrlIsPendingInPrerenderManager(url_b));
464 EXPECT_FALSE(UrlIsPendingInPrerenderManager(url_c));
465 }
cbentzel 2011/03/15 18:42:24 Nit: insert an extra newline here.
dominich 2011/03/15 20:41:14 Done.
356 } // namespace prerender 466 } // namespace prerender
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/prerender/prerender_manager.h » ('j') | chrome/browser/prerender/prerender_manager.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698