Skip to content

test(interaction-harness): name a touch play the runner starved - #10551

Merged
cixzhang merged 5 commits into
meta:mainfrom
vjeux:test/harness-touch-retake
Nov 9, 2026
Merged

cixzhang merged 5 commits into
meta:mainfrom
vjeux:test/harness-touch-retake

Conversation

@vjeux

@vjeux vjeux commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Maintainer impact

A paced WebKit touch play on a starved runner failed as TouchPacingError, as a harness-stalled dispatch does. A reader could not tell the two apart. The touch pacing self-test failed 20 of 20 under four CPUs and eight busy loops. Its one re-take hid the cause.

Intended invariant

A paced touch play stretched by a starved runner fails by name, as TouchStarvationError, with no pass, re-take or re-pace. The touch pacing self-test fails only on a move the harness itself sent late.

Change

  • TouchStarvationError: the page drew no frame for longer than FRAME_STARVATION_MS across the late gap, and no listener hold or wait explains it. The lift stall, TouchPageStallError and a named wait still come first.
  • The touch driver reads the page's frames from armInputRun's frame log, after its first frame. FRAME_STARVATION_MS moves to a leaf module.
  • The self-test judges each move against its paced deadline on the play's own clock, which played events now carry, with no re-take. A late move is the runner's (touch-runner-late) only when a control timer woke over 2 ms late. The process must have run under half that delay.
  • NavigationStack's flick names its fault through touchPlayError, with the page's frames.
  • README, engine-limits table and JSDoc.

Evidence

  • Eight new unit cases. Controls, NOT FOR LANDING, each red: no starvation branch (fb4f3ed), the whole gesture's frame gap (14ba915), a wait ignored (b906e6e).
  • CI's profile (WebKit, four CPUs, one worker):
    • the self-test 20 of 20; LightboxDismissCancel's two proofs 20 of 20 each;
    • 0 of 5 each: twice the script's times (f6313ac), a slow send (5c739cf), a send holding the process 20 ms (2e2cdb6);
    • 0 of 5 each: spinning 20 ms (221638e) or 4 ms (a40b4b5) past each deadline;
    • spinning 3 ms past each deadline (52f6b5e): 0 of 20, as main's self-test;
    • a helper process stopping the test process 20 ms (fdb9e04) or 30 ms (174a7ea) before every third send: 5 of 5 each.
  • Four CPUs and eight busy loops, three alternating rounds: main's self-test 0 of 15, this one 15 of 15.
  • Limit: there the quota throttles the test process itself, so the 3 ms spin passes 5 of 15.
  • Under extreme load, a listener's wall time includes its CPU wait, so TouchPageStallError comes first.
  • Product/runtime behavior verified unchanged: test harness only.
  • CI impact (for a change to workflows, actions or CI scripts): none.

Scope

  • No intended public API, product behavior, visual direction, or policy change.
  • Product changes discovered during the work were removed or split.
  • Public text and artifacts contain no internal Meta context.

Testing

  • Harness unit tests: 267 of 267. Harness tsc: 0 errors.
  • Harness spec: WebKit 148 passed, Chromium 162 passed. LightboxDismissCancel, LightboxDismiss, LightboxZoom, SnapPaging and NavigationStack in WebKit: 146 passed. NavigationStack in Chromium: 53 passed.
  • Prettier, ESLint 0 errors, pnpm review:pre: 0 findings against main.

@vercel

vercel Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Nov 9, 2026 8:43pm UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Nov 7, 2026
@astracat-bot

astracat-bot Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 9, 2026, 8:47 PM UTC

@github-actions

github-actions Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · 07443c3

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC Visual · A11y · RTL
lab/NavigationScreen 82.6 kB (0) · 1.5 kB CSS (0) — — · ✓ · ✗
lab/NavigationStack 82.6 kB (0) · 1.5 kB CSS (0) — — · ✓ · ✓

Package size: no published package changed; no new dependencies.

API changes: none in this pull request

Committed API report behind this build: cli 29 rows, core 36 rows, theme-butter 1 row, theme-y2k 1 row; run pnpm api:report.

Touched components checked; add ci:run-visual, ci:run-a11y or ci:run-rtl to run the full suites.


