Service Worker: Fix getRegistrations.html layout test.

Serialize the registration and unregistration sequence between top-level window
and its iframe so that the registration object in the iframe cannot be
derefenced before created.

Also this CL improves the performace of the registration purging operations at
the beginning of the test by using Promise.all(unreg_promises) instead of
serializing the promises. It should be noted that registration.unregister() 
promises resolve before the corresponding registrations are actually deleted 
from the storage as per spec: https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#unregister-algorithm.
Thus this test made the registration purging step be waiting until the 
corresponding registrations are actually deleted from the storage.

BUG=502125

Review URL: https://codereview.chromium.org/1210883002

git-svn-id: svn://svn.chromium.org/blink/trunk@197899 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent d045bf2b
......@@ -214,4 +214,3 @@ crbug.com/498539 inspector/sources/debugger-step/debugger-step-into-async1.html
crbug.com/498539 inspector/sources/debugger-step/debugger-step-into-async2.html [ Slow ]
crbug.com/485428 [ Debug ] css3/filters/huge-region.html [ Slow ]
crbug.com/503175 http/tests/serviceworker/getregistrations.html [ Slow ]
......@@ -424,7 +424,6 @@ crbug.com/433727 [ XP ] http/tests/cachestorage/serviceworker/cache-put.html [ P
crbug.com/503175 [ Linux Win ] http/tests/fetch/serviceworker/request-base-https-other-https.html [ Pass Failure ]
crbug.com/503175 [ Linux Win ] http/tests/fetch/serviceworker/request.html [ Pass Failure ]
crbug.com/503175 http/tests/serviceworker/getregistrations.html [ Pass Failure ]
crbug.com/503175 [ Linux Win ] http/tests/fetch/window/request-base-https-other-https.html [ Pass Failure ]
# Untriaged Linux-specific Aura failures
......@@ -1726,7 +1725,7 @@ crbug.com/450493 [ Win ] inspector/console/console-trace-arguments.html [ Failur
crbug.com/450493 [ Win ] virtual/threaded/fast/scroll-behavior/subframe-interrupted-scroll.html [ Failure Pass ]
# Very flaky on Win Debug since it was last updated in r191233
crbug.com/461903 [ Win Debug ] media/encrypted-media/encrypted-media-waiting-for-a-key.html [ Pass Failure ]
crbug.com/461903 [ Win Debug ] media/encrypted-media/encrypted-media-waiting-for-a-key.html [ Pass Failure ]
# Slow expected on debug builds
crbug.com/445194 [ Debug ] fast/dom/shadow/focus-controller-recursion-crash.html [ Skip ]
......@@ -10,26 +10,31 @@
// getRegistrations() is used in order to avoid adding additional complexity
// e.g. adding an internal function.
sequential_promise_test(function(t) {
return navigator.serviceWorker.getRegistrations()
.then(function(registrations) {
return registrations.reduce(function(sequence, registration) {
return sequence.then(function() {
return registration.unregister();
});
}, Promise.resolve());
var resolve;
var timer;
var p = new Promise(function(r) { resolve = r; });
navigator.serviceWorker.getRegistrations()
.then(function(regs) {
return Promise.all(regs.map(function(r) { r.unregister(); }));
})
.then(function() {
// As registration.unregister() promises resolve before the
// corresponding registrations are deleted from the storage, we must
// wait until the registrations are actually removed from the storage.
// Spec reference: https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#unregister-algorithm
timer = setInterval(function() {
navigator.serviceWorker.getRegistrations()
.then(function(regs) {
if (regs.length == 0) {
clearInterval(timer);
resolve();
}
});
}, 100);
});
return p;
}, 'Purge the existing registrations.');
sequential_promise_test(function(t) {
return navigator.serviceWorker.getRegistrations()
.then(function(value) {
assert_array_equals(
value,
[],
'getRegistrations should resolve with an empty array.');
});
}, 'getRegistrations');
sequential_promise_test(function(t) {
var scope = 'resources/scope/getregistrations/normal';
var script = 'resources/empty-worker.js';
......@@ -93,8 +98,8 @@ sequential_promise_test(function(t) {
}, 'Register then Unregister then getRegistrations');
sequential_promise_test(function(t) {
// Top-level window's origin is http://127.0.0.1:8000
// Set frame's origin to http://localhost:8000
// Top-level window's origin: http://127.0.0.1:8000.
// Frame's origin: http://localhost:8000.
var host_info = get_host_info();
var frame_url = host_info['HTTP_REMOTE_ORIGIN'] +
'/serviceworker/resources/frame-for-getregistrations.html';
......@@ -105,32 +110,34 @@ sequential_promise_test(function(t) {
return with_iframe(frame_url)
.then(function(f) {
// frame registered its registration scoped
// http://localhost:8000/serviceworker/resources/scope-for-getregistrations
frame = f;
// Top-level window registers its registration scoped
// http://127.0.0.1:8000/serviceworker/resources/scope-for-getregistrations
return service_worker_unregister_and_register(t, script, scope);
})
.then(function(r) {
registrations.push(r);
return navigator.serviceWorker.getRegistrations();
})
.then(function(value) {
assert_array_equals(
value,
registrations,
'getRegistrations should only return same origin registrations.');
var channel = new MessageChannel();
var resolve;
var p = new Promise(function(r) { resolve = r; });
var channel = new MessageChannel();
channel.port1.onmessage = function(e) {
if (e.data == 'unregistered')
// Frame's registration is registered.
if (e.data == 'registered') {
// Top-level window registers a registration scoped
// http://127.0.0.1:8000/serviceworker/resources/scope-for-getregistrations.
service_worker_unregister_and_register(t, script, scope)
.then(function(r) {
registrations.push(r);
return navigator.serviceWorker.getRegistrations();
})
.then(function(value) {
assert_array_equals(value, registrations,
'getRegistrations should return only the same origin ' +
'registrations.');
channel.port1.postMessage('unregister');
});
} else if (e.data == 'unregistered') {
resolve();
}
};
frame.contentWindow.postMessage('unregister', '*', [channel.port2]);
frame.contentWindow.postMessage('register', '*', [channel.port2]);
return p;
})
.then(function() {
......
......@@ -4,16 +4,27 @@
var scope = 'scope-for-getregistrations';
var script = 'empty-worker.js';
var registration;
navigator.serviceWorker.register(script, { scope: scope })
.then(function(r) { registration = r; });
var port;
self.onmessage = function(e) {
if (e.data == 'unregister') {
registration.unregister()
.then(function() {
e.ports[0].postMessage('unregistered');
});
if (e.data == 'register') {
port = e.ports[0];
port.onmessage = function(e) {
if (e.data == 'unregister') {
registration.unregister()
.then(function() {
port.postMessage('unregistered');
});
}
};
}
// Frame registers a registration scoped
// http://localhost:8000/serviceworker/resources/scope-for-getregistrations
navigator.serviceWorker.register(script, { scope: scope })
.then(function(r) {
registration = r;
e.ports[0].postMessage('registered');
});
};
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment