| OLD | NEW |
| 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 #include "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "base/strings/string16.h" | 6 #include "base/strings/string16.h" |
| 7 #include "base/strings/string_split.h" | 7 #include "base/strings/string_split.h" |
| 8 #include "base/task_scheduler/post_task.h" | 8 #include "base/task_scheduler/post_task.h" |
| 9 #include "chrome/browser/prerender/prerender_handle.h" |
| 9 #include "chrome/browser/prerender/prerender_manager.h" | 10 #include "chrome/browser/prerender/prerender_manager.h" |
| 10 #include "chrome/browser/prerender/prerender_manager_factory.h" | 11 #include "chrome/browser/prerender/prerender_manager_factory.h" |
| 11 #include "chrome/browser/prerender/prerender_test_utils.h" | 12 #include "chrome/browser/prerender/prerender_test_utils.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/task_manager/task_manager_browsertest_util.h" | 14 #include "chrome/browser/task_manager/task_manager_browsertest_util.h" |
| 14 #include "chrome/browser/ui/browser.h" | 15 #include "chrome/browser/ui/browser.h" |
| 15 #include "chrome/browser/ui/browser_commands.h" | 16 #include "chrome/browser/ui/browser_commands.h" |
| 16 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 17 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 17 #include "chrome/common/chrome_switches.h" | 18 #include "chrome/common/chrome_switches.h" |
| 18 #include "chrome/grit/generated_resources.h" | 19 #include "chrome/grit/generated_resources.h" |
| 19 #include "chrome/test/base/ui_test_utils.h" | 20 #include "chrome/test/base/ui_test_utils.h" |
| 20 #include "content/public/common/content_switches.h" | 21 #include "content/public/common/content_switches.h" |
| 21 #include "content/public/common/url_constants.h" | 22 #include "content/public/common/url_constants.h" |
| 22 #include "content/public/test/browser_test_utils.h" | 23 #include "content/public/test/browser_test_utils.h" |
| 23 #include "net/base/escape.h" | 24 #include "net/base/escape.h" |
| 24 #include "net/dns/mock_host_resolver.h" | 25 #include "net/dns/mock_host_resolver.h" |
| 25 #include "net/test/embedded_test_server/request_handler_util.h" | 26 #include "net/test/embedded_test_server/request_handler_util.h" |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
| 27 #include "ui/base/l10n/l10n_util.h" | 28 #include "ui/base/l10n/l10n_util.h" |
| 28 | 29 |
| 29 using prerender::test_utils::CreateCountingInterceptorOnIO; | 30 using prerender::test_utils::CreateCountingInterceptorOnIO; |
| 30 using prerender::test_utils::DestructionWaiter; | 31 using prerender::test_utils::DestructionWaiter; |
| 31 using prerender::test_utils::RequestCounter; | 32 using prerender::test_utils::RequestCounter; |
| 32 using prerender::test_utils::TestPrerender; | 33 using prerender::test_utils::TestPrerender; |
| 33 using prerender::test_utils::TestPrerenderContents; | |
| 34 using task_manager::browsertest_util::WaitForTaskManagerRows; | |
| 35 | 34 |
| 36 namespace prerender { | 35 namespace prerender { |
| 37 | 36 |
| 38 // These URLs used for test resources must be relative with the exception of | 37 // These URLs used for test resources must be relative with the exception of |
| 39 // |PrefetchLoaderPath|, which is only used in |PrerenderTestURLImpl()|. | 38 // |kPrefetchLoaderPath|. |
| 40 const char kPrefetchImagePage[] = "prerender/prefetch_image.html"; | 39 const char kPrefetchImagePage[] = "prerender/prefetch_image.html"; |
| 41 const char kPrefetchJpeg[] = "prerender/image.jpeg"; | 40 const char kPrefetchJpeg[] = "prerender/image.jpeg"; |
| 42 const char kPrefetchLoaderPath[] = "/prerender/prefetch_loader.html"; | 41 const char kPrefetchLoaderPath[] = "/prerender/prefetch_loader.html"; |
| 43 const char kPrefetchLoopPage[] = "prerender/prefetch_loop.html"; | 42 const char kPrefetchLoopPage[] = "prerender/prefetch_loop.html"; |
| 44 const char kPrefetchMetaCSP[] = "prerender/prefetch_meta_csp.html"; | 43 const char kPrefetchMetaCSP[] = "prerender/prefetch_meta_csp.html"; |
| 45 const char kPrefetchPage[] = "prerender/prefetch_page.html"; | 44 const char kPrefetchPage[] = "prerender/prefetch_page.html"; |
| 46 const char kPrefetchPage2[] = "prerender/prefetch_page2.html"; | 45 const char kPrefetchPage2[] = "prerender/prefetch_page2.html"; |
| 47 const char kPrefetchPng[] = "prerender/image.png"; | 46 const char kPrefetchPng[] = "prerender/image.png"; |
| 48 const char kPrefetchResponseHeaderCSP[] = | 47 const char kPrefetchResponseHeaderCSP[] = |
| 49 "prerender/prefetch_response_csp.html"; | 48 "prerender/prefetch_response_csp.html"; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 base::FilePath url_file = ui_test_utils::GetTestFilePath( | 121 base::FilePath url_file = ui_test_utils::GetTestFilePath( |
| 123 base::FilePath(), base::FilePath::FromUTF8Unsafe(path_str)); | 122 base::FilePath(), base::FilePath::FromUTF8Unsafe(path_str)); |
| 124 content::BrowserThread::PostTask( | 123 content::BrowserThread::PostTask( |
| 125 content::BrowserThread::IO, FROM_HERE, | 124 content::BrowserThread::IO, FROM_HERE, |
| 126 base::Bind(&CreateCountingInterceptorOnIO, url, url_file, | 125 base::Bind(&CreateCountingInterceptorOnIO, url, url_file, |
| 127 counter->AsWeakPtr())); | 126 counter->AsWeakPtr())); |
| 128 } | 127 } |
| 129 | 128 |
| 130 BrowserTestTime* GetTimeOverride() const { return browser_test_time_; } | 129 BrowserTestTime* GetTimeOverride() const { return browser_test_time_; } |
| 131 | 130 |
| 132 private: | 131 protected: |
| 133 std::vector<std::unique_ptr<TestPrerender>> PrerenderTestURLImpl( | 132 std::unique_ptr<TestPrerender> PrefetchFromURL( |
| 134 const GURL& prerender_url, | 133 const GURL& target_url, |
| 135 const std::vector<FinalStatus>& expected_final_status_queue, | 134 FinalStatus expected_final_status) { |
| 136 int expected_number_of_loads) override { | 135 GURL loader_url = ServeLoaderURL( |
| 137 base::StringPairs replacement_text; | 136 kPrefetchLoaderPath, "REPLACE_WITH_PREFETCH_URL", target_url, ""); |
| 138 replacement_text.push_back( | 137 std::vector<FinalStatus> expected_final_status_queue(1, |
| 139 make_pair("REPLACE_WITH_PREFETCH_URL", prerender_url.spec())); | 138 expected_final_status); |
| 140 std::string replacement_path; | |
| 141 net::test_server::GetFilePathWithReplacements( | |
| 142 kPrefetchLoaderPath, replacement_text, &replacement_path); | |
| 143 GURL loader_url = src_server()->GetURL(replacement_path); | |
| 144 | |
| 145 std::vector<std::unique_ptr<TestPrerender>> prerenders = | 139 std::vector<std::unique_ptr<TestPrerender>> prerenders = |
| 146 NavigateWithPrerenders(loader_url, expected_final_status_queue, | 140 NavigateWithPrerenders(loader_url, expected_final_status_queue); |
| 147 expected_number_of_loads); | 141 prerenders[0]->WaitForStop(); |
| 148 | 142 return std::move(prerenders[0]); |
| 149 TestPrerenderContents* prerender_contents = prerenders[0]->contents(); | |
| 150 if (expected_number_of_loads > 0) { | |
| 151 CHECK(prerender_contents); | |
| 152 // Checks that the prerender contents final status is unchanged from its | |
| 153 // default value, meaning that the contents has not been destroyed. | |
| 154 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status()); | |
| 155 } | |
| 156 EXPECT_EQ(expected_number_of_loads, prerenders[0]->number_of_loads()); | |
| 157 | |
| 158 return prerenders; | |
| 159 } | 143 } |
| 160 | 144 |
| 145 std::unique_ptr<TestPrerender> PrefetchFromFile( |
| 146 const std::string& html_file, |
| 147 FinalStatus expected_final_status) { |
| 148 return PrefetchFromURL(src_server()->GetURL(MakeAbsolute(html_file)), |
| 149 expected_final_status); |
| 150 } |
| 151 |
| 152 private: |
| 161 BrowserTestTime* browser_test_time_; | 153 BrowserTestTime* browser_test_time_; |
| 154 |
| 155 DISALLOW_COPY_AND_ASSIGN(NoStatePrefetchBrowserTest); |
| 162 }; | 156 }; |
| 163 | 157 |
| 164 // Checks that a page is correctly prefetched in the case of a | 158 // Checks that a page is correctly prefetched in the case of a |
| 165 // <link rel=prerender> tag and the JavaScript on the page is not executed. | 159 // <link rel=prerender> tag and the JavaScript on the page is not executed. |
| 166 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimple) { | 160 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimple) { |
| 167 RequestCounter main_counter; | 161 RequestCounter main_counter; |
| 168 CountRequestFor(kPrefetchPage, &main_counter); | 162 CountRequestFor(kPrefetchPage, &main_counter); |
| 169 RequestCounter script_counter; | 163 RequestCounter script_counter; |
| 170 CountRequestFor(kPrefetchScript, &script_counter); | 164 CountRequestFor(kPrefetchScript, &script_counter); |
| 171 RequestCounter script2_counter; | 165 RequestCounter script2_counter; |
| 172 CountRequestFor(kPrefetchScript2, &script2_counter); | 166 CountRequestFor(kPrefetchScript2, &script2_counter); |
| 173 | 167 |
| 174 std::unique_ptr<TestPrerender> test_prerender = | 168 std::unique_ptr<TestPrerender> test_prerender = |
| 175 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_APP_TERMINATING, 1); | 169 PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 176 main_counter.WaitForCount(1); | 170 main_counter.WaitForCount(1); |
| 177 script_counter.WaitForCount(1); | 171 script_counter.WaitForCount(1); |
| 178 script2_counter.WaitForCount(0); | 172 script2_counter.WaitForCount(0); |
| 173 |
| 174 // Verify that the page load did not happen. |
| 175 test_prerender->WaitForLoads(0); |
| 179 } | 176 } |
| 180 | 177 |
| 181 // Checks the prefetch of an img tag. | 178 // Checks the prefetch of an img tag. |
| 182 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchImage) { | 179 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchImage) { |
| 183 RequestCounter image_counter; | 180 RequestCounter image_counter; |
| 184 CountRequestFor(kPrefetchJpeg, &image_counter); | 181 CountRequestFor(kPrefetchJpeg, &image_counter); |
| 185 base::StringPairs replacement_text; | 182 base::StringPairs replacement_text; |
| 186 replacement_text.push_back( | 183 replacement_text.push_back( |
| 187 std::make_pair("REPLACE_WITH_IMAGE_URL", MakeAbsolute(kPrefetchJpeg))); | 184 std::make_pair("REPLACE_WITH_IMAGE_URL", MakeAbsolute(kPrefetchJpeg))); |
| 188 std::string main_page_path; | 185 std::string main_page_path; |
| 189 net::test_server::GetFilePathWithReplacements( | 186 net::test_server::GetFilePathWithReplacements( |
| 190 kPrefetchImagePage, replacement_text, &main_page_path); | 187 kPrefetchImagePage, replacement_text, &main_page_path); |
| 191 // Note CountRequestFor cannot be used on the main page as the test server | 188 // Note CountRequestFor cannot be used on the main page as the test server |
| 192 // must handling the image url replacement. | 189 // must handling the image url replacement. |
| 193 PrerenderTestURL(main_page_path, FINAL_STATUS_APP_TERMINATING, 1); | 190 PrefetchFromFile(main_page_path, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 194 image_counter.WaitForCount(1); | 191 image_counter.WaitForCount(1); |
| 195 } | 192 } |
| 196 | 193 |
| 197 // Checks that a cross-domain prefetching works correctly. | 194 // Checks that a cross-domain prefetching works correctly. |
| 198 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchCrossDomain) { | 195 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchCrossDomain) { |
| 199 static const std::string secondary_domain = "www.foo.com"; | 196 static const std::string secondary_domain = "www.foo.com"; |
| 200 host_resolver()->AddRule(secondary_domain, "127.0.0.1"); | 197 host_resolver()->AddRule(secondary_domain, "127.0.0.1"); |
| 201 GURL cross_domain_url(base::StringPrintf( | 198 GURL cross_domain_url(base::StringPrintf( |
| 202 "http://%s:%d/%s", secondary_domain.c_str(), | 199 "http://%s:%d/%s", secondary_domain.c_str(), |
| 203 embedded_test_server()->host_port_pair().port(), kPrefetchPage)); | 200 embedded_test_server()->host_port_pair().port(), kPrefetchPage)); |
| 204 RequestCounter cross_domain_counter; | 201 RequestCounter cross_domain_counter; |
| 205 CountRequestForUrl(cross_domain_url, kPrefetchPage, &cross_domain_counter); | 202 CountRequestForUrl(cross_domain_url, kPrefetchPage, &cross_domain_counter); |
| 206 PrerenderTestURL(cross_domain_url, FINAL_STATUS_APP_TERMINATING, 1); | 203 PrefetchFromURL(cross_domain_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 207 cross_domain_counter.WaitForCount(1); | 204 cross_domain_counter.WaitForCount(1); |
| 208 } | 205 } |
| 209 | 206 |
| 210 // Checks that response header CSP is respected. | 207 // Checks that response header CSP is respected. |
| 211 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, ResponseHeaderCSP) { | 208 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, ResponseHeaderCSP) { |
| 212 static const std::string secondary_domain = "foo.bar"; | 209 static const std::string secondary_domain = "foo.bar"; |
| 213 host_resolver()->AddRule(secondary_domain, "127.0.0.1"); | 210 host_resolver()->AddRule(secondary_domain, "127.0.0.1"); |
| 214 RequestCounter main_page; | 211 RequestCounter main_page; |
| 215 CountRequestFor(kPrefetchResponseHeaderCSP, &main_page); | 212 CountRequestFor(kPrefetchResponseHeaderCSP, &main_page); |
| 216 RequestCounter first_script; | 213 RequestCounter first_script; |
| 217 CountRequestFor(kPrefetchScript, &first_script); | 214 CountRequestFor(kPrefetchScript, &first_script); |
| 218 RequestCounter second_script; | 215 RequestCounter second_script; |
| 219 GURL second_script_url(std::string("http://foo.bar/") + kPrefetchScript2); | 216 GURL second_script_url(std::string("http://foo.bar/") + kPrefetchScript2); |
| 220 CountRequestForUrl(second_script_url, kPrefetchScript2, &second_script); | 217 CountRequestForUrl(second_script_url, kPrefetchScript2, &second_script); |
| 221 PrerenderTestURL(kPrefetchResponseHeaderCSP, FINAL_STATUS_APP_TERMINATING, 1); | 218 PrefetchFromFile(kPrefetchResponseHeaderCSP, |
| 219 FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 222 // The second script is in the correct domain for CSP, but the first script is | 220 // The second script is in the correct domain for CSP, but the first script is |
| 223 // not. | 221 // not. |
| 224 main_page.WaitForCount(1); | 222 main_page.WaitForCount(1); |
| 225 second_script.WaitForCount(1); | 223 second_script.WaitForCount(1); |
| 226 // TODO(pasko): wait for prefetch to be finished before checking the counts. | |
| 227 first_script.WaitForCount(0); | 224 first_script.WaitForCount(0); |
| 228 } | 225 } |
| 229 | 226 |
| 230 // Checks that CSP in the meta tag cancels the prefetch. | 227 // Checks that CSP in the meta tag cancels the prefetch. |
| 231 // TODO(mattcary): probably this behavior should be consistent with | 228 // TODO(mattcary): probably this behavior should be consistent with |
| 232 // response-header CSP. See crbug/656581. | 229 // response-header CSP. See crbug/656581. |
| 233 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, MetaTagCSP) { | 230 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, MetaTagCSP) { |
| 234 static const std::string secondary_domain = "foo.bar"; | 231 static const std::string secondary_domain = "foo.bar"; |
| 235 host_resolver()->AddRule(secondary_domain, "127.0.0.1"); | 232 host_resolver()->AddRule(secondary_domain, "127.0.0.1"); |
| 236 RequestCounter main_page; | 233 RequestCounter main_page; |
| 237 CountRequestFor(kPrefetchMetaCSP, &main_page); | 234 CountRequestFor(kPrefetchMetaCSP, &main_page); |
| 238 RequestCounter first_script; | 235 RequestCounter first_script; |
| 239 CountRequestFor(kPrefetchScript, &first_script); | 236 CountRequestFor(kPrefetchScript, &first_script); |
| 240 RequestCounter second_script; | 237 RequestCounter second_script; |
| 241 GURL second_script_url(std::string("http://foo.bar/") + kPrefetchScript2); | 238 GURL second_script_url(std::string("http://foo.bar/") + kPrefetchScript2); |
| 242 CountRequestForUrl(second_script_url, kPrefetchScript2, &second_script); | 239 CountRequestForUrl(second_script_url, kPrefetchScript2, &second_script); |
| 243 PrerenderTestURL(kPrefetchMetaCSP, FINAL_STATUS_APP_TERMINATING, 1); | 240 PrefetchFromFile(kPrefetchMetaCSP, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 244 // TODO(mattcary): See test comment above. If the meta CSP tag were parsed, | 241 // TODO(mattcary): See test comment above. If the meta CSP tag were parsed, |
| 245 // |second_script| would be loaded. Instead as the background scanner bails as | 242 // |second_script| would be loaded. Instead as the background scanner bails as |
| 246 // soon as the meta CSP tag is seen, only |main_page| is fetched. | 243 // soon as the meta CSP tag is seen, only |main_page| is fetched. |
| 247 main_page.WaitForCount(1); | 244 main_page.WaitForCount(1); |
| 248 // TODO(pasko): wait for prefetch to be finished before checking the counts. | |
| 249 second_script.WaitForCount(0); | 245 second_script.WaitForCount(0); |
| 250 first_script.WaitForCount(0); | 246 first_script.WaitForCount(0); |
| 251 } | 247 } |
| 252 | 248 |
| 253 // Checks simultaneous prefetch. | 249 // Checks that the second prefetch request succeeds. TODO(pasko): This test |
| 250 // waits for Prerender Stop before starting the second request, add a test that |
| 251 // starts the second request from the UI thread immediately without waiting. |
| 254 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimultaneous) { | 252 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimultaneous) { |
| 255 RequestCounter first_main_counter; | 253 RequestCounter first_main_counter; |
| 256 CountRequestFor(kPrefetchPage, &first_main_counter); | 254 CountRequestFor(kPrefetchPage, &first_main_counter); |
| 257 RequestCounter second_main_counter; | 255 RequestCounter second_main_counter; |
| 258 CountRequestFor(kPrefetchPage2, &second_main_counter); | 256 CountRequestFor(kPrefetchPage2, &second_main_counter); |
| 259 RequestCounter first_script_counter; | 257 RequestCounter first_script_counter; |
| 260 CountRequestFor(kPrefetchScript, &first_script_counter); | 258 CountRequestFor(kPrefetchScript, &first_script_counter); |
| 261 RequestCounter second_script_counter; | 259 RequestCounter second_script_counter; |
| 262 CountRequestFor(kPrefetchScript2, &second_script_counter); | 260 CountRequestFor(kPrefetchScript2, &second_script_counter); |
| 263 | 261 |
| 264 // The first prerender is marked as canceled. When the second prerender | 262 // The first prerender is marked as canceled. When the second prerender |
| 265 // starts, it sees that the first has been abandoned (because the earlier | 263 // starts, it sees that the first has been abandoned (because the earlier |
| 266 // prerender is detached immediately and so dies quickly). | 264 // prerender is detached immediately and so dies quickly). |
| 267 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_CANCELLED, 1); | 265 PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 268 PrerenderTestURL(kPrefetchPage2, FINAL_STATUS_APP_TERMINATING, 1); | 266 PrefetchFromFile(kPrefetchPage2, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 269 first_main_counter.WaitForCount(1); | 267 first_main_counter.WaitForCount(1); |
| 270 second_main_counter.WaitForCount(1); | 268 second_main_counter.WaitForCount(1); |
| 271 first_script_counter.WaitForCount(1); | 269 first_script_counter.WaitForCount(1); |
| 272 second_script_counter.WaitForCount(1); | 270 second_script_counter.WaitForCount(1); |
| 273 } | 271 } |
| 274 | 272 |
| 275 // Checks a prefetch to a nonexisting page. | 273 // Checks a prefetch to a nonexisting page. |
| 276 // TODO(mattcary): disabled as prefetch process teardown is racey with prerender | 274 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchNonexisting) { |
| 277 // contents destruction, can fix when prefetch prerenderers are destroyed | 275 std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile( |
| 278 // deterministically. | 276 "nonexisting-page.html", FINAL_STATUS_UNSUPPORTED_SCHEME); |
| 279 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, | |
| 280 DISABLED_PrefetchNonexisting) { | |
| 281 PrerenderTestURL("nonexisting-page.html", FINAL_STATUS_APP_TERMINATING, 0); | |
| 282 // TODO(mattcary): we fire up a prerenderer before we discover that the main | |
| 283 // page doesn't exist, we still count this as a prerender. Also we don't fail | |
| 284 // the renderer (presumably because we've detached the resource, etc). Is this | |
| 285 // what we want? At any rate, we can't positively check any of that now due to | |
| 286 // histogram race conditions, and only test that we don't crash on a | |
| 287 // nonexisting page. | |
| 288 } | 277 } |
| 289 | 278 |
| 290 // Checks that a 301 redirect is followed. | 279 // Checks that a 301 redirect is followed. |
| 291 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Prefetch301Redirect) { | 280 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Prefetch301Redirect) { |
| 292 RequestCounter script_counter; | 281 RequestCounter script_counter; |
| 293 CountRequestFor(kPrefetchScript, &script_counter); | 282 CountRequestFor(kPrefetchScript, &script_counter); |
| 294 PrerenderTestURL( | 283 PrefetchFromFile( |
| 295 "/server-redirect/?" + | 284 "/server-redirect/?" + |
| 296 net::EscapeQueryParamValue(MakeAbsolute(kPrefetchPage), false), | 285 net::EscapeQueryParamValue(MakeAbsolute(kPrefetchPage), false), |
| 297 FINAL_STATUS_APP_TERMINATING, 1); | 286 FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 298 script_counter.WaitForCount(1); | 287 script_counter.WaitForCount(1); |
| 299 } | 288 } |
| 300 | 289 |
| 301 // Checks that a subresource 301 redirect is followed. | 290 // Checks that a subresource 301 redirect is followed. |
| 302 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Prefetch301Subresource) { | 291 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Prefetch301Subresource) { |
| 303 RequestCounter script_counter; | 292 RequestCounter script_counter; |
| 304 CountRequestFor(kPrefetchScript, &script_counter); | 293 CountRequestFor(kPrefetchScript, &script_counter); |
| 305 PrerenderTestURL(kPrefetchSubresourceRedirectPage, | 294 PrefetchFromFile(kPrefetchSubresourceRedirectPage, |
| 306 FINAL_STATUS_APP_TERMINATING, 1); | 295 FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 307 script_counter.WaitForCount(1); | 296 script_counter.WaitForCount(1); |
| 308 } | 297 } |
| 309 | 298 |
| 310 // Checks a client redirect is not followed. | 299 // Checks a client redirect is not followed. |
| 311 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchClientRedirect) { | 300 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchClientRedirect) { |
| 312 RequestCounter script_counter; | 301 RequestCounter script_counter; |
| 313 CountRequestFor(kPrefetchScript, &script_counter); | 302 CountRequestFor(kPrefetchScript, &script_counter); |
| 314 // A complete load of kPrefetchPage2 is used as a sentinal. Otherwise the test | 303 // A complete load of kPrefetchPage2 is used as a sentinal. Otherwise the test |
| 315 // ends before script_counter would reliably see the load of kPrefetchScript, | 304 // ends before script_counter would reliably see the load of kPrefetchScript, |
| 316 // were it to happen. | 305 // were it to happen. |
| 317 RequestCounter sentinel_counter; | 306 RequestCounter sentinel_counter; |
| 318 CountRequestFor(kPrefetchScript2, &sentinel_counter); | 307 CountRequestFor(kPrefetchScript2, &sentinel_counter); |
| 319 PrerenderTestURL( | 308 PrefetchFromFile( |
| 320 "/client-redirect/?" + | 309 "/client-redirect/?" + |
| 321 net::EscapeQueryParamValue(MakeAbsolute(kPrefetchPage), false), | 310 net::EscapeQueryParamValue(MakeAbsolute(kPrefetchPage), false), |
| 322 FINAL_STATUS_APP_TERMINATING, 1); | 311 FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 323 ui_test_utils::NavigateToURL( | 312 ui_test_utils::NavigateToURL( |
| 324 current_browser(), src_server()->GetURL(MakeAbsolute(kPrefetchPage2))); | 313 current_browser(), src_server()->GetURL(MakeAbsolute(kPrefetchPage2))); |
| 325 sentinel_counter.WaitForCount(1); | 314 sentinel_counter.WaitForCount(1); |
| 326 script_counter.WaitForCount(0); | 315 script_counter.WaitForCount(0); |
| 327 } | 316 } |
| 328 | 317 |
| 329 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchHttps) { | 318 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchHttps) { |
| 330 UseHttpsSrcServer(); | 319 UseHttpsSrcServer(); |
| 331 RequestCounter main_counter; | 320 RequestCounter main_counter; |
| 332 CountRequestFor(kPrefetchPage, &main_counter); | 321 CountRequestFor(kPrefetchPage, &main_counter); |
| 333 RequestCounter script_counter; | 322 RequestCounter script_counter; |
| 334 CountRequestFor(kPrefetchScript, &script_counter); | 323 CountRequestFor(kPrefetchScript, &script_counter); |
| 335 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_APP_TERMINATING, 1); | 324 PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 336 main_counter.WaitForCount(1); | 325 main_counter.WaitForCount(1); |
| 337 script_counter.WaitForCount(1); | 326 script_counter.WaitForCount(1); |
| 338 } | 327 } |
| 339 | 328 |
| 340 // Checks that an SSL error prevents prefetch. | 329 // Checks that an SSL error prevents prefetch. |
| 341 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, SSLError) { | 330 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, SSLError) { |
| 342 // Only send the loaded page, not the loader, through SSL. | 331 // Only send the loaded page, not the loader, through SSL. |
| 343 net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); | 332 net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); |
| 344 https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME); | 333 https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME); |
| 345 https_server.ServeFilesFromSourceDirectory("chrome/test/data"); | 334 https_server.ServeFilesFromSourceDirectory("chrome/test/data"); |
| 346 ASSERT_TRUE(https_server.Start()); | 335 ASSERT_TRUE(https_server.Start()); |
| 347 std::unique_ptr<TestPrerender> prerender = | 336 std::unique_ptr<TestPrerender> prerender = PrefetchFromURL( |
| 348 PrerenderTestURL(https_server.GetURL(MakeAbsolute(kPrefetchPage)), | 337 https_server.GetURL(MakeAbsolute(kPrefetchPage)), FINAL_STATUS_SSL_ERROR); |
| 349 FINAL_STATUS_SSL_ERROR, 0); | |
| 350 DestructionWaiter waiter(prerender->contents(), FINAL_STATUS_SSL_ERROR); | 338 DestructionWaiter waiter(prerender->contents(), FINAL_STATUS_SSL_ERROR); |
| 351 EXPECT_TRUE(waiter.WaitForDestroy()); | 339 EXPECT_TRUE(waiter.WaitForDestroy()); |
| 352 } | 340 } |
| 353 | 341 |
| 354 // Checks that a subresource failing SSL does not prevent prefetch on the rest | 342 // Checks that a subresource failing SSL does not prevent prefetch on the rest |
| 355 // of the page. | 343 // of the page. |
| 356 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, SSLSubresourceError) { | 344 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, SSLSubresourceError) { |
| 357 // First confirm that the image loads as expected. | 345 // First confirm that the image loads as expected. |
| 358 | 346 |
| 359 // A separate HTTPS server is started for the subresource; src_server() is | 347 // A separate HTTPS server is started for the subresource; src_server() is |
| 360 // non-HTTPS. | 348 // non-HTTPS. |
| 361 net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); | 349 net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); |
| 362 https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME); | 350 https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME); |
| 363 https_server.ServeFilesFromSourceDirectory("chrome/test/data"); | 351 https_server.ServeFilesFromSourceDirectory("chrome/test/data"); |
| 364 ASSERT_TRUE(https_server.Start()); | 352 ASSERT_TRUE(https_server.Start()); |
| 365 GURL https_url = https_server.GetURL("/prerender/image.jpeg"); | 353 GURL https_url = https_server.GetURL("/prerender/image.jpeg"); |
| 366 base::StringPairs replacement_text; | 354 base::StringPairs replacement_text; |
| 367 replacement_text.push_back( | 355 replacement_text.push_back( |
| 368 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec())); | 356 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec())); |
| 369 std::string main_page_path; | 357 std::string main_page_path; |
| 370 net::test_server::GetFilePathWithReplacements( | 358 net::test_server::GetFilePathWithReplacements( |
| 371 kPrefetchImagePage, replacement_text, &main_page_path); | 359 kPrefetchImagePage, replacement_text, &main_page_path); |
| 372 RequestCounter script_counter; | 360 RequestCounter script_counter; |
| 373 CountRequestFor(kPrefetchScript, &script_counter); | 361 CountRequestFor(kPrefetchScript, &script_counter); |
| 374 | 362 |
| 375 std::unique_ptr<TestPrerender> prerender = | 363 std::unique_ptr<TestPrerender> prerender = |
| 376 PrerenderTestURL(main_page_path, FINAL_STATUS_APP_TERMINATING, 1); | 364 PrefetchFromFile(main_page_path, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 377 // Checks that the presumed failure of the image load didn't affect the script | 365 // Checks that the presumed failure of the image load didn't affect the script |
| 378 // fetch. This assumes waiting for the script load is enough to see any error | 366 // fetch. This assumes waiting for the script load is enough to see any error |
| 379 // from the image load. | 367 // from the image load. |
| 380 script_counter.WaitForCount(1); | 368 script_counter.WaitForCount(1); |
| 381 } | 369 } |
| 382 | 370 |
| 383 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Loop) { | 371 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Loop) { |
| 384 RequestCounter script_counter; | 372 RequestCounter script_counter; |
| 385 CountRequestFor(kPrefetchScript, &script_counter); | 373 CountRequestFor(kPrefetchScript, &script_counter); |
| 386 RequestCounter main_counter; | 374 RequestCounter main_counter; |
| 387 CountRequestFor(kPrefetchLoopPage, &main_counter); | 375 CountRequestFor(kPrefetchLoopPage, &main_counter); |
| 388 | 376 |
| 389 std::unique_ptr<TestPrerender> test_prerender = | 377 std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile( |
| 390 PrerenderTestURL(kPrefetchLoopPage, FINAL_STATUS_APP_TERMINATING, 1); | 378 kPrefetchLoopPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 391 main_counter.WaitForCount(1); | 379 main_counter.WaitForCount(1); |
| 392 script_counter.WaitForCount(1); | 380 script_counter.WaitForCount(1); |
| 393 } | 381 } |
| 394 | 382 |
| 395 #if defined(ENABLE_TASK_MANAGER) | 383 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, RendererCrash) { |
| 384 // Navigate to about:blank to get the session storage namespace. |
| 385 ui_test_utils::NavigateToURL(current_browser(), GURL(url::kAboutBlankURL)); |
| 386 content::SessionStorageNamespace* storage_namespace = |
| 387 GetActiveWebContents() |
| 388 ->GetController() |
| 389 .GetDefaultSessionStorageNamespace(); |
| 396 | 390 |
| 397 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, | 391 // Navigate to about:crash without an intermediate loader because chrome:// |
| 398 OpenTaskManagerBeforePrefetch) { | 392 // URLs are ignored in renderers, and the test server has no support for them. |
| 399 const base::string16 any_prerender = MatchTaskManagerPrerender("*"); | 393 const gfx::Size kSize(640, 480); |
| 400 const base::string16 any_tab = MatchTaskManagerTab("*"); | 394 std::unique_ptr<TestPrerender> test_prerender = |
| 401 const base::string16 original = MatchTaskManagerTab("Prefetch Loader"); | 395 prerender_contents_factory()->ExpectPrerenderContents( |
| 402 // The page title is not visible in the task manager, presumably because the | 396 FINAL_STATUS_RENDERER_CRASHED); |
| 403 // page has not been fully parsed. | 397 std::unique_ptr<PrerenderHandle> prerender_handle( |
| 404 const base::string16 prerender = | 398 GetPrerenderManager()->AddPrerenderFromExternalRequest( |
| 405 MatchTaskManagerPrerender("*prefetch_page.html*"); | 399 GURL(content::kChromeUICrashURL), content::Referrer(), |
| 406 | 400 storage_namespace, gfx::Rect(kSize))); |
| 407 // Show the task manager. This populates the model. | 401 ASSERT_EQ(prerender_handle->contents(), test_prerender->contents()); |
| 408 chrome::OpenTaskManager(current_browser()); | 402 test_prerender->WaitForStop(); |
| 409 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab)); | |
| 410 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender)); | |
| 411 | |
| 412 // Prerender a page in addition to the original tab. | |
| 413 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_APP_TERMINATING, 1); | |
| 414 | |
| 415 // A TaskManager entry should appear like "Prerender: Prerender Page" | |
| 416 // alongside the original tab entry. There should be just these two entries. | |
| 417 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, prerender)); | |
| 418 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, original)); | |
| 419 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_prerender)); | |
| 420 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab)); | |
| 421 } | |
| 422 | |
| 423 #endif // defined(ENABLE_TASK_MANAGER) | |
| 424 | |
| 425 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, RendererCrash) { | |
| 426 std::unique_ptr<TestPrerender> prerender = | |
| 427 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_RENDERER_CRASHED, 1); | |
| 428 prerender->contents()->prerender_contents()->GetController().LoadURL( | |
| 429 GURL(content::kChromeUICrashURL), content::Referrer(), | |
| 430 ui::PAGE_TRANSITION_TYPED, std::string()); | |
| 431 prerender->WaitForStop(); | |
| 432 } | 403 } |
| 433 | 404 |
| 434 // Checks that the prefetch of png correctly loads the png. | 405 // Checks that the prefetch of png correctly loads the png. |
| 435 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Png) { | 406 // TODO(pasko): Add support for prefetching non-HTML documents and re-enable the |
| 407 // test. |
| 408 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, DISABLED_Png) { |
| 436 RequestCounter counter; | 409 RequestCounter counter; |
| 437 CountRequestFor(kPrefetchPng, &counter); | 410 CountRequestFor(kPrefetchPng, &counter); |
| 438 PrerenderTestURL(kPrefetchPng, FINAL_STATUS_APP_TERMINATING, 1); | 411 PrefetchFromFile(kPrefetchPng, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 439 counter.WaitForCount(1); | 412 counter.WaitForCount(1); |
| 440 } | 413 } |
| 441 | 414 |
| 442 // Checks that the prefetch of png correctly loads the jpeg. | 415 // Checks that the prefetch of png correctly loads the jpeg. |
| 443 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Jpeg) { | 416 // TODO(pasko): Add support for prefetching non-HTML documents and re-enable the |
| 417 // test. |
| 418 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, DISABLED_Jpeg) { |
| 444 RequestCounter counter; | 419 RequestCounter counter; |
| 445 CountRequestFor(kPrefetchJpeg, &counter); | 420 CountRequestFor(kPrefetchJpeg, &counter); |
| 446 PrerenderTestURL(kPrefetchJpeg, FINAL_STATUS_APP_TERMINATING, 1); | 421 PrefetchFromFile(kPrefetchJpeg, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 447 counter.WaitForCount(1); | 422 counter.WaitForCount(1); |
| 448 } | 423 } |
| 449 | 424 |
| 450 // Checks that nothing is prefetched from malware sites. | 425 // Checks that nothing is prefetched from malware sites. |
| 451 // TODO(mattcary): disabled as prefetch process teardown is racey with prerender | 426 // TODO(mattcary): disabled as prefetch process teardown is racey with prerender |
| 452 // contents destruction, can fix when prefetch prerenderers are destroyed | 427 // contents destruction, can fix when prefetch prerenderers are destroyed |
| 453 // deterministically. | 428 // deterministically. |
| 454 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, | 429 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, |
| 455 DISABLED_PrerenderSafeBrowsingTopLevel) { | 430 DISABLED_PrerenderSafeBrowsingTopLevel) { |
| 456 GURL url = src_server()->GetURL(MakeAbsolute(kPrefetchPage)); | 431 GURL url = src_server()->GetURL(MakeAbsolute(kPrefetchPage)); |
| 457 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( | 432 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( |
| 458 url, safe_browsing::SB_THREAT_TYPE_URL_MALWARE); | 433 url, safe_browsing::SB_THREAT_TYPE_URL_MALWARE); |
| 459 // Prefetch resources are blocked, but the prerender is not killed in any | 434 // Prefetch resources are blocked, but the prerender is not killed in any |
| 460 // special way. | 435 // special way. |
| 461 // TODO(mattcary): since the prerender will count itself as loaded even if the | 436 // TODO(mattcary): since the prerender will count itself as loaded even if the |
| 462 // fetch of the main resource fails, the test doesn't actually confirm what we | 437 // fetch of the main resource fails, the test doesn't actually confirm what we |
| 463 // want it to confirm. This may be fixed by planned changes to the prerender | 438 // want it to confirm. This may be fixed by planned changes to the prerender |
| 464 // lifecycle. | 439 // lifecycle. |
| 465 std::unique_ptr<TestPrerender> prerender = | 440 std::unique_ptr<TestPrerender> prerender = |
| 466 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_SAFE_BROWSING, 1); | 441 PrefetchFromFile(kPrefetchPage, FINAL_STATUS_SAFE_BROWSING); |
| 467 } | 442 } |
| 468 | 443 |
| 469 } // namespace prerender | 444 } // namespace prerender |
| OLD | NEW |