Backed out changeset 445c2952117c (bug 996238)
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 01 Apr 2015 16:14:00 +0200
changeset 236991 b9e06340bf6645f74d1a31d4841c6047ffca5e99
parent 236990 b4efb3f1976f6db138152e5b28fbebec90737b29
child 236992 7a5a0fe28e9c0bcfc8bbb42b38c0d8afc1cfcbdf
push id57845
push usercbook@mozilla.com
push dateWed, 01 Apr 2015 14:15:16 +0000
treeherdermozilla-inbound@f3d44e807d1b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs996238
milestone40.0a1
backs out445c2952117cd6721889d130f366821b169c564f
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
Backed out changeset 445c2952117c (bug 996238)
dom/media/tests/mochitest/blacksilence.js
dom/media/tests/mochitest/identity/.#identityPcTest.js
dom/media/tests/mochitest/identity/identityPcTest.js
dom/media/tests/mochitest/identity/test_peerConnection_asymmetricIsolation.html
dom/media/tests/mochitest/pc.js
dom/media/tests/mochitest/templates.js
dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html
--- a/dom/media/tests/mochitest/blacksilence.js
+++ b/dom/media/tests/mochitest/blacksilence.js
@@ -8,114 +8,125 @@
     var good = constraintApplied ? condition : !condition;
     message = (constraintApplied ? 'with' : 'without') +
       ' constraint: should ' + (constraintApplied ? '' : 'not ') +
       message + ' = ' + (good ? 'OK' : 'waiting...');
     info(message);
     return good;
   }
 
-  function mkElement(type) {
-    // This makes an unattached element.
-    // It's not rendered to save the cycles that costs on b2g emulator
-    // and it gets dropped (and GC'd) when the test is done.
-    var e = document.createElement(type);
-    e.width = 32;
-    e.height = 24;
-    document.getElementById('display').appendChild(e);
-    return e;
-  }
-
-  // Runs checkFunc until it reports success.
-  // This is kludgy, but you have to wait for media to start flowing, and it
-  // can't be any old media, it has to include real data, for which we have no
-  // reliable signals to use as a trigger.
-  function periodicCheck(checkFunc) {
-    var resolve;
-    var done = false;
-    // This returns a function so that we create 10 closures in the loop, not
-    // one; and so that the timers don't all start straight away
-    var waitAndCheck = counter => () => {
-      if (done) {
-        return Promise.resolve();
-      }
-      return new Promise(r => setTimeout(r, 200 << counter))
-        .then(() => {
-          if (checkFunc()) {
-            done = true;
-            resolve();
-          }
-        });
-    };
-
-    var chain = Promise.resolve();
-    for (var i = 0; i < 10; ++i) {
-      chain = chain.then(waitAndCheck(i));
-    }
-    return new Promise(r => resolve = r);
-  }
-
   function isSilence(audioData) {
     var silence = true;
     for (var i = 0; i < audioData.length; ++i) {
       if (audioData[i] !== 128) {
         silence = false;
       }
     }
     return silence;
   }
 
