Revision control

1
<!DOCTYPE html>
2
<script src='../resources/testharness.js'></script>
3
<script src='../resources/testharnessreport.js'></script>
4
<script src='reference-implementation/resources/streams-utils.js'></script>
5
<script>
7
8
// This test is alone here for timing reasons though it should be at streams/reference-implementation/pipe-to.html.
9
var test24 = async_test('Piping to a writable stream that does not consume the writes fast enough exerts backpressure on the source');
10
test24.step(function() {
11
const timeoutMultiplier = 15;
12
var desiredSizes = [];
13
var rs = new ReadableStream({
14
start: function(c) {
15
setTimeout(test24.step_func(function() { enqueue('a'); }), 100 * timeoutMultiplier);
16
setTimeout(test24.step_func(function() { enqueue('b'); }), 200 * timeoutMultiplier);
17
setTimeout(test24.step_func(function() { enqueue('c'); }), 300 * timeoutMultiplier);
18
setTimeout(test24.step_func(function() { enqueue('d'); }), 400 * timeoutMultiplier);
19
setTimeout(test24.step_func(function() { c.close(); }), 500 * timeoutMultiplier);
20
21
function enqueue(chunk) {
22
c.enqueue(chunk);
23
desiredSizes.push(c.desiredSize);
24
}
25
}
26
});
27
28
var chunksGivenToWrite = [];
29
var chunksFinishedWriting = [];
30
var startPromise = Promise.resolve();
31
var ws = new WritableStream({
32
start: function() {
33
return startPromise;
34
},
35
write: function(chunk) {
36
chunksGivenToWrite.push(chunk);
37
return new Promise(test24.step_func(function(resolve) {
38
setTimeout(test24.step_func(function() {
39
chunksFinishedWriting.push(chunk);
40
resolve();
41
}), 350 * timeoutMultiplier);
42
}));
43
}
44
});
45
46
startPromise.then(test24.step_func(function() {
47
rs.pipeTo(ws).then(test24.step_func(function() {
48
assert_array_equals(desiredSizes, [1, 1, 0, -1], 'backpressure was correctly exerted at the source');
49
assert_array_equals(chunksFinishedWriting, ['a', 'b', 'c', 'd'], 'all chunks were written');
50
test24.done();
51
}));
52
53
assert_equals(ws.state, 'writable', 'at t = 0 ms, ws should be writable');
54
55
setTimeout(test24.step_func(function() {
56
assert_equals(ws.state, 'waiting', 'at t = 125 ms, ws should be waiting');
57
assert_array_equals(chunksGivenToWrite, ['a'], 'at t = 125 ms, ws.write should have been called with one chunk');
58
assert_array_equals(chunksFinishedWriting, [], 'at t = 125 ms, no chunks should have finished writing');
59
60
// When 'a' (the very first chunk) was enqueued, it was immediately used to fulfill the outstanding read request
61
// promise, leaving room in the queue
62
assert_array_equals(desiredSizes, [1], 'at t = 125 ms, the one enqueued chunk in rs did not cause backpressure');
63
}), 125 * timeoutMultiplier);
64
65
setTimeout(test24.step_func(function() {
66
assert_equals(ws.state, 'waiting', 'at t = 225 ms, ws should be waiting');
67
assert_array_equals(chunksGivenToWrite, ['a'], 'at t = 225 ms, ws.write should have been called with one chunk');
68
assert_array_equals(chunksFinishedWriting, [], 'at t = 225 ms, no chunks should have finished writing');
69
70
// When 'b' was enqueued at 200 ms, the queue was also empty, since immediately after enqueuing 'a' at
71
// t = 100 ms, it was dequeued in order to fulfill the read() call that was made at time t = 0.
72
assert_array_equals(desiredSizes, [1, 1], 'at t = 225 ms, the two enqueued chunks in rs did not cause backpressure');
73
}), 225 * timeoutMultiplier);
74
75
setTimeout(test24.step_func(function() {
76
assert_equals(ws.state, 'waiting', 'at t = 325 ms, ws should be waiting');
77
assert_array_equals(chunksGivenToWrite, ['a'], 'at t = 325 ms, ws.write should have been called with one chunk');
78
assert_array_equals(chunksFinishedWriting, [], 'at t = 325 ms, no chunks should have finished writing');
79
80
// When 'c' was enqueued at 300 ms, the queue was again empty, since at time t = 200 ms when 'b' was enqueued,
81
// it was immediately dequeued in order to fulfill the second read() call that was made at time t = 0.
82
// However, this time there was no pending read request to whisk it away, so after the enqueue desired size is 0.
83
assert_array_equals(desiredSizes, [1, 1, 0], 'at t = 325 ms, the three enqueued chunks in rs did not cause backpressure');
84
}), 325 * timeoutMultiplier);
85
86
setTimeout(test24.step_func(function() {
87
assert_equals(ws.state, 'waiting', 'at t = 425 ms, ws should be waiting');
88
assert_array_equals(chunksGivenToWrite, ['a'], 'at t = 425 ms, ws.write should have been called with one chunk');
89
assert_array_equals(chunksFinishedWriting, [], 'at t = 425 ms, no chunks should have finished writing');
90
91
// When 'd' was enqueued at 400 ms, the queue was *not* empty. 'c' was still in it, since the write() of 'b' will
92
// not finish until t = 100 ms + 350 ms = 450 ms. Thus backpressure should have been exerted.
93
assert_array_equals(desiredSizes, [1, 1, 0, -1], 'at t = 425 ms, the fourth enqueued chunks in rs did cause backpressure');
94
}), 425 * timeoutMultiplier);
95
96
setTimeout(test24.step_func(function() {
97
assert_equals(ws.state, 'waiting', 'at t = 475 ms, ws should be waiting');
98
assert_array_equals(chunksGivenToWrite, ['a', 'b'], 'at t = 475 ms, ws.write should have been called with two chunks');
99
assert_array_equals(chunksFinishedWriting, ['a'], 'at t = 475 ms, one chunk should have finished writing');
100
}), 475 * timeoutMultiplier);
101
}));
102
});
103
</script>