Implement RTCQuicTransport.onquicstream and stream reset/finish
This CL implements the RTCQuicTransport createStream method and the
corresponding quicstream event hooked up to the QUIC adapters. It
also implements RTCQuicStream.reset/finish and statechange event to
allow end-to-end testing.
Bug: 874296
Change-Id: I331d37f3e21c606697b8768bf9eea59c90487163
Reviewed-on: https://chromium-review.googlesource.com/c/1217846
Commit-Queue: Steve Anton <steveanton@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Henrik Boström <hbos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#596068}
diff --git a/webrtc/RTCQuicStream.https.html b/webrtc/RTCQuicStream.https.html
index 3302545..68c88e2 100644
--- a/webrtc/RTCQuicStream.https.html
+++ b/webrtc/RTCQuicStream.https.html
@@ -13,13 +13,14 @@
// The following helper functions are called from RTCQuicTransport-helper.js:
// makeStandaloneQuicTransport
+// makeTwoConnectedQuicTransports
promise_test(async t => {
- const quicTransport = await makeStandaloneQuicTransport(t);
+ const [ quicTransport, ] = await makeTwoConnectedQuicTransports(t);
const quicStream = quicTransport.createStream();
assert_equals(quicStream.transport, quicTransport,
'Expect transport to be set to the creating RTCQuicTransport.');
- assert_equals(quicStream.state, 'new', `Expect state to be 'new'.`);
+ assert_equals(quicStream.state, 'open', `Expect state to be 'open'.`);
assert_equals(quicStream.readBufferedAmount, 0,
'Expect read buffered amount to be 0.');
assert_equals(quicStream.writeBufferedAmount, 0,
@@ -28,17 +29,130 @@
promise_test(async t => {
const quicTransport = await makeStandaloneQuicTransport(t);
+ assert_throws('InvalidStateError', () => quicTransport.createStream());
+}, 'createStream() throws if the transport is not connected.');
+
+promise_test(async t => {
+ const quicTransport = await makeStandaloneQuicTransport(t);
quicTransport.stop();
assert_throws('InvalidStateError', () => quicTransport.createStream());
}, 'createStream() throws if the transport is closed.');
promise_test(async t => {
- const quicTransport = await makeStandaloneQuicTransport(t);
+ const [ quicTransport, ] = await makeTwoConnectedQuicTransports(t);
const firstQuicStream = quicTransport.createStream();
const secondQuicStream = quicTransport.createStream();
quicTransport.stop();
assert_equals(firstQuicStream.state, 'closed');
assert_equals(secondQuicStream.state, 'closed');
-}, 'RTCQuicTransport.stop() closes all streams.');
+}, 'RTCQuicTransport.stop() closes all local streams.');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const firstLocalStream = localQuicTransport.createStream();
+ firstLocalStream.finish();
+ const secondLocalStream = localQuicTransport.createStream();
+ secondLocalStream.finish();
+ const remoteWatcher =
+ new EventWatcher(t, remoteQuicTransport, [ 'quicstream', 'statechange' ]);
+ const { stream: firstRemoteStream } =
+ await remoteWatcher.wait_for('quicstream');
+ const { stream: secondRemoteStream } =
+ await remoteWatcher.wait_for('quicstream');
+ localQuicTransport.stop();
+ await remoteWatcher.wait_for('statechange');
+ assert_equals(firstRemoteStream.state, 'closed');
+ assert_equals(secondRemoteStream.state, 'closed');
+}, 'RTCQuicTransport.stop() closes all remote streams.');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.finish();
+ assert_equals(localStream.state, 'closing');
+}, `finish() changes state to 'closing'.`);
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.finish();
+ localStream.finish();
+ assert_equals(localStream.state, 'closing');
+}, `finish() twice does not change state.`);
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.reset();
+ assert_equals(localStream.state, 'closed');
+}, `reset() changes state to 'closed'.`);
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.finish();
+ localStream.reset();
+ assert_equals(localStream.state, 'closed');
+}, `reset() following 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');
+ assert_equals(remoteStream.state, 'open');
+ const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
+ await remoteStreamWatcher.wait_for('statechange');
+ assert_equals(remoteStream.state, 'closing');
+}, 'createStream() followed by finish() fires a quicstream event followed by ' +
+ `a statechange event to 'closing' on the remote side.`);
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.reset();
+ 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 remoteStreamWatcher.wait_for('statechange');
+ assert_equals(remoteStream.state, 'closed');
+}, 'createStream() followed by reset() fires a quicstream event followed ' +
+ `by a statechange event to 'closed' on the remote side.`);
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ remoteQuicTransport.onquicstream = ({ stream }) => stream.reset();
+ const localStream = localQuicTransport.createStream();
+ localStream.finish();
+ const localWatcher = new EventWatcher(t, localStream, 'statechange');
+ await localWatcher.wait_for('statechange');
+ assert_equals(localStream.state, 'closed');
+}, 'finish() on a remote stream that has already finished fires a ' +
+ `statechange event to 'closed' on the remote side.`);
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.finish();
+ localStream.reset();
+ const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
+ const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
+ await remoteStreamWatcher.wait_for('statechange');
+ assert_equals(remoteStream.state, 'closing');
+ await remoteStreamWatcher.wait_for('statechange');
+ assert_equals(remoteStream.state, 'closed');
+}, 'finish() then reset() fires two statechange events on the remote side.');
</script>
diff --git a/webrtc/RTCQuicTransport-helper.js b/webrtc/RTCQuicTransport-helper.js
index 3ea19d7..7e28fea 100644
--- a/webrtc/RTCQuicTransport-helper.js
+++ b/webrtc/RTCQuicTransport-helper.js
@@ -79,4 +79,3 @@
]);
return [ localQuicTransport, remoteQuicTransport ];
}
-
diff --git a/webrtc/RTCQuicTransport.https.html b/webrtc/RTCQuicTransport.https.html
index ec79bc2..3bcc93d 100644
--- a/webrtc/RTCQuicTransport.https.html
+++ b/webrtc/RTCQuicTransport.https.html
@@ -17,6 +17,7 @@
// makeAndGatherTwoIceTransports
// The following helper functions are called from RTCQuicTransport-helper.js:
+// generateCertificate
// makeQuicTransport
// makeStandaloneQuicTransport
// makeAndStartTwoQuicTransports