Commit 276256f3 authored by Matthew Cary's avatar Matthew Cary Committed by Commit Bot

Prerender: test no recursive NoStatePrefetch.

Obsolete and flaky tests for the disabled classical prerender are
removed.

This test also adds an ignored ExpectedContents to prevent a race
condition in the test when a PrerenderContents final status may be
checked before or after the test tears itself down.

Bug: 903695
Change-Id: Ia77b3beb79bf579ca1904c54e469f0de4b648f94
Reviewed-on: https://chromium-review.googlesource.com/c/1333779
Commit-Queue: Matthew Cary <mattcary@chromium.org>
Reviewed-by: default avatarEgor Pasko <pasko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#607944}
parent 678fc40f
...@@ -1691,84 +1691,6 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderQuickQuit) { ...@@ -1691,84 +1691,6 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderQuickQuit) {
FINAL_STATUS_APP_TERMINATING, 0); FINAL_STATUS_APP_TERMINATING, 0);
} }
// Checks that we don't prerender in an infinite loop.
// TODO(crbug.com/903695): This test is flaky.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderInfiniteLoop) {
const char* const kHtmlFileA = "/prerender/prerender_infinite_a.html";
const char* const kHtmlFileB = "/prerender/prerender_infinite_b.html";
std::vector<FinalStatus> expected_final_status_queue;
expected_final_status_queue.push_back(FINAL_STATUS_USED);
expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
std::vector<std::unique_ptr<TestPrerender>> prerenders =
PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
ASSERT_TRUE(prerenders[0]->contents());
// Assert that the pending prerender is in there already. This relies on the
// fact that the renderer sends out the AddLinkRelPrerender IPC before sending
// the page load one.
EXPECT_EQ(2U, GetLinkPrerenderCount());
EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
// Next url should be in pending list but not an active entry.
EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
NavigateToDestURL();
// Make sure the PrerenderContents for the next url is now in the manager and
// not pending. This relies on pending prerenders being resolved in the same
// event loop iteration as OnPrerenderStop.
EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB));
EXPECT_EQ(1U, GetLinkPrerenderCount());
EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
}
// Checks that we don't prerender in an infinite loop and multiple links are
// handled correctly.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
DISABLED_PrerenderInfiniteLoopMultiple) {
const char* const kHtmlFileA =
"/prerender/prerender_infinite_a_multiple.html";
const char* const kHtmlFileB =
"/prerender/prerender_infinite_b_multiple.html";
const char* const kHtmlFileC =
"/prerender/prerender_infinite_c_multiple.html";
// This test is conceptually simplest if concurrency is at two, since we
// don't have to worry about which of kHtmlFileB or kHtmlFileC gets evicted.
GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
std::vector<FinalStatus> expected_final_status_queue;
expected_final_status_queue.push_back(FINAL_STATUS_USED);
expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
std::vector<std::unique_ptr<TestPrerender>> prerenders =
PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
ASSERT_TRUE(prerenders[0]->contents());
// Next url should be in pending list but not an active entry. This relies on
// the fact that the renderer sends out the AddLinkRelPrerender IPC before
// sending the page load one.
EXPECT_EQ(3U, GetLinkPrerenderCount());
EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC));
NavigateToDestURL();
// Make sure the PrerenderContents for the next urls are now in the manager
// and not pending. One and only one of the URLs (the last seen) should be the
// active entry. This relies on pending prerenders being resolved in the same
// event loop iteration as OnPrerenderStop.
bool url_b_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileB);
bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC);
EXPECT_TRUE(url_b_is_active_prerender && url_c_is_active_prerender);
EXPECT_EQ(2U, GetLinkPrerenderCount());
EXPECT_EQ(2U, GetRunningLinkPrerenderCount());
}
// Checks that pending prerenders are aborted (and never launched) when launched // Checks that pending prerenders are aborted (and never launched) when launched
// by a prerender that itself gets aborted. // by a prerender that itself gets aborted.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAbortPendingOnCancel) { IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAbortPendingOnCancel) {
......
...@@ -72,12 +72,14 @@ const char kPrefetchJpeg[] = "/prerender/image.jpeg"; ...@@ -72,12 +72,14 @@ const char kPrefetchJpeg[] = "/prerender/image.jpeg";
const char kPrefetchLoaderPath[] = "/prerender/prefetch_loader.html"; const char kPrefetchLoaderPath[] = "/prerender/prefetch_loader.html";
const char kPrefetchLoopPage[] = "/prerender/prefetch_loop.html"; const char kPrefetchLoopPage[] = "/prerender/prefetch_loop.html";
const char kPrefetchMetaCSP[] = "/prerender/prefetch_meta_csp.html"; const char kPrefetchMetaCSP[] = "/prerender/prefetch_meta_csp.html";
const char kPrefetchNostorePage[] = "/prerender/prefetch_nostore_page.html";
const char kPrefetchPage[] = "/prerender/prefetch_page.html"; const char kPrefetchPage[] = "/prerender/prefetch_page.html";
const char kPrefetchPage2[] = "/prerender/prefetch_page2.html"; const char kPrefetchPage2[] = "/prerender/prefetch_page2.html";
const char kPrefetchPageBigger[] = "/prerender/prefetch_page_bigger.html"; const char kPrefetchPageBigger[] = "/prerender/prefetch_page_bigger.html";
const char kPrefetchPng[] = "/prerender/image.png"; const char kPrefetchPng[] = "/prerender/image.png";
const char kPrefetchPng2[] = "/prerender/image2.png"; const char kPrefetchPng2[] = "/prerender/image2.png";
const char kPrefetchPngRedirect[] = "/prerender/image-redirect.png"; const char kPrefetchPngRedirect[] = "/prerender/image-redirect.png";
const char kPrefetchRecursePage[] = "/prerender/prefetch_recurse.html";
const char kPrefetchResponseHeaderCSP[] = const char kPrefetchResponseHeaderCSP[] =
"/prerender/prefetch_response_csp.html"; "/prerender/prefetch_response_csp.html";
const char kPrefetchScript[] = "/prerender/prefetch.js"; const char kPrefetchScript[] = "/prerender/prefetch.js";
...@@ -481,6 +483,24 @@ IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimultaneous) { ...@@ -481,6 +483,24 @@ IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimultaneous) {
WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 1); WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 1);
} }
// Checks that a prefetch does not recursively prefetch.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, NoPrefetchRecursive) {
// A prefetch of a page with a prefetch of the image page should not load the
// image page.
PrefetchFromFile(kPrefetchRecursePage,
FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
WaitForRequestCount(src_server()->GetURL(kPrefetchRecursePage), 1);
WaitForRequestCount(src_server()->GetURL(kPrefetchNostorePage), 0);
// When the first page is loaded, the image page should be prefetched. The
// test may finish before the prerender is torn down, so
// IgnorePrerenderContents() is called to skip the final status check.
prerender_contents_factory()->IgnorePrerenderContents();
ui_test_utils::NavigateToURL(current_browser(),
src_server()->GetURL(kPrefetchRecursePage));
WaitForRequestCount(src_server()->GetURL(kPrefetchNostorePage), 1);
}
// Checks a prefetch to a nonexisting page. // Checks a prefetch to a nonexisting page.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchNonexisting) { IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchNonexisting) {
std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile( std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile(
......
...@@ -277,7 +277,8 @@ TestPrerenderContents::TestPrerenderContents( ...@@ -277,7 +277,8 @@ TestPrerenderContents::TestPrerenderContents(
const GURL& url, const GURL& url,
const content::Referrer& referrer, const content::Referrer& referrer,
Origin origin, Origin origin,
FinalStatus expected_final_status) FinalStatus expected_final_status,
bool ignore_final_status)
: PrerenderContents(prerender_manager, profile, url, referrer, origin), : PrerenderContents(prerender_manager, profile, url, referrer, origin),
expected_final_status_(expected_final_status), expected_final_status_(expected_final_status),
observer_(this), observer_(this),
...@@ -285,7 +286,7 @@ TestPrerenderContents::TestPrerenderContents( ...@@ -285,7 +286,7 @@ TestPrerenderContents::TestPrerenderContents(
was_hidden_(false), was_hidden_(false),
was_shown_(false), was_shown_(false),
should_be_shown_(expected_final_status == FINAL_STATUS_USED), should_be_shown_(expected_final_status == FINAL_STATUS_USED),
skip_final_checks_(false) {} skip_final_checks_(ignore_final_status) {}
TestPrerenderContents::~TestPrerenderContents() { TestPrerenderContents::~TestPrerenderContents() {
if (skip_final_checks_) if (skip_final_checks_)
...@@ -519,6 +520,10 @@ TestPrerenderContentsFactory::ExpectPrerenderContents( ...@@ -519,6 +520,10 @@ TestPrerenderContentsFactory::ExpectPrerenderContents(
return handle; return handle;
} }
void TestPrerenderContentsFactory::IgnorePrerenderContents() {
expected_contents_queue_.push_back(ExpectedContents(true));
}
PrerenderContents* TestPrerenderContentsFactory::CreatePrerenderContents( PrerenderContents* TestPrerenderContentsFactory::CreatePrerenderContents(
PrerenderManager* prerender_manager, PrerenderManager* prerender_manager,
Profile* profile, Profile* profile,
...@@ -530,15 +535,15 @@ PrerenderContents* TestPrerenderContentsFactory::CreatePrerenderContents( ...@@ -530,15 +535,15 @@ PrerenderContents* TestPrerenderContentsFactory::CreatePrerenderContents(
expected = expected_contents_queue_.front(); expected = expected_contents_queue_.front();
expected_contents_queue_.pop_front(); expected_contents_queue_.pop_front();
} }
TestPrerenderContents* contents = new TestPrerenderContents( TestPrerenderContents* contents =
prerender_manager, profile, url, referrer, origin, expected.final_status); new TestPrerenderContents(prerender_manager, profile, url, referrer,
origin, expected.final_status, expected.ignore);
if (expected.handle) if (expected.handle)
expected.handle->OnPrerenderCreated(contents); expected.handle->OnPrerenderCreated(contents);
return contents; return contents;
} }
TestPrerenderContentsFactory::ExpectedContents::ExpectedContents() TestPrerenderContentsFactory::ExpectedContents::ExpectedContents() {}
: final_status(FINAL_STATUS_MAX) {}
TestPrerenderContentsFactory::ExpectedContents::ExpectedContents( TestPrerenderContentsFactory::ExpectedContents::ExpectedContents(
const ExpectedContents& other) = default; const ExpectedContents& other) = default;
...@@ -548,6 +553,9 @@ TestPrerenderContentsFactory::ExpectedContents::ExpectedContents( ...@@ -548,6 +553,9 @@ TestPrerenderContentsFactory::ExpectedContents::ExpectedContents(
const base::WeakPtr<TestPrerender>& handle) const base::WeakPtr<TestPrerender>& handle)
: final_status(final_status), handle(handle) {} : final_status(final_status), handle(handle) {}
TestPrerenderContentsFactory::ExpectedContents::ExpectedContents(bool ignore)
: ignore(ignore) {}
TestPrerenderContentsFactory::ExpectedContents::~ExpectedContents() {} TestPrerenderContentsFactory::ExpectedContents::~ExpectedContents() {}
PrerenderInProcessBrowserTest::PrerenderInProcessBrowserTest() PrerenderInProcessBrowserTest::PrerenderInProcessBrowserTest()
......
...@@ -109,7 +109,8 @@ class TestPrerenderContents : public PrerenderContents, ...@@ -109,7 +109,8 @@ class TestPrerenderContents : public PrerenderContents,
const GURL& url, const GURL& url,
const content::Referrer& referrer, const content::Referrer& referrer,
Origin origin, Origin origin,
FinalStatus expected_final_status); FinalStatus expected_final_status,
bool ignore_final_status);
~TestPrerenderContents() override; ~TestPrerenderContents() override;
...@@ -280,6 +281,8 @@ class TestPrerenderContentsFactory : public PrerenderContents::Factory { ...@@ -280,6 +281,8 @@ class TestPrerenderContentsFactory : public PrerenderContents::Factory {
std::unique_ptr<TestPrerender> ExpectPrerenderContents( std::unique_ptr<TestPrerender> ExpectPrerenderContents(
FinalStatus final_status); FinalStatus final_status);
void IgnorePrerenderContents();
PrerenderContents* CreatePrerenderContents( PrerenderContents* CreatePrerenderContents(
PrerenderManager* prerender_manager, PrerenderManager* prerender_manager,
Profile* profile, Profile* profile,
...@@ -293,10 +296,12 @@ class TestPrerenderContentsFactory : public PrerenderContents::Factory { ...@@ -293,10 +296,12 @@ class TestPrerenderContentsFactory : public PrerenderContents::Factory {
ExpectedContents(const ExpectedContents& other); ExpectedContents(const ExpectedContents& other);
ExpectedContents(FinalStatus final_status, ExpectedContents(FinalStatus final_status,
const base::WeakPtr<TestPrerender>& handle); const base::WeakPtr<TestPrerender>& handle);
explicit ExpectedContents(bool ignore);
~ExpectedContents(); ~ExpectedContents();
FinalStatus final_status; FinalStatus final_status = FINAL_STATUS_MAX;
base::WeakPtr<TestPrerender> handle; bool ignore = false;
base::WeakPtr<TestPrerender> handle = nullptr;
}; };
base::circular_deque<ExpectedContents> expected_contents_queue_; base::circular_deque<ExpectedContents> expected_contents_queue_;
......
<html>
<body>
This is a page containing text.
</body>
</html>
Cache-Control: no-store
\ No newline at end of file
<html>
<head>
<link rel="prerender" href="prefetch_nostore_page.html">
</head>
<body>
Nonempty body for First Contentful Paint
</body>
</html>
<html>
<head>
<script>
var pageWasPrerendered = false;
function DidPrerenderPass() {
pageWasPrerendered = true;
return true;
}
function DidDisplayPass() {
return pageWasPrerendered;
}
</script>
</head>
<body>
<link rel="prerender" href="prerender_infinite_b_multiple.html">
<a href="prerender_infinite_b_multiple.html">B</a>
<link rel="prerender" href="prerender_infinite_c_multiple.html">
<a href="prerender_infinite_c_multiple.html">C</a>
</body>
</html>
<html>
<head>
</head>
<body>
<link rel="prerender" href="prerender_infinite_a_multiple.html">
<a href="prerender_infinite_a_multiple.html">A</a>
</body>
</html>
<html>
<head>
</head>
<body>
<link rel="prerender" href="prerender_infinite_a_multiple.html">
<a href="prerender_infinite_a_multiple.html">A</a>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment