Skip to content

Stop the process-tree timeout test flashing a console window - #158

Merged
0101 merged 1 commit into
mainfrom
fix-ping-window-flash
Jul 31, 2026
Merged

Stop the process-tree timeout test flashing a console window#158
0101 merged 1 commit into
mainfrom
fix-ping-window-flash

Conversation

@0101

@0101 0101 commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Problem

A terminal window periodically flashed on screen for about a second on my dev machine and vanished before it could be read. It turned out to be this test suite.

ProcessRunnerTests.fs — "timeout returns a typed error and terminates the process tree" — spawns ping -n 30 as a grandchild to prove ProcessRunner's deadline kills a whole process tree, not just the direct child:

$child = Start-Process ping -ArgumentList '127.0.0.1','-n','30' -PassThru; ...

Start-Process defaults to UseShellExecute = $true, so Windows allocates a new console for ping.exe. On Windows 11, where Windows Terminal is the default console host, that appears as a Windows Terminal window. Two seconds later the timeout kills the tree and the window disappears.

ProcessRunner already starts the outer powershell.exe with CreateNoWindow = true (ProcessRunner.fs), but that does not propagate to a grandchild launched through Start-Process — which is exactly the gap.

The test carries Category("Unit") / Category("Fast"), so unlike the other window-spawning fixtures (SessionManagerSpawnTests, ActionLaunchSpawnTests), it is not gated behind [<Explicit>] and runs in every normal test run. With several worktrees and background agents running the suite, the flashes appeared at unpredictable intervals.

I tracked this down with a process/window watcher, which caught the exact ancestry:

PROC powershell.exe(72720) cmd=["powershell" -NoProfile -Command
     "$child = Start-Process ping -ArgumentList '127.0.0.1','-n','30' -PassThru; ..."]
  PARENTCHAIN=
     testhost.exe    [src\Tests\bin\Debug\net10.0\testhost.exe]
  <= dotnet.exe      [vstest.console.dll --testCaseFilter:Category=Unit]
  <= dotnet.exe      [dotnet test src/Tests/Tests.fsproj --filter Category=Unit]

PROC conhost.exe(74004) PARENTCHAIN=powershell.exe(72720)

Fix

Add -NoNewWindow to the Start-Process call. ping then inherits the parent PowerShell's console — and since that parent is started with CreateNoWindow = true, there is no console to inherit and nothing is displayed.

-NoNewWindow is preferred over -WindowStyle Hidden: the latter is a display hint that only applies with UseShellExecute and is ignored by some hosts, whereas -NoNewWindow suppresses console allocation outright.

Everything the test asserts is unchanged: -PassThru still returns the child, the pid file is still written, and the parent/child process-tree relationship under test is untouched. The non-Windows sh/sleep 30 branch needed no change.

Tests

dotnet test src/Tests/Tests.fsproj --filter "FullyQualifiedName~ProcessRunner"

Passed! - Failed: 0, Passed: 15, Skipped: 0, Total: 15, Duration: 22 s

I also A/B tested the window suppression directly, reproducing how ProcessRunner starts the outer shell (UseShellExecute = false, CreateNoWindow = true) and counting visible console-class top-level windows across the run:

Variant New visible windows ping pid captured
before (no -NoNewWindow) 1 68132
after (-NoNewWindow) 0 45560

The window is gone, and the child pid is still captured — confirming the fix is cosmetic-only and the test's guarantees hold.

The process-tree timeout test spawns `ping -n 30` as a grandchild via
`Start-Process`, which defaults to UseShellExecute and therefore allocates a
new console. On Windows 11 that surfaces as a Windows Terminal window that
flashes on screen for the ~2s until the deadline kills the tree.

`ProcessRunner` already starts the outer powershell with CreateNoWindow, but
that does not propagate to a grandchild launched through Start-Process.
`-NoNewWindow` makes ping inherit the parent's (absent) console instead.

The test's assertions are unaffected: -PassThru still returns the child, the
pid file is still written, and the process-tree relationship under test is
unchanged.
Copilot AI balanced review requested due to automatic review settings July 30, 2026 15:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Prevents the Windows process-tree timeout test from flashing a console window.

Changes:

  • Adds -NoNewWindow when spawning ping.
  • Documents why console inheritance is required.
Show a summary per file
File Description
src/Tests/ProcessRunnerTests.fs Suppresses the temporary ping console window.

Review details

  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Medium

@0101
0101 merged commit a6e63fc into main Jul 31, 2026
2 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