From 0e97d09a90f8e384d0a819f9f9be2ea7e17302bb Mon Sep 17 00:00:00 2001 From: youennf Date: Sat, 23 Mar 2019 19:02:56 +0100 Subject: [PATCH] Data channel tests updated by Lennart Grahl (#16038) * Data channel tests modernized/updated by Lennart Grahl * Fix according Harald comments --- webrtc/README.md | 12 + webrtc/RTCDataChannel-bufferedAmount.html | 372 ++++++---- webrtc/RTCDataChannel-id.html | 380 ++++++++-- webrtc/RTCDataChannelEvent-constructor.html | 17 +- .../RTCPeerConnection-createDataChannel.html | 696 ++++++++++++------ webrtc/RTCPeerConnection-helper.js | 74 +- webrtc/RTCPeerConnection-ondatachannel.html | 534 +++++++++----- webrtc/RTCSctpTransport-constructor.html | 198 +++-- webrtc/RTCSctpTransport-maxMessageSize.html | 278 +++---- webrtc/historical.html | 11 +- 10 files changed, 1754 insertions(+), 818 deletions(-) create mode 100644 webrtc/README.md diff --git a/webrtc/README.md b/webrtc/README.md new file mode 100644 index 00000000000000..4477e4f375fdc0 --- /dev/null +++ b/webrtc/README.md @@ -0,0 +1,12 @@ +# WebRTC + +This directory contains the WebRTC test suite. + +## Acknowledgements + +Some data channel tests are based on the [data channel conformance test +suite][nplab-webrtc-dc-playground] of the Network Programming Lab of the Münster +University of Applied Sciences. We would like to thank Peter Titz, Felix Weinrank and Timo +Völker for agreeing to contribute their test cases to this repository. + +[nplab-webrtc-dc-playground]: https://github.com/nplab/WebRTC-Data-Channel-Playground/tree/master/conformance-tests diff --git a/webrtc/RTCDataChannel-bufferedAmount.html b/webrtc/RTCDataChannel-bufferedAmount.html index f4a7104a4e5f33..b982b29b3b957e 100644 --- a/webrtc/RTCDataChannel-bufferedAmount.html +++ b/webrtc/RTCDataChannel-bufferedAmount.html @@ -5,166 +5,222 @@ + diff --git a/webrtc/RTCDataChannelEvent-constructor.html b/webrtc/RTCDataChannelEvent-constructor.html index 997f65c43801a9..03211eccb920e1 100644 --- a/webrtc/RTCDataChannelEvent-constructor.html +++ b/webrtc/RTCDataChannelEvent-constructor.html @@ -4,6 +4,9 @@ diff --git a/webrtc/RTCPeerConnection-createDataChannel.html b/webrtc/RTCPeerConnection-createDataChannel.html index 450a25002ed221..ae74b62d42c3de 100644 --- a/webrtc/RTCPeerConnection-createDataChannel.html +++ b/webrtc/RTCPeerConnection-createDataChannel.html @@ -3,44 +3,51 @@ RTCPeerConnection.prototype.createDataChannel + diff --git a/webrtc/RTCPeerConnection-helper.js b/webrtc/RTCPeerConnection-helper.js index 0b25df26190c14..310f028c605cbf 100644 --- a/webrtc/RTCPeerConnection-helper.js +++ b/webrtc/RTCPeerConnection-helper.js @@ -261,51 +261,93 @@ function listenForSSRCs(t, receiver) { // end points to open. function createDataChannelPair( pc1=new RTCPeerConnection(), - pc2=new RTCPeerConnection()) + pc2=new RTCPeerConnection(), + options={}) { - const channel1 = pc1.createDataChannel(''); + options = Object.assign({}, { + channelLabel: '', + channelOptions: undefined, + doSignaling: true + }, options); + + let channel1Options; + let channel2Options = null; + if (options.channelOptions instanceof Array) { + [channel1Options, channel2Options] = options.channelOptions; + } else { + channel1Options = options.channelOptions; + } - exchangeIceCandidates(pc1, pc2); + const channel1 = pc1.createDataChannel(options.channelLabel, channel1Options); return new Promise((resolve, reject) => { let channel2; let opened1 = false; let opened2 = false; + function cleanup() { + channel1.removeEventListener('open', onOpen1); + channel2.removeEventListener('open', onOpen2); + channel1.removeEventListener('error', onError); + channel2.removeEventListener('error', onError); + } + function onBothOpened() { + cleanup(); resolve([channel1, channel2]); } + function onError(...args) { + cleanup(); + reject(...args); + } + function onOpen1() { opened1 = true; - if(opened2) onBothOpened(); + if (opened2) { + onBothOpened(); + } } function onOpen2() { opened2 = true; - if(opened1) onBothOpened(); + if (opened1) { + onBothOpened(); + } } - function onDataChannel(event) { - channel2 = event.channel; - channel2.addEventListener('error', reject); + function onDataChannelPairFound() { + channel2.addEventListener('error', onError, { once: true }); const { readyState } = channel2; - if(readyState === 'open') { + if (readyState === 'open') { onOpen2(); - } else if(readyState === 'connecting') { - channel2.addEventListener('open', onOpen2); + } else if (readyState === 'connecting') { + channel2.addEventListener('open', onOpen2, { once: true }); } else { - reject(new Error(`Unexpected ready state ${readyState}`)); + onError(new Error(`Unexpected ready state ${readyState}`)); } } - channel1.addEventListener('open', onOpen1); - channel1.addEventListener('error', reject); + function onDataChannel(event) { + channel2 = event.channel; + onDataChannelPairFound(); + } + + channel1.addEventListener('open', onOpen1, { once: true }); + channel1.addEventListener('error', onError, { once: true }); - pc2.addEventListener('datachannel', onDataChannel); + if (channel2Options !== null) { + channel2 = pc2.createDataChannel(options.channelLabel, channel2Options); + onDataChannelPairFound(); + } else { + pc2.addEventListener('datachannel', onDataChannel); + } - doSignalingHandshake(pc1, pc2); + if (options.doSignaling) { + exchangeIceCandidates(pc1, pc2); + doSignalingHandshake(pc1, pc2, options); + } }); } diff --git a/webrtc/RTCPeerConnection-ondatachannel.html b/webrtc/RTCPeerConnection-ondatachannel.html index 1070ee701d2336..711027439b3ab4 100644 --- a/webrtc/RTCPeerConnection-ondatachannel.html +++ b/webrtc/RTCPeerConnection-ondatachannel.html @@ -5,180 +5,376 @@ diff --git a/webrtc/RTCSctpTransport-constructor.html b/webrtc/RTCSctpTransport-constructor.html index 28dae055532490..e837d9b127b909 100644 --- a/webrtc/RTCSctpTransport-constructor.html +++ b/webrtc/RTCSctpTransport-constructor.html @@ -5,85 +5,121 @@ diff --git a/webrtc/RTCSctpTransport-maxMessageSize.html b/webrtc/RTCSctpTransport-maxMessageSize.html index 9163a66af151e3..99767611509197 100644 --- a/webrtc/RTCSctpTransport-maxMessageSize.html +++ b/webrtc/RTCSctpTransport-maxMessageSize.html @@ -9,10 +9,13 @@ 'use strict'; // This test has an assert_unreached() that requires that the variable -// canSendSize (initiated below) is greater than 2, if non-zero. The reason -// is that we need two non-zero values that are less that that value for -// testing with predictable results. This is a bit unfortunate but shouldn't -// have any practical impact. +// canSendSize (initiated below) must be 0 or greater than 2. The reason +// is that we need two non-zero values for testing the following two cases: +// +// * if remote MMS `1` < canSendSize it should result in `1`. +// * renegotiation of the above case with remoteMMS `2` should result in `2`. +// +// This is a bit unfortunate but shouldn't have any practical impact. // Helper class to read SDP attributes and generate SDPs with modified attribute values class SDPAttributeHelper { @@ -39,148 +42,165 @@ } const mmsAttributeHelper = new SDPAttributeHelper('max-message-size', '\\d+'); -let canSendSize; -const remoteValue1 = 1; -const remoteValue2 = 2; +let canSendSize = null; +const remoteSize1 = 1; +const remoteSize2 = 2; -promise_test(t => { +promise_test(async (t) => { const pc = new RTCPeerConnection(); t.add_cleanup(() => pc.close()); - assert_equals(pc.sctp, null); - let maxMessageSize; - - return generateDataChannelOffer(pc) - .then((offer) => { - assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, - 'SDP should have max-message-size attribute'); - - offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, 0) }; - return pc.setRemoteDescription(offer); - }) - .then(() => pc.createAnswer()) - .then((answer) => pc.setLocalDescription(answer)) - .then(() => { - assert_not_equals(pc.sctp, null); - canSendSize = pc.sctp.maxMessageSize == Number.POSITIVE_INFINITY ? 0 : pc.sctp.maxMessageSize; - if (canSendSize != 0 && canSendSize < remoteValue2) { - assert_unreached('This test needs two values that are less than canSendSize (unless it is zero)'); - } - }); + + assert_equals(pc.sctp, null, 'RTCSctpTransport must be null'); + + let offer = await generateDataChannelOffer(pc); + assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, + 'SDP should have max-message-size attribute'); + offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, 0) }; + await pc.setRemoteDescription(offer); + const answer = await pc.createAnswer(); + await pc.setLocalDescription(answer); + + assert_not_equals(pc.sctp, null, 'RTCSctpTransport must be available'); + canSendSize = pc.sctp.maxMessageSize === Number.POSITIVE_INFINITY ? 0 : pc.sctp.maxMessageSize; + if (canSendSize !== 0 && canSendSize < remoteSize2) { + assert_unreached( + 'This test needs canSendSize to be 0 or > 2 for further "below" and "above" tests'); + } }, 'Determine the local side send limitation (canSendSize) by offering a max-message-size of 0'); -promise_test(t => { +promise_test(async (t) => { + assert_not_equals(canSendSize, null, 'canSendSize needs to be determined'); + const pc = new RTCPeerConnection(); t.add_cleanup(() => pc.close()); - assert_equals(pc.sctp, null); - - return generateDataChannelOffer(pc) - .then((offer) => { - assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, - 'SDP should have max-message-size attribute'); - - // Remove the max-message-size SDP attribute - offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithoutAttribute(offer.sdp) }; - return pc.setRemoteDescription(offer) - }) - .then(() => pc.createAnswer()) - .then((answer) => pc.setLocalDescription(answer)) - .then(() => { - assert_not_equals(pc.sctp, null); - // Test outcome depends on canSendSize value - if (canSendSize) { - assert_equals(pc.sctp.maxMessageSize, Math.min(65536, canSendSize), - 'Missing SDP attribute and a non-zero canSendSize should give an maxMessageSize of min(65536, canSendSize)'); - } else { - assert_equals(pc.sctp.maxMessageSize, 65536, - 'Missing SDP attribute and a canSendSize of 0 should give an maxMessageSize of 65536'); - } - }); + + assert_equals(pc.sctp, null, 'RTCSctpTransport must be null'); + + let offer = await generateDataChannelOffer(pc); + assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, + 'SDP should have max-message-size attribute'); + + // Remove the max-message-size SDP attribute + offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithoutAttribute(offer.sdp) }; + await pc.setRemoteDescription(offer); + const answer = await pc.createAnswer(); + await pc.setLocalDescription(answer); + + assert_not_equals(pc.sctp, null, 'RTCSctpTransport must be available'); + // Test outcome depends on canSendSize value + if (canSendSize !== 0) { + assert_equals(pc.sctp.maxMessageSize, Math.min(65536, canSendSize), + 'Missing SDP attribute and a non-zero canSendSize should give an maxMessageSize of min(65536, canSendSize)'); + } else { + assert_equals(pc.sctp.maxMessageSize, 65536, + 'Missing SDP attribute and a canSendSize of 0 should give an maxMessageSize of 65536'); + } }, 'Remote offer SDP missing max-message-size attribute'); -promise_test(t => { +promise_test(async (t) => { + assert_not_equals(canSendSize, null, 'canSendSize needs to be determined'); + const pc = new RTCPeerConnection(); t.add_cleanup(() => pc.close()); - assert_equals(pc.sctp, null); - - return generateDataChannelOffer(pc) - .then((offer) => { - assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, - 'SDP should have max-message-size attribute'); - - offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue1) }; - return pc.setRemoteDescription(offer); - }) - .then(() => pc.createAnswer()) - .then((answer) => pc.setLocalDescription(answer)) - .then(() => { - assert_not_equals(pc.sctp, null); - assert_equals(pc.sctp.maxMessageSize, remoteValue1, - 'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)'); - }); + + assert_equals(pc.sctp, null, 'RTCSctpTransport must be null'); + + let offer = await generateDataChannelOffer(pc); + assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, + 'SDP should have max-message-size attribute'); + + offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteSize1) }; + await pc.setRemoteDescription(offer); + const answer = await pc.createAnswer(); + await pc.setLocalDescription(answer); + + assert_not_equals(pc.sctp, null, 'RTCSctpTransport must be available'); + assert_equals(pc.sctp.maxMessageSize, remoteSize1, + 'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)'); }, 'max-message-size with a (non-zero) value provided by the remote peer'); -promise_test(t => { +promise_test(async (t) => { + assert_not_equals(canSendSize, null, 'canSendSize needs to be determined'); + const pc = new RTCPeerConnection(); t.add_cleanup(() => pc.close()); - assert_equals(pc.sctp, null); - - return generateDataChannelOffer(pc) - .then((offer) => { - assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, - 'SDP should have max-message-size attribute'); - - offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue1) }; - return pc.setRemoteDescription(offer) - }) - .then(() => pc.createAnswer()) - .then((answer) => pc.setLocalDescription(answer)) - .then(() => { - assert_not_equals(pc.sctp, null); - assert_equals(pc.sctp.maxMessageSize, remoteValue1, - 'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)'); - }) - .then(() => pc.createOffer()) // Start new O/A exchange that updates max-message-size - .then((offer) => { - offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue2)}; - return pc.setRemoteDescription(offer) - }) - .then(() => pc.createAnswer()) - .then((answer) => pc.setLocalDescription(answer)) - .then(() => { - assert_not_equals(pc.sctp, null); - assert_equals(pc.sctp.maxMessageSize, remoteValue2, - 'maxMessageSize should be the new value provided by the remote peer (as long as it is less than canSendSize)'); - }) - ; -}, 'Renegotiate max-message-size with a (non-zero) value provided by the remote peer'); - -promise_test(t => { + + assert_equals(pc.sctp, null, 'RTCSctpTransport must be null'); + + let offer = await generateDataChannelOffer(pc); + assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, + 'SDP should have max-message-size attribute'); + + offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteSize1) }; + await pc.setRemoteDescription(offer); + let answer = await pc.createAnswer(); + await pc.setLocalDescription(answer); + + assert_not_equals(pc.sctp, null, 'RTCSctpTransport must be available'); + assert_equals(pc.sctp.maxMessageSize, remoteSize1, + 'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)'); + + // Start new O/A exchange that updates max-message-size to remoteSize2 + offer = await pc.createOffer(); + offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteSize2)}; + await pc.setRemoteDescription(offer); + answer = await pc.createAnswer(); + await pc.setLocalDescription(answer); + + assert_not_equals(pc.sctp, null, 'RTCSctpTransport must be available'); + assert_equals(pc.sctp.maxMessageSize, remoteSize2, + 'maxMessageSize should be the new value provided by the remote peer (as long as it is less than canSendSize)'); + + // Start new O/A exchange that updates max-message-size to zero + offer = await pc.createOffer(); + offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, 0)}; + await pc.setRemoteDescription(offer); + answer = await pc.createAnswer(); + await pc.setLocalDescription(answer); + + assert_not_equals(pc.sctp, null, 'RTCSctpTransport must be available'); + assert_equals(pc.sctp.maxMessageSize, canSendSize, + 'maxMessageSize should be canSendSize'); + + // Start new O/A exchange that updates max-message-size to remoteSize1 again + offer = await pc.createOffer(); + offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteSize1)}; + await pc.setRemoteDescription(offer); + answer = await pc.createAnswer(); + await pc.setLocalDescription(answer); + + assert_not_equals(pc.sctp, null, 'RTCSctpTransport must be available'); + assert_equals(pc.sctp.maxMessageSize, remoteSize1, + 'maxMessageSize should be the new value provided by the remote peer (as long as it is less than canSendSize)'); +}, 'Renegotiate max-message-size with various values provided by the remote peer'); + +promise_test(async (t) => { + assert_not_equals(canSendSize, null, 'canSendSize needs to be determined'); + const pc = new RTCPeerConnection(); t.add_cleanup(() => pc.close()); - assert_equals(pc.sctp, null); - const largerThanCanSendSize = canSendSize + 1; - - return generateDataChannelOffer(pc) - .then((offer) => { - assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, - 'SDP should have max-message-size attribute'); - - offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, largerThanCanSendSize) }; - return pc.setRemoteDescription(offer) - }) - .then(() => pc.createAnswer()) - .then((answer) => pc.setLocalDescription(answer)) - .then(() => { - assert_not_equals(pc.sctp, null); - // Test outcome depends on canSendSize value - if (canSendSize) { - assert_equals(pc.sctp.maxMessageSize, canSendSize, - 'A remote value larger than a non-zero canSendSize should limit maxMessageSize to canSendSize'); - } else { - assert_equals(pc.sctp.maxMessageSize, 65536, - 'A canSendSize of zero should let the remote value set maxMessageSize'); - } - }); + + assert_equals(pc.sctp, null, 'RTCSctpTransport must be null'); + const largerThanCanSendSize = canSendSize === 0 ? 0 : canSendSize + 1; + + let offer = await generateDataChannelOffer(pc); + assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null, + 'SDP should have max-message-size attribute'); + + offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, largerThanCanSendSize) }; + await pc.setRemoteDescription(offer); + const answer = await pc.createAnswer(); + await pc.setLocalDescription(answer); + + assert_not_equals(pc.sctp, null, 'RTCSctpTransport must be available'); + // Test outcome depends on canSendSize value + if (canSendSize !== 0) { + assert_equals(pc.sctp.maxMessageSize, canSendSize, + 'A remote value larger than a non-zero canSendSize should limit maxMessageSize to canSendSize'); + } else { + assert_equals(pc.sctp.maxMessageSize, Number.POSITIVE_INFINITY, + 'A remote value of zero and canSendSize zero should result in "infinity"'); + } }, 'max-message-size with a (non-zero) value larger than canSendSize provided by the remote peer'); diff --git a/webrtc/historical.html b/webrtc/historical.html index ffa28be5bca307..ae7a29dec0c184 100644 --- a/webrtc/historical.html +++ b/webrtc/historical.html @@ -4,9 +4,14 @@