Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!DOCTYPE HTML>
<html>
<!--
Test that a self updating service worker can't keep running forever when the
script changes.
- self_update_worker.sjs is a stateful server-side js script that returns a
SW script with a different version every time it's invoked. (version=1..n)
- The SW script will trigger an update when it reaches the activating state,
which, if not for the update delaying mechanism, would result in an iterative
cycle.
- We currently delay registration.update() calls originating from SWs not currently
controlling any clients. The delay is: 0s, 30s, 900s etc, but for the purpose of
this test, the delay is: 0s, infinite etc.
- We assert that the SW script never reaches version 3, meaning it will only
successfully update once.
- We give the worker reasonable time to self update by repeatedly registering
and unregistering an empty service worker.
-->
<head>
<title>Test for Bug 1432846</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="error_reporting_helpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
</head>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
<script src="utils.js"></script>
<script class="testbody" type="text/javascript">
add_task(function setupPrefs() {
return SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
]});
});
function activateDummyWorker() {
return navigator.serviceWorker.register("empty.js",
{ scope: "./empty?random=" + Date.now() })
.then(function(registration) {
var worker = registration.installing;
return waitForState(worker, 'activated', registration).then(function() {
ok(true, "got dummy!");
return registration.unregister();
});
});
}
add_task(async function test_update() {
navigator.serviceWorker.onmessage = function(event) {
ok (event.data.version < 3, "Service worker updated too many times." + event.data.version);
}
await SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.update_delay", 30000],
["dom.serviceWorkers.idle_extended_timeout", 299999]]});
// clear version counter
await fetch("self_update_worker.sjs?clearcounter");
var worker;
let registration = await navigator.serviceWorker.register(
"self_update_worker.sjs",
{ scope: "./test_self_update_worker.html?random=" + Date.now()})
.then(function(reg) {
worker = reg.installing;
// We can't wait for 'activated' here, since it's possible for
// the update process to kill the worker before it activates.
return waitForState(worker, 'activating', reg);
});
// We need to wait a reasonable time to give the self updating worker a chance
// to change to a newer version. Register and activate an empty worker 5 times.
for (i = 0; i < 5; i++) {
await activateDummyWorker();
}
await registration.unregister();
await SpecialPowers.popPrefEnv();
await SpecialPowers.popPrefEnv();
});
// Test variant to ensure that we properly keep the timer alive by having a
// non-zero but small timer duration. In this case, the delay is simply our
// exponential growth rate of 30, so if we end up getting to version 4, that's
// okay and the test may need to be updated.
add_task(async function test_delay_update() {
let version;
navigator.serviceWorker.onmessage = function(event) {
ok (event.data.version <= 3, "Service worker updated too many times." + event.data.version);
version = event.data.version;
}
await SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.update_delay", 1],
["dom.serviceWorkers.idle_extended_timeout", 299999]]});
// clear version counter
await fetch("self_update_worker.sjs?clearcounter");
var worker;
let registration = await navigator.serviceWorker.register(
"self_update_worker.sjs",
{ scope: "./test_self_update_worker.html?random=" + Date.now()})
.then(function(reg) {
worker = reg.installing;
// We can't wait for 'activated' here, since it's possible for
// the update process to kill the worker before it activates.
return waitForState(worker, 'activating', reg);
});
// We need to wait a reasonable time to give the self updating worker a chance
// to change to a newer version. Register and activate an empty worker 5 times.
for (i = 0; i < 5; i++) {
await activateDummyWorker();
}
is(version, 3, "Service worker version should be 3.");
await registration.unregister();
await SpecialPowers.popPrefEnv();
await SpecialPowers.popPrefEnv();
});
</script>
</body>
</html>