-  function checkAudio(constraintApplied, stream) {
-    var audio = mkElement('audio');
-    audio.mozSrcObject = stream;
-    audio.play();
+  function periodicCheck(type, checkFunc, successMessage, done) {
+    var num = 0;
+    var timeout;
+    function periodic() {
+      if (checkFunc()) {
+        ok(true, type + ' is ' + successMessage);
+        done();
+      } else {
+        setupNext();
+      }
+    }
+    function setupNext() {
+      // exponential backoff on the timer
+      // on a very slow system (like the b2g emulator) a long timeout is
+      // necessary, but we want to run fast if we can
+      timeout = setTimeout(periodic, 200 << num);
+      num++;
+    }
 
+    setupNext();
+
+    return function cancel() {
+      if (timeout) {
+        ok(false, type + ' (' + successMessage + ')' +
+           ' failed after waiting full duration');
+        clearTimeout(timeout);
+        done();
+      }
+    };
+  }
+
+  function checkAudio(constraintApplied, stream, done) {
     var context = new AudioContext();
     var source = context.createMediaStreamSource(stream);
     var analyser = context.createAnalyser();
     source.connect(analyser);
     analyser.connect(context.destination);
 
-    return periodicCheck(() => {
+    function testAudio() {
       var sampleCount = analyser.frequencyBinCount;
       info('got some audio samples: ' + sampleCount);
-      var buffer = new Uint8Array(sampleCount);
-      analyser.getByteTimeDomainData(buffer);
+      var bucket = new ArrayBuffer(sampleCount);
+      var view = new Uint8Array(bucket);
+      analyser.getByteTimeDomainData(view);
 
-      var silent = check(constraintApplied, isSilence(buffer),
-                         'be silence for audio');
+      var silent = check(constraintApplied, isSilence(view), 'be silence for audio');
       return sampleCount > 0 && silent;
-    }).then(() => {
+    }
+    function disconnect() {
       source.disconnect();
       analyser.disconnect();
-      audio.pause();
-      ok(true, 'audio is ' + (constraintApplied ? '' : 'not ') + 'silent');
-    });
+      done();
+    }
+    return periodicCheck('audio', testAudio,
+                         (constraintApplied ? '' : 'not ') + 'silent', disconnect);
   }
 
-  function checkVideo(constraintApplied, stream) {
+  function mkElement(type) {
+    // this makes an unattached element
+    // it's not rendered to save the cycles that costs on b2g emulator
+    // and it gets droped (and GC'd) when the test is done
+    var e = document.createElement(type);
+    e.width = 32;
+    e.height = 24;
+    return e;
+  }
+
+  function checkVideo(constraintApplied, stream, done) {
     var video = mkElement('video');
     video.mozSrcObject = stream;
+
+    var ready = false;
+    video.onplaying = function() {
+      ready = true;
+    }
     video.play();
 
-    return periodicCheck(() => {
+    function tryToRenderToCanvas() {
+      if (!ready) {
+        info('waiting for video to start');
+        return false;
+      }
+
       try {
+        // every try needs a new canvas, otherwise a taint from an earlier call
+        // will affect subsequent calls
         var canvas = mkElement('canvas');
         var ctx = canvas.getContext('2d');
-        // Have to guard drawImage with the try as well, due to bug 879717. If
-        // we get an error, this round fails, but that failure is usually just
-        // transitory.
+        // have to guard drawImage with the try as well, due to bug 879717
+        // if we get an error, this round fails, but that failure is usually
+        // just transitory
         ctx.drawImage(video, 0, 0);
         ctx.getImageData(0, 0, 1, 1);
         return check(constraintApplied, false, 'throw on getImageData for video');
       } catch (e) {
         return check(constraintApplied, e.name === 'SecurityError',
                      'get a security error: ' + e.name);
       }
-    }).then(() => {
-      video.pause();
-      ok(true, 'video is ' + (constraintApplied ? '' : 'not ') + 'protected');
-    });
+    }
+
+    return periodicCheck('video', tryToRenderToCanvas,
+                         (constraintApplied ? '' : 'not ') + 'protected', done);
   }
 
   global.audioIsSilence = checkAudio;
   global.videoIsBlack = checkVideo;
 }(this));
new file mode 120000
--- /dev/null
+++ b/dom/media/tests/mochitest/identity/.#identityPcTest.js
@@ -0,0 +1,1 @@
+martin@Martins-MacBook-Pro.local.287
\ No newline at end of file
--- a/dom/media/tests/mochitest/identity/identityPcTest.js
+++ b/dom/media/tests/mochitest/identity/identityPcTest.js
@@ -18,37 +18,34 @@ function identityPcTest(remoteOptions) {
     video: true,
     peerIdentity: id2
   }], [remoteOptions || {
     audio: true,
     video: true,
     fake: true,
     peerIdentity: id1
   }]);
-  test.pcLocal.setIdentityProvider('test1.example.com', 'idp.js');
-  test.pcRemote.setIdentityProvider('test2.example.com', 'idp.js');
+  test.setIdentityProvider(test.pcLocal, 'test1.example.com', 'idp.html');
+  test.setIdentityProvider(test.pcRemote, 'test2.example.com', 'idp.html');
   test.chain.append([
+
     function PEER_IDENTITY_IS_SET_CORRECTLY(test) {
       // no need to wait to check identity in this case,
       // setRemoteDescription should wait for the IdP to complete
       function checkIdentity(pc, pfx, idp, name) {
-        return pc.peerIdentity.then(peerInfo => {
-          is(peerInfo.idp, idp, pfx + "IdP check");
-          is(peerInfo.name, name + "@" + idp, pfx + "identity check");
-        });
+        is(pc.peerIdentity.idp, idp, pfx + "IdP is correct");
+        is(pc.peerIdentity.name, name + "@" + idp, pfx + "identity is correct");
       }
 
-      return Promise.all([
-        checkIdentity(test.pcLocal._pc, "local: ", "test2.example.com", "someone"),
-        checkIdentity(test.pcRemote._pc, "remote: ", "test1.example.com", "someone")
-      ]);
+      checkIdentity(test.pcLocal._pc, "local: ", "test2.example.com", "someone");
+      checkIdentity(test.pcRemote._pc, "remote: ", "test1.example.com", "someone");
     },
 
     function REMOTE_STREAMS_ARE_RESTRICTED(test) {
       var remoteStream = test.pcLocal._pc.getRemoteStreams()[0];
       return Promise.all([
-        audioIsSilence(true, remoteStream),
-        videoIsBlack(true, remoteStream)
+        new Promise(done => audioIsSilence(true, remoteStream, done)),
+        new Promise(done => videoIsBlack(true, remoteStream, done))
       ]);
     }
   ]);
   test.run();
 }
