test_self_update_worker.html (5008B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 Test that a self updating service worker can't keep running forever when the 5 script changes. 6 7 - self_update_worker.sjs is a stateful server-side js script that returns a 8 SW script with a different version every time it's invoked. (version=1..n) 9 - The SW script will trigger an update when it reaches the activating state, 10 which, if not for the update delaying mechanism, would result in an iterative 11 cycle. 12 - We currently delay registration.update() calls originating from SWs not currently 13 controlling any clients. The delay is: 0s, 30s, 900s etc, but for the purpose of 14 this test, the delay is: 0s, infinite etc. 15 - We assert that the SW script never reaches version 3, meaning it will only 16 successfully update once. 17 - We give the worker reasonable time to self update by repeatedly registering 18 and unregistering an empty service worker. 19 --> 20 <head> 21 <title>Test for Bug 1432846</title> 22 <script src="/tests/SimpleTest/SimpleTest.js"></script> 23 <script src="error_reporting_helpers.js"></script> 24 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 25 <meta http-equiv="Content-type" content="text/html;charset=UTF-8"> 26 </head> 27 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1432846">Mozilla Bug 1432846</a> 28 <p id="display"></p> 29 <div id="content" style="display: none"> 30 31 </div> 32 <pre id="test"> 33 </pre> 34 35 <script src="utils.js"></script> 36 <script class="testbody" type="text/javascript"> 37 add_task(function setupPrefs() { 38 return SpecialPowers.pushPrefEnv({"set": [ 39 ["dom.serviceWorkers.enabled", true], 40 ["dom.serviceWorkers.testing.enabled", true], 41 ]}); 42 }); 43 44 function activateDummyWorker() { 45 return navigator.serviceWorker.register("empty.js", 46 { scope: "./empty?random=" + Date.now() }) 47 .then(function(registration) { 48 var worker = registration.installing; 49 return waitForState(worker, 'activated', registration).then(function() { 50 ok(true, "got dummy!"); 51 return registration.unregister(); 52 }); 53 }); 54 } 55 56 add_task(async function test_update() { 57 navigator.serviceWorker.onmessage = function(event) { 58 ok (event.data.version < 3, "Service worker updated too many times." + event.data.version); 59 } 60 61 await SpecialPowers.pushPrefEnv({"set": [ 62 ["dom.serviceWorkers.update_delay", 30000], 63 ["dom.serviceWorkers.idle_extended_timeout", 299999]]}); 64 65 // clear version counter 66 await fetch("self_update_worker.sjs?clearcounter"); 67 68 var worker; 69 let registration = await navigator.serviceWorker.register( 70 "self_update_worker.sjs", 71 { scope: "./test_self_update_worker.html?random=" + Date.now()}) 72 .then(function(reg) { 73 worker = reg.installing; 74 // We can't wait for 'activated' here, since it's possible for 75 // the update process to kill the worker before it activates. 76 // See: https://github.com/w3c/ServiceWorker/issues/1285 77 return waitForState(worker, 'activating', reg); 78 }); 79 80 // We need to wait a reasonable time to give the self updating worker a chance 81 // to change to a newer version. Register and activate an empty worker 5 times. 82 for (i = 0; i < 5; i++) { 83 await activateDummyWorker(); 84 } 85 86 87 await registration.unregister(); 88 await SpecialPowers.popPrefEnv(); 89 await SpecialPowers.popPrefEnv(); 90 }); 91 92 // Test variant to ensure that we properly keep the timer alive by having a 93 // non-zero but small timer duration. In this case, the delay is simply our 94 // exponential growth rate of 30, so if we end up getting to version 4, that's 95 // okay and the test may need to be updated. 96 add_task(async function test_delay_update() { 97 let version; 98 navigator.serviceWorker.onmessage = function(event) { 99 ok (event.data.version <= 3, "Service worker updated too many times." + event.data.version); 100 version = event.data.version; 101 } 102 103 await SpecialPowers.pushPrefEnv({"set": [ 104 ["dom.serviceWorkers.update_delay", 1], 105 ["dom.serviceWorkers.idle_extended_timeout", 299999]]}); 106 107 // clear version counter 108 await fetch("self_update_worker.sjs?clearcounter"); 109 110 var worker; 111 let registration = await navigator.serviceWorker.register( 112 "self_update_worker.sjs", 113 { scope: "./test_self_update_worker.html?random=" + Date.now()}) 114 .then(function(reg) { 115 worker = reg.installing; 116 // We can't wait for 'activated' here, since it's possible for 117 // the update process to kill the worker before it activates. 118 // See: https://github.com/w3c/ServiceWorker/issues/1285 119 return waitForState(worker, 'activating', reg); 120 }); 121 122 // We need to wait a reasonable time to give the self updating worker a chance 123 // to change to a newer version. Register and activate an empty worker 5 times. 124 for (i = 0; i < 5; i++) { 125 await activateDummyWorker(); 126 } 127 128 is(version, 3, "Service worker version should be 3."); 129 130 await registration.unregister(); 131 await SpecialPowers.popPrefEnv(); 132 await SpecialPowers.popPrefEnv(); 133 }); 134 </script> 135 </body> 136 </html>