Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Unified Diff: third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/usecounter.html

Issue 2658603003: ServiceWorker: Enable UseCounter for ServiceWorkerGlobalScope (Closed)
Patch Set: int32_t -> uint32_t Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/usecounter.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/usecounter.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/usecounter.html
new file mode 100644
index 0000000000000000000000000000000000000000..9b0f94fbf8a29c2a5d487df58a7026897c5fa9bf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/usecounter.html
@@ -0,0 +1,325 @@
+<!DOCTYPE html>
+<title>Service Worker: UseCounter</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../resources/test-helpers.js"></script>
+<script>
+
+const kFeature = 675; // From UseCounter.h
+const kDeprecatedFeature = 538; // From Deprecation.h
+
+function isUseCounted(win, feature) {
+ return win.internals.isUseCounted(win.document, feature);
+}
+
+function observeUseCounter(win, feature) {
+ return win.internals.observeUseCounter(win.document, feature);
+}
+
+// Use a window instead of an iframe because UseCounter is shared among frames
+// in a document and these tests cannot be conducted in such an environment.
+// A window has its own UseCounter.
+function openWindow(url) {
+ return new Promise(resolve => {
+ let win = window.open(url, '_blank');
+ add_completion_callback(() => win.close());
+ window.onmessage = e => {
+ assert_equals(e.data, 'LOADED');
+ resolve(win);
+ };
+ });
+}
+
+promise_test(t => {
+ const kUrl = 'resources/usecounter-worker.js';
+ const kScope = 'resources/usecounter-window.html?basic';
+ let worker;
+ let win1;
+ let win2;
+
+ return service_worker_unregister_and_register(t, kUrl, kScope)
+ .then(registration => {
+ add_completion_callback(function() { registration.unregister(); });
+ worker = registration.installing;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(() => { return openWindow(kScope); })
+ .then(win => {
+ win1 = win;
+ return openWindow(kScope);
+ })
+ .then(win => {
+ win2 = win;
+
+ assert_false(isUseCounted(win1, kFeature));
+ assert_false(isUseCounted(win2, kFeature));
+
+ // Request to count a feature.
+ worker.postMessage({type: 'COUNT_FEATURE', feature: kFeature});
+ return Promise.all([
+ observeUseCounter(win1, kFeature),
+ observeUseCounter(win2, kFeature)
+ ]);
+ })
+ .then(() => {
+ // API use on ServiceWorkerGlobalScope should be recorded in all
+ // controlled windows.
+ assert_true(isUseCounted(win1, kFeature));
+ assert_true(isUseCounted(win2, kFeature));
+
+ assert_false(isUseCounted(win1, kDeprecatedFeature));
+ assert_false(isUseCounted(win2, kDeprecatedFeature));
+
+ // Request to count a deprecated feature.
+ worker.postMessage(
+ {type: 'COUNT_DEPRECATION', feature: kDeprecatedFeature});
+ return Promise.all([
+ observeUseCounter(win1, kDeprecatedFeature),
+ observeUseCounter(win2, kDeprecatedFeature)
+ ]);
+ })
+ .then(() => {
+ // Deprecated API use on ServiceWorkerGlobalScope should be recorded
+ // in all controlled windows.
+ assert_true(isUseCounted(win1, kDeprecatedFeature));
+ assert_true(isUseCounted(win2, kDeprecatedFeature));
+
+ return openWindow(kScope);
+ })
+ .then(win => {
+ assert_true(isUseCounted(win, kFeature));
+ assert_true(isUseCounted(win, kDeprecatedFeature));
+ });
+ }, 'UseCounter on ServiceWorkerGlobalScope');
+
+promise_test(t => {
+ const kUrl = 'resources/usecounter-worker.js';
+ const kScope = 'resources/usecounter-window.html?claim';
+ let worker;
+ let win1;
+ let win2;
+
+ return openWindow(kScope)
+ .then(win => {
+ win1 = win;
+ return openWindow(kScope);
+ })
+ .then(win => {
+ win2 = win;
+ return service_worker_unregister_and_register(t, kUrl, kScope)
+ })
+ .then(registration => {
+ add_completion_callback(function() { registration.unregister(); });
+ worker = registration.installing;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(() => {
+ // Request to count a feature.
+ worker.postMessage({type: 'COUNT_FEATURE', feature: kFeature});
+ return new Promise(resolve => {
+ navigator.serviceWorker.onmessage = resolve;
+ // There is no way to verify that API use is never counted. As a
+ // workaround, wait for only one round-trip.
+ worker.postMessage({type: 'PING'});
+ });
+ })
+ .then(e => {
+ assert_equals(e.data.type, 'PONG');
+
+ // API use on ServiceWorkerGlobalScope should not be recorded in
+ // windows because they are not controlled yet.
+ assert_false(isUseCounted(win1, kFeature));
+ assert_false(isUseCounted(win2, kFeature));
+
+ // Request to count a deprecated feature.
+ worker.postMessage(
+ {type: 'COUNT_DEPRECATION', feature: kDeprecatedFeature});
+ return new Promise(resolve => {
+ navigator.serviceWorker.onmessage = resolve;
+ // There is no way to verify that API use is never counted. As a
+ // workaround, wait for only one round-trip.
+ worker.postMessage({type: 'PING'});
+ });
+ })
+ .then(e => {
+ assert_equals(e.data.type, 'PONG');
+
+ // Deprecated API use on ServiceWorkerGlobalScope should not be
+ // recorded in windows because they are not controlled yet.
+ assert_false(isUseCounted(win1, kDeprecatedFeature));
+ assert_false(isUseCounted(win2, kDeprecatedFeature));
+
+ assert_equals(win1.navigator.serviceWorker.controller, null);
+ assert_equals(win2.navigator.serviceWorker.controller, null);
+
+ // Request to claim.
+ return new Promise(resolve => {
+ navigator.serviceWorker.onmessage = resolve;
+ worker.postMessage({type: 'CLAIM'});
+ });
+ })
+ .then(e => {
+ assert_equals(e.data.type, 'CLAIMED');
+ assert_false(e.data.restarted);
+ assert_not_equals(win1.navigator.serviceWorker.controller, null);
+ assert_not_equals(win2.navigator.serviceWorker.controller, null);
+
+ // The windows are now controlled by the service worker. Their
+ // UseCounter should be synchronized with worker's counter.
+ assert_true(isUseCounted(win1, kFeature));
+ assert_true(isUseCounted(win2, kFeature));
+ assert_true(isUseCounted(win1, kDeprecatedFeature));
+ assert_true(isUseCounted(win2, kDeprecatedFeature));
+ });
+ }, 'UseCounter on ServiceWorkerGlobalScope - A use counter owned by newly ' +
+ 'controlled window should be synchronized with worker\'s counter');
+
+// Test that features used during service worker installation are persisted.
+// This test could be non-deterministic because there is no handy way to
+// sweep out on-memory representation of ServiceWorker in the browser process
+// and make sure to restore it from the storage.
+promise_test(t => {
+ const kUrl = 'resources/usecounter-worker.js';
+ const kScope = 'resources/usecounter-window.html' +
+ '?type=features-during-install' +
+ '&feature=' + kFeature +
+ '&deprecated=' + kDeprecatedFeature;
+ let worker;
+ let win1;
+ let win2;
+
+ return openWindow(kScope)
+ .then(win => {
+ win1 = win;
+ return openWindow(kScope);
+ })
+ .then(win => {
+ win2 = win;
+ // A service worker will call some APIs during the install event.
+ return service_worker_unregister_and_register(t, kUrl, kScope)
+ })
+ .then(registration => {
+ add_completion_callback(function() { registration.unregister(); });
+ worker = registration.installing;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(e => {
+ assert_equals(win1.navigator.serviceWorker.controller, null);
+ assert_equals(win2.navigator.serviceWorker.controller, null);
+
+ // API use on ServiceWorkerGlobalScope should not be recorded in
+ // windows because they are not controlled yet.
+ assert_false(isUseCounted(win1, kFeature));
+ assert_false(isUseCounted(win2, kFeature));
+ assert_false(isUseCounted(win1, kDeprecatedFeature));
+ assert_false(isUseCounted(win2, kDeprecatedFeature));
+
+ // Terminate the service worker.
+ internals.terminateServiceWorker(worker);
+
+ // Request to claim. This will restart the service worker.
+ return new Promise(resolve => {
+ navigator.serviceWorker.onmessage = resolve;
+ worker.postMessage({type: 'CLAIM'});
+ });
+ })
+ .then(e => {
+ assert_equals(e.data.type, 'CLAIMED');
+ assert_true(e.data.restarted);
+ assert_not_equals(win1.navigator.serviceWorker.controller, null);
+ assert_not_equals(win2.navigator.serviceWorker.controller, null);
+
+ // The windows are now controlled by the service worker. Their
+ // UseCounter should be synchronized with worker's counter retrieved
+ // from the storage.
+ assert_true(isUseCounted(win1, kFeature));
+ assert_true(isUseCounted(win2, kFeature));
+ assert_true(isUseCounted(win1, kDeprecatedFeature));
+ assert_true(isUseCounted(win2, kDeprecatedFeature));
+ });
+ }, 'UseCounter on ServiceWorkerGlobalScope - counts during the install ' +
+ 'event should be persisted');
+
+// TODO(nhiroki): Test that features used after service worker installation are
+// not persisted. This could be impossible because there is no handy way to
+// sweep out on-memory representation of ServiceWorker in the browser process
+// and make sure to restore it from the storage.
+
+promise_test(t => {
+ const kUrl = 'resources/usecounter-worker.js';
+ const kScope = 'resources/usecounter-window.html?type=skip-waiting';
+ let worker1;
+ let worker2;
+ let win1;
+ let win2;
+
+ return service_worker_unregister_and_register(t, kUrl, kScope)
+ .then(registration => {
+ add_completion_callback(function() { registration.unregister(); });
+ worker1 = registration.installing;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(() => { return openWindow(kScope); })
+ .then(win => {
+ win1 = win;
+ assert_false(isUseCounted(win1, kFeature));
+
+ // Request to count a feature.
+ worker1.postMessage({type: 'COUNT_FEATURE', feature: kFeature});
+ return observeUseCounter(win1, kFeature);
+ })
+ .then(e => {
+ // API use on ServiceWorkerGlobalScope should be recorded in a
+ // controlled window.
+ assert_true(isUseCounted(win1, kFeature));
+
+ // Update a controller using skipWaiting().
+ return navigator.serviceWorker.register(
+ kUrl + '?skip-waiting', {scope: kScope});
+ })
+ .then(registration => {
+ add_completion_callback(function() { registration.unregister(); });
+ worker2 = registration.installing;
+ // Wait until the new worker gets activated.
+ return wait_for_state(t, worker2, 'activated');
+ })
+ .then(() => { return openWindow(kScope); })
+ .then(win => {
+ // This window wasn't controlled by the previous worker.
+ win2 = win;
+ assert_not_equals(win2.navigator.serviceWorker.controller, undefined);
+
+ // An updated worker does not take over the previous counter, so API
+ // use on the previous worker should not be recorded in the newly
+ // controlled window.
+ assert_true(isUseCounted(win1, kFeature));
+ assert_false(isUseCounted(win2, kFeature));
+
+ assert_false(isUseCounted(win1, kDeprecatedFeature));
+ assert_false(isUseCounted(win2, kDeprecatedFeature));
+
+ // Request to count a deprecated feature.
+ worker2.postMessage(
+ {type: 'COUNT_DEPRECATION', feature: kDeprecatedFeature});
+ return Promise.all([
+ observeUseCounter(win1, kDeprecatedFeature),
+ observeUseCounter(win2, kDeprecatedFeature)
+ ]);
+ })
+ .then(e => {
+ // Deprecated API use on the updated worker should be recorded in
+ // all controlled windows.
+ assert_true(isUseCounted(win1, kFeature));
+ assert_false(isUseCounted(win2, kFeature));
+ assert_true(isUseCounted(win1, kDeprecatedFeature));
+ assert_true(isUseCounted(win2, kDeprecatedFeature));
+ });
+ }, 'UseCounter on ServiceWorkerGlobalScope - an updated worker should not ' +
+ 'take over a previous counter');
+
+// TODO(nhiroki): Test a case where ServiceWorker controls SharedWorker that is
+// connected from multiple windows. In such a case, API use on ServiceWorker
+// should be propagated to all connecting windows via SharedWorker.
+
+</script>
+</html>

Powered by Google App Engine
This is Rietveld 408576698