зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1647892 - Improve the reliability of test_double_submit.html, r=farre
Unlike the previous implementation, this new version performs the waiting before sending response headers, meaning that it delays OnStartRequest rather than just delaying the response body. As the double-submission prevention currently only waits for OnStartRequest, this should improve the reliability of the test. Because the test no longer requires large amounts of data for delay purposes, it has also been simplified to not generate random large payloads anymore. Differential Revision: https://phabricator.services.mozilla.com/D141427
This commit is contained in:
Родитель
08b1e68cb1
Коммит
c14c6bb509
|
@ -12,35 +12,10 @@ const BinaryInputStream = CC(
|
|||
"setInputStream"
|
||||
);
|
||||
|
||||
const BinaryOutputStream = CC(
|
||||
"@mozilla.org/binaryoutputstream;1",
|
||||
"nsIBinaryOutputStream",
|
||||
"setOutputStream"
|
||||
);
|
||||
|
||||
function log(str) {
|
||||
// dump(`LOG: ${str}\n`);
|
||||
}
|
||||
|
||||
function* generateBody(fragments, size) {
|
||||
let result = [];
|
||||
let chunkSize = (size / fragments) | 0;
|
||||
let remaining = size;
|
||||
|
||||
log(`Chunk size ${chunkSize}`);
|
||||
while (remaining > 0) {
|
||||
let data = new Uint8Array(Math.min(remaining, chunkSize));
|
||||
for (let i = 0; i < data.length; ++i) {
|
||||
// Generate a character in the [a-z] range.
|
||||
data[i] = 97 + Math.random() * (123 - 97);
|
||||
}
|
||||
|
||||
yield data;
|
||||
log(`Remaining to chunk ${remaining}`);
|
||||
remaining -= data.length;
|
||||
}
|
||||
}
|
||||
|
||||
function readStream(inputStream) {
|
||||
let available = 0;
|
||||
let result = [];
|
||||
|
@ -60,9 +35,9 @@ async function handleRequest(request, response) {
|
|||
Cu.importGlobalProperties(["URLSearchParams"]);
|
||||
let params = new URLSearchParams(request.queryString);
|
||||
|
||||
let start = now();
|
||||
let delay = parseInt(params.get("delay")) || 0;
|
||||
let delayUntil = now() + delay;
|
||||
log(`Delay until ${delayUntil}`);
|
||||
log(`Delay for ${delay}`);
|
||||
|
||||
let message = "good";
|
||||
if (request.method !== "POST") {
|
||||
|
@ -76,54 +51,28 @@ async function handleRequest(request, response) {
|
|||
log(`The result was ${message}`);
|
||||
}
|
||||
|
||||
let fragments = parseInt(params.get("fragments")) || 1;
|
||||
let size = parseInt(params.get("size")) || 1024;
|
||||
let body = `<!doctype html>
|
||||
<script>
|
||||
"use strict";
|
||||
let target = (opener || parent);
|
||||
target.postMessage(${JSON.stringify(message)}, '*');
|
||||
</script>`;
|
||||
|
||||
let outputStream = new BinaryOutputStream(response.bodyOutputStream);
|
||||
// Sieze power from the response to allow manually transmitting data at any
|
||||
// rate we want, so we can delay transmitting headers.
|
||||
response.seizePower();
|
||||
|
||||
let header = "<!doctype html><!-- ";
|
||||
let footer = ` --><script>"use strict"; let target = (opener || parent); target.postMessage('${message}', '*');</script>`;
|
||||
log(`Writing HTTP status line at ${now() - start}`);
|
||||
response.write("HTTP/1.1 200 OK\r\n");
|
||||
|
||||
log("Set headers");
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.setHeader(
|
||||
"Content-Length",
|
||||
`${size + header.length + footer.length}`,
|
||||
false
|
||||
);
|
||||
response.setStatusLine(request.httpVersion, "200", "OK");
|
||||
|
||||
response.processAsync();
|
||||
log("Write header");
|
||||
response.write(header);
|
||||
log("Write body");
|
||||
for (let data of generateBody(fragments, size)) {
|
||||
delay = Math.max(0, delayUntil - now());
|
||||
log(`Delay sending fragment for ${delay / fragments}`);
|
||||
let failed = false;
|
||||
await new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
outputStream.writeByteArray(data, data.length);
|
||||
} catch (e) {
|
||||
log(e.message);
|
||||
failed = true;
|
||||
}
|
||||
resolve();
|
||||
}, delay / fragments);
|
||||
});
|
||||
|
||||
if (failed) {
|
||||
log("Stopped sending data");
|
||||
break;
|
||||
}
|
||||
|
||||
fragments = Math.max(--fragments, 1);
|
||||
log(`Fragments left ${fragments}`);
|
||||
}
|
||||
|
||||
log("Write footer");
|
||||
response.write(footer);
|
||||
await new Promise(resolve => setTimeout(() => resolve(), delay));
|
||||
|
||||
log(`Delay completed at ${now() - start}`);
|
||||
response.write("Content-Type: text/html\r\n");
|
||||
response.write(`Content-Length: ${body.length}\r\n`);
|
||||
response.write("\r\n");
|
||||
response.write(body);
|
||||
response.finish();
|
||||
|
||||
log("Finished");
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
</head>
|
||||
<body>
|
||||
<iframe name="targetFrame" id="targetFrame"></iframe>
|
||||
<form id="form" action="double_submit.sjs?size=4096&fragments=10&delay=1000" method="POST" target="targetFrame">
|
||||
<input id="input" type="text" name="text" value="value">
|
||||
<form id="form" action="double_submit.sjs?delay=1000" method="POST" target="targetFrame">
|
||||
<input id="token" type="text" name="token" value="">
|
||||
<input id="button" type="submit">
|
||||
</form>
|
||||
|
@ -18,15 +17,6 @@
|
|||
|
||||
const CROSS_ORIGIN_URI = "http://test1.example.com/tests/docshell/test/mochitest/ping.html";
|
||||
|
||||
function generateBody(size) {
|
||||
let data = new Uint8Array(size);
|
||||
for (let i = 0; i < size; ++i) {
|
||||
data[i] = 97 + Math.random() * (123 - 97);
|
||||
}
|
||||
|
||||
return new TextDecoder().decode(data);
|
||||
}
|
||||
|
||||
function asyncClick(counts) {
|
||||
let frame = document.createElement('iframe');
|
||||
frame.addEventListener(
|
||||
|
@ -59,7 +49,6 @@
|
|||
let form = document.getElementById('form');
|
||||
let button = document.getElementById('button');
|
||||
|
||||
document.getElementById('input').value = generateBody(1024*1024);
|
||||
let token = document.getElementById('token');
|
||||
token.value = "first";
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче