Bug 1000512 - If a test cleanup function returns a promise, wait for it to be resolved before running other tests. r=jmaher
authorMarco Castelluccio <mar.castelluccio@studenti.unina.it>
Thu, 24 Apr 2014 16:34:00 +0200
changeset 198595 2b2f0809d1c0cdeb230562426750fcb207285b30
parent 198594 05519890c1cc85202cdd998e42aba8abee5b58cb
child 198596 bd83aff8800a96cf11c5369da465012cea54165b
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmaher
bugs1000512
milestone31.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 1000512 - If a test cleanup function returns a promise, wait for it to be resolved before running other tests. r=jmaher
testing/mochitest/browser-test.js
testing/mochitest/tests/SimpleTest/SimpleTest.js
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -309,25 +309,25 @@ Tester.prototype = {
       else
         this.dumper.dump("TEST-INFO | (browser-test.js) | " + msg.replace(/\n$/, "") + "\n");
     } catch (ex) {
       // Swallow exception so we don't lead to another error being reported,
       // throwing us into an infinite loop
     }
   },
 
-  nextTest: function Tester_nextTest() {
+  nextTest: this.Task.async(function*() {
     if (this.currentTest) {
       // Run cleanup functions for the current test before moving on to the
       // next one.
       let testScope = this.currentTest.scope;
       while (testScope.__cleanupFunctions.length > 0) {
         let func = testScope.__cleanupFunctions.shift();
         try {
-          func.apply(testScope);
+          yield func.apply(testScope);
         }
         catch (ex) {
           this.currentTest.addResult(new testResult(false, "Cleanup function threw an exception", ex, false));
         }
       };
 
       this.Promise.Debugging.flushUncaughtErrors();
 
@@ -526,17 +526,17 @@ Tester.prototype = {
         });
 
         return;
       }
 
       this.currentTestIndex++;
       this.execTest();
     }).bind(this));
-  },
+  }),
 
   execTest: function Tester_execTest() {
     this.dumper.dump("TEST-START | " + this.currentTest.path + "\n");
 
     this.SimpleTest.reset();
 
     // Load the tests into a testscope
     let currentScope = this.currentTest.scope = new testScope(this, this.currentTest);
--- a/testing/mochitest/tests/SimpleTest/SimpleTest.js
+++ b/testing/mochitest/tests/SimpleTest/SimpleTest.js
@@ -841,68 +841,72 @@ SimpleTest.executeSoon = function(aFunc)
 SimpleTest.registerCleanupFunction = function(aFunc) {
     SimpleTest._cleanupFunctions.push(aFunc);
 };
 
 /**
  * Finishes the tests. This is automatically called, except when
  * SimpleTest.waitForExplicitFinish() has been invoked.
 **/
-SimpleTest.finish = function () {
+SimpleTest.finish = function() {
+    var Task = SpecialPowers.Cu.import("resource://gre/modules/Task.jsm").Task;
+
     if (SimpleTest._alreadyFinished) {
         SimpleTest.ok(false, "[SimpleTest.finish()] this test already called finish!");
     }
 
     SimpleTest._alreadyFinished = true;
 
-    // Execute all of our cleanup functions.
-    var func;
-    while ((func = SimpleTest._cleanupFunctions.pop())) {
-      try {
-        func();
-      }
-      catch (ex) {
-        SimpleTest.ok(false, "Cleanup function threw exception: " + ex);
-      }
-    }
+    Task.spawn(function*() {
+        // Execute all of our cleanup functions.
+        var func;
+        while ((func = SimpleTest._cleanupFunctions.pop())) {
+          try {
+            yield func();
+          }
+          catch (ex) {
+            SimpleTest.ok(false, "Cleanup function threw exception: " + ex);
+          }
+        }
 
-    if (SpecialPowers.DOMWindowUtils.isTestControllingRefreshes) {
-        SimpleTest.ok(false, "test left refresh driver under test control");
-        SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
-    }
-    if (SimpleTest._expectingUncaughtException) {
-        SimpleTest.ok(false, "expectUncaughtException was called but no uncaught exception was detected!");
-    }
-    if (SimpleTest._pendingWaitForFocusCount != 0) {
-        SimpleTest.is(SimpleTest._pendingWaitForFocusCount, 0,
-                      "[SimpleTest.finish()] waitForFocus() was called a "
-                      + "different number of times from the number of "
-                      + "callbacks run.  Maybe the test terminated "
-                      + "prematurely -- be sure to use "
-                      + "SimpleTest.waitForExplicitFinish().");
-    }
-    if (SimpleTest._tests.length == 0) {
-        SimpleTest.ok(false, "[SimpleTest.finish()] No checks actually run. "
-                           + "(You need to call ok(), is(), or similar "
-                           + "functions at least once.  Make sure you use "
-                           + "SimpleTest.waitForExplicitFinish() if you need "
-                           + "it.)");
-    }
+        if (SpecialPowers.DOMWindowUtils.isTestControllingRefreshes) {
+            SimpleTest.ok(false, "test left refresh driver under test control");
+            SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
+        }
+        if (SimpleTest._expectingUncaughtException) {
+            SimpleTest.ok(false, "expectUncaughtException was called but no uncaught exception was detected!");
+        }
+        if (SimpleTest._pendingWaitForFocusCount != 0) {
+            SimpleTest.is(SimpleTest._pendingWaitForFocusCount, 0,
+                          "[SimpleTest.finish()] waitForFocus() was called a "
+                          + "different number of times from the number of "
+                          + "callbacks run.  Maybe the test terminated "
+                          + "prematurely -- be sure to use "
+                          + "SimpleTest.waitForExplicitFinish().");
+        }
+        if (SimpleTest._tests.length == 0) {
+            SimpleTest.ok(false, "[SimpleTest.finish()] No checks actually run. "
+                               + "(You need to call ok(), is(), or similar "
+                               + "functions at least once.  Make sure you use "
+                               + "SimpleTest.waitForExplicitFinish() if you need "
+                               + "it.)");
+        }
 
-    if (parentRunner) {
-        /* We're running in an iframe, and the parent has a TestRunner */
-        parentRunner.testFinished(SimpleTest._tests);
-    } else {
-        SpecialPowers.flushAllAppsLaunchable();
-        SpecialPowers.flushPermissions(function () {
-          SpecialPowers.flushPrefEnv(function() {
-            SimpleTest.showReport();
-          });
-        });
-    }
+        if (parentRunner) {
+            /* We're running in an iframe, and the parent has a TestRunner */
+            parentRunner.testFinished(SimpleTest._tests);
+        } else {
+            SpecialPowers.flushAllAppsLaunchable();
+            SpecialPowers.flushPermissions(function () {
+              SpecialPowers.flushPrefEnv(function() {
+                SimpleTest.showReport();
+              });
+            });
+        }
+    });
 };
 
 /**
  * Monitor console output from now until endMonitorConsole is called.
  *
  * Expect to receive all console messages described by the elements of
  * |msgs|, an array, in the order listed in |msgs|; each element is an
  * object which may have any number of the following properties: