diff options
Diffstat (limited to '')
-rw-r--r-- | testing/web-platform/tests/webrtc/RTCPeerConnection-addIceCandidate-timing.https.html | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webrtc/RTCPeerConnection-addIceCandidate-timing.https.html b/testing/web-platform/tests/webrtc/RTCPeerConnection-addIceCandidate-timing.https.html new file mode 100644 index 0000000000..9793844f56 --- /dev/null +++ b/testing/web-platform/tests/webrtc/RTCPeerConnection-addIceCandidate-timing.https.html @@ -0,0 +1,149 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + +'use strict'; + +// In this test, the promises should resolve in the execution order +// (setLocalDescription, setLocalDescription, addIceCandidate) as is ensured by +// the Operations Chain; if an operation is pending, executing another operation +// will queue it. This test will fail if an Operations Chain is not implemented, +// but it gives the implementation some slack: it only ensures that +// addIceCandidate() is not resolved first, allowing timing issues in resolving +// promises where the test still passes even if addIceCandidate() is resolved +// *before* the second setLocalDescription(). +// +// This test covers Chrome issue (https://crbug.com/1019222), but does not +// require setLocalDescription-promises to resolve immediately which is another +// Chrome bug (https://crbug.com/1019232). The true order is covered by the next +// test. +// TODO(https://crbug.com/1019232): Delete this test when the next test passes +// in Chrome. +promise_test(async t => { + const caller = new RTCPeerConnection(); + t.add_cleanup(() => caller.close()); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => callee.close()); + caller.addTransceiver('audio'); + + const candidatePromise = new Promise(resolve => { + caller.onicecandidate = e => resolve(e.candidate); + }); + await caller.setLocalDescription(await caller.createOffer()); + await callee.setRemoteDescription(caller.localDescription); + const candidate = await candidatePromise; + + // Chain setLocalDescription(), setLocalDescription() and addIceCandidate() + // without performing await between the calls. + const pendingPromises = []; + const resolveOrder = []; + pendingPromises.push(callee.setLocalDescription().then(() => { + resolveOrder.push('setLocalDescription 1'); + })); + pendingPromises.push(callee.setLocalDescription().then(() => { + resolveOrder.push('setLocalDescription 2'); + })); + pendingPromises.push(callee.addIceCandidate(candidate).then(() => { + resolveOrder.push('addIceCandidate'); + })); + await Promise.all(pendingPromises); + + assert_equals(resolveOrder[0], 'setLocalDescription 1'); +}, 'addIceCandidate is not resolved first if 2x setLocalDescription ' + + 'operations are pending'); + +promise_test(async t => { + const caller = new RTCPeerConnection(); + t.add_cleanup(() => caller.close()); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => callee.close()); + caller.addTransceiver('audio'); + + const candidatePromise = new Promise(resolve => { + caller.onicecandidate = e => resolve(e.candidate); + }); + await caller.setLocalDescription(await caller.createOffer()); + await callee.setRemoteDescription(caller.localDescription); + const candidate = await candidatePromise; + + // Chain setLocalDescription(), setLocalDescription() and addIceCandidate() + // without performing await between the calls. + const pendingPromises = []; + const resolveOrder = []; + pendingPromises.push(callee.setLocalDescription().then(() => { + resolveOrder.push('setLocalDescription 1'); + })); + pendingPromises.push(callee.setLocalDescription().then(() => { + resolveOrder.push('setLocalDescription 2'); + })); + pendingPromises.push(callee.addIceCandidate(candidate).then(() => { + resolveOrder.push('addIceCandidate'); + })); + await Promise.all(pendingPromises); + + // This test verifies that both issues described in https://crbug.com/1019222 + // and https://crbug.com/1019232 are fixed. If this test passes in Chrome, the + // ICE candidate exchange issues described in + // https://github.com/web-platform-tests/wpt/issues/19866 should be resolved. + assert_array_equals( + resolveOrder, + ['setLocalDescription 1', 'setLocalDescription 2', 'addIceCandidate']); +}, 'addIceCandidate and setLocalDescription are resolved in the correct ' + + 'order, as defined by the operations chain specification'); + +promise_test(async t => { + const caller = new RTCPeerConnection(); + t.add_cleanup(() => caller.close()); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => callee.close()); + caller.addTransceiver('audio'); + let events = []; + let pendingPromises = []; + + const onCandidatePromise = new Promise(resolve => { + caller.onicecandidate = () => { + events.push('candidate generated'); + resolve(); + } + }); + pendingPromises.push(onCandidatePromise); + pendingPromises.push(caller.setLocalDescription().then(() => { + events.push('setLocalDescription'); + })); + await Promise.all(pendingPromises); + assert_array_equals(events, ['setLocalDescription', 'candidate generated']); +}, 'onicecandidate fires after resolving setLocalDescription in offerer'); + +promise_test(async t => { + const caller = new RTCPeerConnection(); + t.add_cleanup(() => caller.close()); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => callee.close()); + caller.addTransceiver('audio'); + let events = []; + let pendingPromises = []; + + caller.onicecandidate = (ev) => { + if (ev.candidate) { + callee.addIceCandidate(ev.candidate); + } + } + const offer = await caller.createOffer(); + const onCandidatePromise = new Promise(resolve => { + callee.onicecandidate = () => { + events.push('candidate generated'); + resolve(); + } + }); + await callee.setRemoteDescription(offer); + const answer = await callee.createAnswer(); + pendingPromises.push(onCandidatePromise); + pendingPromises.push(callee.setLocalDescription(answer).then(() => { + events.push('setLocalDescription'); + })); + await Promise.all(pendingPromises); + assert_array_equals(events, ['setLocalDescription', 'candidate generated']); +}, 'onicecandidate fires after resolving setLocalDescription in answerer'); + +</script> |