Bug 1060102 - added test cases for non trickle ICE offer-answer. r=bwc
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -1,13 +1,14 @@
[DEFAULT]
support-files =
head.js
constraints.js
mediaStreamPlayback.js
+ nonTrickleIce.js
pc.js
templates.js
NetworkPreparationChromeScript.js
blacksilence.js
turnConfig.js
[test_dataChannel_basicAudio.html]
skip-if = toolkit == 'gonk' # Bug 962984 for debug, bug 963244 for opt
@@ -85,16 +86,22 @@ skip-if = toolkit == 'gonk' # b2g (Bug 1
[test_peerConnection_bug1013809.html]
skip-if = toolkit == 'gonk' # b2g emulator seems to be too slow (Bug 1016498 and 1008080)
[test_peerConnection_bug1042791.html]
skip-if = buildapp == 'b2g' || os == 'android' # bug 1043403
[test_peerConnection_close.html]
skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
[test_peerConnection_errorCallbacks.html]
skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_noTrickleAnswer.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_noTrickleOffer.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_noTrickleOfferAnswer.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
[test_peerConnection_offerRequiresReceiveAudio.html]
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
[test_peerConnection_offerRequiresReceiveVideo.html]
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
[test_peerConnection_offerRequiresReceiveVideoAudio.html]
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
[test_peerConnection_replaceTrack.html]
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/nonTrickleIce.js
@@ -0,0 +1,133 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function makeOffererNonTrickle(chain) {
+ chain.replace('PC_LOCAL_SETUP_ICE_HANDLER', [
+ ['PC_LOCAL_SETUP_NOTRICKLE_ICE_HANDLER',
+ function (test) {
+ test.pcLocalWaitingForEndOfTrickleIce = false;
+ // We need to install this callback before calling setLocalDescription
+ // otherwise we might miss callbacks
+ test.pcLocal.setupIceCandidateHandler(test, function () {
+ // We ignore ICE candidates because we want the full offer
+ } , function (label) {
+ if (test.pcLocalWaitingForEndOfTrickleIce) {
+ // This callback is needed for slow environments where ICE
+ // trickling has not finished before the other side needs the
+ // full SDP. In this case, this call to test.next() will complete
+ // the PC_REMOTE_WAIT_FOR_OFFER step (see below).
+ info("Looks like we were still waiting for Trickle to finish");
+ // TODO replace this with a Promise
+ test.next();
+ }
+ });
+ // We can't wait for trickle to finish here as it will only start once
+ // we have called setLocalDescription in the next step
+ test.next();
+ }
+ ]
+ ]);
+ chain.replace('PC_REMOTE_GET_OFFER', [
+ ['PC_REMOTE_WAIT_FOR_OFFER',
+ function (test) {
+ if (test.pcLocal.endOfTrickleIce) {
+ info("Trickle ICE finished already");
+ test.next();
+ } else {
+ info("Waiting for trickle ICE to finish");
+ test.pcLocalWaitingForEndOfTrickleIce = true;
+ // In this case we rely on the callback from
+ // PC_LOCAL_SETUP_NOTRICKLE_ICE_HANDLER above to proceed to the next
+ // step once trickle is finished.
+ }
+ }
+ ],
+ ['PC_REMOTE_GET_FULL_OFFER',
+ function (test) {
+ test._local_offer = test.pcLocal.localDescription;
+ test._offer_constraints = test.pcLocal.constraints;
+ test._offer_options = test.pcLocal.offerOptions;
+ test.next();
+ }
+ ]
+ ]);
+ chain.insertAfter('PC_REMOTE_SANE_REMOTE_SDP', [
+ ['PC_REMOTE_REQUIRE_REMOTE_SDP_CANDIDATES',
+ function (test) {
+ info("test.pcLocal.localDescription.sdp: " + JSON.stringify(test.pcLocal.localDescription.sdp));
+ info("test._local_offer.sdp" + JSON.stringify(test._local_offer.sdp));
+ ok(!test.localRequiresTrickleIce, "Local does NOT require trickle");
+ ok(test._local_offer.sdp.contains("a=candidate"), "offer has ICE candidates")
+ // TODO check for a=end-of-candidates once implemented
+ test.next();
+ }
+ ]
+ ]);
+}
+
+function makeAnswererNonTrickle(chain) {
+ chain.replace('PC_REMOTE_SETUP_ICE_HANDLER', [
+ ['PC_REMOTE_SETUP_NOTRICKLE_ICE_HANDLER',
+ function (test) {
+ test.pcRemoteWaitingForEndOfTrickleIce = false;
+ // We need to install this callback before calling setLocalDescription
+ // otherwise we might miss callbacks
+ test.pcRemote.setupIceCandidateHandler(test, function () {
+ // We ignore ICE candidates because we want the full answer
+ }, function (label) {
+ if (test.pcRemoteWaitingForEndOfTrickleIce) {
+ // This callback is needed for slow environments where ICE
+ // trickling has not finished before the other side needs the
+ // full SDP. In this case this callback will call the step after
+ // PC_LOCAL_WAIT_FOR_ANSWER
+ info("Looks like we were still waiting for Trickle to finish");
+ // TODO replace this with a Promise
+ test.next();
+ }
+ });
+ // We can't wait for trickle to finish here as it will only start once
+ // we have called setLocalDescription in the next step
+ test.next();
+ }
+ ]
+ ]);
+ chain.replace('PC_LOCAL_GET_ANSWER', [
+ ['PC_LOCAL_WAIT_FOR_ANSWER',
+ function (test) {
+ test._remote_answer = test.pcRemote.localDescription;
+ test._answer_constraints = test.pcRemote.constraints;
+ if (test.pcRemote.endOfTrickleIce) {
+ info("Trickle ICE finished already");
+ test.next();
+ } else {
+ info("Waiting for trickle ICE to finish");
+ test.pcRemoteWaitingForEndOfTrickleIce = true;
+ // In this case we rely on the callback from
+ // PC_REMOTE_SETUP_NOTRICKLE_ICE_HANDLER above to proceed to the next
+ // step once trickle is finished.
+ }
+ }
+ ],
+ ['PC_LOCAL_GET_FULL_ANSWER',
+ function (test) {
+ test._local_offer = test.pcLocal.localDescription;
+ test._offer_constraints = test.pcLocal.constraints;
+ test._offer_options = test.pcLocal.offerOptions;
+ test.next();
+ }
+ ]
+ ]);
+ chain.insertAfter('PC_LOCAL_SANE_REMOTE_SDP', [
+ ['PC_LOCAL_REQUIRE_REMOTE_SDP_CANDIDATES',
+ function (test) {
+ info("test.pcRemote.localDescription.sdp: " + JSON.stringify(test.pcRemote.localDescription.sdp));
+ info("test._remote_answer.sdp" + JSON.stringify(test._remote_answer.sdp));
+ ok(!test.remoteRequiresTrickleIce, "Remote does NOT require trickle");
+ ok(test._remote_answer.sdp.contains("a=candidate"), "answer has ICE candidates")
+ // TODO check for a=end-of-candidates once implemented
+ test.next();
+ }
+ ]
+ ]);
+}
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -220,16 +220,30 @@ CommandChain.prototype = {
if (index > -1) {
return this._commands.splice(0, index);
}
return null;
},
/**
+ * Replaces a single command.
+ *
+ * @param {string} id
+ * Identifier of the command to be replaced
+ * @param {Array[]} commands
+ * List of commands
+ * @returns {object[]} Removed commands
+ */
+ replace : function (id, commands) {
+ this.insertBefore(id, commands);
+ return this.remove(id);
+ },
+
+ /**
* Replaces all commands after the specified one.
*
* @param {string} id
* Identifier of the command
* @returns {object[]} Removed commands
*/
replaceAfter : function (id, commands) {
var oldCommands = this.removeAfter(id);
@@ -2080,39 +2094,43 @@ PeerConnectionWrapper.prototype = {
/**
* Setup a onicecandidate handler
*
* @param {object} test
* A PeerConnectionTest object to which the ice candidates gets
* forwarded.
*/
- setupIceCandidateHandler : function PCW_setupIceCandidateHandler(test) {
+ setupIceCandidateHandler : function
+ PCW_setupIceCandidateHandler(test, candidateHandler, endHandler) {
var self = this;
self._local_ice_candidates = [];
self._remote_ice_candidates = [];
self._ice_candidates_to_add = [];
+ candidateHandler = candidateHandler || test.iceCandidateHandler.bind(test);
+ endHandler = endHandler || test.signalEndOfTrickleIce.bind(test);
+
function iceCandidateCallback (anEvent) {
info(self.label + ": received iceCandidateEvent");
if (!anEvent.candidate) {
info(self.label + ": received end of trickle ICE event");
self.endOfTrickleIce = true;
- test.signalEndOfTrickleIce(self.label);
+ endHandler(self.label);
} else {
if (self.endOfTrickleIce) {
ok(false, "received ICE candidate after end of trickle");
}
info(self.label + ": iceCandidate = " + JSON.stringify(anEvent.candidate));
ok(anEvent.candidate.candidate.length > 0, "ICE candidate contains candidate");
// we don't support SDP MID's yet
ok(anEvent.candidate.sdpMid.length === 0, "SDP MID has length zero");
ok(typeof anEvent.candidate.sdpMLineIndex === 'number', "SDP MLine Index needs to exist");
self._local_ice_candidates.push(anEvent.candidate);
- test.iceCandidateHandler(self.label, anEvent.candidate);
+ candidateHandler(self.label, anEvent.candidate);
}
}
self._pc.onicecandidate = iceCandidateCallback;
},
/**
* Counts the amount of audio tracks in a given media constraint.
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_noTrickleAnswer.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
+ <script type="application/javascript" src="nonTrickleIce.js"></script>
+ <script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+ createHTML({
+ bug: "1060102",
+ title: "Basic audio only SDP answer without trickle ICE"
+ });
+
+ var test;
+ runNetworkTest(function (options) {
+ test = new PeerConnectionTest(options);
+ makeAnswererNonTrickle(test.chain);
+ test.setMediaConstraints([{audio: true}], [{audio: true}]);
+ test.run();
+ });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_noTrickleOffer.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
+ <script type="application/javascript" src="nonTrickleIce.js"></script>
+ <script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+ createHTML({
+ bug: "1060102",
+ title: "Basic audio only SDP offer without trickle ICE"
+ });
+
+ var test;
+ runNetworkTest(function (options) {
+ test = new PeerConnectionTest(options);
+ makeOffererNonTrickle(test.chain);
+ test.setMediaConstraints([{audio: true}], [{audio: true}]);
+ test.run();
+ });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_noTrickleOfferAnswer.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
+ <script type="application/javascript" src="nonTrickleIce.js"></script>
+ <script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+ createHTML({
+ bug: "1060102",
+ title: "Basic audio only SDP offer and answer without trickle ICE"
+ });
+
+ var test;
+ runNetworkTest(function (options) {
+ test = new PeerConnectionTest(options);
+ makeOffererNonTrickle(test.chain);
+ makeAnswererNonTrickle(test.chain);
+ test.setMediaConstraints([{audio: true}], [{audio: true}]);
+ test.run();
+ });
+</script>
+</pre>
+</body>
+</html>