Skip to content

test(daemon): the OS process lookup tests pass on a loaded Windows machine - #2842

Merged
colbymchenry merged 1 commit into
mainfrom
claude/daemon-lock-holder-load-flake
Oct 23, 2026
Merged

colbymchenry merged 1 commit into
mainfrom
claude/daemon-lock-holder-load-flake

Conversation

@colbymchenry

@colbymchenry colbymchenry commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Summary

__tests__/daemon-lock-holder.test.ts › "reads a running process from the OS" failed on a loaded Windows machine. So, under the same load, did the seven CLI tests in the file that look a process up. They now pass under load. Production behaviour is unchanged.

Root cause

describeProcess (src/mcp/process-identity.ts) gives each OS query 5 s. On Windows it asks PowerShell's Get-CimInstance Win32_Process for the command line, and when that fails or runs out of time, it falls back to tasklist, which only has the image name. On a busy machine, PowerShell takes longer than 5 s to start and answer. The command line is then null, and the test's toMatch(/ping/) fails. Under heavier load tasklist runs out too, and the lookup returns nothing at all.

The seven CLI tests hit the same budget inside the codegraph index / codegraph unlock they spawn. A Node holder is classified only by its command line, so without one it stays unknown, the lock is kept, and the test sees "could not tell what it is" instead of a cleared lock.

In production that fallback is the intended fail-safe. A holder the OS won't describe stays unknown, its lock is kept, and the message says how to clear it by hand. Nothing there changes.

Fix

  • process-identity.ts. The per-query budget is still 5 s, unless CODEGRAPH_PROCESS_LOOKUP_TIMEOUT_MS says otherwise. Nothing sets it outside the tests. An env var rather than a parameter, because the CLI tests need it inside the CLI processes they spawn, and the env reaches both those and the in-process test.
  • daemon-lock-holder.test.ts.
    • It sets the budget to 60 s for the whole file (restored in afterAll), so it reaches the in-process lookups and every CLI the file runs.
    • The tests that look a process up get timeouts that fit that budget. runCli allows 240 s per CLI run, and the waits for a killed holder go from 10 s to 30 s. At normal load the file still takes about 20 s.
    • A new Windows-only test sets a 1 ms budget and checks that a lookup that runs out says nothing, so the holder stays unknown. That is the fail-safe the production path relies on, and the test also proves the override is read.

There is no CHANGELOG bullet: nothing a user sees changes. Earlier test-only fixes (#2772, #2629) had none either.

Validation

Windows 11, 16 logical CPUs. "Burn" means a 48-thread CPU-burn loop (node worker threads spinning) running alongside, started on an otherwise idle gate.

what main (51c4124 / cf3e6bc, same files) this branch
describeProcess on a live PING.EXE, under burn 5 s budget: 8 of 8 lookups returned nothing (about 11 s each: PowerShell and tasklist both ran out) 60 s budget: 6 of 6 read the command line (median 12.6 s, max 13.6 s)
"reads a running process from the OS" alone, under burn 0 of 4 passed, each expected '' to match /ping/i 2 of 2 (54 s each); 6 of 6 with an earlier revision that passed the same 60 s budget as an argument
the whole file, under burn 3 of 11 passed. The 8 failures are exactly the tests that look a process up 12 of 12, twice (923 s and 792 s; slowest test 106 s)
the whole file, normal load 11 of 11 12 of 12 in 20 s

One more single-test run of this branch under the burn never loaded its test file: vitest's own module fetch timed out. It's left out of the counts.

Suite. The full suite was run on the pushed commit 3b10207, with CODEGRAPH_KERNEL_EXPECT=1 and the kernel built. It covered 751 files (745 passed, 6 skipped) and 8,983 tests: 8,901 passed, 0 failed, 82 skipped, with no reruns.

Left out

  • The production budget stays 5 s. A longer default would only make codegraph index wait longer on a loaded machine before it falls back to the fail-safe it already has.
  • Other load-sensitive tests elsewhere in the suite (git, sync, daemon, WAL timeouts under load) are untouched.

🤖 Generated with Claude Code

…chine

daemon-lock-holder.test.ts > "reads a running process from the OS" failed
under load on Windows, and so did the seven CLI tests in the file that look
a process up. describeProcess gives each OS query 5 s: on a busy machine
PowerShell takes longer than that to start and run its CIM query, so the
lookup falls back to tasklist (the image name only, or nothing once tasklist
runs out too) and the command line is null. The in-process test's
toMatch(/ping/) then fails, and the CLI the other tests spawn sees a Node
holder it can't classify, keeps the lock, and says so. In production that
fallback is the intended fail-safe: an undescribed holder stays "unknown"
and its lock is kept.

The per-query budget is still 5 s unless CODEGRAPH_PROCESS_LOOKUP_TIMEOUT_MS
says otherwise, and nothing outside the tests sets it. The test file sets it
to 60 s for itself and for every CLI it spawns (an env var reaches both),
gives the lookup tests time to match (240 s per CLI run, 30 s for a killed
holder to go), and adds a Windows-only test that a lookup that runs out says
nothing, so the holder stays "unknown".

Validation (Windows, 16 logical CPUs, a 48-thread CPU burn running):
- describeProcess on a live PING.EXE: the 5 s budget answered nothing in 8
  of 8 lookups (about 11 s each); a 60 s budget read the command line in 6
  of 6 (median 12.6 s, max 13.6 s).
- The reported test alone: main 0 of 4, each "expected '' to match
  /ping/i"; this branch 2 of 2, and 6 of 6 with an earlier revision that
  passed the same 60 s budget as an argument.
- The whole file: main 3 of 11, the 8 failures being exactly the tests that
  look a process up; this branch 12 of 12, twice.
- No load: 12 of 12 in 20 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant