2 <script src="/js-test-resources/js-test.js"></script>
3 <script src="../resources/test-helpers.js"></script>
5 window.jsTestIsAsync = true;
6 description('Test that ServiceWorker and ServiceWorkerRegistration are not garbage collected prematurely');
7 var registrationObservation = null;
8 var swObservation = null;
9 var scope = base_path() + '../resources/gc';
11 if (!window.internals) {
12 testFailed('This test requires internals.observeGC');
19 var worker = '../resources/empty-worker.js';
20 unregisterAndRegister(worker, scope).then(onRegister);
23 function unregisterAndRegister(url, scope) {
24 return navigator.serviceWorker.getRegistration(scope)
25 .then(function(registration) {
27 return registration.unregister();
30 return navigator.serviceWorker.register(url, { scope: scope });
32 .catch(function(error) {
33 testFailed('Could not register worker: ' + error);
38 function onRegister(registration) {
39 registrationObservation = internals.observeGC(registration);
40 registration.addEventListener('updatefound', (function() {
41 onUpdate(registration.installing);
45 function onUpdate(sw) {
46 swObservation = internals.observeGC(sw);
47 sw.addEventListener('statechange', onStateChange);
50 function onStateChange(event) {
51 // Use setTimeout to ensure a fresh stack with no references to the worker.
52 switch (event.target.state) {
54 setTimeout(unregister, 0);
57 setTimeout(finish, 0);
62 function unregister() {
63 // The worker has an event handler that can still receive the state change
64 // to 'redundant', so it shouldn't be collected yet.
66 shouldBeFalse('registrationObservation.wasCollected');
67 shouldBeFalse('swObservation.wasCollected');
68 navigator.serviceWorker.getRegistration(scope)
69 .then(function(registration) {
70 registration.unregister();
72 .catch(function(error) {
73 testFailed('Could not unregister worker: ' + error);
80 // The worker is 'redundant' but the registration holds a reference to it,
81 // so it shouldn't be collected yet.
82 // FIXME: When crbug.com/398355 is fixed, register a new script URL and
83 // once the new worker is activated, check that the old worker is gc'd.
85 shouldBeFalse('registrationObservation.wasCollected');
86 shouldBeFalse('swObservation.wasCollected');