--- a/dom/media/tests/mochitest/identity/test_peerConnection_asymmetricIsolation.html
+++ b/dom/media/tests/mochitest/identity/test_peerConnection_asymmetricIsolation.html
@@ -10,19 +10,19 @@
 <pre id="test">
 <script type="application/javascript">
 createHTML({
   title: "Non-isolated media entering an isolated session becomes isolated",
   bug: "996238"
 });
 
 function theTest() {
-  // Override the remote media capture options to remove isolation for the
-  // remote party; the test verifies that the media it receives on the local
-  // side is isolated anyway.
+  // override the remote media capture options to remove isolation
+  // for the remote party; the test verifies that the media it receives
+  // on the local side is isolated
   identityPcTest({
     audio: true,
     video: true,
     fake: true
   });
 }
 runNetworkTest(theTest);
 
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -23,18 +23,16 @@ const signalingStateTransitions = {
   "stable": ["have-local-offer", "have-remote-offer", "closed"],
   "have-local-offer": ["have-remote-pranswer", "stable", "closed", "have-local-offer"],
   "have-remote-pranswer": ["stable", "closed", "have-remote-pranswer"],
   "have-remote-offer": ["have-local-pranswer", "stable", "closed", "have-remote-offer"],
   "have-local-pranswer": ["stable", "closed", "have-local-pranswer"],
   "closed": []
 }
 
-var wait = (time) => new Promise(r => setTimeout(r, time));
-
 /**
  * This class provides a state checker for media elements which store
  * a media stream to check for media attribute state and events fired.
  * When constructed by a caller, an object instance is created with
  * a media element, event state checkers for canplaythrough, timeupdate, and
  * time changing on the media element and stream.
  *
  * @param {HTMLMediaElement} element the media element being analyzed
@@ -59,18 +57,18 @@ function MediaElementChecker(element) {
   // When timeupdate fires, we track that it's fired and check if time
   // has passed on the media stream and media element.
   var timeUpdateCallback = () => {
     this.timeUpdateFired = true;
     info('timeupdate fired for media element ' + elementId);
 
     // If time has passed, then track that and remove the timeupdate event
     // listener.
-    if (element.mozSrcObject && element.mozSrcObject.currentTime > 0 &&
-        element.currentTime > 0) {
+    if(element.mozSrcObject && element.mozSrcObject.currentTime > 0 &&
+       element.currentTime > 0) {
       info('time passed for media element ' + elementId);
       this.timePassed = true;
       this.element.removeEventListener('timeupdate', timeUpdateCallback,
                                        false);
     }
   };
 
   element.addEventListener('canplaythrough', canPlayThroughCallback, false);
--- a/dom/media/tests/mochitest/templates.js
+++ b/dom/media/tests/mochitest/templates.js
@@ -552,8 +552,10 @@ var addRenegotiation = (chain, commands,
 var addRenegotiationAnswerer = (chain, commands, checks) => {
   chain.append(function SWAP_PC_LOCAL_PC_REMOTE(test) {
     var temp = test.pcLocal;
     test.pcLocal = test.pcRemote;
     test.pcRemote = temp;
   });
   addRenegotiation(chain, commands, checks);
 };
+
+
--- a/dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html
@@ -2,40 +2,48 @@
 <html>
 <head>
   <script type="application/javascript" src="mediaStreamPlayback.js"></script>
   <script type="application/javascript" src="blacksilence.js"></script>
 </head>
 <body>
 <pre id="test">
 <script type="application/javascript">
-createHTML({
-  title: "Test getUserMedia peerIdentity Constraint",
-  bug: "942367"
-});
+createHTML({ title: "Test getUserMedia peerIdentity Constraint", bug: "942367" });
 function theTest() {
-  function testPeerIdentityConstraint(withConstraint) {
+  function testPeerIdentityConstraint(withConstraint, done) {
     var config = { audio: true, video: true, fake: true };
     if (withConstraint) {
       config.peerIdentity = 'user@example.com';
     }
     info('getting media with constraints: ' + JSON.stringify(config));
-    return getUserMedia(config)
-      .then(stream => Promise.all([
-        audioIsSilence(withConstraint, stream),
-        videoIsBlack(withConstraint, stream)
-      ]));
+    navigator.mediaDevices.getUserMedia(config).then(function(stream) {
+      var oneDone = false;
+      function checkDone() {
+        if (oneDone) {
+          done();
+        }
+        oneDone = true;
+      }
+      var cancelAudioCheck = audioIsSilence(withConstraint, stream, checkDone);
+      var cancelVideoCheck = videoIsBlack(withConstraint, stream, checkDone);
+      setTimeout(cancelAudioCheck, 3*60*1000);
+      setTimeout(cancelVideoCheck, 3*60*1000);
+    })
+    .catch(function(e) {
+      ok(false, 'gUM error: ' + e);
+    });
   };
 
-  // both without and with the constraint
-  testPeerIdentityConstraint(false)
-    .then(() => testPeerIdentityConstraint(true))
-    .catch(e => ok(false, 'error in test: ' + e))
-    .then(() => SimpleTest.finish())
-    .catch(e => ok(false, 'something is really messed up: ' + e));
+  // without constraint
+  testPeerIdentityConstraint(false, function() {
+    // with the constraint
+    testPeerIdentityConstraint(true, SimpleTest.finish.bind(SimpleTest));
+  });
 }
 
 runTest(theTest);
+SimpleTest.waitForExplicitFinish();
 
 </script>
 </pre>
 </body>
 </html>