Bug 1346247 - Avoid race conditions when SW are updated - part 2 - tests, r=bkelly, a=jcristau
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 28 Mar 2017 11:48:57 +0200
changeset 395633 c8138453b0fcf052e9d0214af448947f3c242917
parent 395632 b300a55f3d9bfacd3ecf7f901f4976a40cb412ae
child 395634 929d6fc313e63aa9775b436659c6207f7de47b6a
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbkelly, jcristau
bugs1346247
milestone54.0a2
Bug 1346247 - Avoid race conditions when SW are updated - part 2 - tests, r=bkelly, a=jcristau
dom/workers/test/serviceworkers/browser.ini
dom/workers/test/serviceworkers/browser_multie10s_update.js
dom/workers/test/serviceworkers/file_multie10s_update.html
dom/workers/test/serviceworkers/server_multie10s_update.sjs
--- a/dom/workers/test/serviceworkers/browser.ini
+++ b/dom/workers/test/serviceworkers/browser.ini
@@ -1,10 +1,14 @@
 [DEFAULT]
 support-files =
   browser_base_force_refresh.html
   browser_cached_force_refresh.html
   download/window.html
   download/worker.js
+  file_multie10s_update.html
   force_refresh_browser_worker.js
+  server_multie10s_update.sjs
 
 [browser_force_refresh.js]
 [browser_download.js]
+[browser_multie10s_update.js]
+run-if=e10s
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/browser_multie10s_update.js
@@ -0,0 +1,80 @@
+"use strict";
+
+const { classes: Cc, interfaces: Ci, results: Cr } = Components;
+
+// Testing if 2 child processes are correctly managed when they both try to do
+// an SW update.
+
+const BASE_URI = "http://mochi.test:8888/browser/dom/workers/test/serviceworkers/";
+
+add_task(function* test_update() {
+  info("Setting the prefs to having multi-e10s enabled");
+  yield SpecialPowers.pushPrefEnv({"set": [
+    ["dom.ipc.processCount", 4],
+    ["dom.serviceWorkers.enabled", true],
+    ["dom.serviceWorkers.testing.enabled", true],
+  ]});
+
+  let url = BASE_URI + "file_multie10s_update.html";
+
+  info("Creating the first tab...");
+  let tab1 = gBrowser.addTab(url);
+  let browser1 = gBrowser.getBrowserForTab(tab1);
+  yield BrowserTestUtils.browserLoaded(browser1);
+
+  info("Creating the second tab...");
+  let tab2 = gBrowser.addTab(url);
+  let browser2 = gBrowser.getBrowserForTab(tab2);
+  yield BrowserTestUtils.browserLoaded(browser2);
+
+  let sw = BASE_URI + "server_multie10s_update.sjs";
+
+  info("Let's start the test...");
+  let status = yield ContentTask.spawn(browser1, sw, function(url) {
+    // Registration of the SW
+    return content.navigator.serviceWorker.register(url)
+
+    // Activation
+    .then(function(r) {
+      return new content.window.Promise(resolve => {
+        let worker = r.installing;
+        worker.addEventListener('statechange', () => {
+          if (worker.state === 'installed') {
+            resolve(true);
+          }
+        });
+      });
+    })
+
+    // Waiting for the result.
+    .then(() => {
+      return new content.window.Promise(resolve => {
+        let results = [];
+        let bc = new content.window.BroadcastChannel('result');
+        bc.onmessage = function(e) {
+          results.push(e.data);
+          if (results.length != 2) {
+            return;
+          }
+
+          resolve(results[0] + results[1]);
+        }
+
+        // Let's inform the tabs.
+        bc = new content.window.BroadcastChannel('start');
+        bc.postMessage('go');
+      });
+    });
+  });
+
+  if (status == 0) {
+    ok(false, "both succeeded. This is wrong.");
+  } else if (status == 1) {
+    ok(true, "one succeded, one failed. This is good.");
+  } else {
+    ok(false, "both failed. This is definitely wrong.");
+  }
+
+  yield BrowserTestUtils.removeTab(tab1);
+  yield BrowserTestUtils.removeTab(tab2);
+});
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/file_multie10s_update.html
@@ -0,0 +1,34 @@
+<html>
+<body>
+<script>
+
+var bc = new BroadcastChannel('start');
+bc.onmessage = function(e) {
+  // This message is not for us.
+  if (e.data != 'go') {
+    return;
+  }
+
+  // It can happen that we don't have the registrations yet. Let's try with a
+  // timeout.
+  function proceed() {
+    return navigator.serviceWorker.getRegistrations().then(regs => {
+      if (regs.length == 0) {
+        setTimeout(proceed, 200);
+        return;
+      }
+
+      bc = new BroadcastChannel('result');
+      regs[0].update().then(() => {
+        bc.postMessage(0);
+      }, () => {
+        bc.postMessage(1);
+      });
+    });
+  }
+
+  proceed();
+}
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/server_multie10s_update.sjs
@@ -0,0 +1,12 @@
+function handleRequest(request, response)
+{
+  response.processAsync();
+  response.setHeader("Content-Type", "application/javascript", false);
+
+  timer = Components.classes["@mozilla.org/timer;1"].
+          createInstance(Components.interfaces.nsITimer);
+  timer.init(function() {
+    response.write("42");
+    response.finish();
+  }, 3000, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
+}