summaryrefslogtreecommitdiffstats
path: root/dom/serviceworkers/test/test_self_update_worker.html
blob: d6d4544dd924b3842c11420714008b2359ebcc60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<!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>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1432846">Mozilla Bug 1432846</a>
<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.
      // See: https://github.com/w3c/ServiceWorker/issues/1285
      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.
      // See: https://github.com/w3c/ServiceWorker/issues/1285
      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>