Generated by PR Enrichment workflow | View full report

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changes requested: one fix in the new failure naming.

  • internal/interaction-harness/src/harness.interaction.browser.spec.ts:346 starts the runner-starvation span at the move's scripted time instead of the due time (in practice the send before the move) that the comment above it describes, so under intermittent runner stalls a pacer that sends each step late is reported as "the runner was starved"; start the span at sentAt[i - 1], or say in the comment why a stall before the previous send can make this move late.

The rest looks right: dueAt matches the harness's keep-the-gap pacing, and the one-take check still fails a slow or bursting pacer. Optional: the >= at line 351 blames the runner at exactly half the off-pace moves, while the comment says "most".

[Automated review]

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved pending CI: CI has not run on this head yet, so once this draft is marked ready for review, a maintainer adds the ci:run label so CI runs.

Both points from the last review are fixed: a slow pacer under intermittent runner stalls is now named as the pacer, and the runner is named only for a strict majority of the off-pace moves.

  • Miss: (optional, non-blocking) internal/interaction-harness/src/touch.ts:29-30 still says a watched 'schedule' play does not keep gaps, and its SYNC note names this test, so dropping that clause keeps the two in step.

[Automated review]

@vjeux vjeux changed the title test(interaction-harness): a touch pacing take is never re-taken test(interaction-harness): name a touch play the runner starved Nov 9, 2026
@vjeux
vjeux force-pushed the test/harness-touch-retake branch from c8d4b5e to 9b36c38 Compare November 9, 2026 11:47
@cixzhang

cixzhang commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 9b36c38

@astracat-bot astracat-bot Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changes requested: one blocking fix in the WebKit touch pacing self-test.

  • The self-test credits a late move to the runner whenever a control timer in the same test process woke about as late (harness.interaction.browser.spec.ts:414-415), but harness code that holds that process delays the timer too, so a pacer whose wait spins 20 ms past every deadline, or a send that holds the process 20 ms, now passes 3 of 3 where main fails both; please credit a wake to the runner only when the process used little CPU across it (for example with process.cpuUsage()), and model the runner-stall control as a stop from outside the process.

Non-blocking:

  • The off-pace count can list one move twice ("left late" and "followed a slow send"), so :429-432 compares reasons, not moves, with half the moves.
  • The README's engine-limits table (README.md:576) still ends with "else TouchPacingError"; add TouchStarvationError there, as the prose below it now does.
  • The comment at harness.interaction.browser.spec.ts:325-326 says no step waits for WebKit's answer, which the rewritten paragraph right below it contradicts.
  • Miss: the NavigationStack proof (NavigationStack.interaction.browser.spec.ts:1037-1046) still chooses between TouchPacingError and TouchPageStallError itself, so its flick on a starved runner never reads as TouchStarvationError; routing it through touchPlayError with frames would close that gap.

The new unit cases each fail when their branch is removed, and the harness typechecks and passes its unit tests.

[Automated review]

A paced WebKit play whose page drew no frame across its late gap, with
no page work holding the event, now fails as TouchStarvationError, not
TouchPacingError. The touch driver reads the page's frames from the
input run's frame log, after its first frame. The touch pacing
self-test judges each move against its paced deadline, with no
re-take. It names a move the runner woke late only when a control
timer woke as late while the test process ran for under half of that
wait.
@vjeux
vjeux force-pushed the test/harness-touch-retake branch from 9b36c38 to 8af3622 Compare November 9, 2026 13:29
@cixzhang

cixzhang commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 8af3622

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved pending CI: CI has not run on this head yet, so once this draft is marked ready for review, a maintainer adds the ci:run label so CI runs.

The earlier blocking point is fixed: the touch pacing self-test now fails a pacer that holds its own process past each deadline (a 20 ms spin or a 20 ms held send fails 3 of 3 in WebKit), while a 30 ms stop from outside the process is still named as the runner. The off-pace count, the README's engine-limits table, the self-test comment and the NavigationStack proof's error choice are fixed too, and each new unit case fails when its branch is removed.

[Automated review]

@cixzhang cixzhang added the ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) label Nov 9, 2026
@vjeux
vjeux marked this pull request as ready for review November 9, 2026 14:35
@vjeux
vjeux marked this pull request as draft November 9, 2026 14:39
@cixzhang

