Skip to content

Use monotonic clock and inclusive lower bounds in dart_async test - #160

Merged
chavic merged 1 commit into
Uniffi-Dart:mainfrom
chavic:fix-async-timing-clock
Sep 2, 2026
Merged

Use monotonic clock and inclusive lower bounds in dart_async test#160
chavic merged 1 commit into
Uniffi-Dart:mainfrom
chavic:fix-async-timing-clock

Conversation

@chavic

@chavic chavic commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What

  • targeting the flaky async time tests
  • measureTime now uses a monotonic Stopwatch instead of DateTime.now().
  • The three lower-bound assertions that used a strict > now use >=, like the rest of the file.

Why

DateTime.now() is the wall clock. NTP can slew or step it on a CI runner during a measurement, so the interval it reports can be shorter than the time that actually elapsed. Rust's thread::sleep never returns early, so the lower-bound failure on #149 (sleep(200) measured as <= 200ms) can only come from the clock, not from the code under test.

A sleep of exactly N ms also truncates to N milliseconds, which fails a strict bound. Two of the three strict bounds sit on a single sleep, so this is latent on any fast runner.

Refs #139.

🤖 Generated with Claude Code

@chavic
chavic requested a review from spacebear21 August 31, 2026 10:58
@chavic chavic changed the title test(dart_async): monotonic clock and inclusive lower bounds Use monotonic clock and inclusive lower bounds in dart_async test Aug 31, 2026
@chavic chavic mentioned this pull request Aug 31, 2026

@spacebear21 spacebear21 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

utACK

Comment on lines +4 to +8
// Uses a monotonic Stopwatch, not DateTime.now(). DateTime.now() is the wall
// clock, which NTP can slew or step during a measurement on a CI runner, so an
// interval it reports can be shorter than the time that actually elapsed. That
// makes a lower-bound assertion fail even though the sleep ran for its full
// duration (#139).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This kind of comment belongs in the commit message, not a code comment (common frustrating pattern from the robots to overly explain things in comments...)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, nice catch, I'll clean it up

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, nice catch, I'll clean it up

…wer bounds

measureTime used DateTime.now(), which is the wall clock. NTP can slew or
step the wall clock on a CI runner during a measurement, so the interval it
reports can be shorter than the time that actually elapsed. Rust's
thread::sleep never returns early, so a lower-bound failure such as the one
on Uniffi-Dart#149 (sleep(200) measured as <= 200ms) can only come from the clock, not
from the code under test. Stopwatch is monotonic and immune to this.

Three lower-bound assertions also used a strict '>' where the rest of the
file uses '>='. A sleep of exactly N ms truncates to N milliseconds and
fails a strict bound, so they are now inclusive.

Local measurements of sleep(200), five runs each with the release cdylib:
uniffi 0.31.2 (main) 202.7-204.2ms, uniffi 0.32 (Uniffi-Dart#149) 202.5-203.0ms. The
distributions are identical, which rules out a runtime change as the cause.

Refs Uniffi-Dart#139.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HDnKiUL8NDSpeaPvyKJeoR
@chavic
chavic force-pushed the fix-async-timing-clock branch from 8b07d78 to 1fd2728 Compare September 2, 2026 08:41
@chavic
chavic merged commit 4a28b64 into Uniffi-Dart:main Sep 2, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants