Fix Y/n input race in ChannelUpdateWorkflowTests + add CLI E2E troubleshooting doc - #17533
Conversation
…g.md
The Spectre.Console [Y/n] confirmation prompt is a single-character reader,
not a line reader. Sending TypeAsync("n") + EnterAsync() queues both bytes
in the TTY input buffer; when the CLI returns on "n" and tears down its
stdin handler before \n is consumed, bash receives the stray \n as an
empty command and bumps CMDCOUNT via PROMPT_COMMAND.
The test's SequenceCounter then ends up coincidentally agreeing with bash's
drifted CMDCOUNT. The next WaitForAspireAddSuccessAsync false-positives on
the typed-command prompt header line ([N OK] $ aspire add ...) that bash
printed when accepting the command, returning success before aspire add has
actually written aspire.config.json. The follow-on Assert reads the file
too early and fails.
This matches the existing convention in DeclineAgentInitPromptAsync which
documents the same race and avoids it by not sending Enter after the
single-character answer.
Also adds .github/skills/cli-e2e-testing/troubleshooting.md describing the
diagnostic recipe (right-artifact selection, cast reconstruction, prompt-
counter desync, Y/n race signature) so future agent sessions can recognize
the pattern, and references it from SKILL.md.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17533Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17533" |
There was a problem hiding this comment.
Pull request overview
Fixes a flaky CLI E2E test by removing a stray EnterAsync() after a single-character [Y/n] prompt response, which was causing a TTY input race that desynced the shell's CMDCOUNT from the test's SequenceCounter. Also adds a troubleshooting guide documenting the diagnostic recipe.
Changes:
- Drop trailing
EnterAsync()afterTypeAsync("n")inPreviewStableUpdateAndDeclineAsync, matching the established convention inDeclineAgentInitPromptAsync. - Add a new
.github/skills/cli-e2e-testing/troubleshooting.mdcataloging the Y/n race and related flake patterns. - Link the troubleshooting guide from
SKILL.md.
Show a summary per file
| File | Description |
|---|---|
| tests/Aspire.Cli.EndToEnd.Tests/ChannelUpdateWorkflowTests.cs | Removes the racy EnterAsync() and adds an explanatory comment. |
| .github/skills/cli-e2e-testing/troubleshooting.md | New diagnostic guide for CLI E2E flakes. |
| .github/skills/cli-e2e-testing/SKILL.md | Adds pointer to the new troubleshooting guide. |
Copilot's findings
- Files reviewed: 3/3 changed files
- Comments generated: 0
|
❓ CLI E2E Tests unknown — 107 passed, 0 failed, 2 unknown (commit View all recordings
📹 Recordings uploaded automatically from CI run #26507778122 |
|
This problem only exists for this one test? |
|
/backport to release/13.4 |
|
Started backporting to |
|
✅ No documentation update needed. docs_optional → No triggered signals ( All 3 changed files fall under the
None of these paths ship to |
aspire add failed to add the integration package after stopping the detach process
#17587
Description
ChannelUpdateWorkflowTests.UpdateProjectChannelToStable_TypeScript_PreviewsStablePackagesAndPreservesChannelhas been flaking with an assertion that readsaspire.config.jsonbeforeaspire addhas actually written it. The root cause is a TTY input race against Spectre.Console's[Y/n]prompt.The Spectre
[Y/n]confirmation is a single-character reader, not a line reader. When the test answered withTypeAsync("n") + EnterAsync(), both bytes went into the TTY input queue; the CLI returned on thenkeystroke and tore down its stdin handler before\nwas consumed. Bash then received the stray\nas an empty command line and bumpedCMDCOUNTviaPROMPT_COMMAND. The test'sSequenceCounterdidn't know about that extra cycle, so the nextWaitForAspireAddSuccessAsyncfalse-positively matched the[N OK] $ aspire add ...command-echo prompt header line that bash printed when accepting the command, returning success beforeaspire addactually wroteaspire.config.jsonviaGuestAppHostProject.SaveConfiguration(which only runs after a fullBuildAndGenerateSdkAsyncround-trip).The recording signature is unambiguous: a passing run goes straight from
[Y/n]: nto[21 OK] $ aspire add ...; the failing run shows an extra empty[21 OK] $cycle, then[22 OK] $ aspire add ....The fix
Drop the trailing
EnterAsync(). This matches the existing convention inHex1bAutomatorTestHelpers.DeclineAgentInitPromptAsync, whose comment documents the same race. The fix is only needed when both a character and Enter are sent for a single-character prompt;EnterAsync()-alone (accept-default) andType(...) + Enteragainst text-input or selection prompts are not affected because\nis the commit byte for those readers.Troubleshooting doc
I also added
.github/skills/cli-e2e-testing/troubleshooting.mdwith the diagnostic recipe so future agent sessions can recognize the pattern without re-deriving it:gh run downloadreturns the latest, often a passing rerun; onlygh api .../artifacts/<id>/zipfiltered bycreated_atworks)..castfiles.PROMPT_COMMAND/CMDCOUNT/SequenceCounterlockstep).SKILL.mdgets a one-line pointer to it.Checklist