Bug 995198 - Make uncaught async errors cause KNOWN-FAIL in xpcshell. r=ted
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Tue, 15 Apr 2014 12:51:20 -0400
changeset 197183 1dbade92ce0a37b9a5db2373b68dd81bf2cca210
parent 197182 963eaafdb70f7f3fbaaf4d27734f1ec9709a4a22
child 197184 6e5d5104b3ea4967fd4b28ca6ba0a18f59bc008a
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)
reviewersted
bugs995198
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 995198 - Make uncaught async errors cause KNOWN-FAIL in xpcshell. r=ted
testing/xpcshell/head.js
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -14,16 +14,18 @@ var _quit = false;
 var _passed = true;
 var _tests_pending = 0;
 var _passedChecks = 0, _falsePassedChecks = 0;
 var _todoChecks = 0;
 var _cleanupFunctions = [];
 var _pendingTimers = [];
 var _profileInitialized = false;
 
+let _Promise = Components.utils.import("resource://gre/modules/Promise.jsm", this).Promise;
+
 let _log = function (action, params) {
   if (typeof _XPCSHELL_PROCESS != "undefined") {
     params.process = _XPCSHELL_PROCESS;
   }
   params.action = action;
   params._time = Date.now();
   dump("\n" + JSON.stringify(params) + "\n");
 }
@@ -175,17 +177,17 @@ function _do_main() {
 
   while (thr.hasPendingEvents())
     thr.processNextEvent(true);
 }
 
 function _do_quit() {
   _log("test_info",
        {_message: "TEST-INFO | (xpcshell/head.js) | exiting test\n"});
-
+  _Promise.Debugging.flushUncaughtErrors();
   _quit = true;
 }
 
 function _format_exception_stack(stack) {
   if (typeof stack == "object" && stack.caller) {
     let frame = stack;
     let strStack = "";
     while (frame != null) {
@@ -343,16 +345,25 @@ function _register_protocol_handlers() {
 
 function _execute_test() {
   _register_protocol_handlers();
 
   // Override idle service by default.
   // Call do_get_idle() to restore the factory and get the service.
   _fakeIdleService.activate();
 
+  _Promise.Debugging.clearUncaughtErrorObservers();
+  _Promise.Debugging.addUncaughtErrorObserver(function observer({message, date, fileName, stack, lineNumber}) {
+    let text = "Once bug 976205 has landed, THIS ERROR WILL CAUSE A TEST FAILURE.\n" +
+        " A promise chain failed to handle a rejection: " +
+        message + " - rejection date: " + date;
+    _log_message_with_stack("test_known_fail",
+                            text, stack, fileName);
+  });
+
   // _HEAD_FILES is dynamically defined by <runxpcshelltests.py>.
   _load_files(_HEAD_FILES);
   // _TEST_FILE is dynamically defined by <runxpcshelltests.py>.
   _load_files(_TEST_FILE);
 
   // Support a common assertion library, Assert.jsm.
   let Assert = Components.utils.import("resource://testing-common/Assert.jsm", null).Assert;
   // Pass a custom report function for xpcshell-test style reporting.
@@ -1423,20 +1434,22 @@ let _gTestIndex = 0; // The index of the
 let _gTaskRunning = false;
 function run_next_test()
 {
   if (_gTaskRunning) {
     throw new Error("run_next_test() called from an add_task() test function. " +
                     "run_next_test() should not be called from inside add_task() " +
                     "under any circumstances!");
   }
-
+ 
   function _run_next_test()
   {
     if (_gTestIndex < _gTests.length) {
+      // Flush uncaught errors as early and often as possible.
+      _Promise.Debugging.flushUncaughtErrors();
       let _isTask;
       [_isTask, _gRunningTest] = _gTests[_gTestIndex++];
       print("TEST-INFO | " + _TEST_FILE + " | Starting " + _gRunningTest.name);
       do_test_pending(_gRunningTest.name);
 
       if (_isTask) {
         _gTaskRunning = true;
         _Task.spawn(_gRunningTest).then(