Bug 1060103 - Add trickle ICE support for steeplechase. r=ted

This commit is contained in:
Nils Ohlmeier [:drno] 2014-09-08 04:53:00 -04:00
parent 749a14ea8a
commit dd2f0dc0eb
2 changed files with 150 additions and 27 deletions

View File

@ -547,6 +547,8 @@ function PeerConnectionTest(options) {
else else
this.pcRemote = null; this.pcRemote = null;
this.steeplechase = this.pcLocal === null || this.pcRemote === null;
// Create command chain instance and assign default commands // Create command chain instance and assign default commands
this.chain = new CommandChain(this, options.commands); this.chain = new CommandChain(this, options.commands);
if (!options.is_local) { if (!options.is_local) {
@ -863,10 +865,109 @@ PCT_iceCandidateHandler(caller, candidate) {
target.storeOrAddIceCandidate(candidate); target.storeOrAddIceCandidate(candidate);
} else { } else {
info("sending ice candidate to signaling server"); info("sending ice candidate to signaling server");
send_message({"ice_candidate": candidate}); send_message({"type": "ice_candidate", "ice_candidate": candidate});
} }
}; };
/**
* Installs a polling function for the socket.io client to read
* all messages from the chat room into a message queue.
*/
PeerConnectionTest.prototype.setupSignalingClient = function
PCT_setupSignalingClient() {
var self = this;
self.signalingMessageQueue = [];
self.signalingCallbacks = {};
self.signalingLoopRun = true;
function queueMessage(message) {
info("Received signaling message: " + JSON.stringify(message));
var fired = false;
Object.keys(self.signalingCallbacks).forEach(function(name) {
if (name === message.type) {
info("Invoking callback for message type: " + name);
self.signalingCallbacks[name](message);
fired = true;
}
});
if (!fired) {
self.signalingMessageQueue.push(message);
info("signalingMessageQueue.length: " + self.signalingMessageQueue.length);
}
if (self.signalingLoopRun) {
wait_for_message().then(queueMessage);
} else {
info("Exiting signaling message event loop");
}
}
wait_for_message().then(queueMessage);
}
/**
* Sets a flag to stop reading further messages from the chat room.
*/
PeerConnectionTest.prototype.signalingMessagesFinished = function
PCT_signalingMessagesFinished() {
this.signalingLoopRun = false;
}
/**
* Callback to stop reading message from chat room once trickle ICE
* on the far end is over.
*
* @param {string} caller
* The lable of the caller of the function
*/
PeerConnectionTest.prototype.signalEndOfTrickleIce = function
PCT_signalEndOfTrickleIce(caller) {
if (this.steeplechase) {
send_message({"type": "end_of_trickle_ice"});
}
};
/**
* Register a callback function to deliver messages from the chat room
* directly instead of storing them in the message queue.
*
* @param {string} messageType
* For which message types should the callback get invoked.
*
* @param {function} onMessage
* The function which gets invoked if a message of the messageType
* has been received from the chat room.
*/
PeerConnectionTest.prototype.registerSignalingCallback = function
PCT_registerSignalingCallback(messageType, onMessage) {
this.signalingCallbacks[messageType] = onMessage;
}
/**
* Searches the message queue for the first message of a given type
* and invokes the given callback function, or registers the callback
* function for future messages if the queue contains no such message.
*
* @param {string} messageType
* The type of message to search and register for.
*
* @param {function} onMessage
* The callback function which gets invoked with the messages
* of the given mesage type.
*/
PeerConnectionTest.prototype.getSignalingMessage = function
PCT_getSignalingMessage(messageType, onMessage) {
for(var i=0; i < this.signalingMessageQueue.length; i++) {
if (messageType === this.signalingMessageQueue[i].type) {
//FIXME
info("invoking callback on message " + i + " from message queue, for message type:" + messageType);
onMessage(this.signalingMessageQueue.splice(i, 1)[0]);
return;
}
}
this.registerSignalingCallback(messageType, onMessage);
}
/** /**
* This class handles tests for data channels. * This class handles tests for data channels.
* *
@ -1991,6 +2092,7 @@ PeerConnectionWrapper.prototype = {
if (!anEvent.candidate) { if (!anEvent.candidate) {
info(self.label + ": received end of trickle ICE event"); info(self.label + ": received end of trickle ICE event");
self.endOfTrickleIce = true; self.endOfTrickleIce = true;
test.signalEndOfTrickleIce(self.label);
} else { } else {
if (self.endOfTrickleIce) { if (self.endOfTrickleIce) {
ok(false, "received ICE candidate after end of trickle"); ok(false, "received ICE candidate after end of trickle");
@ -2005,8 +2107,6 @@ PeerConnectionWrapper.prototype = {
} }
} }
//FIXME: in the steeplecase scenario we need to setup a permanent listener
// for ice candidates from the signaling server here
self._pc.onicecandidate = iceCandidateCallback; self._pc.onicecandidate = iceCandidateCallback;
}, },

View File

@ -24,24 +24,27 @@ function dumpSdp(test) {
dump("ERROR: SDP answer: " + test._remote_answer.sdp.replace(/[\r]/g, '')); dump("ERROR: SDP answer: " + test._remote_answer.sdp.replace(/[\r]/g, ''));
} }
if (typeof test.pcLocal.iceConnectionLog !== 'undefined') { if ((test.pcLocal) && (typeof test.pcLocal.iceConnectionLog !== 'undefined')) {
dump("pcLocal ICE connection state log: " + test.pcLocal.iceConnectionLog + "\n"); dump("pcLocal ICE connection state log: " + test.pcLocal.iceConnectionLog + "\n");
} }
if (typeof test.pcRemote.iceConnectionLog !== 'undefined') { if ((test.pcRemote) && (typeof test.pcRemote.iceConnectionLog !== 'undefined')) {
dump("pcRemote ICE connection state log: " + test.pcRemote.iceConnectionLog + "\n"); dump("pcRemote ICE connection state log: " + test.pcRemote.iceConnectionLog + "\n");
} }
if ((typeof test.pcLocal.setRemoteDescDate !== 'undefined') && if ((test.pcLocal) && (test.pcRemote) &&
(typeof test.pcLocal.setRemoteDescDate !== 'undefined') &&
(typeof test.pcRemote.setLocalDescDate !== 'undefined')) { (typeof test.pcRemote.setLocalDescDate !== 'undefined')) {
var delta = deltaSeconds(test.pcLocal.setRemoteDescDate, test.pcRemote.setLocalDescDate); var delta = deltaSeconds(test.pcLocal.setRemoteDescDate, test.pcRemote.setLocalDescDate);
dump("Delay between pcLocal.setRemote <-> pcRemote.setLocal: " + delta + "\n"); dump("Delay between pcLocal.setRemote <-> pcRemote.setLocal: " + delta + "\n");
} }
if ((typeof test.pcLocal.setRemoteDescDate !== 'undefined') && if ((test.pcLocal) && (test.pcRemote) &&
(typeof test.pcLocal.setRemoteDescDate !== 'undefined') &&
(typeof test.pcLocal.setRemoteDescStableEventDate !== 'undefined')) { (typeof test.pcLocal.setRemoteDescStableEventDate !== 'undefined')) {
var delta = deltaSeconds(test.pcLocal.setRemoteDescDate, test.pcLocal.setRemoteDescStableEventDate); var delta = deltaSeconds(test.pcLocal.setRemoteDescDate, test.pcLocal.setRemoteDescStableEventDate);
dump("Delay between pcLocal.setRemote <-> pcLocal.signalingStateStable: " + delta + "\n"); dump("Delay between pcLocal.setRemote <-> pcLocal.signalingStateStable: " + delta + "\n");
} }
if ((typeof test.pcRemote.setLocalDescDate !== 'undefined') && if ((test.pcLocal) && (test.pcRemote) &&
(typeof test.pcRemote.setLocalDescDate !== 'undefined') &&
(typeof test.pcRemote.setLocalDescStableEventDate !== 'undefined')) { (typeof test.pcRemote.setLocalDescStableEventDate !== 'undefined')) {
var delta = deltaSeconds(test.pcRemote.setLocalDescDate, test.pcRemote.setLocalDescStableEventDate); var delta = deltaSeconds(test.pcRemote.setLocalDescDate, test.pcRemote.setLocalDescStableEventDate);
dump("Delay between pcRemote.setLocal <-> pcRemote.signalingStateStable: " + delta + "\n"); dump("Delay between pcRemote.setLocal <-> pcRemote.signalingStateStable: " + delta + "\n");
@ -49,6 +52,22 @@ function dumpSdp(test) {
} }
var commandsPeerConnection = [ var commandsPeerConnection = [
[
'PC_SETUP_SIGNALING_CLIENT',
function (test) {
if (test.steeplechase) {
test.setupSignalingClient();
test.registerSignalingCallback("ice_candidate", function (message) {
var pc = test.pcRemote ? test.pcRemote : test.pcLocal;
pc.storeOrAddIceCandidate(new mozRTCIceCandidate(message.ice_candidate));
});
test.registerSignalingCallback("end_of_trickle_ice", function (message) {
test.signalingMessagesFinished();
});
}
test.next();
}
],
[ [
'PC_LOCAL_SETUP_ICE_LOGGER', 'PC_LOCAL_SETUP_ICE_LOGGER',
function (test) { function (test) {
@ -145,11 +164,12 @@ var commandsPeerConnection = [
test.createOffer(test.pcLocal, function (offer) { test.createOffer(test.pcLocal, function (offer) {
is(test.pcLocal.signalingState, STABLE, is(test.pcLocal.signalingState, STABLE,
"Local create offer does not change signaling state"); "Local create offer does not change signaling state");
if (!test.pcRemote) { if (test.steeplechase) {
send_message({"offer": test.originalOffer, send_message({"type": "offer",
"offer": test.originalOffer,
"offer_constraints": test.pcLocal.constraints, "offer_constraints": test.pcLocal.constraints,
"offer_options": test.pcLocal.offerOptions}); "offer_options": test.pcLocal.offerOptions});
test._local_offer = test.pcLocal._last_offer; test._local_offer = test.originalOffer;
test._offer_constraints = test.pcLocal.constraints; test._offer_constraints = test.pcLocal.constraints;
test._offer_options = test.pcLocal.offerOptions; test._offer_options = test.pcLocal.offerOptions;
} }
@ -170,13 +190,13 @@ var commandsPeerConnection = [
[ [
'PC_REMOTE_GET_OFFER', 'PC_REMOTE_GET_OFFER',
function (test) { function (test) {
if (test.pcLocal) { if (!test.steeplechase) {
test._local_offer = test.originalOffer; test._local_offer = test.originalOffer;
test._offer_constraints = test.pcLocal.constraints; test._offer_constraints = test.pcLocal.constraints;
test._offer_options = test.pcLocal.offerOptions; test._offer_options = test.pcLocal.offerOptions;
test.next(); test.next();
} else { } else {
wait_for_message().then(function(message) { test.getSignalingMessage("offer", function (message) {
ok("offer" in message, "Got an offer message"); ok("offer" in message, "Got an offer message");
test._local_offer = new mozRTCSessionDescription(message.offer); test._local_offer = new mozRTCSessionDescription(message.offer);
test._offer_constraints = message.offer_constraints; test._offer_constraints = message.offer_constraints;
@ -224,8 +244,9 @@ var commandsPeerConnection = [
test.createAnswer(test.pcRemote, function (answer) { test.createAnswer(test.pcRemote, function (answer) {
is(test.pcRemote.signalingState, HAVE_REMOTE_OFFER, is(test.pcRemote.signalingState, HAVE_REMOTE_OFFER,
"Remote createAnswer does not change signaling state"); "Remote createAnswer does not change signaling state");
if (!test.pcLocal) { if (test.steeplechase) {
send_message({"answer": test.originalAnswer, send_message({"type": "answer",
"answer": test.originalAnswer,
"answer_constraints": test.pcRemote.constraints}); "answer_constraints": test.pcRemote.constraints});
test._remote_answer = test.pcRemote._last_answer; test._remote_answer = test.pcRemote._last_answer;
test._answer_constraints = test.pcRemote.constraints; test._answer_constraints = test.pcRemote.constraints;
@ -261,7 +282,7 @@ var commandsPeerConnection = [
return resultArray; return resultArray;
} }
const offerTriples = _sdpCandidatesIntoArray(test.originalOffer.sdp); const offerTriples = _sdpCandidatesIntoArray(test._local_offer.sdp);
info("Offer ICE host candidates: " + JSON.stringify(offerTriples)); info("Offer ICE host candidates: " + JSON.stringify(offerTriples));
const answerTriples = _sdpCandidatesIntoArray(test.originalAnswer.sdp); const answerTriples = _sdpCandidatesIntoArray(test.originalAnswer.sdp);
@ -269,7 +290,7 @@ var commandsPeerConnection = [
for (var i=0; i< offerTriples.length; i++) { for (var i=0; i< offerTriples.length; i++) {
if (answerTriples.indexOf(offerTriples[i]) !== -1) { if (answerTriples.indexOf(offerTriples[i]) !== -1) {
dump("SDP offer: " + test.originalOffer.sdp.replace(/[\r]/g, '') + "\n"); dump("SDP offer: " + test._local_offer.sdp.replace(/[\r]/g, '') + "\n");
dump("SDP answer: " + test.originalAnswer.sdp.replace(/[\r]/g, '') + "\n"); dump("SDP answer: " + test.originalAnswer.sdp.replace(/[\r]/g, '') + "\n");
ok(false, "This IP:Port " + offerTriples[i] + " appears in SDP offer and answer!"); ok(false, "This IP:Port " + offerTriples[i] + " appears in SDP offer and answer!");
} }
@ -293,12 +314,12 @@ var commandsPeerConnection = [
[ [
'PC_LOCAL_GET_ANSWER', 'PC_LOCAL_GET_ANSWER',
function (test) { function (test) {
if (test.pcRemote) { if (!test.steeplechase) {
test._remote_answer = test.originalAnswer; test._remote_answer = test.originalAnswer;
test._answer_constraints = test.pcRemote.constraints; test._answer_constraints = test.pcRemote.constraints;
test.next(); test.next();
} else { } else {
wait_for_message().then(function(message) { test.getSignalingMessage("answer", function (message) {
ok("answer" in message, "Got an answer message"); ok("answer" in message, "Got an answer message");
test._remote_answer = new mozRTCSessionDescription(message.answer); test._remote_answer = new mozRTCSessionDescription(message.answer);
test._answer_constraints = message.answer_constraints; test._answer_constraints = message.answer_constraints;
@ -762,8 +783,9 @@ var commandsDataChannel = [
"Local create offer does not change signaling state"); "Local create offer does not change signaling state");
ok(offer.sdp.contains("m=application"), ok(offer.sdp.contains("m=application"),
"m=application is contained in the SDP"); "m=application is contained in the SDP");
if (!test.pcRemote) { if (test.steeplechase) {
send_message({"offer": test.originalOffer, send_message({"type": "offer",
"offer": test.originalOffer,
"offer_constraints": test.pcLocal.constraints, "offer_constraints": test.pcLocal.constraints,
"offer_options": test.pcLocal.offerOptions}); "offer_options": test.pcLocal.offerOptions});
test._local_offer = test.pcLocal._last_offer; test._local_offer = test.pcLocal._last_offer;
@ -788,13 +810,13 @@ var commandsDataChannel = [
[ [
'PC_REMOTE_GET_OFFER', 'PC_REMOTE_GET_OFFER',
function (test) { function (test) {
if (test.pcLocal) { if (!test.steeplechase) {
test._local_offer = test.originalOffer; test._local_offer = test.originalOffer;
test._offer_constraints = test.pcLocal.constraints; test._offer_constraints = test.pcLocal.constraints;
test._offer_options = test.pcLocal.offerOptions; test._offer_options = test.pcLocal.offerOptions;
test.next(); test.next();
} else { } else {
wait_for_message().then(function(message) { test.getSignalingMessage("offer", function (message) {
ok("offer" in message, "Got an offer message"); ok("offer" in message, "Got an offer message");
test._local_offer = new mozRTCSessionDescription(message.offer); test._local_offer = new mozRTCSessionDescription(message.offer);
test._offer_constraints = message.offer_constraints; test._offer_constraints = message.offer_constraints;
@ -845,8 +867,9 @@ var commandsDataChannel = [
"Remote createAnswer does not change signaling state"); "Remote createAnswer does not change signaling state");
ok(answer.sdp.contains("m=application"), ok(answer.sdp.contains("m=application"),
"m=application is contained in the SDP"); "m=application is contained in the SDP");
if (!test.pcLocal) { if (test.steeplechase) {
send_message({"answer": test.originalAnswer, send_message({"type":"answer",
"answer": test.originalAnswer,
"answer_constraints": test.pcRemote.constraints}); "answer_constraints": test.pcRemote.constraints});
test._remote_answer = test.pcRemote._last_answer; test._remote_answer = test.pcRemote._last_answer;
test._answer_constraints = test.pcRemote.constraints; test._answer_constraints = test.pcRemote.constraints;
@ -892,12 +915,12 @@ var commandsDataChannel = [
[ [
'PC_LOCAL_GET_ANSWER', 'PC_LOCAL_GET_ANSWER',
function (test) { function (test) {
if (test.pcRemote) { if (!test.steeplechase) {
test._remote_answer = test.originalAnswer; test._remote_answer = test.originalAnswer;
test._answer_constraints = test.pcRemote.constraints; test._answer_constraints = test.pcRemote.constraints;
test.next(); test.next();
} else { } else {
wait_for_message().then(function(message) { test.getSignalingMessage("answer", function (message) {
ok("answer" in message, "Got an answer message"); ok("answer" in message, "Got an answer message");
test._remote_answer = new mozRTCSessionDescription(message.answer); test._remote_answer = new mozRTCSessionDescription(message.answer);
test._answer_constraints = message.answer_constraints; test._answer_constraints = message.answer_constraints;