104 lines
5.9 KiB
HTML
104 lines
5.9 KiB
HTML
<!DOCTYPE html>
|
|
<script src='../resources/testharness.js'></script>
|
|
<script src='../resources/testharnessreport.js'></script>
|
|
<script src='reference-implementation/resources/streams-utils.js'></script>
|
|
<script>
|
|
// This is updated till https://github.com/whatwg/streams/commit/4ba861e6f60c248060811830e11271c84b439cc3
|
|
|
|
// This test is alone here for timing reasons though it should be at streams/reference-implementation/pipe-to.html.
|
|
var test24 = async_test('Piping to a writable stream that does not consume the writes fast enough exerts backpressure on the source');
|
|
test24.step(function() {
|
|
const timeoutMultiplier = 15;
|
|
var desiredSizes = [];
|
|
var rs = new ReadableStream({
|
|
start: function(c) {
|
|
setTimeout(test24.step_func(function() { enqueue('a'); }), 100 * timeoutMultiplier);
|
|
setTimeout(test24.step_func(function() { enqueue('b'); }), 200 * timeoutMultiplier);
|
|
setTimeout(test24.step_func(function() { enqueue('c'); }), 300 * timeoutMultiplier);
|
|
setTimeout(test24.step_func(function() { enqueue('d'); }), 400 * timeoutMultiplier);
|
|
setTimeout(test24.step_func(function() { c.close(); }), 500 * timeoutMultiplier);
|
|
|
|
function enqueue(chunk) {
|
|
c.enqueue(chunk);
|
|
desiredSizes.push(c.desiredSize);
|
|
}
|
|
}
|
|
});
|
|
|
|
var chunksGivenToWrite = [];
|
|
var chunksFinishedWriting = [];
|
|
var startPromise = Promise.resolve();
|
|
var ws = new WritableStream({
|
|
start: function() {
|
|
return startPromise;
|
|
},
|
|
write: function(chunk) {
|
|
chunksGivenToWrite.push(chunk);
|
|
return new Promise(test24.step_func(function(resolve) {
|
|
setTimeout(test24.step_func(function() {
|
|
chunksFinishedWriting.push(chunk);
|
|
resolve();
|
|
}), 350 * timeoutMultiplier);
|
|
}));
|
|
}
|
|
});
|
|
|
|
startPromise.then(test24.step_func(function() {
|
|
rs.pipeTo(ws).then(test24.step_func(function() {
|
|
assert_array_equals(desiredSizes, [1, 1, 0, -1], 'backpressure was correctly exerted at the source');
|
|
assert_array_equals(chunksFinishedWriting, ['a', 'b', 'c', 'd'], 'all chunks were written');
|
|
test24.done();
|
|
}));
|
|
|
|
assert_equals(ws.state, 'writable', 'at t = 0 ms, ws should be writable');
|
|
|
|
setTimeout(test24.step_func(function() {
|
|
assert_equals(ws.state, 'waiting', 'at t = 125 ms, ws should be waiting');
|
|
assert_array_equals(chunksGivenToWrite, ['a'], 'at t = 125 ms, ws.write should have been called with one chunk');
|
|
assert_array_equals(chunksFinishedWriting, [], 'at t = 125 ms, no chunks should have finished writing');
|
|
|
|
// When 'a' (the very first chunk) was enqueued, it was immediately used to fulfill the outstanding read request
|
|
// promise, leaving room in the queue
|
|
assert_array_equals(desiredSizes, [1], 'at t = 125 ms, the one enqueued chunk in rs did not cause backpressure');
|
|
}), 125 * timeoutMultiplier);
|
|
|
|
setTimeout(test24.step_func(function() {
|
|
assert_equals(ws.state, 'waiting', 'at t = 225 ms, ws should be waiting');
|
|
assert_array_equals(chunksGivenToWrite, ['a'], 'at t = 225 ms, ws.write should have been called with one chunk');
|
|
assert_array_equals(chunksFinishedWriting, [], 'at t = 225 ms, no chunks should have finished writing');
|
|
|
|
// When 'b' was enqueued at 200 ms, the queue was also empty, since immediately after enqueuing 'a' at
|
|
// t = 100 ms, it was dequeued in order to fulfill the read() call that was made at time t = 0.
|
|
assert_array_equals(desiredSizes, [1, 1], 'at t = 225 ms, the two enqueued chunks in rs did not cause backpressure');
|
|
}), 225 * timeoutMultiplier);
|
|
|
|
setTimeout(test24.step_func(function() {
|
|
assert_equals(ws.state, 'waiting', 'at t = 325 ms, ws should be waiting');
|
|
assert_array_equals(chunksGivenToWrite, ['a'], 'at t = 325 ms, ws.write should have been called with one chunk');
|
|
assert_array_equals(chunksFinishedWriting, [], 'at t = 325 ms, no chunks should have finished writing');
|
|
|
|
// When 'c' was enqueued at 300 ms, the queue was again empty, since at time t = 200 ms when 'b' was enqueued,
|
|
// it was immediately dequeued in order to fulfill the second read() call that was made at time t = 0.
|
|
// However, this time there was no pending read request to whisk it away, so after the enqueue desired size is 0.
|
|
assert_array_equals(desiredSizes, [1, 1, 0], 'at t = 325 ms, the three enqueued chunks in rs did not cause backpressure');
|
|
}), 325 * timeoutMultiplier);
|
|
|
|
setTimeout(test24.step_func(function() {
|
|
assert_equals(ws.state, 'waiting', 'at t = 425 ms, ws should be waiting');
|
|
assert_array_equals(chunksGivenToWrite, ['a'], 'at t = 425 ms, ws.write should have been called with one chunk');
|
|
assert_array_equals(chunksFinishedWriting, [], 'at t = 425 ms, no chunks should have finished writing');
|
|
|
|
// When 'd' was enqueued at 400 ms, the queue was *not* empty. 'c' was still in it, since the write() of 'b' will
|
|
// not finish until t = 100 ms + 350 ms = 450 ms. Thus backpressure should have been exerted.
|
|
assert_array_equals(desiredSizes, [1, 1, 0, -1], 'at t = 425 ms, the fourth enqueued chunks in rs did cause backpressure');
|
|
}), 425 * timeoutMultiplier);
|
|
|
|
setTimeout(test24.step_func(function() {
|
|
assert_equals(ws.state, 'waiting', 'at t = 475 ms, ws should be waiting');
|
|
assert_array_equals(chunksGivenToWrite, ['a', 'b'], 'at t = 475 ms, ws.write should have been called with two chunks');
|
|
assert_array_equals(chunksFinishedWriting, ['a'], 'at t = 475 ms, one chunk should have finished writing');
|
|
}), 475 * timeoutMultiplier);
|
|
}));
|
|
});
|
|
</script>
|