Skip to content

test(cmd/grafel): strictly advance cpu.json mtime in writeCPUJSON (Windows caps-store flake)#5897

Merged
cajasmota merged 1 commit into
mainfrom
worktree-agent-ad3d4b468b735f54b
Jul 22, 2026
Merged

test(cmd/grafel): strictly advance cpu.json mtime in writeCPUJSON (Windows caps-store flake)#5897
cajasmota merged 1 commit into
mainfrom
worktree-agent-ad3d4b468b735f54b

Conversation

@cajasmota

Copy link
Copy Markdown
Owner

Fixes the sole windows-latest failure in v0.1.9 acceptance CI #2: TestApplyDaemonGOMAXPROCSFromCapsraise: got (n=2, prev=2, changed=false), want (5, 2, true). Pre-existing Windows flake, unrelated to the memory epic (this test passed on the prior CI run that already contained every epic change). Refs #5850.

Root cause (test artifact, not product): caps.Store.Load() caches the parsed cpu.json on a (mtime, size) key — a deliberate stat-only hot-path optimization (avoids re-parsing JSON on the reindex hot path). The test's writeCPUJSON stamped both back-to-back writes with the same now+2s, and the two step-3 payloads ({"daemon_gomaxprocs": 2} / 5) are byte-identical in size, so size can't discriminate and mtime is the sole key. On Windows's coarse (~15ms) wall clock the two rapid writes get the identical mtime, the key never advances, and Load() returns the stale parse (2). Unix's finer mtime distinguishes them → Unix-green, Windows-flaky.

Fix: writeCPUJSON anchors the new mtime to max(now, prevFileMtime + 2s) (stat-before-overwrite), so each successive write is strictly newer regardless of clock resolution and the (mtime, size) key always advances. Deterministic on all platforms; macOS stays green. Store left unchanged — hardening it to a content-hash key would force a ReadFile on every Load(), regressing exactly the stat-only cheapness it was built for, for a same-mtime-same-size collision that can't occur with real seconds-apart operator edits.

Class scan: the sibling caps tests (caps_test.go) already Chtimes only the second write, so they're safe; writeCPUJSON was the sole symmetric-offset instance.

🤖 Generated with Claude Code

https://claude.ai/code/session_017quGgaqK7NRoxGT6BTqV2o

…ndows de-flake)

TestApplyDaemonGOMAXPROCSFromCaps flaked on windows-latest only, failing
step 3 with (n=2, changed=false) instead of (5, ..., true): the caps.Store
served the STALE cached parse of the first cpu.json write.

Root cause is a test artifact, not a product bug. The store caches the
parsed cpu.json keyed on its (mtime,size) -- a deliberate, documented
stat-only hot-path optimisation. The two payloads written back-to-back
({"daemon_gomaxprocs": 2} vs 5) are byte-identical in size, so mtime is
the sole cache discriminator. writeCPUJSON stamped BOTH writes with
time.Now().Add(2s); on Windows the wall clock is coarse (~15ms) so two
rapid writes read the same time.Now(), the constant offset cancels, both
files land on the same mtime, and the (mtime,size) key never changes ->
stale cache hit. Unix has finer mtime resolution, hence Unix-green /
Windows-flaky.

Fix is in the TEST (smallest deterministic change; keeps the store's
stat-only hot path intact -- a content-hash key would force a ReadFile on
every Load, regressing exactly what the package optimises for; in prod
operator edits are seconds-to-minutes apart on sub-second-resolution
filesystems, so the collision never occurs). writeCPUJSON now anchors the
new mtime to the previous file's mtime + 2s (falling back to now for the
first write), making each successive write strictly newer regardless of
clock resolution, so the cache key always advances.

Sibling caps tests (caps_test.go TestLoad_ReReadOnChange /
TestLoad_MalformedKeepsLastGood) are already safe: they Chtimes only the
SECOND write, so the +2s offset creates a guaranteed gap from the first
write's natural OS-timestamp mtime.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017quGgaqK7NRoxGT6BTqV2o
@cajasmota
cajasmota merged commit 1dc3588 into main Jul 22, 2026
1 of 2 checks passed
@cajasmota
cajasmota deleted the worktree-agent-ad3d4b468b735f54b branch July 22, 2026 02:36
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