| 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/strings/stringprintf.h" | |
| 9 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 10 #include "base/task_scheduler/post_task.h" | 9 #include "base/task_scheduler/post_task.h" |
| 11 #include "base/test/simple_test_tick_clock.h" | |
| 12 #include "chrome/browser/history/history_service_factory.h" | 10 #include "chrome/browser/history/history_service_factory.h" |
| 13 #include "chrome/browser/history/history_test_utils.h" | 11 #include "chrome/browser/history/history_test_utils.h" |
| 14 #include "chrome/browser/prerender/prerender_handle.h" | 12 #include "chrome/browser/prerender/prerender_handle.h" |
| 15 #include "chrome/browser/prerender/prerender_manager.h" | 13 #include "chrome/browser/prerender/prerender_manager.h" |
| 16 #include "chrome/browser/prerender/prerender_manager_factory.h" | 14 #include "chrome/browser/prerender/prerender_manager_factory.h" |
| 17 #include "chrome/browser/prerender/prerender_test_utils.h" | 15 #include "chrome/browser/prerender/prerender_test_utils.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/task_manager/task_manager_browsertest_util.h" | 17 #include "chrome/browser/task_manager/task_manager_browsertest_util.h" |
| 20 #include "chrome/browser/ui/browser.h" | 18 #include "chrome/browser/ui/browser.h" |
| 21 #include "chrome/browser/ui/browser_commands.h" | 19 #include "chrome/browser/ui/browser_commands.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 35 #include "ui/base/l10n/l10n_util.h" | 33 #include "ui/base/l10n/l10n_util.h" |
| 36 | 34 |
| 37 using prerender::test_utils::DestructionWaiter; | 35 using prerender::test_utils::DestructionWaiter; |
| 38 using prerender::test_utils::RequestCounter; | 36 using prerender::test_utils::RequestCounter; |
| 39 using prerender::test_utils::TestPrerender; | 37 using prerender::test_utils::TestPrerender; |
| 40 | 38 |
| 41 namespace prerender { | 39 namespace prerender { |
| 42 | 40 |
| 43 // These URLs used for test resources must be relative with the exception of | 41 // These URLs used for test resources must be relative with the exception of |
| 44 // |kPrefetchLoaderPath|. | 42 // |kPrefetchLoaderPath|. |
| 45 const char kPrefetchAppcache[] = "prerender/prefetch_appcache.html"; | |
| 46 const char kPrefetchAppcacheManifest[] = "prerender/appcache.manifest"; | |
| 47 const char kPrefetchImagePage[] = "prerender/prefetch_image.html"; | 43 const char kPrefetchImagePage[] = "prerender/prefetch_image.html"; |
| 48 const char kPrefetchJpeg[] = "prerender/image.jpeg"; | 44 const char kPrefetchJpeg[] = "prerender/image.jpeg"; |
| 49 const char kPrefetchLoaderPath[] = "/prerender/prefetch_loader.html"; | 45 const char kPrefetchLoaderPath[] = "/prerender/prefetch_loader.html"; |
| 50 const char kPrefetchLoopPage[] = "prerender/prefetch_loop.html"; | 46 const char kPrefetchLoopPage[] = "prerender/prefetch_loop.html"; |
| 51 const char kPrefetchMetaCSP[] = "prerender/prefetch_meta_csp.html"; | 47 const char kPrefetchMetaCSP[] = "prerender/prefetch_meta_csp.html"; |
| 52 const char kPrefetchPage[] = "prerender/prefetch_page.html"; | 48 const char kPrefetchPage[] = "prerender/prefetch_page.html"; |
| 53 const char kPrefetchPage2[] = "prerender/prefetch_page2.html"; | 49 const char kPrefetchPage2[] = "prerender/prefetch_page2.html"; |
| 54 const char kPrefetchPng[] = "prerender/image.png"; | 50 const char kPrefetchPng[] = "prerender/image.png"; |
| 55 const char kPrefetchResponseHeaderCSP[] = | 51 const char kPrefetchResponseHeaderCSP[] = |
| 56 "prerender/prefetch_response_csp.html"; | 52 "prerender/prefetch_response_csp.html"; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 86 const std::string& path_str, | 82 const std::string& path_str, |
| 87 RequestCounter* counter) { | 83 RequestCounter* counter) { |
| 88 base::FilePath url_file = ui_test_utils::GetTestFilePath( | 84 base::FilePath url_file = ui_test_utils::GetTestFilePath( |
| 89 base::FilePath(), base::FilePath::FromUTF8Unsafe(path_str)); | 85 base::FilePath(), base::FilePath::FromUTF8Unsafe(path_str)); |
| 90 content::BrowserThread::PostTask( | 86 content::BrowserThread::PostTask( |
| 91 content::BrowserThread::IO, FROM_HERE, | 87 content::BrowserThread::IO, FROM_HERE, |
| 92 base::Bind(&prerender::test_utils::CreateCountingInterceptorOnIO, url, | 88 base::Bind(&prerender::test_utils::CreateCountingInterceptorOnIO, url, |
| 93 url_file, counter->AsWeakPtr())); | 89 url_file, counter->AsWeakPtr())); |
| 94 } | 90 } |
| 95 | 91 |
| 96 base::SimpleTestTickClock* OverridePrerenderManagerTimeTicks() { | |
| 97 auto clock = base::MakeUnique<base::SimpleTestTickClock>(); | |
| 98 auto* clock_ptr = clock.get(); | |
| 99 // The default zero time causes the prerender manager to do strange things. | |
| 100 clock->Advance(base::TimeDelta::FromSeconds(1)); | |
| 101 GetPrerenderManager()->SetTickClockForTesting(std::move(clock)); | |
| 102 return clock_ptr; | |
| 103 } | |
| 104 | |
| 105 protected: | 92 protected: |
| 106 std::unique_ptr<TestPrerender> PrefetchFromURL( | 93 std::unique_ptr<TestPrerender> PrefetchFromURL( |
| 107 const GURL& target_url, | 94 const GURL& target_url, |
| 108 FinalStatus expected_final_status) { | 95 FinalStatus expected_final_status) { |
| 109 GURL loader_url = ServeLoaderURL( | 96 GURL loader_url = ServeLoaderURL( |
| 110 kPrefetchLoaderPath, "REPLACE_WITH_PREFETCH_URL", target_url, ""); | 97 kPrefetchLoaderPath, "REPLACE_WITH_PREFETCH_URL", target_url, ""); |
| 111 std::vector<FinalStatus> expected_final_status_queue(1, | 98 std::vector<FinalStatus> expected_final_status_queue(1, |
| 112 expected_final_status); | 99 expected_final_status); |
| 113 std::vector<std::unique_ptr<TestPrerender>> prerenders = | 100 std::vector<std::unique_ptr<TestPrerender>> prerenders = |
| 114 NavigateWithPrerenders(loader_url, expected_final_status_queue); | 101 NavigateWithPrerenders(loader_url, expected_final_status_queue); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 "Prerender.websame_PrefetchTTFCP.Warm.Cacheable.Visible", 1); | 178 "Prerender.websame_PrefetchTTFCP.Warm.Cacheable.Visible", 1); |
| 192 histogram_tester().ExpectTotalCount( | 179 histogram_tester().ExpectTotalCount( |
| 193 "Prerender.websame_NoStatePrefetchResponseTypes", 2); | 180 "Prerender.websame_NoStatePrefetchResponseTypes", 2); |
| 194 histogram_tester().ExpectTotalCount("Prerender.websame_PrefetchAge", 1); | 181 histogram_tester().ExpectTotalCount("Prerender.websame_PrefetchAge", 1); |
| 195 } | 182 } |
| 196 | 183 |
| 197 // Checks the prefetch of an img tag. | 184 // Checks the prefetch of an img tag. |
| 198 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchImage) { | 185 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchImage) { |
| 199 RequestCounter image_counter; | 186 RequestCounter image_counter; |
| 200 CountRequestFor(kPrefetchJpeg, &image_counter); | 187 CountRequestFor(kPrefetchJpeg, &image_counter); |
| 201 GURL main_page_url = | 188 base::StringPairs replacement_text; |
| 202 GetURLWithReplacement(kPrefetchImagePage, "REPLACE_WITH_IMAGE_URL", | 189 replacement_text.push_back( |
| 203 MakeAbsolute(kPrefetchJpeg)); | 190 std::make_pair("REPLACE_WITH_IMAGE_URL", MakeAbsolute(kPrefetchJpeg))); |
| 204 PrefetchFromURL(main_page_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); | 191 std::string main_page_path; |
| 192 net::test_server::GetFilePathWithReplacements( |
| 193 kPrefetchImagePage, replacement_text, &main_page_path); |
| 194 // Note CountRequestFor cannot be used on the main page as the test server |
| 195 // must handling the image url replacement. |
| 196 PrefetchFromFile(main_page_path, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 205 image_counter.WaitForCount(1); | 197 image_counter.WaitForCount(1); |
| 206 } | 198 } |
| 207 | 199 |
| 208 // Checks that a cross-domain prefetching works correctly. | 200 // Checks that a cross-domain prefetching works correctly. |
| 209 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchCrossDomain) { | 201 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchCrossDomain) { |
| 210 static const std::string secondary_domain = "www.foo.com"; | 202 static const std::string secondary_domain = "www.foo.com"; |
| 211 host_resolver()->AddRule(secondary_domain, "127.0.0.1"); | 203 host_resolver()->AddRule(secondary_domain, "127.0.0.1"); |
| 212 GURL cross_domain_url(base::StringPrintf( | 204 GURL cross_domain_url(base::StringPrintf( |
| 213 "http://%s:%d/%s", secondary_domain.c_str(), | 205 "http://%s:%d/%s", secondary_domain.c_str(), |
| 214 embedded_test_server()->host_port_pair().port(), kPrefetchPage)); | 206 embedded_test_server()->host_port_pair().port(), kPrefetchPage)); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, SSLSubresourceError) { | 398 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, SSLSubresourceError) { |
| 407 // First confirm that the image loads as expected. | 399 // First confirm that the image loads as expected. |
| 408 | 400 |
| 409 // A separate HTTPS server is started for the subresource; src_server() is | 401 // A separate HTTPS server is started for the subresource; src_server() is |
| 410 // non-HTTPS. | 402 // non-HTTPS. |
| 411 net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); | 403 net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); |
| 412 https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME); | 404 https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME); |
| 413 https_server.ServeFilesFromSourceDirectory("chrome/test/data"); | 405 https_server.ServeFilesFromSourceDirectory("chrome/test/data"); |
| 414 ASSERT_TRUE(https_server.Start()); | 406 ASSERT_TRUE(https_server.Start()); |
| 415 GURL https_url = https_server.GetURL("/prerender/image.jpeg"); | 407 GURL https_url = https_server.GetURL("/prerender/image.jpeg"); |
| 416 GURL main_page_url = GetURLWithReplacement( | 408 base::StringPairs replacement_text; |
| 417 kPrefetchImagePage, "REPLACE_WITH_IMAGE_URL", https_url.spec()); | 409 replacement_text.push_back( |
| 410 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec())); |
| 411 std::string main_page_path; |
| 412 net::test_server::GetFilePathWithReplacements( |
| 413 kPrefetchImagePage, replacement_text, &main_page_path); |
| 418 RequestCounter script_counter; | 414 RequestCounter script_counter; |
| 419 CountRequestFor(kPrefetchScript, &script_counter); | 415 CountRequestFor(kPrefetchScript, &script_counter); |
| 420 | 416 |
| 421 std::unique_ptr<TestPrerender> prerender = | 417 std::unique_ptr<TestPrerender> prerender = |
| 422 PrefetchFromURL(main_page_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); | 418 PrefetchFromFile(main_page_path, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 423 // Checks that the presumed failure of the image load didn't affect the script | 419 // Checks that the presumed failure of the image load didn't affect the script |
| 424 // fetch. This assumes waiting for the script load is enough to see any error | 420 // fetch. This assumes waiting for the script load is enough to see any error |
| 425 // from the image load. | 421 // from the image load. |
| 426 script_counter.WaitForCount(1); | 422 script_counter.WaitForCount(1); |
| 427 } | 423 } |
| 428 | 424 |
| 429 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Loop) { | 425 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Loop) { |
| 430 RequestCounter script_counter; | 426 RequestCounter script_counter; |
| 431 CountRequestFor(kPrefetchScript, &script_counter); | 427 CountRequestFor(kPrefetchScript, &script_counter); |
| 432 RequestCounter main_counter; | 428 RequestCounter main_counter; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 | 596 |
| 601 // The SW intercepts kPrefetchPage and replaces it with a body that contains | 597 // The SW intercepts kPrefetchPage and replaces it with a body that contains |
| 602 // an <img> tage for kPrefetchPng. This verifies that the SW ran correctly by | 598 // an <img> tage for kPrefetchPng. This verifies that the SW ran correctly by |
| 603 // observing the fetch of the image. | 599 // observing the fetch of the image. |
| 604 RequestCounter image_counter; | 600 RequestCounter image_counter; |
| 605 CountRequestFor(kPrefetchPng, &image_counter); | 601 CountRequestFor(kPrefetchPng, &image_counter); |
| 606 PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); | 602 PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); |
| 607 image_counter.WaitForCount(1); | 603 image_counter.WaitForCount(1); |
| 608 } | 604 } |
| 609 | 605 |
| 610 // Checks that prefetching happens if an appcache is mentioned in the html tag | |
| 611 // but is uninitialized. | |
| 612 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, AppCacheHtmlUninitialized) { | |
| 613 RequestCounter image_counter; | |
| 614 CountRequestFor(kPrefetchPng, &image_counter); | |
| 615 PrefetchFromFile(kPrefetchAppcache, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); | |
| 616 image_counter.WaitForCount(1); | |
| 617 } | |
| 618 | |
| 619 // Checks that prefetching does not if an initialized appcache is mentioned in | |
| 620 // the html tag. | |
| 621 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, AppCacheHtmlInitialized) { | |
| 622 base::TimeTicks current_time = GetPrerenderManager()->GetCurrentTimeTicks(); | |
| 623 auto* clock = OverridePrerenderManagerTimeTicks(); | |
| 624 // Some navigations have already occurred in test setup. In order to track | |
| 625 // duplicate prefetches correctly the test clock needs to be beyond those | |
| 626 // navigations. | |
| 627 clock->SetNowTicks(current_time); | |
| 628 clock->Advance(base::TimeDelta::FromSeconds(600)); | |
| 629 | |
| 630 // Fill manifest with the image url. The main resource will be cached | |
| 631 // implicitly. | |
| 632 GURL image_url = src_server()->GetURL(MakeAbsolute(kPrefetchPng)); | |
| 633 GURL manifest_url = GetURLWithReplacement( | |
| 634 kPrefetchAppcacheManifest, "REPLACE_WITH_URL", image_url.spec()); | |
| 635 GURL appcache_page_url = GetURLWithReplacement( | |
| 636 kPrefetchAppcache, "REPLACE_WITH_MANIFEST", manifest_url.spec()); | |
| 637 | |
| 638 // Load the page into the appcache. | |
| 639 ui_test_utils::NavigateToURL(current_browser(), appcache_page_url); | |
| 640 | |
| 641 // If a page is prefetch shortly after being loading, the prefetch is | |
| 642 // canceled. Advancing the clock prevents the cancelation. | |
| 643 clock->Advance(base::TimeDelta::FromSeconds(6000)); | |
| 644 | |
| 645 RequestCounter script_counter; | |
| 646 CountRequestFor(kPrefetchScript, &script_counter); | |
| 647 // While the prefetch stops when it sees the AppCache manifest, from the point | |
| 648 // of view of the prerender manager the prefetch stops normally. | |
| 649 PrefetchFromURL(appcache_page_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); | |
| 650 | |
| 651 // The prefetch should have been canceled before the script in | |
| 652 // kPrefetchAppcache is loaded (note the script is not mentioned in the | |
| 653 // manifest). | |
| 654 script_counter.WaitForCount(0); | |
| 655 } | |
| 656 | |
| 657 // If a page has been cached by another AppCache, the prefetch should be | |
| 658 // canceled. | |
| 659 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, AppCacheRegistered) { | |
| 660 base::TimeTicks current_time = GetPrerenderManager()->GetCurrentTimeTicks(); | |
| 661 auto* clock = OverridePrerenderManagerTimeTicks(); | |
| 662 // Some navigations have already occurred in test setup. In order to track | |
| 663 // duplicate prefetches correctly the test clock needs to be beyond those | |
| 664 // navigations. | |
| 665 clock->SetNowTicks(current_time); | |
| 666 clock->Advance(base::TimeDelta::FromSeconds(600)); | |
| 667 | |
| 668 // Fill manifest with kPrefetchPage so that it is cached without explicitly | |
| 669 // listing a manifest. | |
| 670 GURL prefetch_page_url = src_server()->GetURL(MakeAbsolute(kPrefetchPage)); | |
| 671 GURL manifest_url = GetURLWithReplacement( | |
| 672 kPrefetchAppcacheManifest, "REPLACE_WITH_URL", prefetch_page_url.spec()); | |
| 673 | |
| 674 GURL appcache_page_url = GetURLWithReplacement( | |
| 675 kPrefetchAppcache, "REPLACE_WITH_MANIFEST", manifest_url.spec()); | |
| 676 | |
| 677 // Load the page into the appcache. | |
| 678 ui_test_utils::NavigateToURL(current_browser(), appcache_page_url); | |
| 679 // Load the prefetch page so it can be cached. | |
| 680 ui_test_utils::NavigateToURL(current_browser(), prefetch_page_url); | |
| 681 | |
| 682 // If a page is prefetch shortly after being loading, the prefetch is | |
| 683 // canceled. Advancing the clock prevents the cancelation. | |
| 684 clock->Advance(base::TimeDelta::FromSeconds(6000)); | |
| 685 | |
| 686 RequestCounter page_counter; | |
| 687 CountRequestFor(kPrefetchPage, &page_counter); | |
| 688 RequestCounter script_counter; | |
| 689 CountRequestFor(kPrefetchScript, &script_counter); | |
| 690 PrefetchFromURL(prefetch_page_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); | |
| 691 // Neither the page nor the script should be prefetched. | |
| 692 script_counter.WaitForCount(0); | |
| 693 page_counter.WaitForCount(0); | |
| 694 } | |
| 695 | |
| 696 } // namespace prerender | 606 } // namespace prerender |
| OLD | NEW |