Bug 508128 - Additional diagnostics to report more data about test exceptions. r=waldo a=test-only
authorRobert O'Callahan <roc@ocallahan.org>
Thu, 05 Nov 2009 15:06:00 -0500
changeset 56372 24c51e16703af3a08347f976aba7f6cb7e0a294d
parent 56371 3671178287951e2c122697f8675470b8736a17c1
child 56373 031018350d0f3e85f63aa658cfcee14950e5ff60
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo, test-only
bugs508128
milestone2.0b8pre
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 508128 - Additional diagnostics to report more data about test exceptions. r=waldo a=test-only
netwerk/test/httpserver/test/head_utils.js
netwerk/test/unit/test_traceable_channel.js
testing/xpcshell/head.js
--- a/netwerk/test/httpserver/test/head_utils.js
+++ b/netwerk/test/httpserver/test/head_utils.js
@@ -288,36 +288,39 @@ function runHttpTests(testArray, done)
     if (++testIndex == testArray.length)
     {
       try
       {
         done();
       }
       catch (e)
       {
-        do_throw("error running test-completion callback: " + e);
+        do_report_unexpected_exception(e, "running test-completion callback");
       }
       return;
     }
 
     do_test_pending();
 
     var test = testArray[testIndex];
     var ch = makeChannel(test.path);
     try
     {
       test.initChannel(ch);
     }
     catch (e)
     {
       try
       {
-        do_throw("testArray[" + testIndex + "].initChannel(ch) failed: " + e);
+        do_report_unexpected_exception(e, "testArray[" + testIndex + "].initChannel(ch)");
       }
-      catch (e) { /* swallow and let tests continue */ }
+      catch (e)
+      {
+        /* swallow and let tests continue */
+      }
     }
 
     ch.asyncOpen(listener, null);
   }
 
   /** Index of the test being run. */
   var testIndex = -1;
 
@@ -336,22 +339,22 @@ function runHttpTests(testArray, done)
         try
         {
           try
           {
             testArray[testIndex].onStartRequest(ch, cx);
           }
           catch (e)
           {
-            do_throw("testArray[" + testIndex + "].onStartRequest: " + e);
+            do_report_unexpected_exception(e, "testArray[" + testIndex + "].onStartRequest");
           }
         }
         catch (e)
         {
-          dumpn("!!! swallowing onStartRequest exception so onStopRequest is " +
+          do_note_exception(e, "!!! swallowing onStartRequest exception so onStopRequest is " +
                 "called...");
         }
       },
       onDataAvailable: function(request, cx, inputStream, offset, count)
       {
         Array.prototype.push.apply(this._data,
                                    makeBIS(inputStream).readByteArray(count));
       },
@@ -459,17 +462,17 @@ function runRawTests(testArray, done)
     {
       do_test_finished();
       try
       {
         done();
       }
       catch (e)
       {
-        do_throw("error running test-completion callback: " + e);
+        do_report_unexpected_exception(e, "running test-completion callback");
       }
       return;
     }
 
 
     var rawTest = testArray[testIndex];
 
     var transport =
@@ -514,45 +517,63 @@ function runRawTests(testArray, done)
   /** Data received so far from the server. */
   var received = "";
 
   /** Reads data from the socket. */
   var reader =
     {
       onInputStreamReady: function(stream)
       {
-        var bis = new BinaryInputStream(stream);
-
-        var av = 0;
         try
         {
-          av = bis.available();
-        }
-        catch (e) { /* default to 0 */ }
+          var bis = new BinaryInputStream(stream);
 
-        if (av > 0)
+          var av = 0;
+          try
+          {
+            av = bis.available();
+          }
+          catch (e)
+          {
+            /* default to 0 */
+            do_note_exception(e);
+          }
+
+          if (av > 0)
+          {
+            received += String.fromCharCode.apply(null, bis.readByteArray(av));
+            waitForMoreInput(stream);
+            return;
+          }
+        }
+        catch(e)
         {
-          received += String.fromCharCode.apply(null, bis.readByteArray(av));
-          waitForMoreInput(stream);
-          return;
+          do_report_unexpected_exception(e);
         }
 
         var rawTest = testArray[testIndex];
         try
         {
           rawTest.responseCheck(received);
         }
         catch (e)
         {
-          do_throw("error thrown by responseCheck: " + e);
+          do_report_unexpected_exception(e);
         }
         finally
         {
-          stream.close();
-          performNextTest();
+          try
+          {
+            stream.close();
+            performNextTest();
+          }
+          catch (e)
+          {
+            do_report_unexpected_exception(e);
+          }
         }
       }
     };
 
   /** Writes data to the socket. */
   var writer = 
     {
       onOutputStreamReady: function(stream)
@@ -563,21 +584,32 @@ function runRawTests(testArray, done)
         try
         {
           written = stream.write(str, str.length);
           if (written == str.length)
             dataIndex++;
           else
             testArray[testIndex].data[dataIndex] = str.substring(written);
         }
-        catch (e) { /* stream could have been closed, just ignore */ }
+        catch (e)
+        {
+          do_note_exception(e);
+          /* stream could have been closed, just ignore */
+        }
 
-        // Keep writing data while we can write and 
-        // until there's no more data to read
-        if (written > 0 && dataIndex < testArray[testIndex].data.length)
-          waitToWriteOutput(stream);
-        else
-          stream.close();
+        try
+        {
+          // Keep writing data while we can write and 
+          // until there's no more data to read
+          if (written > 0 && dataIndex < testArray[testIndex].data.length)
+            waitToWriteOutput(stream);
+          else
+            stream.close();
+        }
+        catch (e)
+        {
+          do_report_unexpected_exception(e);
+        }
       }
     };
 
   performNextTest();
 }
