Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Service worker: Altering ready test due to resurrection #17203

Merged

Conversation

jakearchibald
Copy link
Contributor

Found another resurrection test.

If I'm reading the spec correctly:

  • When the ready property is accessed, and there's a matching registration with an active service worker. This takes care of clients that were created after the registration was already 'ready'.
  • When a new service worker becomes active, it goes through all clients that would be controlled by this worker if they loaded now, and resolves their ready promise.

Chrome times outs on the first test, which I didn't expect. Firefox & Safari behave as I'd expect (given they implement resurrection).

@jakearchibald
Copy link
Contributor Author

I removed the timeout stuff due to https://web-platform-tests.org/writing-tests/testharness-api.html#timeouts-in-tests

In particular if a test should fail when something doesn’t happen, it is good practice to simply let the test run to the full timeout rather than trying to guess an appropriate shorter timeout to use.

Copy link
Member

@mfalken mfalken left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This lgtm and I agree with your analysis. Curious to figure out why Chrome's timing out here.

@jakearchibald
Copy link
Contributor Author

@foolip I'm not sure how to interpret this failure. What did I break?

@foolip
Copy link
Member

foolip commented Jun 7, 2019

Cause of Taskcluster failures are too hard to figure out , but if you know to look at the end of the logs, here it is:

Unstable results

Test Subtest Results Messages
/service-workers/service-worker/ready.https.html ready on a potential controlled document FAIL: 1/10, PASS: 9/10 assert_equals: uncontrolled document should not have a controller expected null but got object "[object ServiceWorker]"
/service-workers/service-worker/ready.https.html access ready after it has been resolved FAIL: 1/10, PASS: 9/10 assert_equals: matched registration should be returned expected "https://web-platform.test:8443/service-workers/service-worker/resources/blank.html?ready-after-resolve" but got "https://web-platform.test:8443/service-workers/service-worker/resources/blank.html?ready-after-resolve-longer"

Does that failure with "https://web-platform.test:8443/service-workers/service-worker/resources/blank.html?ready-after-resolve-longer" seem like it could be a problem with the setup? Or is it a Firefox bug?

@jakearchibald
Copy link
Contributor Author

Pretty sure this is a Firefox bug. It isn't any of the tests touched in this PR either.

@foolip
Copy link
Member

foolip commented Jun 7, 2019

@jakearchibald can you file a Gecko bug or let the relevant maintainer know? Then I can admin merge this.

@jakearchibald
Copy link
Contributor Author

@foolip foolip merged commit 3fb7ab3 into web-platform-tests:master Jun 7, 2019
@jakearchibald jakearchibald deleted the no-service-worker-resurrection branch June 7, 2019 08:28

const readyReg = await readyPromise;

assert_equals(readyReg.active.scriptURL, reg1Active.scriptURL, 'Resolves with the first registration');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jakearchibald Could you explain where this assumption is coming from?
The way I'd interpret the spec here is that it should be the url of the new worker, which is also how Firefox seems to understand it [1].

In step 4 of the Unregister algorithm [2], we remove the registration from scope to registration map. Step 2.1 of serviceWorker.ready [3] invokes the Match Service Worker Registration algorithm [4], which only looks at registrations that are in scope to registration map. Since there is no non-uninstalled registration at the time we're calling serviceWorker.ready, the Promise should only resolve after the new worker is registered. Hence, we shouln't get the registration we intent to assert against here.

Am I missing something, or is this a bug in the test?

//cc @mattto

[1] https://wpt.fyi/results/service-workers/service-worker/ready.https.html?label=master&label=experimental&aligned&q=service-workers%2Fservice-worker%2Fready.https.html
[2] https://w3c.github.io/ServiceWorker/#unregister-algorithm
[3] https://w3c.github.io/ServiceWorker/#navigator-service-worker-ready
[4] https://w3c.github.io/ServiceWorker/#match-service-worker-registration

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't the promise be resolved earlier, in step 7.2 of https://w3c.github.io/ServiceWorker/#activation-algorithm?

Copy link
Contributor

@Yannic Yannic Oct 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'd be true if we move .ready before line 292.

.ready returns a new Promise every time it's called and runs https://w3c.github.io/ServiceWorker/#match-service-worker-registration to resolve it. Resolving it once after activating and return the same Promise for every call would contradict ready after a longer matched registration registered in this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.ready returns a new Promise every time it's called

That isn't how I interpret the spec. A service worker container has a ready promise, so the promise is created the same time the service worker container is created.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, that's what the spec says. Thanks for the explanation!

With that model, how do we explain that .ready resolves to the second worker here and here? Shouln't it be resolved by the first activation?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oof this isn't how Chrome implements .ready. Chrome doesn't try to resolve the promise until .ready is accessed. Then once it resolves, it always resolves with the same registration. I agree though the spec says to resolve each client's ready promise at activation time.

For the first link, the test matches the spec because frame is created after the activation of the first worker.

For the second link, I think you're right. frame is created, then the first activation occurs, so .ready should resolve to the first registration.

If browsers are all doing the "don't try to figure the value until the property is accessed thing", we could potentially change the spec for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like the spec used to match the implementations. For example, I reference this behavior in this issue:

w3c/ServiceWorker#1278 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants