Bug 1316780: Part 3 - Capture the current unprivileged stack in browser.test.* assertion functions. r=aswan
authorKris Maglione <maglione.k@gmail.com>
Fri, 11 Nov 2016 15:25:30 -0800
changeset 352356 ee3edae1e4e0ac07b3032a30b2685d2cd8c85658
parent 352355 c93fbd9ced3c64a4e48bb45ee90187be46f65212
child 352357 6790d8962ad997c31d17c15e78d3a39692ec390a
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan
bugs1316780
milestone52.0a1
Bug 1316780: Part 3 - Capture the current unprivileged stack in browser.test.* assertion functions. r=aswan MozReview-Commit-ID: AxjMeoodpTX
testing/mochitest/tests/SimpleTest/ExtensionTestUtils.js
testing/mochitest/tests/SimpleTest/SimpleTest.js
toolkit/components/extensions/ext-c-test.js
toolkit/components/extensions/test/mochitest/test_ext_test.html
--- a/testing/mochitest/tests/SimpleTest/ExtensionTestUtils.js
+++ b/testing/mochitest/tests/SimpleTest/ExtensionTestUtils.js
@@ -48,29 +48,29 @@ ExtensionTestUtils.loadExtension = funct
   function checkDuplicateListeners(msg) {
     if (messageHandler.has(msg) || messageAwaiter.has(msg)) {
       throw new Error("only one message handler allowed");
     }
   }
 
   function testHandler(kind, pass, msg, ...args) {
     if (kind == "test-eq") {
-      var [expected, actual] = args;
-      SimpleTest.ok(pass, `${msg} - Expected: ${expected}, Actual: ${actual}`);
+      let [expected, actual, stack] = args;
+      SimpleTest.ok(pass, `${msg} - Expected: ${expected}, Actual: ${actual}`, undefined, stack);
     } else if (kind == "test-log") {
       SimpleTest.info(msg);
     } else if (kind == "test-result") {
-      SimpleTest.ok(pass, msg);
+      SimpleTest.ok(pass, msg, undefined, args[0]);
     }
   }
 
   var handler = {
     testResult(kind, pass, msg, ...args) {
       if (kind == "test-done") {
-        SimpleTest.ok(pass, msg);
+        SimpleTest.ok(pass, msg, undefined, args[0]);
         return testResolve(msg);
       }
       testHandler(kind, pass, msg, ...args);
     },
 
     testMessage(msg, ...args) {
       var handler = messageHandler.get(msg);
       if (handler) {
--- a/testing/mochitest/tests/SimpleTest/SimpleTest.js
+++ b/testing/mochitest/tests/SimpleTest/SimpleTest.js
@@ -229,33 +229,34 @@ SimpleTest.setExpected = function () {
     SimpleTest.expected = parent.TestRunner.expected;
   }
 }
 SimpleTest.setExpected();
 
 /**
  * Something like assert.
 **/
-SimpleTest.ok = function (condition, name, diag) {
+SimpleTest.ok = function (condition, name, diag, stack = null) {
 
     var test = {'result': !!condition, 'name': name, 'diag': diag};
     if (SimpleTest.expected == 'fail') {
       if (!test.result) {
         SimpleTest.num_failed++;
         test.result = !test.result;
       }
       var successInfo = {status:"FAIL", expected:"FAIL", message:"TEST-KNOWN-FAIL"};
       var failureInfo = {status:"PASS", expected:"FAIL", message:"TEST-UNEXPECTED-PASS"};
     } else {
       var successInfo = {status:"PASS", expected:"PASS", message:"TEST-PASS"};
       var failureInfo = {status:"FAIL", expected:"PASS", message:"TEST-UNEXPECTED-FAIL"};
     }
 
-    var stack = null;
-    if (!condition) {
+    if (condition) {
+        stack = null;
+    } else if (!stack) {
       stack = (new Error).stack.replace(/^(.*@)http:\/\/mochi.test:8888\/tests\//gm, '    $1').split('\n');
       stack.splice(0, 1);
       stack = stack.join('\n');
     }
 
     SimpleTest._logResult(test, successInfo, failureInfo, stack);
     SimpleTest._tests.push(test);
 };
--- a/toolkit/components/extensions/ext-c-test.js
+++ b/toolkit/components/extensions/ext-c-test.js
@@ -73,36 +73,40 @@ function toSource(value) {
   } catch (e) {
     return "<unknown>";
   }
 }
 
 function makeTestAPI(context) {
   const {extension} = context;
 
+  function getStack() {
+    return new context.cloneScope.Error().stack.replace(/^/gm, "    ");
+  }
+
   function assertTrue(value, msg) {
-    extension.emit("test-result", Boolean(value), String(msg));
+    extension.emit("test-result", Boolean(value), String(msg), getStack());
   }
 
   return {
     test: {
       sendMessage(...args) {
         extension.emit("test-message", ...args);
       },
 
       notifyPass(msg) {
-        extension.emit("test-done", true, msg);
+        extension.emit("test-done", true, msg, getStack());
       },
 
       notifyFail(msg) {
-        extension.emit("test-done", false, msg);
+        extension.emit("test-done", false, msg, getStack());
       },
 
       log(msg) {
-        extension.emit("test-log", true, msg);
+        extension.emit("test-log", true, msg, getStack());
       },
 
       fail(msg) {
         assertTrue(false, msg);
       },
 
       succeed(msg) {
         assertTrue(true, msg);
@@ -120,17 +124,17 @@ function makeTestAPI(context) {
         let equal = expected === actual;
 
         expected = String(expected);
         actual = String(actual);
 
         if (!equal && expected === actual) {
           actual += " (different)";
         }
-        extension.emit("test-eq", equal, String(msg), expected, actual);
+        extension.emit("test-eq", equal, String(msg), expected, actual, getStack());
       },
 
       assertRejects(promise, expectedError, msg) {
         // Wrap in a native promise for consistency.
         promise = Promise.resolve(promise);
 
         if (msg) {
           msg = `: ${msg}`;
--- a/toolkit/components/extensions/test/mochitest/test_ext_test.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_test.html
@@ -13,16 +13,17 @@
 "use strict";
 
 function loadExtensionAndInterceptTest(extensionData) {
   let results = [];
   let testResolve;
   let testDone = new Promise(resolve => { testResolve = resolve; });
   let handler = {
     testResult(...result) {
+      result.pop();
       results.push(result);
       SimpleTest.info(`Received test result: ${JSON.stringify(result)}`);
     },
 
     testMessage(msg, ...args) {
       results.push(["test-message", msg, ...args]);
       SimpleTest.info(`Received message: ${msg} ${JSON.stringify(args)}`);
       if (msg === "This is the last browser.test call") {