Bug 1231975 - Part 1: Basic audio mochitests for NAT scenarios. r=drno
authorByron Campen [:bwc] <docfaraday@gmail.com>
Mon, 14 Mar 2016 13:31:01 -0500
changeset 294935 ae1dc75009e73744bc3686a427d985e4e59dd24f
parent 294934 baa6c68ec41333ffc90107a3343fe38e0c060f99
child 294936 29dce05596c6c854af6f2e71fdfde138033ac1a3
push id75735
push userbcampen@mozilla.com
push dateTue, 26 Apr 2016 15:06:29 +0000
treeherdermozilla-inbound@8ed054e5853e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdrno
bugs1231975
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1231975 - Part 1: Basic audio mochitests for NAT scenarios. r=drno MozReview-Commit-ID: 1chfSrXeCL1
dom/media/tests/mochitest/mochitest.ini
dom/media/tests/mochitest/pc.js
dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelay.html
dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTCP.html
dom/media/tests/mochitest/test_peerConnection_basicAudioNATSrflx.html
dom/network/TCPSocketParent.cpp
media/mtransport/nr_socket_prsock.cpp
media/mtransport/nricectx.cpp
media/mtransport/test_nr_socket.cpp
media/mtransport/test_nr_socket.h
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -79,16 +79,22 @@ skip-if = (toolkit == 'gonk' || buildapp
 [test_getUserMedia_stopVideoStream.html]
 [test_getUserMedia_stopVideoStreamWithFollowupVideo.html]
 [test_getUserMedia_peerIdentity.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 1021776, too --ing slow on b2g)
 [test_peerConnection_addIceCandidate.html]
 [test_peerConnection_addTrack.html]
 [test_peerConnection_basicAudio.html]
 skip-if = toolkit == 'gonk' # B2G emulator is too slow to handle a two-way audio call reliably
+[test_peerConnection_basicAudioNATSrflx.html]
+skip-if = toolkit == 'gonk' # B2G emulator is too slow to handle a two-way audio call reliably
+[test_peerConnection_basicAudioNATRelay.html]
+skip-if = toolkit == 'gonk' # B2G emulator is too slow to handle a two-way audio call reliably
+[test_peerConnection_basicAudioNATRelayTCP.html]
+skip-if = toolkit == 'gonk' # B2G emulator is too slow to handle a two-way audio call reliably
 [test_peerConnection_basicAudioRequireEOC.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
 [test_peerConnection_basicAudioPcmaPcmuOnly.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
 [test_peerConnection_basicAudioDynamicPtMissingRtpmap.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
 [test_peerConnection_basicAudioVideo.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -60,20 +60,24 @@ function PeerConnectionTest(options) {
   options.is_remote = "is_remote" in options ? options.is_remote : true;
 
   options.h264 = "h264" in options ? options.h264 : false;
   options.bundle = "bundle" in options ? options.bundle : true;
   options.rtcpmux = "rtcpmux" in options ? options.rtcpmux : true;
   options.opus = "opus" in options ? options.opus : true;
 
   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;
+    if (!options.turn_disabled_local) {
+      options.config_local = options.config_local || {}
+      options.config_local.iceServers = iceServersArray;
+    }
+    if (!options.turn_disabled_remote) {
+      options.config_remote = options.config_remote || {}
+      options.config_remote.iceServers = iceServersArray;
+    }
   }
   else if (typeof turnServers !== "undefined") {
     if ((!options.turn_disabled_local) && (turnServers.local)) {
       if (!options.hasOwnProperty("config_local")) {
         options.config_local = {};
       }
       if (!options.config_local.hasOwnProperty("iceServers")) {
         options.config_local.iceServers = turnServers.local.iceServers;
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelay.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1231975",
+    title: "Basic audio-only peer connection with port dependent NAT"
+  });
+
+  var test;
+  runNetworkTest(options => {
+    SpecialPowers.pushPrefEnv(
+      {
+        'set': [
+          ['media.peerconnection.nat_simulator.filtering_type', 'PORT_DEPENDENT'],
+          ['media.peerconnection.nat_simulator.mapping_type', 'PORT_DEPENDENT']
+        ]
+      }, function (options) {
+        options = options || {};
+        options.expectedLocalCandidateType = "serverreflexive";
+        options.expectedRemoteCandidateType = "relayed";
+        // If both have TURN, it is a toss-up which one will end up using a
+        // relay.
+        options.turn_disabled_local = true;
+        test = new PeerConnectionTest(options);
+        test.setMediaConstraints([{audio: true}], [{audio: true}]);
+        test.run();
+      })
+  }, { useIceServer: true });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTCP.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1231975",
+    title: "Basic audio-only peer connection with port dependent NAT that blocks UDP"
+  });
+
+  var test;
+  runNetworkTest(options => {
+    SpecialPowers.pushPrefEnv(
+      {
+        'set': [
+          ['media.peerconnection.nat_simulator.filtering_type', 'PORT_DEPENDENT'],
+          ['media.peerconnection.nat_simulator.mapping_type', 'PORT_DEPENDENT'],
+          ['media.peerconnection.nat_simulator.block_udp', true]
+        ]
+      }, function (options) {
+        options = options || {};
+        options.expectedLocalCandidateType = "relayed-tcp";
+        options.expectedRemoteCandidateType = "relayed-tcp";
+        test = new PeerConnectionTest(options);
+        test.setMediaConstraints([{audio: true}], [{audio: true}]);
+        test.run();
+      })
+  }, { useIceServer: true });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioNATSrflx.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1231975",
+    title: "Basic audio-only peer connection with endpoint independent NAT"
+  });
+
+  var test;
+  runNetworkTest(options => {
+    SpecialPowers.pushPrefEnv(
+      {
+        'set': [
+          ['media.peerconnection.nat_simulator.filtering_type', 'ENDPOINT_INDEPENDENT'],
+          ['media.peerconnection.nat_simulator.mapping_type', 'ENDPOINT_INDEPENDENT']
+        ]
+      }, function (options) {
+        options = options || {};
+        options.expectedLocalCandidateType = "serverreflexive";
+        options.expectedRemoteCandidateType = "serverreflexive";
+        test = new PeerConnectionTest(options);
+        test.setMediaConstraints([{audio: true}], [{audio: true}]);
+        test.run();
+      })
+  }, { useIceServer: true });
+</script>
+</pre>
+</body>
+</html>
--- a/dom/network/TCPSocketParent.cpp
+++ b/dom/network/TCPSocketParent.cpp
@@ -335,17 +335,17 @@ TCPSocketParent::RecvData(const Sendable
       const nsCString& strData = aData.get_nsCString();
       mSocket->SendWithTrackingNumber(strData, aTrackingNumber, rv);
       break;
     }
 
     default:
       MOZ_CRASH("unexpected SendableData type");
   }
-  NS_ENSURE_FALSE(rv.Failed(), true);
+  NS_ENSURE_SUCCESS(rv.StealNSResult(), true);
   return true;
 }
 
 bool
 TCPSocketParent::RecvClose()
 {
   NS_ENSURE_TRUE(mSocket, true);
   mSocket->Close();
--- a/media/mtransport/nr_socket_prsock.cpp
+++ b/media/mtransport/nr_socket_prsock.cpp
@@ -705,17 +705,18 @@ int NrSocket::create(nr_transport_addr *
   // Remember our thread.
   ststhread_ = do_QueryInterface(stservice, &rv);
   if (!NS_SUCCEEDED(rv))
     ABORT(R_INTERNAL);
 
   // Finally, register with the STS
   rv = stservice->AttachSocket(fd_, this);
   if (!NS_SUCCEEDED(rv)) {
-    r_log(LOG_GENERIC, LOG_CRIT, "Couldn't attach socket to STS");
+    r_log(LOG_GENERIC, LOG_CRIT, "Couldn't attach socket to STS, rv=%u",
+          static_cast<unsigned>(rv));
     ABORT(R_INTERNAL);
   }
 
   _status = 0;
 
 abort:
   return(_status);
 }
--- a/media/mtransport/nricectx.cpp
+++ b/media/mtransport/nricectx.cpp
@@ -571,46 +571,46 @@ NrIceCtx::Initialize(bool hide_non_defau
   if (generating_trickle()) {
     r = nr_ice_ctx_set_trickle_cb(ctx_, &NrIceCtx::trickle_cb, this);
     if (r) {
       MOZ_MTLOG(ML_ERROR, "Couldn't set trickle cb for '" << name_ << "'");
       return false;
     }
   }
 
-  char* mapping_type = nullptr;
-  char* filtering_type = nullptr;
+  nsCString mapping_type;
+  nsCString filtering_type;
   bool block_udp = false;
 
   nsresult rv;
   nsCOMPtr<nsIPrefService> pref_service =
     do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
 
   if (NS_SUCCEEDED(rv)) {
     nsCOMPtr<nsIPrefBranch> pref_branch;
     rv = pref_service->GetBranch(nullptr, getter_AddRefs(pref_branch));
     if (NS_SUCCEEDED(rv)) {
       rv = pref_branch->GetCharPref(
           "media.peerconnection.nat_simulator.mapping_type",
-          &mapping_type);
+          getter_Copies(mapping_type));
       rv = pref_branch->GetCharPref(
           "media.peerconnection.nat_simulator.filtering_type",
-          &filtering_type);
+          getter_Copies(filtering_type));
       rv = pref_branch->GetBoolPref(
           "media.peerconnection.nat_simulator.block_udp",
           &block_udp);
     }
   }
 
