| <!doctype html> |
| <meta charset=utf-8> |
| <title>RTCQuicTransport.https.html</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="RTCIceTransport-extension-helper.js"></script> |
| <script src="RTCQuicTransport-helper.js"></script> |
| <script> |
| 'use strict'; |
| |
| // These tests are based on the following specification: |
| // https://w3c.github.io/webrtc-quic/ |
| |
| // The following helper functions are called from |
| // RTCIceTransport-extension-helper.js: |
| // makeIceTransport |
| // makeAndGatherTwoIceTransports |
| |
| // The following helper functions are called from RTCQuicTransport-helper.js: |
| // makeQuicTransport |
| // makeStandaloneQuicTransport |
| // makeAndStartTwoQuicTransports |
| // makeTwoConnectedQuicTransports |
| |
| promise_test(async t => { |
| const certificate = await generateCertificate(); |
| const iceTransport = makeIceTransport(t); |
| const quicTransport = makeQuicTransport(t, iceTransport, [ certificate ]); |
| assert_equals(quicTransport.transport, iceTransport, |
| 'Expect transport to be the same as the one passed in the constructor.'); |
| assert_equals(quicTransport.state, 'new', `Expect state to be 'new'.`); |
| assert_object_equals(quicTransport.getLocalParameters(), |
| { role: 'auto', fingerprints: certificate.getFingerprints() }, |
| 'Expect local parameters to be initialized.'); |
| assert_equals(quicTransport.getRemoteParameters(), null, |
| 'Expect no remote parameters.'); |
| assert_array_equals(quicTransport.getCertificates(), [ certificate ], |
| 'Expect one certificate.'); |
| assert_array_equals(quicTransport.getRemoteCertificates(), [], |
| 'Expect no remote certificates.'); |
| }, 'RTCQuicTransport initial properties are set.'); |
| |
| promise_test(async t => { |
| const [ firstCertificate, secondCertificate ] = |
| await Promise.all([ generateCertificate(), generateCertificate() ]); |
| const quicTransport = |
| makeQuicTransport(t, makeIceTransport(t), |
| [ firstCertificate, secondCertificate ]); |
| assert_array_equals(quicTransport.getCertificates(), |
| [ firstCertificate, secondCertificate ]); |
| }, 'getCertificates() returns the certificates passed in the constructor.'); |
| |
| promise_test(async t => { |
| const [ firstCertificate, secondCertificate ] = |
| await Promise.all([ generateCertificate(), generateCertificate() ]); |
| const quicTransport = |
| makeQuicTransport(t, makeIceTransport(t), |
| [ firstCertificate, secondCertificate ]); |
| assert_object_equals(quicTransport.getLocalParameters(), { |
| role: 'auto', |
| fingerprints: |
| [ firstCertificate.getFingerprints()[0], |
| secondCertificate.getFingerprints()[0] ], |
| }); |
| assert_array_equals(quicTransport.getCertificates(), |
| [ firstCertificate, secondCertificate ]); |
| }, 'getLocalParameters() has fingerprints for all certificates passed in the ' + |
| 'constructor.'); |
| |
| promise_test(async t => { |
| const expiredCertificate = await generateCertificate({ expires: 0 }); |
| assert_throws(new TypeError(), |
| () => makeQuicTransport(t, makeIceTransport(t), [ expiredCertificate ])); |
| }, 'RTCQuicTransport constructor throws if passed an expired certificate.'); |
| |
| promise_test(async t => { |
| const certificate = await generateCertificate(); |
| const iceTransport = makeIceTransport(t); |
| iceTransport.stop(); |
| assert_throws('InvalidStateError', |
| () => makeQuicTransport(t, iceTransport, [ certificate ])); |
| }, 'RTCQuicTransport constructor throws if passed a closed RTCIceTransport.'); |
| |
| promise_test(async t => { |
| const certificate = await generateCertificate(); |
| const iceTransport = makeIceTransport(t); |
| const firstQuicTransport = |
| makeQuicTransport(t, iceTransport, [ certificate ]); |
| assert_throws('InvalidStateError', |
| () => makeQuicTransport(t, iceTransport, [ certificate ])); |
| }, 'RTCQuicTransport constructor throws if passed an RTCIceTransport that ' + |
| 'already has an active RTCQuicTransport.'); |
| |
| promise_test(async t => { |
| const quicTransport = await makeStandaloneQuicTransport(t); |
| quicTransport.stop(); |
| assert_equals(quicTransport.state, 'closed'); |
| }, `stop() changes state to 'closed'.`); |
| |
| promise_test(async t => { |
| const quicTransport = await makeStandaloneQuicTransport(t); |
| quicTransport.transport.stop(); |
| assert_equals(quicTransport.state, 'closed'); |
| }, `RTCIceTransport.stop() changes RTCQuicTransport.state to 'closed'.`); |
| |
| promise_test(async t => { |
| const quicTransport = await makeStandaloneQuicTransport(t); |
| quicTransport.start(quicTransport.getLocalParameters()); |
| assert_equals(quicTransport.state, 'new'); |
| }, 'start() with a non-started RTCIceTransport does not change state.'); |
| |
| promise_test(async t => { |
| const certificate = await generateCertificate(); |
| const [ localIceTransport, remoteIceTransport ] = |
| makeAndGatherTwoIceTransports(t); |
| const quicTransport = |
| makeQuicTransport(t, localIceTransport, [ certificate ]); |
| quicTransport.start(quicTransport.getLocalParameters()); |
| const iceTransportWatcher = |
| new EventWatcher(t, remoteIceTransport, 'icecandidate'); |
| await iceTransportWatcher.wait_for('icecandidate'); |
| localIceTransport.start(remoteIceTransport.getLocalParameters(), |
| 'controlling'); |
| assert_equals(quicTransport.state, 'connecting'); |
| }, 'start() with a non-started RTCIceTransport later changes state to ' + |
| `'connecting' once the RTCIceTransport.start() is called.`); |
| |
| promise_test(async t => { |
| const certificate = await generateCertificate(); |
| const [ localIceTransport, remoteIceTransport ] = |
| makeAndGatherTwoIceTransports(t); |
| const quicTransport = |
| makeQuicTransport(t, localIceTransport, [ certificate ]); |
| const iceTransportWatcher = |
| new EventWatcher(t, remoteIceTransport, 'icecandidate'); |
| await iceTransportWatcher.wait_for('icecandidate'); |
| localIceTransport.start(remoteIceTransport.getLocalParameters()); |
| quicTransport.start(quicTransport.getLocalParameters()); |
| assert_equals(quicTransport.state, 'connecting'); |
| }, `start() with a started RTCIceTransport changes state to 'connecting'.`); |
| |
| promise_test(async t => { |
| const quicTransport = await makeStandaloneQuicTransport(t); |
| quicTransport.stop(); |
| assert_throws('InvalidStateError', |
| () => quicTransport.start(quicTransport.getLocalParameters())); |
| }, 'start() throws if called after stop().'); |
| |
| promise_test(async t => { |
| const quicTransport = await makeStandaloneQuicTransport(t); |
| quicTransport.transport.stop(); |
| assert_throws('InvalidStateError', |
| () => quicTransport.start(quicTransport.getLocalParameters())); |
| }, 'start() throws if called after the RTCIceTransport has stopped.'); |
| |
| promise_test(async t => { |
| const quicTransport = await makeStandaloneQuicTransport(t); |
| quicTransport.start(quicTransport.getLocalParameters()); |
| assert_throws('InvalidStateError', |
| () => quicTransport.start(quicTransport.getLocalParameters())); |
| }, 'start() throws if called twice.'); |
| |
| promise_test(async t => { |
| const [ localQuicTransport, remoteQuicTransport ] = |
| await makeAndStartTwoQuicTransports(t); |
| const localWatcher = new EventWatcher(t, localQuicTransport, 'statechange'); |
| const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'statechange'); |
| await Promise.all([ |
| localWatcher.wait_for('statechange').then(() => { |
| assert_equals(localQuicTransport.state, 'connected'); |
| }), |
| remoteWatcher.wait_for('statechange').then(() => { |
| assert_equals(remoteQuicTransport.state, 'connected'); |
| }), |
| ]); |
| }, 'Two RTCQuicTransports connect to each other.'); |
| |
| promise_test(async t => { |
| const [ localQuicTransport, remoteQuicTransport ] = |
| await makeTwoConnectedQuicTransports(t); |
| localQuicTransport.stop(); |
| const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'statechange'); |
| await remoteWatcher.wait_for('statechange'); |
| assert_equals(remoteQuicTransport.state, 'closed'); |
| }, `stop() fires a statechange event to 'closed' on the remote transport`); |
| |
| </script> |
| |