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
RFC #16 - PRECONDITION_FAILED subtest result (status) #16
RFC #16 - PRECONDITION_FAILED subtest result (status) #16
Conversation
I'm somewhat on the fence about whether this is a good idea. In practice truely optional features are rare and almost always represent compat hazards. We don't want to go out of our way to encouage such optionality. I am concerned about the amount of code that has to change to support this. For example mozlog has to change, and log consumers may also have to change to handle the status in a meaningful way. Of course it's not possible to enumerate the full set of log consumers. In terms of the API, this isn't an assert, it shold be a method on the |
The RFC currently focuses on consumers of test results. You may also want to note that this makes the tests themselves more expressive, allowing authors to be more explicit about their expectations. Currently, tests for proposed specification changes are denoted with a filename pattern ( One nice aspect of implementing this as an assertion is that "failures" will interrupt further testing. Maybe invert the meaning, though. |
While rare (I'm only currently aware of Codecs, and WebCryptoAPI), I still feel like this is an important distinction to make, especially for permanently unimplemented features. WebCryptoAPI, for example, could have a valid implementation that didn't implement any of the encryption algorithms. (IMHO, it's preferable that we achieve interop for the implementations, since this would avoid a web dev needing to worry about which user agents implement which algorithms). We've heard back from Chrome that not supporting AES 192 bit, for example, is working as intended.
Thus, the "FAIL" WebCryptoAPI results aren't really useful as failures (and create unnecessary noise). |
@jugglinmike - nice to hear two sides of the argument. Under further scrutiny, though, I think I side with @jgraham here in that we don't want to encourage people to unnecessarily make spec features optional, so I'm unsure about coupling this change with As I understand, Bailing out (immediately) as a forced test result via |
@foolip - was codecs the only other example you mentioned? Are you aware of other APIs that list optional capabilities? |
@lukebjerring will be OOO for a while, so I suggest we put this on ice until he's back. One option that we could consider is something inspired by what mocha does. There, the context object, which is like our test object, has a test(t => {
if (thingIsntSupported) {
t.skip('maybe a reason here'));
}
}, 'test name'); This aligns with @jgraham's suggestion to use a method and |
@lukebjerring now that you're back, do you want to pick this up again? What do you think about the |
I am currently writing codec related tests for the WebRTC test suite and this feature (or something equivalent) would definitely be useful to convey a better meaning to the test results. I do prefer the |
@lukebjerring https://wpt.fyi/results/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html is the media element codec test I had in mind. It adds "(optional)" to some test names, but unfortunately I don't know that this test would be much improved by a mechanism to skip subtests, as the "is this implemented" check itself is what the test is for. |
I agree with the ergonomics of a |
rfcs/not_implemented.md
Outdated
function(err) { | ||
if ('NotSupportedError' in self && err instanceof NotSupportedError) { | ||
test.skip(algorithm + ' not implemented'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it intentional that the execution continues after the skip()
call in this example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a point of reference, mocha does throw in its this.skip()
:
https://github.com/mochajs/mocha/blob/186ca3657b4d3e0c0a602a500653a695f4e08930/lib/runnable.js#L138
We could do that with a specific error type, or we could treat this as t.done()
and keep going but ignore anything the test does. The difference of course is that it's unlikely there's stuff after t.done()
but very likely there's stuff after t.skip()
.
@lukebjerring WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not intentional (prototype was tweaked to fix that).
@foolip I would expect t.skip
to be the "end of the road" in so far as the test content is concerned, since "ignoring" further execution would be more computationally expensive, and extra code for the testharness.
rfcs/not_implemented.md
Outdated
.then( | ||
function(result) { ... }, | ||
function(err) { | ||
if ('NotSupportedError' in self && err instanceof NotSupportedError) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Presumably this would be a DOMException
and this example code would be broken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're correct. I made some assumptions after skimreading the spec, but on closer inspection, it's a DOMException with no strongly identifiable information :/
@lukebjerring I'm writing a test today that could make use of this. Is there anything I can review to help move this along? |
I commented in the related PR, but I'm somewhat concerned that the approach of reusing |
When disabling tests, isn't the status of the whole test SKIP, rather than of the subtests? |
You can also disable individual subtests (basically meaning that they run but the result is replaced by |
If in understand correctly, there's no overlap between usage of the two features (in-test skip and disable-skip); only a common outcome. There's still a distinguishing message field for the reason they were skipped, and I'd expect you would never disable a skipping subtest as unstable (though I guess we could contrive a badly written test that makes it unstably skip sometimes). Can you give an example of how the feature is used (or point to some docs)? I wasn't aware of it. |
See e.g. https://searchfox.org/mozilla-central/source/testing/web-platform/meta/html/dom/interfaces.https.html.ini#61 which disables that subtest. Actually looking at the code it seems we are just ignoring those tests (see https://searchfox.org/mozilla-central/source/testing/web-platform/tests/tools/wptrunner/wptrunner/testrunner.py#561-562); that's clearly a bug and we should set the status to |
So, we actually started with Is there a way of 'overloading' result types? Like, multiple enum values that use the same numeric value? |
I don't think we can overload result types. Changing |
Naming is only a concern once disambiguation is made a prerequisite. It seems that your need for distinguishing "infra skipped" vs "test skipped" is only theoretical, given that the implementation as-is is omitting the data entirely (which wpt.fyi would show as Another approach, which I understand has come up before, is to support multiple expectations. This is Chromium's approach to ignoring flakiness, and the equivalent here would just be support an What are your thoughts on multi-expectations? |
There is separately work on mutliple expectations happening. But I don't expect it to be a full replacement for disabling tests, so having |
Is there an RFC/PR/bugzilla entry for tracking the work? And yeah that's true, there's still use-cases for disabling tests outside of flakiness, so it won't be a full replacement. In those remaining cases, though, as it stands the behaviour around Given that (due to what you call a bug in the implementation) we're not actually in a position where |
So it seems like this RFC needs to be updated to match the decisions that have been made, but once that's done it should be possible to go ahead and merge it. |
I've updated to reflect the consensus (as I understand it to be). PTAL. |
Renamed file to assert_precondition.md to match the name of the added API surface. |
Since the proposal changed let's leave a little bit more time for people to react, but I think it'd be low risk to start implementing this now across the repos impacted. |
rfcs/assert_precondition.md
Outdated
.then( | ||
function(result) { ... }, | ||
function(err) { | ||
if (isUnsupported(err)) { // "Unsupported" case determined ad-hoc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about
assert_precondition(!isUnsupported(err), algorithm + " not implemented");
assert_unreached("Threw an unexpected error: " + err.toString());
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like collapsing as well, but then we can invert the naming to avoid the negation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear, you're suggesting
assert_precondition(isSupported(err), algorithm + " not implemented");
assert_unreached("Threw an unexpected error: " + err.toString());
? It took me a while to be confident of which part of the naming you wanted to invert.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, isUnsupported
to isSupported
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isUnsupported(err)
makes more sense as a function name ("is this error telling me the feature is unsupported") but supported makes more sense as the param name for the assert... so I made it 3 lines to meet you halfway.
} else { | ||
assert_unreached("Threw an unexpected error: " + err.toString()); | ||
} | ||
var supported = !isUnsupported(err); // "Unsupported" case determined ad-hoc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still agree with @Ms2ger on this one. Most feature detects will be inlined and be "positive" expressions like SharedWorker in self
or navigator.xr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this bikeshedding over an example that doesn't affect the implementation? Or am I missing some reason it's very important to be perfect here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, but isSupported(err)
checks that the error isn't unsupported.. which doesn't make sense.
🚲 And yes, bikeshedding for sure 🚲
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fwiw, I was more concerned about the if (foo) assert(false)
pattern than inlining the condition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was bikeshedding as if this were the documentation and an example people will copy. Happy to leave that scrutiny to the implementation PR and then come back here and update to match how the description needs to be phrased.
Let's merge this and move on to the PR on wpt.
assert_unreached("Threw an unexpected error: " + err.toString()); | ||
} | ||
var supported = !isUnsupported(err); // "Unsupported" case determined ad-hoc | ||
assert_precondition(supported, algorithm + ' not implemented'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realize there's an issue with descriptions that often comes up. Most of the assert methods generate failure message that assume the description describes the actual value or what did happen. But it's somewhat common for people to write descriptions saying what the value shouldn't be or what shouldn't happen. That leads to pretty bad failure messages.
How will the failure message be constructed for this? The prefix "Precondition not met: " would require a positive description of what is (should) be supported, but is that the format you had in mind?
Since it's so easy to get this wrong, a clear example would be great. It'll still be wrong 30% of the time though :)
This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of #16689. Fixes #19844.
This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of #16689. Fixes #19844.
This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of #16689. Fixes #19844.
This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of #16689. Fixes #19844.
This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of #16689. Fixes #19844.
All who participated in this RFC, a review is now up at web-platform-tests/wpt#19993 and I think there are some details worth a second opinion on. I'll add comments on those bits and see if I get any feedback :) |
This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of #16689. Fixes #19844.
This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of #16689. Fixes #19844.
This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of #16689. Fixes #19844.
…ndition`, a=testonly Automatic update from web-platform-tests [testharness.js] introduce `assert_precondition` This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of web-platform-tests/wpt#16689. Fixes web-platform-tests/wpt#19844. -- [vibration] use `assert_precondition` to avoid spurious pass This demonstrates the use of `assert_precondition` for subtests. -- wpt-commits: 17543bc30bdf65838e9ec8e3b3b6fd210dced66e, a90e89fb031b0b357305ac9d874968d8451b1181 wpt-pr: 19993
…ndition`, a=testonly Automatic update from web-platform-tests [testharness.js] introduce `assert_precondition` This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of web-platform-tests/wpt#16689. Fixes web-platform-tests/wpt#19844. -- [vibration] use `assert_precondition` to avoid spurious pass This demonstrates the use of `assert_precondition` for subtests. -- wpt-commits: 17543bc30bdf65838e9ec8e3b3b6fd210dced66e, a90e89fb031b0b357305ac9d874968d8451b1181 wpt-pr: 19993
…ndition`, a=testonly Automatic update from web-platform-tests [testharness.js] introduce `assert_precondition` This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of web-platform-tests/wpt#16689. Fixes web-platform-tests/wpt#19844. -- [vibration] use `assert_precondition` to avoid spurious pass This demonstrates the use of `assert_precondition` for subtests. -- wpt-commits: 17543bc30bdf65838e9ec8e3b3b6fd210dced66e, a90e89fb031b0b357305ac9d874968d8451b1181 wpt-pr: 19993 UltraBlame original commit: 9b458e91114235eb43711dbac7a3acfe30c83fce
…ndition`, a=testonly Automatic update from web-platform-tests [testharness.js] introduce `assert_precondition` This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of web-platform-tests/wpt#16689. Fixes web-platform-tests/wpt#19844. -- [vibration] use `assert_precondition` to avoid spurious pass This demonstrates the use of `assert_precondition` for subtests. -- wpt-commits: 17543bc30bdf65838e9ec8e3b3b6fd210dced66e, a90e89fb031b0b357305ac9d874968d8451b1181 wpt-pr: 19993 UltraBlame original commit: 9b458e91114235eb43711dbac7a3acfe30c83fce
…ndition`, a=testonly Automatic update from web-platform-tests [testharness.js] introduce `assert_precondition` This depends on mozlog 5.0 for the new PRECONDITION_FAILED status: https://bugzilla.mozilla.org/show_bug.cgi?id=1589056 Implements web-platform-tests/rfcs#16. Includes parts of web-platform-tests/wpt#16689. Fixes web-platform-tests/wpt#19844. -- [vibration] use `assert_precondition` to avoid spurious pass This demonstrates the use of `assert_precondition` for subtests. -- wpt-commits: 17543bc30bdf65838e9ec8e3b3b6fd210dced66e, a90e89fb031b0b357305ac9d874968d8451b1181 wpt-pr: 19993 UltraBlame original commit: 9b458e91114235eb43711dbac7a3acfe30c83fce
Rendered