-  if (mapping_type && filtering_type) {
-    MOZ_MTLOG(ML_DEBUG, "NAT filtering type: " << filtering_type);
-    MOZ_MTLOG(ML_DEBUG, "NAT mapping type: " << mapping_type);
+  if (!mapping_type.IsEmpty() && !filtering_type.IsEmpty()) {
+    MOZ_MTLOG(ML_DEBUG, "NAT filtering type: " << filtering_type.get());
+    MOZ_MTLOG(ML_DEBUG, "NAT mapping type: " << mapping_type.get());
     TestNat* test_nat = new TestNat;
-    test_nat->filtering_type_ = TestNat::ToNatBehavior(filtering_type);
-    test_nat->mapping_type_ = TestNat::ToNatBehavior(mapping_type);
+    test_nat->filtering_type_ = TestNat::ToNatBehavior(filtering_type.get());
+    test_nat->mapping_type_ = TestNat::ToNatBehavior(mapping_type.get());
     test_nat->block_udp_ = block_udp;
     test_nat->enabled_ = true;
     SetNat(test_nat);
   }
 
   // Create the handler objects
   ice_handler_vtbl_ = new nr_ice_handler_vtbl();
   ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair;
--- a/media/mtransport/test_nr_socket.cpp
+++ b/media/mtransport/test_nr_socket.cpp
@@ -247,18 +247,20 @@ int TestNrSocket::create(nr_transport_ad
   return NrSocketBase::CreateSocket(addr, &internal_socket_);
 }
 
 int TestNrSocket::getaddr(nr_transport_addr *addrp) {
   return internal_socket_->getaddr(addrp);
 }
 
 void TestNrSocket::close() {
-  // TODO: close port mappings too?
   internal_socket_->close();
+  for (RefPtr<PortMapping>& port_mapping : port_mappings_) {
+    port_mapping->external_socket_->close();
+  }
 }
 
 int TestNrSocket::listen(int backlog) {
   MOZ_ASSERT(internal_socket_->my_addr().protocol == IPPROTO_TCP);
   r_log(LOG_GENERIC, LOG_DEBUG,
         "TestNrSocket %s listening",
         internal_socket_->my_addr().as_string);
 
--- a/media/mtransport/test_nr_socket.h
+++ b/media/mtransport/test_nr_socket.h
@@ -243,17 +243,19 @@ class TestNrSocket : public NrSocketBase
         NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PortMapping);
 
         PRIntervalTime last_used_;
         RefPtr<NrSocketBase> external_socket_;
         // For non-symmetric, most of the data here doesn't matter
         nr_transport_addr remote_address_;
 
       private:
-        ~PortMapping(){}
+        ~PortMapping() {
+          external_socket_->close();
+        }
 
         // If external_socket_ returns E_WOULDBLOCK, we don't want to propagate
         // that to the code using the TestNrSocket. We can also perhaps use this
         // to help simulate things like latency.
         std::list<RefPtr<UdpPacket>> send_queue_;
     };
 
     bool is_port_mapping_stale(const PortMapping &port_mapping) const;