Repository navigation
Conversation
There was a problem hiding this comment.
Code Review
This pull request modifies the teardown callback in TestDefaultBinaryMessenger to conditionally close the StreamController if it is not already closed, and introduces tests to verify that the closure of MockStreamHandlerEventSink does not hang. The feedback suggests simplifying the teardown callback by returning the Future directly instead of using async/await.
Apply PR suggestion. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
endOfStream on a MockStreamHandlerEventSink causes widget tests to hangendOfStream on a MockStreamHandlerEventSink causing widget tests to hang
Co-authored-by: Victor Sanni <[email protected]>
Co-authored-by: Victor Sanni <[email protected]>
Remove redundant initialization call.
|
Thank you for the review @victorsanni - I have accepted/applied your suggestions. :) |
Renzo-Olivares
left a comment
There was a problem hiding this comment.
This seems reasonable to me, though is the real root cause that the returned Future is complete but tagged with the test's Fake async zone which is no longer present during the tearDown phase, rather than it never completes?
| final controller = StreamController<Object?>(); | ||
| addTearDown(controller.close); | ||
| addTearDown(() { | ||
| if (!controller.isClosed) { |
There was a problem hiding this comment.
nit: Add a comment to this guard detailing why it is needed.
| const EventChannel( | ||
| kTestEventChannelName, | ||
| ).receiveBroadcastStream({'close': true}).listen((_) {}); | ||
| }, timeout: const Timeout(Duration(seconds: 1))); |
|
This pull request is being closed because it has not been updated in the last 21 days after a request for more information. If you are still working on this, please feel free to reopen it or file a new pull request. Thanks for your contribution. |
…r#196110) Fixes flutter#190807 This continues flutter#190808 by @SamJakob, which was approved and then closed by the bot while it waited for a reply. It has the same fix, with the review comments on flutter#190808 applied. `TestDefaultBinaryMessenger.setMockStreamHandler` adds `controller.close` as a tear down. If the handler already closed the stream, for example with `MockStreamHandlerEventSink.endOfStream` in a `testWidgets` body, tear down calls `close()` again and waits for the returned future. Tear down then does not finish, and the test times out. The fix closes the controller in tear down only if it is not closed. About the question on flutter#190808: yes, the future completes. The zone is the cause. I checked this with a temporary probe in the tear down (not part of this PR): - The done future of the controller completes during the `testWidgets` body, in the fake async zone. - In tear down, `isClosed` is true, and `close()` returns the same done future. - A `then` callback that tear down adds to this future does not run, also after 2 seconds of real time. A completed `_Future` schedules its listeners as microtasks in its own zone (`_addListener` in `future_impl.dart`). That zone is the fake async zone, and nothing flushes its microtasks after the body ends. So tear down waits forever. The comment on the guard says this. On the other review comments on flutter#190808: - The guard has a comment that says why it is necessary. - The test uses a 5 second timeout (not 1 second), so that a hang fails fast and a slow bot does not make the test flaky. Tests: - New regression test in `test_default_binary_messenger_test.dart`. Without the fix it fails with `TimeoutException after 0:00:05`. With the fix it passes. - `packages/flutter_test` tests and `packages/flutter/test/services` tests pass. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant in-code documentation (doc comments with `///`). No public API changed. - [ ] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). This PR does not add a feature. - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. The `flutter_test` and `flutter/test/services` tests pass locally. The other tests run only in CI. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [AI contribution guidelines]: https://github.com/flutter/flutter/blob/main/CONTRIBUTING.ai.md [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [flutter/website]: https://github.com/flutter/website [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md --------- Co-authored-by: SamJakob <[email protected]>
This fixes the following issue:
endOfStreamon aMockStreamHandlerEventSinkcauses widget tests to hang #190807Calling
endOfStreamon theMockStreamHandlerEventSinkcauses the test to hang as there is a tear-down method that closes theStreamControllerbacking theEventStream. When theStreamControlleris already closed, theclosemethod returns a future that never completes and thus the test hangs.The regression test serves as a means of reproducing the issue on the current stable/beta versions of Flutter. The first test case (without the close) passes before and after the fix, the latter one times out without the fix.
AI tools were not used in relation to this PR (apart from the gemini-code-assist reviewer).
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.