diff --git a/dom/media/tests/mochitest/Makefile.in b/dom/media/tests/mochitest/Makefile.in index 2720ee9ccf2c..9b9c102ca73f 100644 --- a/dom/media/tests/mochitest/Makefile.in +++ b/dom/media/tests/mochitest/Makefile.in @@ -35,6 +35,13 @@ MOCHITEST_FILES = \ test_peerConnection_offerRequiresReceiveVideo.html \ test_peerConnection_offerRequiresReceiveVideoAudio.html \ test_peerConnection_throwInCallbacks.html \ + test_peerConnection_setLocalAnswerInStable.html \ + test_peerConnection_setRemoteAnswerInStable.html \ + test_peerConnection_setLocalAnswerInHaveLocalOffer.html \ + test_peerConnection_setRemoteOfferInHaveLocalOffer.html \ + test_peerConnection_setLocalOfferInHaveRemoteOffer.html \ + test_peerConnection_setRemoteAnswerInHaveRemoteOffer.html \ + test_peerConnection_addCandidateInHaveLocalOffer.html \ test_peerConnection_bug822674.html \ test_peerConnection_bug825703.html \ test_peerConnection_bug827843.html \ diff --git a/dom/media/tests/mochitest/head.js b/dom/media/tests/mochitest/head.js index 0a9a5d307728..2099790644be 100644 --- a/dom/media/tests/mochitest/head.js +++ b/dom/media/tests/mochitest/head.js @@ -182,11 +182,23 @@ function unexpectedCallbackAndFinish(error) { return function(aObj) { var where = error.fileName + ":" + error.lineNumber; if (aObj && aObj.name && aObj.message) { - ok(false, "Unexpected error callback from " + where + " with name = '" + + ok(false, "Unexpected callback/event from " + where + " with name = '" + aObj.name + "', message = '" + aObj.message + "'"); } else { - ok(false, "Unexpected error callback from " + where + " with " + aObj); + ok(false, "Unexpected callback/event from " + where + " with " + aObj); } SimpleTest.finish(); } } + +/** + * Generates a callback function suitable for putting int a success + * callback in circumstances where success is unexpected. The callback, + * if activated, will kill off the test gracefully. + */ + +function unexpectedSuccessCallbackAndFinish(error, reason) { + return function() { + unexpectedCallbackAndFinish(error)(message); + } +} diff --git a/dom/media/tests/mochitest/pc.js b/dom/media/tests/mochitest/pc.js index dc6c747cf1ff..78d17471812d 100644 --- a/dom/media/tests/mochitest/pc.js +++ b/dom/media/tests/mochitest/pc.js @@ -246,10 +246,19 @@ var commandsPeerConnection = [ }); } ], + [ + 'PC_CHECK_INITIAL_SIGNALINGSTATE', + function (test) { + is(test.pcLocal.signalingState,"stable", "Initial local signalingState is stable"); + is(test.pcRemote.signalingState,"stable", "Initial remote signalingState is stable"); + test.next(); + } + ], [ 'PC_LOCAL_CREATE_OFFER', function (test) { test.pcLocal.createOffer(function () { + is(test.pcLocal.signalingState, "stable", "Local create offer does not change signaling state"); test.next(); }); } @@ -257,23 +266,24 @@ var commandsPeerConnection = [ [ 'PC_LOCAL_SET_LOCAL_DESCRIPTION', function (test) { - test.pcLocal.setLocalDescription(test.pcLocal._last_offer, function () { - test.next(); - }); + test.expectStateChange(test.pcLocal, "have-local-offer", test); + test.pcLocal.setLocalDescription(test.pcLocal._last_offer, + test.checkStateInCallback(test.pcLocal, "have-local-offer", test)); } ], [ 'PC_REMOTE_SET_REMOTE_DESCRIPTION', function (test) { - test.pcRemote.setRemoteDescription(test.pcLocal._last_offer, function () { - test.next(); - }); + test.expectStateChange(test.pcRemote, "have-remote-offer", test); + test.pcRemote.setRemoteDescription(test.pcLocal._last_offer, + test.checkStateInCallback(test.pcRemote, "have-remote-offer", test)); } ], [ 'PC_REMOTE_CREATE_ANSWER', function (test) { test.pcRemote.createAnswer(function () { + is(test.pcRemote.signalingState, "have-remote-offer", "Remote create offer does not change signaling state"); test.next(); }); } @@ -281,17 +291,17 @@ var commandsPeerConnection = [ [ 'PC_LOCAL_SET_REMOTE_DESCRIPTION', function (test) { - test.pcLocal.setRemoteDescription(test.pcRemote._last_answer, function () { - test.next(); - }); + test.expectStateChange(test.pcLocal, "stable", test); + test.pcLocal.setRemoteDescription(test.pcRemote._last_answer, + test.checkStateInCallback(test.pcLocal, "stable", test)); } ], [ 'PC_REMOTE_SET_LOCAL_DESCRIPTION', function (test) { - test.pcRemote.setLocalDescription(test.pcRemote._last_answer, function () { - test.next(); - }); + test.expectStateChange(test.pcRemote, "stable", test); + test.pcRemote.setLocalDescription(test.pcRemote._last_answer, + test.checkStateInCallback(test.pcRemote, "stable", test)); } ], [ @@ -394,6 +404,64 @@ PeerConnectionTest.prototype.teardown = function PCT_teardown() { SimpleTest.finish(); }; +/** + * Sets up the "onsignalingstatechange" handler for the indicated peerconnection + * as a one-shot test. If the test.commandSuccess flag is set when the event + * happens, then the next test in the command chain is triggered. After + * running, this sets the event handler so that it will fail the test if + * it fires again before we expect it. This is intended to be used in + * conjunction with checkStateInCallback, below. + * + * @param {pcw} PeerConnectionWrapper + * The peer connection to expect a state change on + * @param {state} string + * The state that we expect to change to + * @param {test} PeerConnectionTest + * The test strucure currently in use. + */ +PeerConnectionTest.prototype.expectStateChange = +function PCT_expectStateChange(pcw, state, test) { + pcw.signalingChangeEvent = false; + pcw._pc.onsignalingstatechange = function() { + pcw._pc.onsignalingstatechange = unexpectedCallbackAndFinish(new Error); + is(pcw._pc.signalingState, state, pcw.label + ": State is " + state + " in onsignalingstatechange"); + pcw.signalingChangeEvent = true; + if (pcw.commandSuccess) { + test.next(); + } else { + info("Waiting for success callback..."); + } + }; +} + +/** + * Returns a function, suitable for use as a success callback, that + * checks the signaling state of the PC; and, if the signalingstatechange + * event has already fired, moves on to the next test case. This is + * intended to be used in conjunction with expectStateChange, above. + * + * @param {pcw} PeerConnectionWrapper + * The peer connection to expect a state change on + * @param {state} string + * The state that we expect to change to + * @param {test} PeerConnectionTest + * The test strucure currently in use. + */ + +PeerConnectionTest.prototype.checkStateInCallback = +function PCT_checkStateInCallback(pcw, state, test) { + pcw.commandSuccess = false; + return function() { + pcw.commandSuccess = true; + is(pcw.signalingState, state, pcw.label + ": State is " + state + " in success callback"); + if (pcw.signalingChangeEvent) { + test.next(); + } else { + info("Waiting for signalingstatechange event..."); + } + }; +} + /** * This class handles acts as a wrapper around a PeerConnection instance. @@ -420,6 +488,9 @@ function PeerConnectionWrapper(label, configuration) { // Bug 834835: Assume type is video until we get get{Audio,Video}Tracks. self.attachMedia(event.stream, 'video', 'remote'); }; + + // Make sure no signaling state changes are fired until we expect them to + this._pc.onsignalingstatechange = unexpectedCallbackAndFinish(new Error); } PeerConnectionWrapper.prototype = { @@ -462,6 +533,15 @@ PeerConnectionWrapper.prototype = { this._pc.remoteDescription = desc; }, + /** + * Returns the remote signaling state. + * + * @returns {object} The local description + */ + get signalingState() { + return this._pc.signalingState; + }, + /** * Callback when we get media from either side. Also an appropriate * HTML media element will be created. @@ -571,6 +651,25 @@ PeerConnectionWrapper.prototype = { }, unexpectedCallbackAndFinish(new Error)); }, + /** + * Tries to set the local description and expect failure. Automatically + * causes the test case to fail if the call succeeds. + * + * @param {object} desc + * mozRTCSessionDescription for the local description request + * @param {function} onFailure + * Callback to execute if the call fails. + */ + setLocalDescriptionAndFail : function PCW_setLocalDescriptionAndFail(desc, onFailure) { + var self = this; + this._pc.setLocalDescription(desc, + unexpectedSuccessCallbackAndFinish(new Error, "setLocalDescription should have failed."), + function (err) { + info("As expected, failed to set the local description for " + self.label); + onFailure(err); + }); + }, + /** * Sets the remote description and automatically handles the failure case. * @@ -587,6 +686,62 @@ PeerConnectionWrapper.prototype = { }, unexpectedCallbackAndFinish(new Error)); }, + /** + * Tries to set the remote description and expect failure. Automatically + * causes the test case to fail if the call succeeds. + * + * @param {object} desc + * mozRTCSessionDescription for the remote description request + * @param {function} onFailure + * Callback to execute if the call fails. + */ + setRemoteDescriptionAndFail : function PCW_setRemoteDescriptionAndFail(desc, onFailure) { + var self = this; + this._pc.setRemoteDescription(desc, + unexpectedSuccessCallbackAndFinish(new Error, "setRemoteDescription should have failed."), + function (err) { + info("As expected, failed to set the remote description for " + self.label); + onFailure(err); + }); + }, + + /** + * Adds an ICE candidate and automatically handles the failure case. + * + * @param {object} candidate + * SDP candidate + * @param {function} onSuccess + * Callback to execute if the local description was set successfully + */ + addIceCandidate : function PCW_addIceCandidate(candidate, onSuccess) { + var self = this; + + this._pc.addIceCandidate(candidate, function () { + info("Successfully added an ICE candidate to " + self.label); + onSuccess(); + }, unexpectedCallbackAndFinish(new Error)); + }, + + /** + * Tries to add an ICE candidate and expects failure. Automatically + * causes the test case to fail if the call succeeds. + * + * @param {object} candidate + * SDP candidate + * @param {function} onFailure + * Callback to execute if the call fails. + */ + addIceCandidateAndFail : function PCW_addIceCandidateAndFail(candidate, onFailure) { + var self = this; + + this._pc.addIceCandidate(candidate, + unexpectedSuccessCallbackAndFinish(new Error, "addIceCandidate should have failed."), + function (err) { + info("As expected, failed to add an ICE candidate to " + self.label); + onFailure(err); + }) ; + }, + /** * Checks that we are getting the media we expect. * diff --git a/dom/media/tests/mochitest/test_peerConnection_addCandidateInHaveLocalOffer.html b/dom/media/tests/mochitest/test_peerConnection_addCandidateInHaveLocalOffer.html new file mode 100644 index 000000000000..21a1fe65b1f8 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_addCandidateInHaveLocalOffer.html @@ -0,0 +1,43 @@ + + +
+ + + + + + + ++ ++ + diff --git a/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInHaveLocalOffer.html b/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInHaveLocalOffer.html new file mode 100644 index 000000000000..1873d52eaf22 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInHaveLocalOffer.html @@ -0,0 +1,41 @@ + + + + + + + + + + +
+ ++ + diff --git a/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInStable.html b/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInStable.html new file mode 100644 index 000000000000..c92b3b686a97 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInStable.html @@ -0,0 +1,41 @@ + + + + + + + + + + +
+ ++ + diff --git a/dom/media/tests/mochitest/test_peerConnection_setLocalOfferInHaveRemoteOffer.html b/dom/media/tests/mochitest/test_peerConnection_setLocalOfferInHaveRemoteOffer.html new file mode 100644 index 000000000000..41052d403708 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_setLocalOfferInHaveRemoteOffer.html @@ -0,0 +1,40 @@ + + + + + + + + + + +
+ ++ + diff --git a/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInHaveRemoteOffer.html b/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInHaveRemoteOffer.html new file mode 100644 index 000000000000..6864c7695fe4 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInHaveRemoteOffer.html @@ -0,0 +1,41 @@ + + + + + + + + + + +
+ ++ + diff --git a/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInStable.html b/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInStable.html new file mode 100644 index 000000000000..33505a9d0a43 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInStable.html @@ -0,0 +1,41 @@ + + + + + + + + + + +
+ ++ + diff --git a/dom/media/tests/mochitest/test_peerConnection_setRemoteOfferInHaveLocalOffer.html b/dom/media/tests/mochitest/test_peerConnection_setRemoteOfferInHaveLocalOffer.html new file mode 100644 index 000000000000..fb1987e66746 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_setRemoteOfferInHaveLocalOffer.html @@ -0,0 +1,40 @@ + + + + + + + + + + +
+ ++ +