diff options
Diffstat (limited to 'dom/media/webrtc/tests/mochitests/test_peerConnection_close.html')
-rw-r--r-- | dom/media/webrtc/tests/mochitests/test_peerConnection_close.html | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/dom/media/webrtc/tests/mochitests/test_peerConnection_close.html b/dom/media/webrtc/tests/mochitests/test_peerConnection_close.html new file mode 100644 index 0000000000..3edf677203 --- /dev/null +++ b/dom/media/webrtc/tests/mochitests/test_peerConnection_close.html @@ -0,0 +1,134 @@ +<!DOCTYPE HTML> +<html> +<head> + <script type="application/javascript" src="pc.js"></script> +</head> +<body> +<pre id="test"> +<script type="application/javascript"> + createHTML({ + bug: "991877", + title: "Basic RTCPeerConnection.close() tests" + }); + + runNetworkTest(function () { + var pc = new RTCPeerConnection(); + var sender = pc.addTrack(getSilentTrack(), new MediaStream()); + var exception = null; + var eTimeout = null; + + // everything should be in initial state + is(pc.signalingState, "stable", "Initial signalingState is 'stable'"); + is(pc.iceConnectionState, "new", "Initial iceConnectionState is 'new'"); + is(pc.iceGatheringState, "new", "Initial iceGatheringState is 'new'"); + + var finish; + var finished = new Promise(resolve => finish = resolve); + + var mustNotSettle = (p, ms, msg) => Promise.race([ + p.then(() => ok(false, msg + " must not settle"), + e => ok(false, msg + " must not settle. Got " + e.name)), + wait(ms).then(() => ok(true, msg + " must not settle")) + ]); + + var silence = mustNotSettle(pc.createOffer(), 1000, + "createOffer immediately followed by close"); + try { + pc.close(); + } catch (e) { + exception = e; + } + is(exception, null, "closing the connection raises no exception"); + is(pc.signalingState, "closed", "Final signalingState is 'closed'"); + is(pc.iceConnectionState, "closed", "Final iceConnectionState is 'closed'"); + + // test that pc is really closed (and doesn't crash, bug 1259728) + try { + pc.getLocalStreams(); + } catch (e) { + exception = e; + } + is(exception && exception.name, "InvalidStateError", + "pc.getLocalStreams should throw when closed"); + exception = null; + + try { + pc.close(); + } catch (e) { + exception = e; + } + is(exception, null, "A second close() should not raise an exception"); + is(pc.signalingState, "closed", "Final signalingState stays at 'closed'"); + is(pc.iceConnectionState, "closed", "Final iceConnectionState stays at 'closed'"); + + // Due to a limitation in our WebIDL compiler that prevents overloads with + // both Promise and non-Promise return types, legacy APIs with callbacks + // are unable to continue to throw exceptions. Luckily the spec uses + // exceptions solely for "programming errors" so this should not hinder + // working code from working, which is the point of the legacy API. All + // new code should use the promise API. + // + // The legacy methods that no longer throw on programming errors like + // "invalid-on-close" are: + // - createOffer + // - createAnswer + // - setLocalDescription + // - setRemoteDescription + // - addIceCandidate + // - getStats + // + // These legacy methods fire the error callback instead. This is not + // entirely to spec but is better than ignoring programming errors. + + var offer = new RTCSessionDescription({ sdp: "sdp", type: "offer" }); + var answer = new RTCSessionDescription({ sdp: "sdp", type: "answer" }); + var candidate = new RTCIceCandidate({ candidate: "dummy", + sdpMid: "test", + sdpMLineIndex: 3 }); + + var doesFail = (p, msg) => p.then(generateErrorCallback(msg), + r => is(r.name, "InvalidStateError", msg)); + Promise.all([ + [pc.createOffer(), "createOffer"], + [pc.createOffer({offerToReceiveAudio: true}), "createOffer({offerToReceiveAudio: true})"], + [pc.createOffer({offerToReceiveAudio: false}), "createOffer({offerToReceiveAudio: false})"], + [pc.createOffer({offerToReceiveVideo: true}), "createOffer({offerToReceiveVideo: true})"], + [pc.createOffer({offerToReceiveVideo: false}), "createOffer({offerToReceiveVideo: false})"], + [pc.createAnswer(), "createAnswer"], + [pc.setLocalDescription(offer), "setLocalDescription"], + [pc.setRemoteDescription(answer), "setRemoteDescription"], + [pc.addIceCandidate(candidate), "addIceCandidate"], + [new Promise((y, n) => pc.createOffer(y, n)), "Legacy createOffer"], + [new Promise((y, n) => pc.createAnswer(y, n)), "Legacy createAnswer"], + [new Promise((y, n) => pc.setLocalDescription(offer, y, n)), "Legacy setLocalDescription"], + [new Promise((y, n) => pc.setRemoteDescription(answer, y, n)), "Legacy setRemoteDescription"], + [new Promise((y, n) => pc.addIceCandidate(candidate, y, n)), "Legacy addIceCandidate"], + [sender.replaceTrack(getSilentTrack()), "replaceTrack"], + ].map(([p, name]) => doesFail(p, name + " fails on close"))) + .catch(reason => ok(false, "unexpected failure: " + reason)) + .then(finish); + + // Other methods are unaffected. + + SimpleTest.doesThrow(function() { + pc.updateIce("Invalid RTC Configuration")}, + "updateIce() on closed PC raised expected exception"); + + SimpleTest.doesThrow(function() { + pc.addStream("Invalid Media Stream")}, + "addStream() on closed PC raised expected exception"); + + SimpleTest.doesThrow(function() { + pc.createDataChannel({})}, + "createDataChannel() on closed PC raised expected exception"); + + SimpleTest.doesThrow(function() { + pc.setIdentityProvider("Invalid Provider")}, + "setIdentityProvider() on closed PC raised expected exception"); + + return Promise.all([finished, silence]); + }); +</script> +</pre> +</body> +</html> |