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