Adding tests for RTCQuicStream.
Bug: 874296
Change-Id: I33e79a0641e38b420a23d0ff42933cd26bc0b368
Reviewed-on: https://chromium-review.googlesource.com/c/1341153
Commit-Queue: Seth Hampson <shampson@chromium.org>
Reviewed-by: Steve Anton <steveanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611242}
diff --git a/webrtc-quic/RTCQuicStream-helper.js b/webrtc-quic/RTCQuicStream-helper.js
index a87668f..9563e53 100644
--- a/webrtc-quic/RTCQuicStream-helper.js
+++ b/webrtc-quic/RTCQuicStream-helper.js
@@ -39,6 +39,43 @@
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
+ localStream.finish();
+ const remoteWatcher =
+ new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
+ remoteStream.finish();
+ await localStream.waitForReadable(localStream.maxReadBufferedAmount);
+ assert_object_equals(
+ localStream.readInto(new Uint8Array(10)),
+ { amount: 0, finished: true });
+ assert_equals(localStream.state, 'closed');
+ return test_func(t, localStream);
+ }, 'Stream closed by finish(), followed by reading remote finish: ' +
+ description);
+
+ promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.write(new Uint8Array(1));
+ const remoteWatcher =
+ new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
+ remoteStream.finish();
+ await localStream.waitForReadable(localStream.maxReadBufferedAmount);
+ assert_object_equals(
+ localStream.readInto(new Uint8Array(10)),
+ { amount: 0, finished: true });
+ localStream.finish();
+ assert_equals(localStream.state, 'closed');
+ return test_func(t, localStream);
+ }, 'Stream closed by by reading remote finish, followed by finish(): ' +
+ description);
+
+ promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
localQuicTransport.stop();
assert_equals(localStream.state, 'closed');
return test_func(t, localStream);
diff --git a/webrtc-quic/RTCQuicStream.https.html b/webrtc-quic/RTCQuicStream.https.html
index 08c3a54..1e24298 100644
--- a/webrtc-quic/RTCQuicStream.https.html
+++ b/webrtc-quic/RTCQuicStream.https.html
@@ -119,12 +119,72 @@
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
- await makeTwoConnectedQuicTransports(t);
+ await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
- const promise = localStream.waitForReadable(1);
+ localStream.finish();
+ const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
+ assert_equals(remoteStream.state, 'open');
+ const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
+ await remoteStream.waitForReadable(remoteStream.maxReadBufferedAmount);
+ assert_object_equals(
+ remoteStream.readInto(new Uint8Array(10)),
+ { amount: 0, finished: true } );
+ assert_equals(remoteStream.state, 'closing');
+}, 'waitForReadable() resolves with remote finish');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.finish();
+ const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
+ await remoteStream.waitForReadable(remoteStream.maxReadBufferedAmount);
+ assert_object_equals(
+ remoteStream.readInto(new Uint8Array(10)),
+ { amount: 0, finished: true } );
+ assert_equals(remoteStream.state, 'closing');
+ remoteStream.finish()
+ assert_equals(remoteStream.state, 'closed');
+}, 'finish() on a stream that has already read out finish changes ' +
+ `state to 'closed'.`);
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.finish();
+ const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
+ remoteStream.finish();
+ assert_equals(localStream.state, 'closing');
+ await localStream.waitForReadable(localStream.maxReadBufferedAmount);
+ assert_object_equals(
+ localStream.readInto(new Uint8Array(10)),
+ { amount: 0, finished: true } );
+ assert_equals(localStream.state, 'closed');
+}, 'Reading out finish on stream that has already called finish() ' +
+ `state to 'closed'.`);
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.finish();
+ const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
+ await remoteStream.waitForReadable(remoteStream.maxReadBufferedAmount);
+ assert_object_equals(
+ remoteStream.readInto(new Uint8Array(10)),
+ { amount: 0, finished: true } );
+ assert_equals(remoteStream.state, 'closing');
localStream.reset();
- await promise_rejects(t, 'InvalidStateError', promise);
-}, 'reset() rejects pending waitForReadable() promises.');
+ const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
+ await remoteStreamWatcher.wait_for('statechange');
+ assert_equals(remoteStream.state, 'closed');
+}, 'Reading out finish then a getting a remote reset fires a statechange event ' +
+ `to 'closed'.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
@@ -214,6 +274,36 @@
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
+ localStream.write(generateData(10));
+ const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream : remoteStream} = await remoteWatcher.wait_for('quicstream');
+ await remoteStream.waitForReadable(10);
+ assert_equals(10, remoteStream.readBufferedAmount);
+ remoteStream.reset();
+ assert_equals(0, remoteStream.readBufferedAmount);
+}, 'readBufferedAmount set to 0 after local reset().');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.write(generateData(10));
+ const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream : remoteStream} = await remoteWatcher.wait_for('quicstream');
+ await remoteStream.waitForReadable(10);
+ assert_equals(10, remoteStream.readBufferedAmount);
+ localStream.reset();
+ const remoteStreamWatcher =
+ new EventWatcher(t, remoteStream, 'statechange');
+ await remoteStreamWatcher.wait_for('statechange');
+ assert_equals(remoteStream.state, 'closed');
+ assert_equals(0, remoteStream.readBufferedAmount);
+}, 'readBufferedAmount set to 0 after remote reset().');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
localStream.write(new Uint8Array(10));
localStream.reset();
assert_equals(localStream.writeBufferedAmount, 0);
@@ -223,6 +313,26 @@
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
+ localStream.write(new Uint8Array(1));
+ const remoteWatcher =
+ new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
+ remoteStream.finish();
+ await localStream.waitForReadable(localStream.maxReadBufferedAmount);
+ assert_object_equals(
+ localStream.readInto(new Uint8Array(10)),
+ { amount: 0, finished: true });
+ localStream.write(new Uint8Array(10));
+ assert_equals(localStream.writeBufferedAmount, 10);
+ localStream.finish();
+ assert_equals(localStream.writeBufferedAmount, 0);
+}, 'writeBufferedAmount set to 0 after reading remote finish, followed ' +
+ 'by finish().');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
localStream.write(new Uint8Array(10));
localQuicTransport.stop();
assert_equals(localStream.writeBufferedAmount, 0);
@@ -251,7 +361,7 @@
await localStream.waitForWriteBufferedAmountBelow(
localStream.maxWriteBufferedAmount);
}, 'waitForWriteBufferedAmountBelow(maxWriteBufferedAmount) resolves ' +
- 'immediately.');
+ 'immediately.');
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
@@ -265,7 +375,21 @@
promise_rejects(t, 'InvalidStateError', promise1),
promise_rejects(t, 'InvalidStateError', promise2)]);
}, 'Pending waitForWriteBufferedAmountBelow() promises rejected after ' +
- 'finish().');
+ 'finish().');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.write(new Uint8Array(localStream.maxWriteBufferedAmount));
+ localStream.finish();
+ const promise1 = localStream.waitForWriteBufferedAmountBelow(0);
+ const promise2 = localStream.waitForWriteBufferedAmountBelow(0);
+ await Promise.all([
+ promise_rejects(t, 'InvalidStateError', promise1),
+ promise_rejects(t, 'InvalidStateError', promise2)]);
+}, 'waitForWriteBufferedAmountBelow() promises immediately rejected after ' +
+ 'finish().');
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
@@ -279,7 +403,21 @@
promise_rejects(t, 'InvalidStateError', promise1),
promise_rejects(t, 'InvalidStateError', promise2)]);
}, 'Pending waitForWriteBufferedAmountBelow() promises rejected after ' +
- 'reset().');
+ 'reset().');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.write(new Uint8Array(localStream.maxWriteBufferedAmount));
+ const promise1 = localStream.waitForWriteBufferedAmountBelow(0);
+ const promise2 = localStream.waitForWriteBufferedAmountBelow(0);
+ localQuicTransport.stop();
+ await Promise.all([
+ promise_rejects(t, 'InvalidStateError', promise1),
+ promise_rejects(t, 'InvalidStateError', promise2)]);
+}, 'Pending waitForWriteBufferedAmountBelow() promises rejected after ' +
+ 'RTCQuicTransport stop().');
closed_stream_test(async (t, stream) => {
await promise_rejects(t, 'InvalidStateError',
@@ -292,7 +430,7 @@
const localStream = localQuicTransport.createStream();
assert_object_equals(
localStream.readInto(new Uint8Array(10)),
- { amount: 0, finished: false });
+ { amount: 0, finished: false } );
}, 'readInto() on new local stream returns amount 0.');
closed_stream_test(async (t, stream) => {
@@ -311,7 +449,7 @@
const readBuffer = new Uint8Array(3);
assert_object_equals(
remoteStream.readInto(readBuffer),
- { amount: 1, finished: false });
+ { amount: 1, finished: false } );
assert_array_equals(readBuffer, [ 65, 0, 0 ]);
assert_equals(remoteStream.readBufferedAmount, 0);
}, 'Read 1 byte.');
@@ -341,6 +479,30 @@
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
+ const data = generateData(10);
+ localStream.write(data);
+ localStream.finish();
+ const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
+ await remoteStream.waitForReadable(data.length + 1);
+ const readBuffer = new Uint8Array(5);
+ assert_object_equals(
+ remoteStream.readInto(readBuffer),
+ { amount: 5, finished: false} );
+ assert_array_equals(
+ readBuffer, data.subarray(0, 5));
+ const finReadBuffer = new Uint8Array(5);
+ assert_object_equals(
+ remoteStream.readInto(finReadBuffer),
+ { amount: 5, finished: true} );
+ assert_array_equals(
+ finReadBuffer, data.subarray(5, data.length));
+}, 'readInto() reads out finish after reading all data.');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
writeGeneratedData(localStream, localStream.maxReadBufferedAmount);
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
@@ -348,7 +510,7 @@
const readBuffer = new Uint8Array(localStream.maxReadBufferedAmount);
assert_object_equals(
remoteStream.readInto(readBuffer),
- { amount: localStream.maxReadBufferedAmount, finished: false });
+ { amount: localStream.maxReadBufferedAmount, finished: false } );
assert_array_equals(
readBuffer, generateData(localStream.maxReadBufferedAmount));
}, 'Read maxReadBufferedAmount bytes all at once.');
@@ -357,6 +519,19 @@
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
+ localStream.finish();
+ const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
+ await remoteStream.waitForReadable(remoteStream.maxReadBufferedAmount);
+ assert_object_equals(
+ remoteStream.readInto(new Uint8Array(10)),
+ { amount: 0, finished: true } );
+}, 'waitForReadable() resolves with finish().');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
const writeData = generateData(10);
localStream.write(writeData);
localStream.finish();
@@ -366,9 +541,9 @@
assert_equals(remoteStream.readBufferedAmount, 10);
const readBuffer = new Uint8Array(10);
assert_object_equals(
- remoteStream.readInto(readBuffer), { amount: 10, finished: true });
+ remoteStream.readInto(readBuffer), { amount: 10, finished: true } );
assert_array_equals(readBuffer, writeData);
-}, 'waitForReadable() resolves early if remote fin is received.');
+}, 'waitForReadable() resolves early if remote finish is received.');
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
@@ -377,7 +552,27 @@
await promise_rejects(t, new TypeError(),
localStream.waitForReadable(localStream.maxReadBufferedAmount + 1));
}, 'waitForReadable() rejects with TypeError if amount is more than ' +
- 'maxReadBufferedAmount.');
+ 'maxReadBufferedAmount.');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.finish();
+ const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
+ await remoteStream.waitForReadable(remoteStream.maxReadBufferedAmount);
+ assert_object_equals(
+ remoteStream.readInto(new Uint8Array(10)),
+ { amount: 0, finished: true } );
+
+ const promise1 = remoteStream.waitForReadable(10);
+ const promise2 = remoteStream.waitForReadable(10);
+ await Promise.all([
+ promise_rejects(t, 'InvalidStateError', promise1),
+ promise_rejects(t, 'InvalidStateError', promise2)]);
+}, 'waitForReadable() promises immediately rejected with InvalidStateError ' +
+ 'after finish is read out.');
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
@@ -406,6 +601,35 @@
promise_rejects(t, 'InvalidStateError', promise2)]);
}, 'Pending waitForReadable() promises rejected after remote reset().');
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ const promise1 = localStream.waitForReadable(10);
+ const promise2 = localStream.waitForReadable(10);
+ localQuicTransport.stop();
+ await Promise.all([
+ promise_rejects(t, 'InvalidStateError', promise1),
+ promise_rejects(t, 'InvalidStateError', promise2)]);
+}, 'Pending waitForReadable() promises rejected after RTCQuicTransport ' +
+ 'stop().');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.write(new Uint8Array(1));
+ const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream : remoteStream} = await remoteWatcher.wait_for('quicstream');
+ const promise1 = remoteStream.waitForReadable(10);
+ const promise2 = remoteStream.waitForReadable(10);
+ localQuicTransport.stop();
+ await Promise.all([
+ promise_rejects(t, 'InvalidStateError', promise1),
+ promise_rejects(t, 'InvalidStateError', promise2)]);
+}, 'Pending waitForReadable() promises rejected after remote RTCQuicTransport ' +
+ 'stop().');
+
closed_stream_test(async (t, stream) => {
await promise_rejects(t, 'InvalidStateError',
stream.waitForReadable(1));