cixzhang commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 9b4050f

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved pending CI: CI has not run on this head yet. The ci:run label is already applied, so CI runs once this draft is marked ready for review.

The merge of main leaves the change itself untouched. On this head the touch pacing self-test still fails a pacer that holds its own process past each deadline (a 20 ms spin or a 20 ms held send fails 3 of 3 in WebKit), while a 30 ms stop from outside the process is named as the runner, and each new touchPlayError unit case fails when its branch is removed.

[Automated review]

@vjeux
vjeux marked this pull request as ready for review November 9, 2026 15:06
@vjeux
vjeux marked this pull request as draft November 9, 2026 17:59
@cixzhang

cixzhang commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 9f1de34

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved pending CI: CI has not run on this head yet. The ci:run label is already applied, so CI runs once this draft is marked ready for review.

The merge of main leaves the change itself untouched. On this head the touch pacing self-test still fails a pacer that holds or delays its own sends (a 20 ms spin, a 20 ms held send or a 20 ms late sleep each fail 3 of 3 in WebKit), while a 30 ms stop from outside the process is named as the runner, and each new touchPlayError unit case fails when its branch is removed.

  • Miss: (non-blocking) TouchStarvationError's message leaves out the gesture-wide frame gap that the README says every pacing error names; using describeFault(fault) there, or narrowing that README sentence, keeps them in step.

[Automated review]

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changes requested: one fix in the WebKit touch pacing self-test.

  • Miss: the self-test credits a late move to the runner even when the control timer woke on time (harness.interaction.browser.spec.ts:433 adds 4 ms of slack whatever runnerMs is), so a pacer that leaves every move 3 ms past its paced deadline passes in WebKit as touch-runner-late with "control 0 ms late", where main's self-test fails it; credit the runner only when the control itself woke late, for example move.runnerMs > 2 && move.ms <= move.runnerMs + 4.

The runner-stall case this pull request targets works as intended: a 30 ms outside stop of the test process before every third step passes and is named, while a pacer that spins 6 ms or 20 ms past each deadline still fails, and every new touchPlayError unit case fails when its branch is removed. The earlier non-blocking note on TouchStarvationError's message (touch.ts:887) still stands.

[Automated review]

The touch pacing self-test credited a late move to the runner when it
left no more than 4 ms after the control timer's wake, even when that
timer woke on time. A pacer that left every move 3 ms past its paced
deadline then passed as the runner's.

A move is now the runner's only when the control itself woke more than
2 ms late, and a wake counts only when the test process ran for less
than half of how late it was. The test reads the moves and the
control's wakes on the clock the play paces on, to a fraction of a
millisecond: each played event now carries its send and its return on
that clock.
TouchStarvationError also names the gesture's longest frame gap, as
the other pacing errors do.
@cixzhang

cixzhang commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 0d9e667

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved pending CI: CI has not run on this head yet. The ci:run label is already applied, so CI runs once this draft is marked ready for review.

Both points from the last review are fixed. The touch pacing self-test now credits a late move to the runner only when its control timer itself woke late, so a pacer that leaves every move 3 ms past its paced deadline fails again, while a 30 ms outside stop of the test process still passes and is named touch-runner-late. TouchStarvationError now names the gesture's longest frame gap, pinned by a unit case.

[Automated review]

@cixzhang

cixzhang commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 07443c3

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved pending CI: CI has not run on this head yet. The ci:run label is already applied, so CI runs once this draft is marked ready for review.

The newest commit only merges main and changes nothing this pull request does: the harness still typechecks and passes its unit tests, and the WebKit touch pacing self-test still passes a healthy take and fails a pacer that leaves every move 3 ms late.

[Automated review]

@vjeux
vjeux marked this pull request as ready for review November 9, 2026 21:13
@cixzhang
cixzhang merged commit f124c2f into meta:main Nov 9, 2026
128 checks passed
@vjeux
vjeux deleted the test/harness-touch-retake branch November 9, 2026 22:18

This branch was successfully deployed

1 active deployment
Preview — 07443c35 Deployed Nov 9, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants