Bug 1453881: Part 2 - Assert that task functions do not return generators. r=florian
authorKris Maglione <maglione.k@gmail.com>
Thu, 12 Apr 2018 12:37:28 -0700
changeset 414191 7f31e4da13c67dc171105e9909b6d81203e9f14a
parent 414190 b05440a8fe3fbb8406354eaadfb213760c2723b3
child 414192 786de338af8a63c33870f606fb7afb32b49798dc
push id33861
push userccoroiu@mozilla.com
push dateWed, 18 Apr 2018 10:50:38 +0000
treeherdermozilla-central@4af4ae0aee55 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian
bugs1453881
milestone61.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 1453881: Part 2 - Assert that task functions do not return generators. r=florian In older builds, task functions were allowed to return generators, which were automatically wrapped into tasks using Task.jsm. This model is no longer supported, so to prevent it from passing silently, we should check for and reject uses of the old pattern. MozReview-Commit-ID: 4cHo7pEqYJn
testing/xpcshell/head.js
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -195,16 +195,20 @@ function _Timer(func, delay) {
 
     // Timer undershot, retry with a little overshoot to try to avoid more
     // undershoots.
     var newDelay = this._delay - elapsed;
     do_timeout(newDelay, this._func);
   }
 };
 
+function _isGenerator(val) {
+  return typeof val === "object" && val && typeof val.next === "function";
+}
+
 function _do_main() {
   if (_quit)
     return;
 
   _testLogger.info("running event loop");
 
   var tm = Cc["@mozilla.org/thread-manager;1"].getService();
 
@@ -569,17 +573,20 @@ function _execute_test() {
                         source_file: filename
                       });
   };
 
   let complete = _cleanupFunctions.length == 0;
   (async () => {
     for (let func of _cleanupFunctions.reverse()) {
       try {
-        await func();
+        let result = await func();
+        if (_isGenerator(result)) {
+          Assert.ok(false, "Cleanup function returned a generator");
+        }
       } catch (ex) {
         reportCleanupError(ex);
       }
     }
     _cleanupFunctions = [];
   })().catch(reportCleanupError).then(() => complete = true);
   _Services.tm.spinEventLoopUntil(() => complete);
 
@@ -1410,18 +1417,21 @@ function run_next_test() {
                                "SKIP",
                                _message);
         executeSoon(run_next_test);
         return;
       }
 
       if (_properties.isTask) {
         _gTaskRunning = true;
-        (async () => _gRunningTest())().then(() => {
+        (async () => _gRunningTest())().then(result => {
           _gTaskRunning = false;
+          if (_isGenerator(result)) {
+            Assert.ok(false, "Task returned a generator");
+          }
           run_next_test();
         }, ex => {
           _gTaskRunning = false;
           try {
             do_report_unexpected_exception(ex);
           } catch (ex) {
             // The above throws NS_ERROR_ABORT and we don't want this to show up
             // as an unhandled rejection later.