--- a/netwerk/test/unit/test_traceable_channel.js
+++ b/netwerk/test/unit/test_traceable_channel.js
@@ -21,40 +21,45 @@ TracingListener.prototype = {
     gotOnStartRequest = true;
 
     // Make sure listener can't be replaced after OnStartRequest was called.
     request.QueryInterface(Components.interfaces.nsITraceableChannel);
     try {
       var newListener = new TracingListener();
       newListener.listener = request.setNewListener(newListener);
     } catch(e) {
+      dump("TracingListener.onStartRequest swallowing exception: " + e + "\n");
       return; // OK
     }
     do_throw("replaced channel's listener during onStartRequest.");
   },
 
   onStopRequest: function(request, context, statusCode) {
     dump("*** tracing listener onStopRequest\n");
     
     do_check_eq(gotOnStartRequest, true);
-    
-    var sin = Components.classes["@mozilla.org/scriptableinputstream;1"].
-        createInstance(Ci.nsIScriptableInputStream);
+
+    try {
+      var sin = Components.classes["@mozilla.org/scriptableinputstream;1"].
+          createInstance(Ci.nsIScriptableInputStream);
 
-    streamSink.close();
-    var input = pipe.inputStream;
-    sin.init(input);
-    do_check_eq(sin.available(), originalBody.length);
+      streamSink.close();
+      var input = pipe.inputStream;
+      sin.init(input);
+      do_check_eq(sin.available(), originalBody.length);
     
-    var result = sin.read(originalBody.length);
-    do_check_eq(result, originalBody);
+      var result = sin.read(originalBody.length);
+      do_check_eq(result, originalBody);
     
-    input.close();
-    
-    httpserver.stop(do_test_finished);
+      input.close();
+    } catch (e) {
+      dump("TracingListener.onStopRequest swallowing exception: " + e + "\n");
+    } finally {
+      httpserver.stop(do_test_finished);
+    }
   },
 
   QueryInterface: function(iid) {
     if (iid.equals(Components.interfaces.nsIRequestObserver) ||
         iid.equals(Components.interfaces.nsISupports)
         )
       return this;
     throw Components.results.NS_NOINTERFACE;
@@ -66,35 +71,38 @@ TracingListener.prototype = {
 
 function HttpResponseExaminer() {}
 
 HttpResponseExaminer.prototype = {
   register: function() {
     Cc["@mozilla.org/observer-service;1"].
       getService(Components.interfaces.nsIObserverService).
       addObserver(this, "http-on-examine-response", true);
+    dump("Did HttpResponseExaminer.register\n");
   },
 
   // Replace channel's listener.
   observe: function(subject, topic, data) {
+    dump("In HttpResponseExaminer.observe\n");
     try {
       subject.QueryInterface(Components.interfaces.nsITraceableChannel);
       
       var tee = Cc["@mozilla.org/network/stream-listener-tee;1"].
           createInstance(Ci.nsIStreamListenerTee);
       var newListener = new TracingListener();
       pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
       pipe.init(false, false, 0, 0xffffffff, null);
       streamSink = pipe.outputStream;
       
       var originalListener = subject.setNewListener(tee);
       tee.init(originalListener, streamSink, newListener);
     } catch(e) {
       do_throw("can't replace listener " + e);
     }
+    dump("Did HttpResponseExaminer.observe\n");
   },
 
   QueryInterface: function(iid) {
     if (iid.equals(Components.interfaces.nsIObserver) ||
         iid.equals(Components.interfaces.nsISupportsWeakReference) ||
         iid.equals(Components.interfaces.nsISupports))
       return this;
     throw Components.results.NS_NOINTERFACE;
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -422,16 +422,38 @@ function do_throw(text, stack) {
     _dump(frame + "\n");
     frame = frame.caller;
   }
 
   _do_quit();
   throw Components.results.NS_ERROR_ABORT;
 }
 
+function do_report_unexpected_exception(ex, text) {
+  var caller_stack = Components.stack.caller;
+  text = text ? text + " - " : "";
+
+  _passed = false;
+  dump("TEST-UNEXPECTED-FAIL | " + caller_stack.filename + " | " + text +
+         "Unexpected exception " + ex + ", see following stack:\n" + ex.stack +
+         "\n");
+
+  _do_quit();
+  throw Components.results.NS_ERROR_ABORT;
+}
+
+function do_note_exception(ex, text) {
+  var caller_stack = Components.stack.caller;
+  text = text ? text + " - " : "";
+
+  dump("TEST-INFO | " + caller_stack.filename + " | " + text +
+         "Swallowed exception " + ex + ", see following stack:\n" + ex.stack +
+         "\n");
+}
+
 function do_check_neq(left, right, stack) {
   if (!stack)
     stack = Components.stack.caller;
 
   var text = left + " != " + right;
   if (left == right) {
     do_throw(text, stack);
   } else {