Commit 15c6f4fb authored by Alex Turner's avatar Alex Turner Committed by Commit Bot

Add Web Platform Tests for the Split Cache

We add a web platform test for the cache when it is partitioned by top-
frame origin. The test caches a resource, then attempts to load it in
a popup window. With the split cache, if the popup window is
cross-origin, we would expect that request to be a cache miss. We
compare the number of requests that hit the server to our expectations.
To enable these tests, the existing framework is slightly refactored,
including to respond to CORS preflight requests.

The virtual test suites virtual/split-http-cache and
virtual/not-split-http-cache explicitly test the cases of a split and
not-split cache, respectively. The default test is disabled as its
result depends on whether the split cache feature is enabled.

Bug: 981970
Change-Id: I049fdaec4aebcbdeebdd3c77d13d6ca420d1bd62
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1890952Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Reviewed-by: default avatarShivani Sharma <shivanisha@chromium.org>
Commit-Queue: Alex Turner <alexmt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#714236}
parent 00c9d3fc
...@@ -3451,7 +3451,11 @@ crbug.com/626703 external/wpt/css/css-shapes/shape-outside/shape-image/gradients ...@@ -3451,7 +3451,11 @@ crbug.com/626703 external/wpt/css/css-shapes/shape-outside/shape-image/gradients
crbug.com/626703 external/wpt/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-010.html [ Failure ] crbug.com/626703 external/wpt/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-010.html [ Failure ]
crbug.com/626703 external/wpt/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-009.html [ Failure ] crbug.com/626703 external/wpt/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-009.html [ Failure ]
crbug.com/626703 external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ] crbug.com/626703 external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ]
crbug.com/981970 external/wpt/fetch/http-cache/split-cache.tentative.html [ Skip ]
crbug.com/626703 virtual/omt-worker-fetch/external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ]
crbug.com/981970 virtual/omt-worker-fetch/external/wpt/fetch/http-cache/split-cache.tentative.html [ Skip ]
crbug.com/626703 virtual/not-split-http-cache/external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ]
crbug.com/626703 virtual/split-http-cache/external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ]
crbug.com/626703 external/wpt/css/css-fonts/font-feature-settings-descriptor-01.html [ Failure ] crbug.com/626703 external/wpt/css/css-fonts/font-feature-settings-descriptor-01.html [ Failure ]
crbug.com/626703 [ Win10 ] external/wpt/fetch/api/redirect/redirect-count.any.worker.html [ Timeout ] crbug.com/626703 [ Win10 ] external/wpt/fetch/api/redirect/redirect-count.any.worker.html [ Timeout ]
crbug.com/626703 [ Win10 ] external/wpt/fetch/api/redirect/redirect-count.any.html [ Timeout ] crbug.com/626703 [ Win10 ] external/wpt/fetch/api/redirect/redirect-count.any.html [ Timeout ]
......
...@@ -634,5 +634,15 @@ ...@@ -634,5 +634,15 @@
"prefix": "hdr", "prefix": "hdr",
"bases": [], "bases": [],
"args": ["--force-color-profile=scrgb-linear"] "args": ["--force-color-profile=scrgb-linear"]
},
{
"prefix": "split-http-cache",
"bases": ["external/wpt/fetch/http-cache"],
"args": ["--enable-features=SplitCacheByNetworkIsolationKey"]
},
{
"prefix": "not-split-http-cache",
"bases": ["external/wpt/fetch/http-cache"],
"args": ["--disable-features=SplitCacheByNetworkIsolationKey"]
} }
] ]
...@@ -42,6 +42,12 @@ function makeTest (test) { ...@@ -42,6 +42,12 @@ function makeTest (test) {
return function () { return function () {
var uuid = token() var uuid = token()
var requests = expandTemplates(test) var requests = expandTemplates(test)
var fetchFunctions = makeFetchFunctions(requests, uuid)
return runTest(fetchFunctions, requests, uuid)
}
}
function makeFetchFunctions(requests, uuid) {
var fetchFunctions = [] var fetchFunctions = []
for (let i = 0; i < requests.length; ++i) { for (let i = 0; i < requests.length; ++i) {
fetchFunctions.push({ fetchFunctions.push({
...@@ -62,6 +68,10 @@ function makeTest (test) { ...@@ -62,6 +68,10 @@ function makeTest (test) {
pauseAfter: 'pause_after' in requests[i] pauseAfter: 'pause_after' in requests[i]
}) })
} }
return fetchFunctions
}
function runTest(fetchFunctions, requests, uuid) {
var idx = 0 var idx = 0
function runNextStep () { function runNextStep () {
if (fetchFunctions.length) { if (fetchFunctions.length) {
...@@ -86,7 +96,6 @@ function makeTest (test) { ...@@ -86,7 +96,6 @@ function makeTest (test) {
checkRequests(requests, testState) checkRequests(requests, testState)
return Promise.resolve() return Promise.resolve()
}) })
}
} }
function expandTemplates (test) { function expandTemplates (test) {
...@@ -226,10 +235,14 @@ function pause () { ...@@ -226,10 +235,14 @@ function pause () {
function makeTestUrl (uuid, config) { function makeTestUrl (uuid, config) {
var arg = '' var arg = ''
var base_url = ''
if ('base_url' in config) {
base_url = config.base_url
}
if ('query_arg' in config) { if ('query_arg' in config) {
arg = `&target=${config.query_arg}` arg = `&target=${config.query_arg}`
} }
return `resources/http-cache.py?dispatch=test&uuid=${uuid}${arg}` return `${base_url}resources/http-cache.py?dispatch=test&uuid=${uuid}${arg}`
} }
function getServerState (uuid) { function getServerState (uuid) {
......
...@@ -13,6 +13,9 @@ DATEHDRS = set(['date', 'expires', 'last-modified']) ...@@ -13,6 +13,9 @@ DATEHDRS = set(['date', 'expires', 'last-modified'])
def main(request, response): def main(request, response):
dispatch = request.GET.first("dispatch", None) dispatch = request.GET.first("dispatch", None)
uuid = request.GET.first("uuid", None) uuid = request.GET.first("uuid", None)
if request.method == "OPTIONS":
return handle_preflight(uuid, request, response)
if not uuid: if not uuid:
response.status = (404, "Not Found") response.status = (404, "Not Found")
response.headers.set("Content-Type", "text/plain") response.headers.set("Content-Type", "text/plain")
...@@ -25,6 +28,14 @@ def main(request, response): ...@@ -25,6 +28,14 @@ def main(request, response):
response.headers.set("Content-Type", "text/plain") response.headers.set("Content-Type", "text/plain")
return "Fallthrough" return "Fallthrough"
def handle_preflight(uuid, request, response):
response.status = (200, "OK")
response.headers.set("Access-Control-Allow-Origin", "*")
response.headers.set("Access-Control-Allow-Methods", "GET")
response.headers.set("Access-Control-Allow-Headers", "*")
response.headers.set("Access-Control-Max-Age", "86400")
return "Preflight request"
def handle_state(uuid, request, response): def handle_state(uuid, request, response):
response.headers.set("Content-Type", "text/plain") response.headers.set("Content-Type", "text/plain")
return json.dumps(request.server.stash.take(uuid)) return json.dumps(request.server.stash.take(uuid))
......
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>HTTP Cache - helper</title>
<meta name="help" href="https://fetch.spec.whatwg.org/#request">
<meta name="timeout" content="normal">
<script src="/resources/testharness.js"></script>
<script src="../http-cache.js"></script>
</head>
<body>
<script>
window.addEventListener("message", function listener(event) {
window.removeEventListener("message", listener)
var fetchFunction = makeFetchFunctions(event.data.requests, event.data.uuid)[event.data.index]
fetchFunction.code(event.data.index).then(
function(response) {
event.source.postMessage("success", event.origin)
},
function(response) {
event.source.postMessage("success", event.origin)
}
)
})
</script>
</body>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>HTTP Cache - Partioning by top-level origin</title>
<meta name="help" href="https://fetch.spec.whatwg.org/#request">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="http-cache.js"></script>
</head>
<body>
<script>
const host = get_host_info();
// We run this entire test twice: first with a same-origin then with a cross-origin popup
function performFullTest(is_same_origin_test) {
const POPUP_HTTP_ORIGIN = is_same_origin_test ? host.HTTP_ORIGIN : host.HTTP_REMOTE_ORIGIN
const LOCAL_HTTP_ORIGIN = host.HTTP_ORIGIN
const popupBaseURL = POPUP_HTTP_ORIGIN + window.location.pathname.replace(/\/[^\/]*$/, '/') ;
const localBaseURL = LOCAL_HTTP_ORIGIN + window.location.pathname.replace(/\/[^\/]*$/, '/') ;
var test = {
name: "HTTP Cache is partitioned by top-frame origin",
requests: [
{
response_headers: [
["Expires", (30 * 24 * 60 * 60)]
],
base_url: localBaseURL
},
{
base_url: localBaseURL
},
{
request_headers: [
["Cache-Control", "no-cache"]
],
// If the popup's request was a cache hit, we would only expect 2
// requests to the server. If it was a cache miss, we would expect 3.
expected_response_headers: [
["server-request-count", is_same_origin_test ? "2" : "3"]
],
base_url: localBaseURL
}
]
}
var uuid = token()
var local_requests = expandTemplates(test)
var fetchFns = makeFetchFunctions(local_requests, uuid)
var popup_requests = expandTemplates(test)
// Request the resource with a long cache expiry
function local_fetch() {
return fetchFns[0].code(0)
}
function popup_fetch() {
return new Promise(function(resolve, reject) {
var win = window.open(popupBaseURL + "resources/split-origin-popup.html")
// Post a message to intisearchte the popup's request and give the necessary
// information. Posted researchtedly to account for dropped messages as the
// popup is loading.
function postMessage(event) {
var payload = {
index: 1,
requests: popup_requests,
uuid: uuid
}
win.postMessage(payload, POPUP_HTTP_ORIGIN)
}
var messagePoster = setInterval(postMessage, 100)
// Listen for the result
function messageListener(event) {
if (event.origin !== POPUP_HTTP_ORIGIN) {
reject("Unknown error")
} else if (event.data === "success") {
resolve()
} else if (event.data === "error") {
reject("Error in popup")
} else {
return; // Ignore testharness.js internal messages
}
window.removeEventListener("message", messageListener)
clearInterval(messagePoster)
win.close()
}
window.addEventListener("message", messageListener)
})
}
function local_fetch2() {
return fetchFns[2].code(2)
}
// Final checks.
function check_server_info() {
return getServerState(uuid)
.then(function (testState) {
checkRequests(local_requests, testState)
return Promise.resolve()
})
}
promise_test(() => local_fetch().then(popup_fetch).then(local_fetch2).then(check_server_info))
}
performFullTest(true);
performFullTest(false);
</script>
</body>
</html>
\ No newline at end of file
# virtual/not-split-http-cache
This directory is for tests when the HTTP cache is *not* partitioned by
top-frame origin. Tests under `virtual/not-split-http-cache` are run with
`--disable-features=SplitCacheByNetworkIsolationKey`.
This is a testharness.js-based test.
PASS HTTP Cache - Partioning by top-level origin
FAIL HTTP Cache - Partioning by top-level origin 1 assert_equals: Response 3 header server-request-count is "2", not "3" expected "3" but got "2"
Harness: the test ran to completion.
# virtual/split-http-cache
This directory is for tests when the HTTP cache is partitioned by
top-frame origin. Tests under `virtual/split-http-cache` are run with
`--enable-features=SplitCacheByNetworkIsolationKey`.
This is a testharness.js-based test.
PASS HTTP Cache - Partioning by top-level origin
PASS HTTP Cache - Partioning by top-level origin 1
Harness: the test ran to completion.
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