Bug 1322274: Test sender.replaceTrack and other methods on close in parallel. draft
authorJan-Ivar Bruaroey <jib@mozilla.com>
Wed, 07 Dec 2016 18:37:51 -0500
changeset 448585 c78a67ae74b17eee4ef0038c033d0ab376122add
parent 448584 0e1f9d3bb1ba0edf2bf8d60896a5319e3373d64a
child 539311 8d03a31e3027801bb24063df76d92686d65fe428
push id38366
push userjbruaroey@mozilla.com
push dateSun, 11 Dec 2016 01:26:04 +0000
bugs1322274
milestone53.0a1
Bug 1322274: Test sender.replaceTrack and other methods on close in parallel. MozReview-Commit-ID: 1aDeoLVDHkL
dom/media/tests/mochitest/head.js
dom/media/tests/mochitest/test_peerConnection_close.html
--- a/dom/media/tests/mochitest/head.js
+++ b/dom/media/tests/mochitest/head.js
@@ -521,16 +521,30 @@ function mustThrowWith(msg, reason, f) {
   try {
     f();
     ok(false, msg + " must throw");
   } catch (e) {
     is(e.name, reason, msg + " must throw: " + e.message);
   }
 };
 
+/* Get a dummy audio track */
+function getSilentTrack() {
+  let ctx = new AudioContext(), oscillator = ctx.createOscillator();
+  let dst = oscillator.connect(ctx.createMediaStreamDestination());
+  oscillator.start();
+  return Object.assign(dst.stream.getAudioTracks()[0], {enabled: false});
+}
+
+function getBlackTrack({width = 640, height = 480} = {}) {
+  let canvas = Object.assign(document.createElement("canvas"), {width, height});
+  canvas.getContext('2d').fillRect(0, 0, width, height);
+  let stream = canvas.captureStream();
+  return Object.assign(stream.getVideoTracks()[0], {enabled: false});
+}
 
 /*** Test control flow methods */
 
 /**
  * Generates a callback function fired only under unexpected circumstances
  * while running the tests. The generated function kills off the test as well
  * gracefully.
  *
--- a/dom/media/tests/mochitest/test_peerConnection_close.html
+++ b/dom/media/tests/mochitest/test_peerConnection_close.html
@@ -1,23 +1,25 @@
 <!DOCTYPE HTML>
 <html>
 <head>
+  <script type="application/javascript" src="head.js"></script>
   <script type="application/javascript" src="pc.js"></script>
 </head>
 <body>
 <pre id="test">
 <script type="application/javascript">
   createHTML({
     bug: "991877",
     title: "Basic RTCPeerConnection.close() tests"
   });
 
   runNetworkTest(function () {
     var pc = new RTCPeerConnection();
+    var sender = pc.addTrack(getSilentTrack(), new MediaStream());
     var exception = null;
     var eTimeout = null;
 
     // everything should be in initial state
     is(pc.signalingState, "stable", "Initial signalingState is 'stable'");
     is(pc.iceConnectionState, "new", "Initial iceConnectionState is 'new'");
     is(pc.iceGatheringState, "new", "Initial iceGatheringState is 'new'");
 
@@ -68,37 +70,31 @@
       // entirely to spec but is better than ignoring programming errors.
 
       var offer = new RTCSessionDescription({ sdp: "sdp", type: "offer" });
       var answer = new RTCSessionDescription({ sdp: "sdp", type: "answer" });
       var candidate = new RTCIceCandidate({ candidate: "dummy",
                                                sdpMid: "test",
                                                sdpMLineIndex: 3 });
 
-      var doesFail = (p, msg) => p.then(generateErrorCallback(),
+      var doesFail = (p, msg) => p.then(generateErrorCallback(msg),
                                         r => is(r.name, "InvalidStateError", msg));
-
-      doesFail(pc.createOffer(), "createOffer fails on close")
-      .then(() => doesFail(pc.createAnswer(), "createAnswer fails on close"))
-      .then(() => doesFail(pc.setLocalDescription(offer),
-                           "setLocalDescription fails on close"))
-      .then(() => doesFail(pc.setRemoteDescription(answer),
-                           "setRemoteDescription fails on close"))
-      .then(() => doesFail(pc.addIceCandidate(candidate),
-                           "addIceCandidate fails on close"))
-      .then(() => doesFail(new Promise((y, n) => pc.createOffer(y, n)),
-                           "Legacy createOffer fails on close"))
-      .then(() => doesFail(new Promise((y, n) => pc.createAnswer(y, n)),
-                           "Legacy createAnswer fails on close"))
-      .then(() => doesFail(new Promise((y, n) => pc.setLocalDescription(offer, y, n)),
-                           "Legacy setLocalDescription fails on close"))
-      .then(() => doesFail(new Promise((y, n) => pc.setRemoteDescription(answer, y, n)),
-                           "Legacy setRemoteDescription fails on close"))
-      .then(() => doesFail(new Promise((y, n) => pc.addIceCandidate(candidate, y, n)),
-                           "Legacy addIceCandidate fails on close"))
+      Promise.all([
+        [pc.createOffer(), "createOffer"],
+        [pc.createAnswer(), "createAnswer"],
+        [pc.setLocalDescription(offer), "setLocalDescription"],
+        [pc.setRemoteDescription(answer), "setRemoteDescription"],
+        [pc.addIceCandidate(candidate), "addIceCandidate"],
+        [new Promise((y, n) => pc.createOffer(y, n)), "Legacy createOffer"],
+        [new Promise((y, n) => pc.createAnswer(y, n)), "Legacy createAnswer"],
+        [new Promise((y, n) => pc.setLocalDescription(offer, y, n)), "Legacy setLocalDescription"],
+        [new Promise((y, n) => pc.setRemoteDescription(answer, y, n)), "Legacy setRemoteDescription"],
+        [new Promise((y, n) => pc.addIceCandidate(candidate, y, n)), "Legacy addIceCandidate"],
+        [sender.replaceTrack(getBlackTrack()), "replaceTrack"],
+      ].map(([p, name]) => doesFail(p, name + " fails on close")))
       .catch(reason => ok(false, "unexpected failure: " + reason))
       .then(finish);
 
       // Other methods are unaffected.
 
       SimpleTest.doesThrow(function() {
         pc.updateIce("Invalid RTC Configuration")},
         "updateIce() on closed PC raised expected exception");