Bug 1177013 - Modernize test_cpows.xul (r=dvander)
☠☠ backed out by 0d06cc55aed1 ☠ ☠
authorBill McCloskey <billm@mozilla.com>
Fri, 19 Jun 2015 17:33:57 -0700
changeset 275495 978a77b60f2a671b93f8f38a242ccb085d1c0341
parent 275494 f5b52fa19511f3ce9bfbdde6d773e775f205afb2
child 275496 de79eba232f017380e07646364aea5e7ca0e6061
push id3189
push userrocallahan@mozilla.com
push dateFri, 03 Jul 2015 11:12:01 +0000
reviewersdvander
bugs1177013
milestone42.0a1
Bug 1177013 - Modernize test_cpows.xul (r=dvander)
dom/base/test/chrome/cpows_child.js
dom/base/test/chrome/cpows_parent.xul
--- a/dom/base/test/chrome/cpows_child.js
+++ b/dom/base/test/chrome/cpows_child.js
@@ -1,43 +1,45 @@
 dump('loaded child cpow test\n');
 
-content.document.title = "Hello, Kitty";
 const Cu = Components.utils;
 
-var done_count = 0;
-var is_remote;
-
 (function start() {
-    [is_remote] = sendSyncMessage("cpows:is_remote");
-    parent_test();
-    error_reporting_test();
-    dom_test();
-    xray_test();
-    if (typeof Symbol === "function") {
-      symbol_test();
+  [is_remote] = sendRpcMessage("cpows:is_remote");
+
+  var tests = [
+    parent_test,
+    error_reporting_test,
+    dom_test,
+    xray_test,
+    symbol_test,
+    compartment_test,
+    regexp_test,
+    postmessage_test,
+    sync_test,
+    async_test,
+    rpc_test,
+    lifetime_test
+  ];
+
+  function go() {
+    if (tests.length == 0) {
+      sendRpcMessage("cpows:done", {});
+      return;
     }
-    compartment_test();
-    regexp_test();
-    postmessage_test();
-    sync_test();
-    async_test();
-    rpc_test();
-    nested_sync_test();
-    // The sync-ness of this call is important, because otherwise
-    // we tear down the child's document while we are
-    // still in the async test in the parent.
-    // This test races with itself to be the final test.
-    lifetime_test(function() {
-      done_count++;
-      if (done_count == 2)
-        sendSyncMessage("cpows:done", {});
+
+    var test = tests[0];
+    tests.shift();
+    test(function() {
+      go();
     });
   }
-)();
+
+  go();
+})();
 
 function ok(condition, message) {
   dump('condition: ' + condition  + ', ' + message + '\n');
   if (!condition) {
     sendAsyncMessage("cpows:fail", { message: message });
     throw 'failed check: ' + message;
   }
 }
@@ -64,32 +66,33 @@ function make_object()
 
   let for_json = { "n": 3, "a": array, "s": "hello", o: { "x": 10 } };
 
   let proto = { data: 42 };
   let with_proto = Object.create(proto);
 
   let with_null_proto = Object.create(null);
 
+  content.document.title = "Hello, Kitty";
   return { "data": o,
            "throwing": throwing,
            "document": content.document,
            "array": array,
            "for_json": for_json,
            "with_proto": with_proto,
            "with_null_proto": with_null_proto
          };
 }
 
 function make_json()
 {
   return { check: "ok" };
 }
 
-function parent_test()
+function parent_test(finish)
 {
   function f(check_func) {
     let result = check_func(10);
     ok(result == 20, "calling function in parent worked");
     return result;
   }
 
   addMessageListener("cpows:from_parent", (msg) => {
@@ -99,67 +102,70 @@ function parent_test()
     // Test that a CPOW reference to a function in the chrome process
     // is callable from unprivileged content. Greasemonkey uses this
     // functionality.
     let func = msg.objects.func;
     let sb = Cu.Sandbox('http://www.example.com', {});
     sb.func = func;
     ok(sb.eval('func()') == 101, "can call parent's function in child");
 
-    done_count++;
-    if (done_count == 2)
-      sendSyncMessage("cpows:done", {});
+    finish();
   });
-  sendSyncMessage("cpows:parent_test", {}, {func: f});
+  sendRpcMessage("cpows:parent_test", {}, {func: f});
 }
 
-function error_reporting_test() {
-  sendSyncMessage("cpows:error_reporting_test", {}, {});
+function error_reporting_test(finish) {
+  sendRpcMessage("cpows:error_reporting_test", {}, {});
+  finish();
 }
 
-function dom_test()
+function dom_test(finish)
 {
   let element = content.document.createElement("div");
   element.id = "it_works";
   content.document.body.appendChild(element);
 
-  sendAsyncMessage("cpows:dom_test", {}, {element: element});
+  sendRpcMessage("cpows:dom_test", {}, {element: element});
   Components.utils.schedulePreciseGC(function() {
-    sendSyncMessage("cpows:dom_test_after_gc");
+    sendRpcMessage("cpows:dom_test_after_gc");
+    finish();
   });
 }
 
-function xray_test()
+function xray_test(finish)
 {
   let element = content.document.createElement("div");
   element.wrappedJSObject.foo = "hello";
 
-  sendSyncMessage("cpows:xray_test", {}, {element: element});
+  sendRpcMessage("cpows:xray_test", {}, {element: element});
+  finish();
 }
 
-function symbol_test()
+function symbol_test(finish)
 {
   let iterator = Symbol.iterator;
   let named = Symbol.for("cpow-test");
 
   let object = {
     [iterator]: iterator,
     [named]: named,
   };
   let test = ['a'];
-  sendSyncMessage("cpows:symbol_test", {}, {object: object, test: test});
+  sendRpcMessage("cpows:symbol_test", {}, {object: object, test: test});
+  finish();
 }
 
 // Parent->Child references should go X->parent.privilegedJunkScope->child.privilegedJunkScope->Y
 // Child->Parent references should go X->child.privilegedJunkScope->parent.unprivilegedJunkScope->Y
-function compartment_test()
+function compartment_test(finish)
 {
   // This test primarily checks various compartment invariants for CPOWs, and
   // doesn't make sense to run in-process.
   if (!is_remote) {
+    finish();
     return;
   }
 
   let sb = Cu.Sandbox('http://www.example.com', { wantGlobalProperties: ['XMLHttpRequest'] });
   sb.eval('function getUnprivilegedObject() { var xhr = new XMLHttpRequest(); xhr.expando = 42; return xhr; }');
   function testParentObject(obj) {
     let results = [];
     function is(a, b, msg) { results.push({ result: a === b ? "PASS" : "FAIL", message: msg }) };
@@ -173,99 +179,86 @@ function compartment_test()
       obj.expando;
       ok(false, "child->parent CPOW cannot access properties");
     } catch (e) {
       ok(true, "child->parent CPOW cannot access properties");
     }
 
     return results;
   }
-  sendSyncMessage("cpows:compartment_test", {}, { getUnprivilegedObject: sb.getUnprivilegedObject,
-                                                  testParentObject: testParentObject });
+  sendRpcMessage("cpows:compartment_test", {}, { getUnprivilegedObject: sb.getUnprivilegedObject,
+                                                 testParentObject: testParentObject });
+  finish();
 }
 
-function regexp_test()
+function regexp_test(finish)
 {
-  sendSyncMessage("cpows:regexp_test", {}, { regexp: /myRegExp/g });
+  sendRpcMessage("cpows:regexp_test", {}, { regexp: /myRegExp/g });
+  finish();
 }
 
-function postmessage_test()
+function postmessage_test(finish)
 {
-  sendSyncMessage("cpows:postmessage_test", {}, { win: content.window });
+  sendRpcMessage("cpows:postmessage_test", {}, { win: content.window });
+  finish();
 }
 
-function sync_test()
+function sync_test(finish)
 {
   dump('beginning cpow sync test\n');
   sync_obj = make_object();
-  sendSyncMessage("cpows:sync",
+  sendRpcMessage("cpows:sync",
     make_json(),
     make_object());
+  finish();
 }
 
-function async_test()
+function async_test(finish)
 {
   dump('beginning cpow async test\n');
   async_obj = make_object();
   sendAsyncMessage("cpows:async",
     make_json(),
     async_obj);
+
+  addMessageListener("cpows:async_done", finish);
 }
 
 var rpc_obj;
 
-function rpc_test()
+function rpc_test(finish)
 {
   dump('beginning cpow rpc test\n');
   rpc_obj = make_object();
   rpc_obj.data.reenter = function  () {
     sendRpcMessage("cpows:reenter", { }, { data: { valid: true } });
     return "ok";
   }
   sendRpcMessage("cpows:rpc",
     make_json(),
     rpc_obj);
-}
-
-function nested_sync_test()
-{
-  dump('beginning cpow nested sync test\n');
-  sync_obj = make_object();
-  sync_obj.data.reenter = function () {
-    let caught = false;
-    try {
-       sendSyncMessage("cpows:reenter_sync", { }, { });
-    } catch (e) {
-      caught = true;
-    }
-    if (!ok(caught, "should not allow nested sync"))
-      return "fail";
-    return "ok";
-  }
-  sendSyncMessage("cpows:nested_sync",
-    make_json(),
-    rpc_obj);
+  finish();
 }
 
 function lifetime_test(finish)
 {
   if (!is_remote) {
     // Only run this test when running out-of-process. Otherwise it
     // will fail, since local CPOWs don't follow the same ownership
     // rules.
     finish();
     return;
   }
 
   dump("beginning lifetime test\n");
   var obj = {"will_die": {"f": 1}};
-  let [result] = sendSyncMessage("cpows:lifetime_test_1", {}, {obj: obj});
+  let [result] = sendRpcMessage("cpows:lifetime_test_1", {}, {obj: obj});
   ok(result == 10, "got sync result");
   ok(obj.wont_die.f == 2, "got reverse CPOW");
   obj.will_die = null;
   Components.utils.schedulePreciseGC(function() {
     addMessageListener("cpows:lifetime_test_3", (msg) => {
       ok(obj.wont_die.f == 2, "reverse CPOW still works");
       finish();
     });
-    sendSyncMessage("cpows:lifetime_test_2");
+    sendRpcMessage("cpows:lifetime_test_2");
   });
 }
--- a/dom/base/test/chrome/cpows_parent.xul
+++ b/dom/base/test/chrome/cpows_parent.xul
@@ -59,17 +59,17 @@
       ok(data.x.i === 10, "nested property");
       ok(data.f() === 99, "function call");
       is(Object.getOwnPropertyDescriptor(data, "doesn't exist"), undefined,
          "getOwnPropertyDescriptor returns undefined for non-existant properties");
       ok(Object.getOwnPropertyDescriptor(data, "i").value, 5,
          "getOwnPropertyDescriptor.value works");
       let obj = new data.ctor();
       ok(obj.a === 3, "constructor call");
-      ok(document.title === "Hello, Kitty", "document node");
+      is(document.title, "Hello, Kitty", "document node");
       is(typeof document.cookie, "string", "can get document.cookie");
       is(typeof document.defaultView.navigator.userAgent, "string", "can get navigator.userAgent");
 
       // Don't crash.
       document.defaultView.screen;
 
       data.i = 6;
       data.b = false;
@@ -136,16 +136,17 @@
 
       let with_null_proto = message.objects.with_null_proto;
       proto = Object.getPrototypeOf(with_null_proto);
       ok(proto === null, "Object.getPrototypeOf works on CPOW (null proto)");
     }
 
     function recvAsyncMessage(message) {
       testCpowMessage(message);
+      savedMM.sendAsyncMessage("cpows:async_done");
     }
 
     function recvSyncMessage(message) {
       testCpowMessage(message);
     }
 
     function recvRpcMessage(message) {
       ok(message.json.check == "ok", "correct json");