-
Notifications
You must be signed in to change notification settings - Fork 28
#1363. Tests for yield updated to the current specification #1370
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
Conversation
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.
Language/Statements/Yield_and_Yield_Each/Yield/execution_async_A01_t01.dart
Outdated
Show resolved
Hide resolved
Language/Statements/Yield_and_Yield_Each/Yield/execution_async_A01_t03.dart
Show resolved
Hide resolved
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.
LGTM, but please consider the following as well:
A couple of things are worth considering: In several situations there is an ss.resume()
followed by code which is intended to check that certain lists contain the expected elements. However, it looks like there should be a suspension point before those checks, because otherwise the generator doesn't get a chance to do anything wrong. So maybe await null;
should be added?
Another thing to consider is that delays will make the trybots/buildbots run more slowly. I suspect that it will work just as well to have a simple await null;
in several situations than it does to have a delay of 100 milliseconds. Waiting for an entire second is of course even more disruptive to the bot execution. We could have several await null;
, too.
Expect.listEquals([1], readyToSend); | ||
ss.resume(); | ||
await Future.delayed(Duration(milliseconds: 100)); | ||
Expect.listEquals([1, 2, 3], sent); |
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.
This looks dangerous: I don't think it would be a bug for an implementation to somehow fail to put all those elements into sent
, in spite of the fact that it is probably extremely unlikely.
Perhaps just test that whatever elements are there is a prefix of the whole list?
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.
Changed to
// `sent` may contain not all elements of the stream
sent.forEach((element) {
Expect.isTrue([1, 2, 3].contains(element));
});
Expect.listEquals([1, 2], readyToSend); | ||
Expect.isTrue(sc.isPaused); | ||
ss.resume(); | ||
await Future.delayed(Duration(milliseconds: 100)); |
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.
Same issue as before: In principle, we can't know that other microtasks have actually been scheduled just because there was a delay.
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.
The delay is a timer-delay, so we know that all microtask-based events have been processed.
I'm not sure we promise that buffered non-sync-controller events are delivered using microtasks, but if they're not, it'd probably be zero-timer events.
So, this likely works.
ss.cancel(); | ||
if (!c.isCompleted) { | ||
c.complete(); | ||
} |
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.
Should it not be safe to replace line 49,50,51 by c.complete()
? How would it fail?
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.
Indeed. Fixed. Thank you
await ss.cancel(); | ||
if (!c.isCompleted) { | ||
c.complete(); | ||
} |
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.
Same as previous test: Why not have only c.complete()
?
late StreamSubscription<int> ss; | ||
ss = s.listen((int x) async { | ||
if (!generatorAlive) { | ||
Expect.fail("Generator function must be terminated"); |
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.
Probably Expect.fail("The generator function is unexpectedly not alive")
would be easier to understand.
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.
Changed
Expect.fail("Generator function must be terminated"); | ||
} | ||
if (x == 5) { | ||
// let generator to work some time |
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.
Perhaps // Allow the generator to work for some time.
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.
Changed everywhere
} | ||
if (x == 5) { | ||
// let generator to work some time | ||
Expect.equals(true, generatorAlive); |
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.
Why not Expect.isTrue(generatorAlive)
?
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.
Fixed
finish = false; | ||
Stream<int> s = generator(); | ||
s.listen((int x) async { | ||
finish = (x > 10); // let generator to work some time |
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.
// Allow the generator...
.
finish = false; | ||
Stream<int> s = generator(); | ||
s.listen((int x) { | ||
finish = (x > 10); // let generator to work some time |
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.
// ...
late StreamSubscription<int> ss; | ||
ss = s.listen((int i) async { | ||
// This 'await' returns control back to event loop and generator goes on | ||
await Future.delayed(Duration(milliseconds: 100)); |
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 tried to replace this by await null; await null; await null;
, and it works fine. ;-)
Replacing it by await null; await null;
does not work, and this illustrates that it is directly connected to the number of other tasks we allow the scheduler to handle (except that we're not supposed to assume that we can control the scheduler in any precise manner by doing these things).
If to add a suspension point after the resume it'll chane the expected behavior. Please see dart-lang/sdk#49465 So, when there is no such point it usually means "resume, make sure that nothing was changed immediately after the resume, then check something more meaningful". If you find this check, immediately after
Please rereview |
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.
LGTM!
I didn't understand that the checks after resume
were intended to check the situation without any asynchronous scheduling events. When that's the purpose it is fine.
…art-lang#1370) Authored by @sgrekhov. Tests for yield fixed and updated to the current specification. Completer added to avoid flakiness. Missing asyncStart()/asyncEnd() added. Some delays replaced by `await null;`.
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.
drive-by comments.
if (i == 2) { | ||
Expect.listEquals([1], sent); | ||
Expect.listEquals([1, 2], readyToSend); | ||
ss.resume(); |
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 sure what ss.resume()
should do. The subscription is never paused, so it should be a no-op.
(But if you are just testing that it's a no-op, then it's correct.)
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.
Description of this test
Check that resuming of the [Stream] which was not paused doesn't affect anything
So yes, it's testing that it's no-op
await Future.delayed(Duration(milliseconds: 100)); | ||
// `sent` may contain not all elements of the stream | ||
sent.forEach((element) { | ||
Expect.isTrue([1, 2, 3].contains(element)); |
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.
Seems like a long way of saying element <= 3
.
Not a very telling test - is it possible to fail it at all?
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.
Indeed. Thanks! Please see #1390
await ss.cancel(); | ||
} | ||
}); | ||
await Future.delayed(Duration(seconds: 1)); |
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.
A very long delay, where seconds: 0
would likely give precisely the same result because everything else is microtask based.
(The next variant, using a Completer
, seems much closer to what I'd write for this test.)
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.
The latest version of this test doen't contain this long delay and is based on a Completer
. Please see https://github.com/dart-lang/co19/blob/master/Language/Statements/Yield_and_Yield_Each/Yield/execution_async_A01_t03.dart
Expect.listEquals([1, 2], readyToSend); | ||
Expect.isTrue(sc.isPaused); | ||
ss.resume(); | ||
await Future.delayed(Duration(milliseconds: 100)); |
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.
The delay is a timer-delay, so we know that all microtask-based events have been processed.
I'm not sure we promise that buffered non-sync-controller events are delivered using microtasks, but if they're not, it'd probably be zero-timer events.
So, this likely works.
2022-08-04 [email protected] dart-lang/co19#993. FFI tests refactored and improved (dart-lang/co19#1387) 2022-08-04 [email protected] dart-lang/co19#993. [FFI] Missed tests added for some new types (dart-lang/co19#1386) 2022-08-03 [email protected] Fixes dart-lang/co19#1129. Don't expect any proxy routine in case of DIRECT connection (dart-lang/co19#1383) 2022-08-03 [email protected] dart-lang/co19#993. [FFI] Missed tests added for some new types (dart-lang/co19#1384) 2022-07-29 [email protected] dart-lang/co19#673. IFrame tests that don't actually test IFrame removed (dart-lang/co19#1382) 2022-07-29 [email protected] dart-lang/co19#1363. Some delays removed or reduced (dart-lang/co19#1380) 2022-07-29 [email protected] dart-lang/co19#1363 Async `for-in` test updated according to the current specification (dart-lang/co19#1379) 2022-07-27 [email protected] dart-lang/co19#1363. Yield each tests updated to the current specification (dart-lang/co19#1374) 2022-07-27 [email protected] Fixes dart-lang/co19#1375. Add test for final variable in a for-in loop (dart-lang/co19#1378) 2022-07-25 [email protected] dart-lang/co19#1363. Tests for yield updated to the current specification (dart-lang/co19#1370) Change-Id: Ie92f4b2157284777177012320883247411e214fa Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/254140 Reviewed-by: Erik Ernst <[email protected]> Commit-Queue: Alexander Thomas <[email protected]>
No description provided.