Skip to content

Commit

Permalink
Add a test to evict the page when the response never ends by fetching…
Browse files Browse the repository at this point in the history
… in a dedicated worker

This CL adds a test for the eviction reason kNetworkRequestTimeout for
dedicated workers.

Design Doc: https://docs.google.com/document/d/1CJfDNqA2tEp_dmxK5kaBHHqGjx7cK2_jhTpsCwSCa3A/edit?usp=sharing

Bug: 1146955
Change-Id: I60c3e248283d949a817586db0921ef1fe37d3633
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3299755
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
Commit-Queue: Hajime Hoshi <hajimehoshi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#949375}
  • Loading branch information
Hajime Hoshi authored and Chromium LUCI CQ committed Dec 8, 2021
1 parent b88cb24 commit 8ef3bd7
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 1 deletion.
117 changes: 117 additions & 0 deletions content/browser/back_forward_cache_features_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,123 @@ IN_PROC_BROWSER_TEST_F(
{}, {}, {}, {}, FROM_HERE);
}

// Tests the case when fetch started in a dedicated worker, but the response
// never ends after the page is frozen. This should result in an eviction due to
// timeout.
IN_PROC_BROWSER_TEST_F(BackForwardCacheWithDedicatedWorkerBrowserTest,
ImageStillLoading_ResponseStartedWhileFrozen_Timeout) {
CreateHttpsServer();

net::test_server::ControllableHttpResponse image_response(https_server(),
"/image.png");
ASSERT_TRUE(https_server()->Start());

GURL url_a(https_server()->GetURL("a.test", "/title1.html"));
GURL url_b(https_server()->GetURL("b.test", "/title1.html"));

// Navigate to A.
EXPECT_TRUE(NavigateToURL(shell(), url_a));
RenderFrameHostImplWrapper rfh_a(current_frame_host());

// Call fetch in a dedicated worker before navigating away.
std::string worker_script =
JsReplace(R"(
fetch($1);
)",
https_server()->GetURL("a.test", "/image.png"));
EXPECT_TRUE(ExecJs(rfh_a.get(), JsReplace(R"(
const blob = new Blob([$1]);
const blobURL = URL.createObjectURL(blob);
const worker = new Worker(blobURL);
)",
worker_script)));

// Wait for the image request, but don't send anything yet.
image_response.WaitForRequest();

// Navigate away.
EXPECT_TRUE(NavigateToURL(shell(), url_b));
// The page was still loading when we navigated away, but it's still eligible
// for back-forward cache.
EXPECT_TRUE(rfh_a->IsInBackForwardCache());

RenderFrameDeletedObserver delete_observer(rfh_a.get());
// Start sending the image response while in the back-forward cache, but never
// finish the request. Eventually the page will get deleted due to network
// request timeout.
image_response.Send(net::HTTP_OK, "image/png");
delete_observer.WaitUntilDeleted();

// 3) Go back to the first page. We should not restore the page from the
// back-forward cache.
ASSERT_TRUE(HistoryGoBack(web_contents()));
ExpectNotRestored(
{BackForwardCacheMetrics::NotRestoredReason::kNetworkRequestTimeout}, {},
{}, {}, {}, FROM_HERE);
}

// Tests the case when fetch started in a nested dedicated worker, but the
// response never ends after the page is frozen. This should result in an
// eviction due to timeout.
IN_PROC_BROWSER_TEST_F(
BackForwardCacheWithDedicatedWorkerBrowserTest,
ImageStillLoading_ResponseStartedWhileFrozen_Timeout_Nested) {
CreateHttpsServer();

net::test_server::ControllableHttpResponse image_response(https_server(),
"/image.png");
ASSERT_TRUE(https_server()->Start());

GURL url_a(https_server()->GetURL("a.test", "/title1.html"));
GURL url_b(https_server()->GetURL("b.test", "/title1.html"));

// Navigate to A.
EXPECT_TRUE(NavigateToURL(shell(), url_a));
RenderFrameHostImplWrapper rfh_a(current_frame_host());

// Call fetch in a dedicated worker before navigating away.
std::string child_worker_script =
JsReplace(R"(
fetch($1);
)",
https_server()->GetURL("a.test", "/image.png"));
std::string parent_worker_script = JsReplace(R"(
const blob = new Blob([$1]);
const blobURL = URL.createObjectURL(blob);
const worker = new Worker(blobURL);
)",
child_worker_script);
EXPECT_TRUE(ExecJs(rfh_a.get(), JsReplace(R"(
const blob = new Blob([$1]);
const blobURL = URL.createObjectURL(blob);
const worker = new Worker(blobURL);
)",
parent_worker_script)));

// Wait for the image request, but don't send anything yet.
image_response.WaitForRequest();

// Navigate away.
EXPECT_TRUE(NavigateToURL(shell(), url_b));
// The page was still loading when we navigated away, but it's still eligible
// for back-forward cache.
EXPECT_TRUE(rfh_a->IsInBackForwardCache());

RenderFrameDeletedObserver delete_observer(rfh_a.get());
// Start sending the image response while in the back-forward cache, but never
// finish the request. Eventually the page will get deleted due to network
// request timeout.
image_response.Send(net::HTTP_OK, "image/png");
delete_observer.WaitUntilDeleted();

// 3) Go back to the first page. We should not restore the page from the
// back-forward cache.
ASSERT_TRUE(HistoryGoBack(web_contents()));
ExpectNotRestored(
{BackForwardCacheMetrics::NotRestoredReason::kNetworkRequestTimeout}, {},
{}, {}, {}, FROM_HERE);
}

// TODO(https://crbug.com/154571): Shared workers are not available on Android.
#if defined(OS_ANDROID)
#define MAYBE_PageWithSharedWorkerNotCached \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,6 @@ IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
// finish the request. Eventually the page will get deleted due to network
// request timeout.
image_response.Send(net::HTTP_OK, "image/png");
std::string body(kMaxBufferedBytesPerRequest + 1, '*');
delete_observer.WaitUntilDeleted();

// 3) Go back to the first page. We should not restore the page from the
Expand Down

0 comments on commit 8ef3bd7

Please sign in to comment.