Skip to content

[iOS] testKeyboardAnimationWillWaitUIThreadVsync is flaky #189352

Description

@cbracken

Overview

testKeyboardAnimationWillWaitUIThreadVsync in FlutterViewControllerTest.mm is flaky. It attempts to verify that the keyboard animation vsync callback is synchronised with the UI thread by blocking that thread with sleep(1) and then asserting that at least ~1 second elapsed before the callback fired. Because the assertion depends on thread scheduling rather than on an observable property of the code, it intermittently fails.

The intent of the test is: post a long-running (sleep(1)) task to the UI thread, trigger a vsync, and assert the keyboard callback does not complete until the UI-thread work has finished — i.e. fulfillTime - startTime >= ~1s.

The problem is that the pass/fail condition is a wall-clock timing assertion coupled to thread scheduling:

  • The keyboard callback is not delivered on the UI task runner. It's delivered via dispatch_async(dispatch_get_main_queue()) (see [FlutterKeyboardInsetManager -setUpKeyboardAnimationVsyncClient:]). The sleep(1) runs on the UI thread, while the callback that records fulfillTime runs on the platform (main) thread.
  • The test relies on a specific interleaving between the sleep task, the display-link registration/trigger, and the main-queue hop to hold fulfillTime back by a full second. That interleaving isn't guaranteed. Under different scheduling — loaded CI machines, thread-pool timing, run-loop servicing order — the measured fulfillTime can end up short of delayTime - epsilon and the assertion fails.
  • Blocking a thread with sleep and asserting on elapsed time is inherently timing-dependent, so the test is sort of racy by design.

I've run into this a fair bit in tweaks to the keyboard manager code, under repeated runs.

We should rewrite the test to assert the contract the code actually implements (asynchronous delivery of the callback) rather than the scheduling-dependent timing, removing the sleep and the wall-clock assertion.

Metadata

Metadata

Assignees

Labels

a: tests"flutter test", flutter_test, or one of our testsc: flakeTests that sometimes, but not always, incorrectly passplatform-iosiOS applications specificallyteam-iosOwned by iOS platform team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions