mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-11 10:01:27 -10:00
The push CI `test (windows-latest)` job has failed on every completed run since #10267 merged, and its 20-minute budget also expired. Four independent root causes are fixed here; each was reproduced and re-verified on a real Windows 11 virtual machine by cross-compiling the affected package test binaries before and after the change. * fix(skill): serve the watcher helper entry from test binaries Problem: internal/skill and internal/skill/skillwatch failed on Windows with "timed out waiting for physical watch registration" and "physical watches = 0", and the two packages took 90s and 70s. Root cause: Windows always routes watching through the helper backend, which starts by re-executing os.Executable(). Under `go test` that is the package test binary, which never calls MaybeRunHelper, so each spawned child re-ran the whole suite instead of serving the pipe. Registration timed out, the client burned its restart budget, and every root degraded to scan fallback. Fix: call MaybeRunHelper from the TestMain of the affected test binaries. Add TestDefaultHelperCommandServesTheRealBinaryEntry, which forces the same default command so a missing entry fails on every platform rather than only on Windows. Also wait for registration instead of asserting it immediately, and compare discovered catalog content rather than two stores' independent rebuild counters, which were never required to be equal. Verification: on Windows the baseline binary left 501 orphaned test processes behind and failed; the fixed binary passes and leaves none. Locally the guard reproduces the exact timeout when the entry is removed (69.5s) and passes with it (0.5s). * fix(session): release session writer leases at their owning boundary Problem: about thirty tests across internal/bot, internal/serve and internal/session failed Windows cleanup with "The process cannot access the file because it is being used by another process" on a sessions-v4 ownership lock. Root cause: a Service holds its writer lease until CloseAll or its idle TTL, and ClientBinding.Release only detaches a client. Test fixtures created services and never closed them, so the lease was still held when t.TempDir removed the directory. POSIX unlinks open files, so the leak was invisible outside Windows. BotGateway.Stop had the same gap in shipping code: it retired session states but never released the per-root service cache, so a stopped gateway kept its leases for the process lifetime. Fix: close the service at each fixture's owning boundary, and release the cached services from BotGateway.Stop after the last state is retired, mirroring the existing desktop shutdown. Two tests that left a running execution bound now idle it first, because a bound runtime refuses to close. Add filelock.HeldPathsForTest and testenv.VerifyNoLeakedFileLocks, wired into RunWithIsolatedUserState and the session and control TestMain, so a leaked lease fails on every platform and names the leaking test through its temp path. Verification: the guard reproduces the exact Windows failure set on macOS. On Windows, internal/session went from 17 failures to none, internal/serve from 16 to none, and internal/bot from 1 to none. * fix(control): wait for close finalization in the controller fixture Problem: TestTurnDoneCarriesValidatedCheckpointAcrossSuccessAndError intermittently failed cleanup with "directory not empty" under load. Root cause: Controller.Close only starts teardown; finalizeControllerClose joins the goal-driver workers that may still write under SessionDir. The fixture waited on closeFinalized only when a SessionService was supplied, so other controllers raced t.TempDir removal. Fix: make that wait unconditional. Verification: six concurrent suite runs reproduced the failure before the change and were clean after it. * test(serve): drain the message-field stream without thousands of round trips Problem: TestCanonicalSessionMessageFieldHTTPStreamsAlignedFragments took 88.8s on Windows CI and was the largest single contributor to the job timeout. Root cause: it read a 144 KB body 64 bytes at a time, costing about 2250 localhost round trips. Rune- and escape-safe cutting is a property of the cut size, not of the number of cuts. Fix: keep narrow 64-byte reads for the first fragments so boundaries still land inside multi-byte runes, then drain the remainder in large fragments. Every existing assertion is retained. Verification: on Windows the test went from failing at 10.66s to passing at 0.20s; round trips dropped from about 2250 to about 11.