Bug 1231981 - Part 3: Set up TURN server for webrtc mochitests, when configured to. r=drno

MozReview-Commit-ID: CVbAYPrwpuB

--HG--
extra : rebase_source : f52583fe21269d4d4214b93315cc75f0535de55d
This commit is contained in:
Byron Campen [:bwc] 2016-03-04 15:45:57 -06:00
Родитель 008efedd31
Коммит 50135632ac
8 изменённых файлов: 118 добавлений и 32 удалений

Просмотреть файл

@ -337,9 +337,12 @@ function run_test(is_initiator,timeout) {
function runTestWhenReady(testFunc) {
setupEnvironment();
return testConfigured.then(options => testFunc(options))
.catch(e => ok(false, 'Error executing test: ' + e +
.catch(e => {
ok(false, 'Error executing test: ' + e +
((typeof e.stack === 'string') ?
(' ' + e.stack.split('\n').join(' ... ')) : '')));
(' ' + e.stack.split('\n').join(' ... ')) : ''));
SimpleTest.finish();
});
}

Просмотреть файл

@ -64,7 +64,13 @@ function PeerConnectionTest(options) {
options.rtcpmux = "rtcpmux" in options ? options.rtcpmux : true;
options.opus = "opus" in options ? options.opus : true;
if (typeof turnServers !== "undefined") {
if (iceServersArray.length) {
options.config_remote = options.config_remote || {}
options.config_local = options.config_local || {}
options.config_remote.iceServers = iceServersArray;
options.config_local.iceServers = iceServersArray;
}
else if (typeof turnServers !== "undefined") {
if ((!options.turn_disabled_local) && (turnServers.local)) {
if (!options.hasOwnProperty("config_local")) {
options.config_local = {};
@ -1679,7 +1685,7 @@ PeerConnectionWrapper.prototype = {
* @param {object} stats
* The stats to be verified for relayed vs. direct connection.
*/
checkStatsIceConnectionType : function(stats) {
checkStatsIceConnectionType : function(stats, expectedLocalCandidateType) {
let lId;
let rId;
for (let stat of stats.values()) {
@ -1698,21 +1704,25 @@ PeerConnectionWrapper.prototype = {
"failed to find candidatepair IDs or stats for local: "+ lId +" remote: "+ rId);
return;
}
info("checkStatsIceConnectionType verifying: local=" +
JSON.stringify(lCand) + " remote=" + JSON.stringify(rCand));
if ((this.configuration) && (typeof this.configuration.iceServers !== 'undefined')) {
info("Ice Server configured");
// Note: the IP comparising is a workaround for bug 1097333
// And this will fail if a TURN server address is a DNS name!
var serverIp = this.configuration.iceServers[0].url.split(':')[1];
ok(lCand.candidateType == "relayed" || rCand.candidateType == "relayed" ||
lCand.ipAddress === serverIp || rCand.ipAddress === serverIp,
"One peer uses a relay");
} else {
info("P2P configured");
ok(lCand.candidateType != "relayed" && rCand.candidateType != "relayed",
"Pure peer to peer call without a relay");
expectedLocalCandidateType = expectedLocalCandidateType || "host";
var candidateType = lCand.candidateType;
if ((lCand.mozLocalTransport === "tcp") && (candidateType === "relayed")) {
candidateType = "relayed-tcp";
}
if ((expectedLocalCandidateType === "serverreflexive") &&
(candidateType === "peerreflexive")) {
// Be forgiving of prflx when expecting srflx, since that can happen due
// to timing.
candidateType = "serverreflexive";
}
is(candidateType,
expectedLocalCandidateType,
"Local candidate type is what we expected for selected pair");
},
/**
@ -1845,10 +1855,59 @@ function createHTML(options) {
return scriptsReady.then(() => realCreateHTML(options));
}
function runNetworkTest(testFunction) {
var iceServerWebsocket;
var iceServersArray = [];
var setupIceServerConfig = useIceServer => {
// We disable ICE support for HTTP proxy when using a TURN server, because
// mochitest uses a fake HTTP proxy to serve content, which will eat our STUN
// packets for TURN TCP.
var enableHttpProxy = enable => new Promise(resolve => {
SpecialPowers.pushPrefEnv(
{'set': [['media.peerconnection.disable_http_proxy', !enable]]},
resolve);
});
var spawnIceServer = () => new Promise( (resolve, reject) => {
iceServerWebsocket = new WebSocket("ws://localhost:8191/");
iceServerWebsocket.onopen = (event) => {
info("websocket/process bridge open, starting ICE Server...");
iceServerWebsocket.send("iceserver");
}
iceServerWebsocket.onmessage = event => {
// The first message will contain the iceServers configuration, subsequent
// messages are just logging.
info("ICE Server: " + event.data);
resolve(event.data);
}
iceServerWebsocket.onerror = () => {
reject("ICE Server error: Is the ICE server websocket up?");
}
iceServerWebsocket.onclose = () => {
info("ICE Server websocket closed");
reject("ICE Server gone before getting configuration");
}
});
if (!useIceServer) {
info("Skipping ICE Server for this test");
return enableHttpProxy(true);
}
return enableHttpProxy(false)
.then(spawnIceServer)
.then(iceServersStr => { iceServersArray = JSON.parse(iceServersStr); });
};
function runNetworkTest(testFunction, fixtureOptions) {
fixtureOptions = fixtureOptions || {}
return scriptsReady.then(() =>
runTestWhenReady(options =>
startNetworkAndTest()
.then(() => setupIceServerConfig(fixtureOptions.useIceServer))
.then(() => testFunction(options))
)
);

Просмотреть файл

@ -441,13 +441,15 @@ var commandsPeerConnectionOfferAnswer = [
function PC_LOCAL_CHECK_ICE_CONNECTION_TYPE(test) {
return test.pcLocal.getStats().then(stats => {
test.pcLocal.checkStatsIceConnectionType(stats);
test.pcLocal.checkStatsIceConnectionType(stats,
test.testOptions.expectedLocalCandidateType);
});
},
function PC_REMOTE_CHECK_ICE_CONNECTION_TYPE(test) {
return test.pcRemote.getStats().then(stats => {
test.pcRemote.checkStatsIceConnectionType(stats);
test.pcRemote.checkStatsIceConnectionType(stats,
test.testOptions.expectedRemoteCandidateType);
});
},

Просмотреть файл

@ -215,8 +215,8 @@ int nr_ice_candidate_create(nr_ice_ctx *ctx,nr_ice_component *comp,nr_ice_socket
nr_ice_candidate_compute_codeword(cand);
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): created candidate %s with type %s",
ctx->label,cand->label,nr_ctype_name(ctype));
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s)/CAND(%s): created candidate %s with type %s",
ctx->label,cand->codeword,cand->label,nr_ctype_name(ctype));
*candp=cand;

Просмотреть файл

@ -515,6 +515,7 @@ void nr_ice_gather_finished_cb(NR_SOCKET s, int h, void *cb_arg)
ctx = cand->ctx;
ctx->uninitialized_candidates--;
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s)/CAND(%s): initialized, %d remaining",ctx->label,cand->codeword,ctx->uninitialized_candidates);
/* Avoid the need for yet another initialization function */
if (cand->state == NR_ICE_CAND_STATE_INITIALIZING && cand->type == HOST)

Просмотреть файл

@ -243,10 +243,20 @@ PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
mIceRestartState(ICE_RESTART_NONE) {
}
nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_servers,
const std::vector<NrIceTurnServer>& turn_servers,
NrIceCtx::Policy policy)
nsresult
PeerConnectionMedia::InitProxy()
{
#if !defined(MOZILLA_EXTERNAL_LINKAGE)
// Allow mochitests to disable this, since mochitest configures a fake proxy
// that serves up content.
bool disable = Preferences::GetBool("media.peerconnection.disable_http_proxy",
false);
if (disable) {
mProxyResolveCompleted = true;
return NS_OK;
}
#endif
nsresult rv;
nsCOMPtr<nsIProtocolProxyService> pps =
do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv);
@ -304,6 +314,16 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_servers,
const std::vector<NrIceTurnServer>& turn_servers,
NrIceCtx::Policy policy)
{
nsresult rv = InitProxy();
NS_ENSURE_SUCCESS(rv, rv);
#if !defined(MOZILLA_EXTERNAL_LINKAGE)
bool ice_tcp = Preferences::GetBool("media.peerconnection.ice.tcp", false);
#else

Просмотреть файл

@ -484,6 +484,7 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
SignalEndOfLocalCandidates;
private:
nsresult InitProxy();
class ProtocolProxyQueryHandler : public nsIProtocolProxyCallback {
public:
explicit ProtocolProxyQueryHandler(PeerConnectionMedia *pcm) :

Просмотреть файл

@ -528,7 +528,7 @@ class MochitestBase(object):
self.update_mozinfo()
self.server = None
self.wsserver = None
self.websocketProcessBridge = None
self.websocketprocessbridge = None
self.sslTunnel = None
self._active_tests = None
self._locations = None
@ -814,11 +814,11 @@ class MochitestBase(object):
command = [sys.executable,
os.path.join("websocketprocessbridge",
"websocketprocessbridge.py")]
self.websocketProcessBridge = mozprocess.ProcessHandler(command,
self.websocketprocessbridge = mozprocess.ProcessHandler(command,
cwd=SCRIPT_DIR)
self.websocketProcessBridge.run()
self.websocketprocessbridge.run()
self.log.info("runtests.py | websocket/process bridge pid: %d"
% self.websocketProcessBridge.pid)
% self.websocketprocessbridge.pid)
# ensure the server is up, wait for at most ten seconds
for i in range(1,100):
@ -892,12 +892,12 @@ class MochitestBase(object):
except Exception:
self.log.critical('Exception stopping ssltunnel')
if self.websocketProcessBridge is not None:
if self.websocketprocessbridge is not None:
try:
self.log.info('Stopping websocketProcessBridge')
self.websocketProcessBridge.kill()
self.log.info('Stopping websocket/process bridge')
self.websocketprocessbridge.kill()
except Exception:
self.log.critical('Exception stopping websocketProcessBridge')
self.log.critical('Exception stopping websocket/process bridge')
def copyExtraFilesToProfile(self, options):
"Copy extra files or dirs specified on the command line to the testing profile."