Bug 1262702 Avoid racing with initial shutdown in test_service_worker_lifetime.html. r=kitcambridge
authorBen Kelly <ben@wanderview.com>
Tue, 30 Aug 2016 10:04:27 -0700
changeset 407623 31b100c982b54fe53a548b57e10f67240bc6a011
parent 407622 0a4166cfb9140526aafbb727f149c252f2c691e3
child 407624 8ca77a9ae536d9593fbb7899b2ba5eaa13abf0a7
push id27999
push usercykesiopka.bmo@gmail.com
push dateTue, 30 Aug 2016 17:35:37 +0000
reviewerskitcambridge
bugs1262702
milestone51.0a1
Bug 1262702 Avoid racing with initial shutdown in test_service_worker_lifetime.html. r=kitcambridge
dom/push/test/lifetime_worker.js
dom/push/test/test_serviceworker_lifetime.html
--- a/dom/push/test/lifetime_worker.js
+++ b/dom/push/test/lifetime_worker.js
@@ -40,23 +40,29 @@ function resolvePromise() {
     dump("ERROR: wait promise was not set.\n");
     return;
   }
   resolvePromiseCallback();
   resolvePromiseCallback = null;
 }
 
 onmessage = function(event) {
-  // FIXME(catalinb): we cannot treat these events as extendable
-  // yet. Bug 1143717
-  event.source.postMessage({type: "message", state: state});
+  var lastState = state;
   state = event.data;
-  if (event.data === "release") {
+  if (state === 'wait') {
+    event.waitUntil(new Promise(function(res, rej) {
+      if (resolvePromiseCallback) {
+        dump("ERROR: service worker was already waiting on a promise.\n");
+      }
+      resolvePromiseCallback = res;
+    }));
+  } else if (state === 'release') {
     resolvePromise();
   }
+  event.source.postMessage({type: "message", state: lastState});
 }
 
 onpush = function(event) {
   var pushResolve;
   event.waitUntil(new Promise(function(resolve) {
     pushResolve = resolve;
   }));
 
--- a/dom/push/test/test_serviceworker_lifetime.html
+++ b/dom/push/test/test_serviceworker_lifetime.html
@@ -248,46 +248,60 @@
         // The service worker should be terminated when the promise is resolved.
         .then(checkStateAndUpdate(fetchEvent, "update", "release"))
         .then(waitOnShutdownObserver)
         .then(setShutdownObserver(false))
         .then(closeIframe)
         .then(cancelShutdownObserver)
 
         // Test with push events and message events
+        .then(setShutdownObserver(true))
         .then(createIframe)
+        // Make sure we are shutdown before entering our "no shutdown" sequence
+        // to avoid races.
+        .then(waitOnShutdownObserver)
         .then(setShutdownObserver(false))
         .then(checkStateAndUpdate(pushEvent, "from_scope", "wait"))
+        .then(checkStateAndUpdate(messageEventIframe, "wait", "update"))
+        .then(checkStateAndUpdate(messageEventIframe, "update", "update"))
         .then(setShutdownObserver(true))
-        .then(checkStateAndUpdate(messageEventIframe, "wait", "release"))
+        .then(checkStateAndUpdate(messageEventIframe, "update", "release"))
         .then(waitOnShutdownObserver)
         .then(closeIframe)
     }
   }
 
   var test2 = {
     prefs: [
       ["dom.serviceWorkers.idle_timeout", 0],
       ["dom.serviceWorkers.idle_extended_timeout", 2999999]
     ],
     steps: function(ctx) {
       // Older versions used to terminate workers when the last controlled
       // window was closed.  This should no longer happen, though.  Verify
       // the new behavior.
+      setShutdownObserver(true)(ctx);
       return createIframe(ctx)
-        .then(setShutdownObserver(true))
+        // Make sure we are shutdown before entering our "no shutdown" sequence
+        // to avoid races.
+        .then(waitOnShutdownObserver)
+        .then(setShutdownObserver(false))
         .then(checkStateAndUpdate(fetchEvent, "from_scope", "wait"))
         .then(closeIframe)
         .then(setShutdownObserver(true))
         .then(checkStateAndUpdate(messageEvent, "wait", "release"))
         .then(waitOnShutdownObserver)
 
       // Push workers were exempt from the old rule and should continue to
       // survive past the closing of the last controlled window.
+        .then(setShutdownObserver(true))
         .then(createIframe)
+        // Make sure we are shutdown before entering our "no shutdown" sequence
+        // to avoid races.
+        .then(waitOnShutdownObserver)
         .then(setShutdownObserver(false))
         .then(checkStateAndUpdate(pushEvent, "from_scope", "wait"))
         .then(closeIframe)
         .then(setShutdownObserver(true))
         .then(checkStateAndUpdate(messageEvent, "wait", "release"))
         .then(waitOnShutdownObserver)
     }
   };