Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetch KeepAlive Quota Tests #4788

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions fetch/api/request/request-keepalive-quota.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Request Keepalive Quota Tests</title>
<meta name="help" href="https://fetch.spec.whatwg.org/#request">
<meta name="help" href="https://fetch.spec.whatwg.org/#body-mixin">
<meta name="author" title="Microsoft Edge" href="https://www.microsoft.com">
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>
"use strict";

// We want to ensure that our keepalive requests hang slightly before completing so we can validate
// the effects of a rolling quota. To do this we will utilize trickle.py with a 1s delay. This should
// prevent any of the Fetch's from finishing in this window.
var trickleURL = "../resources/trickle.py?count=1&ms=";
var standardDelay = 1000;

// We should expect 64KiB of rolling quota for any type of keep-alive request sent.
var expectedQuota = 65536;

function CreateKeepAliveRequest(delay, bodySize) {
// Create a body of the specified size that's filled with *'s
var requestBody = "*".repeat(bodySize);
return new Request(trickleURL+delay, {keepalive: true, body: requestBody, method: "POST"});
}

// Test 1 Byte
promise_test(function(test) {
return fetch(CreateKeepAliveRequest(0 /* delay */, 1 /* bodySize */));
}, "A Keep-Alive fetch() with a small body should succeed.");

// Test Quota full limit
promise_test(function(test) {
return fetch(CreateKeepAliveRequest(0 /* delay */, expectedQuota));
}, "A Keep-Alive fetch() with a body at the Quota Limit should succeed.");

// Test Quota + 1 Byte
promise_test(function(test) {
return promise_rejects(test, new TypeError(), fetch(CreateKeepAliveRequest(0 /* delay */, expectedQuota + 1)));
}, "A Keep-Alive fetch() with a body over the Quota Limit should reject.");

// Test the Quota becomes available upon promise completion.
promise_test(function (test) {
// Fill our Quota then try to send a second fetch.
var firstFetch = fetch(CreateKeepAliveRequest(standardDelay, expectedQuota)).then(function(response) {
// Now validate that we can send another Keep-Alive fetch for the full size of the quota.
return fetch(CreateKeepAliveRequest(0 /* delay */, expectedQuota));
});

return firstFetch;
}, "A Keep-Alive fetch() should return it's allocated Quota upon promise resolution.");

// Ensure only the correct amount of Quota becomes available when a fetch completes.
promise_test(function(test) {
var lastFetchSucceeded = false;
// Create a fetch that uses all but 1 Byte of the Quota and runs for 2x as long as the other requests.
var firstFetch = fetch(CreateKeepAliveRequest(standardDelay * 2, expectedQuota - 1)).then(function(response) {
// This should be our last completing fetch(). We need to validate that the last fetch we sent out actually
// completed.
assert_true(lastFetchSucceeded, "Out last fetch after gaining Quota back should have succeeded.");
});

// Now create a single Byte request that will complete quicker.
fetch(CreateKeepAliveRequest(standardDelay, 1 /* bodySize */)).then(function(response) {
// We shouldn't be able to create a 2 Byte request right now as only 1 Byte should have freed up.
assert_throws(new TypeError(), fetch(CreateKeepAliveRequest(0 /* delay */, 2 /* bodySize */)), "Only 1 Byte of Quota should be available right now.");

// Now validate that we can send another Keep-Alive fetch for just 1 Byte.
fetch(CreateKeepAliveRequest(0 /* delay */, 1 /* bodySize */)).then(function(response) {
// Flag we got a response from this request.
lastFetchSucceeded = true;
});
});

return firstFetch;
}, "A Keep-Alive fetch() should return only it's allocated Quota upon promise resolution.");

// Test rejecting a fetch() after the quota is used up.
promise_test(function (test) {
// Fill our Quota then try to send a second fetch.
fetch(CreateKeepAliveRequest(standardDelay, expectedQuota));

return promise_rejects(test, new TypeError(), fetch(CreateKeepAliveRequest(0 /* delay */, 1 /* bodySize */)));
}, "A Keep-Alive fetch() should not be allowed if the Quota is used up.");

</script>
</body>
</html>