blob: dfe7b5a0cdf70aadf1b64220da81fe43763dfc5d [file] [log] [blame]
<!DOCTYPE html>
<script src="/js-test-resources/js-test.js"></script>
<script src="resources/test-helpers.js"></script>
<script>
window.jsTestIsAsync = true;
description('Test that ServiceWorker and ServiceWorkerRegistration are not garbage collected prematurely');
var registrationObservation = null;
var swObservation = null;
var scope = base_path() + 'resources/gc';
if (!window.internals) {
testFailed('This test requires internals.observeGC');
finishJSTest();
} else {
setup();
}
function setup() {
var worker = 'resources/empty-worker.js';
unregisterAndRegister(worker, scope).then(onRegister);
}
function unregisterAndRegister(url, scope) {
return navigator.serviceWorker.getRegistration(scope)
.then(function(registration) {
if (registration)
return registration.unregister();
})
.then(function() {
return navigator.serviceWorker.register(url, { scope: scope });
})
.catch(function(error) {
testFailed('Could not register worker: ' + error);
finishJSTest();
});
}
function onRegister(registration) {
registrationObservation = internals.observeGC(registration);
registration.addEventListener('updatefound', (function() {
onUpdate(registration.installing);
}));
}
function onUpdate(sw) {
swObservation = internals.observeGC(sw);
sw.addEventListener('statechange', onStateChange);
}
function onStateChange(event) {
// Use setTimeout to ensure a fresh stack with no references to the worker.
switch (event.target.state) {
case 'activated':
setTimeout(unregister, 0);
break;
case 'redundant':
setTimeout(finish, 0);
break;
}
}
function unregister() {
// The worker has an event handler that can still receive the state change
// to 'redundant', so it shouldn't be collected yet.
gc();
shouldBeFalse('registrationObservation.wasCollected');
shouldBeFalse('swObservation.wasCollected');
navigator.serviceWorker.getRegistration(scope)
.then(function(registration) {
registration.unregister();
})
.catch(function(error) {
testFailed('Could not unregister worker: ' + error);
finishJSTest();
});
}
function finish()
{
// The worker is 'redundant' but the registration holds a reference to it,
// so it shouldn't be collected yet.
// FIXME: When crbug.com/398355 is fixed, register a new script URL and
// once the new worker is activated, check that the old worker is gc'd.
gc();
shouldBeFalse('registrationObservation.wasCollected');
shouldBeFalse('swObservation.wasCollected');
finishJSTest();
}
</script>