Skip to content

Flaky: TestSolve_HardTimeout_FakeSolverIgnoringT reds go test ./... on clean dev (pidfile race, survived the CI-flake sprint) #602

Description

@sunholo-voight-kampff

go test ./... is red on unmodified dev for internal/smt, while the same test passes in isolation. Found during mission iteration 151 while verifying an unrelated sprint (#601) outside the codex sandbox; it is not caused by that change.

Measurement

Two controlled arms, run on both the main checkout at 263df3df8 (unmodified) and a sprint worktree:

Arm Command Result
Full suite go test ./... rc=1FAIL internal/smt
Isolated test go test ./internal/smt -run TestSolve_HardTimeout_FakeSolverIgnoringT rc=0
Whole package go test -count=1 ./internal/smt rc=0

The full-suite arm was also run with no other load and still failed, so this is not an artifact of my running two suites concurrently.

Failure:

--- FAIL: TestSolve_HardTimeout_FakeSolverIgnoringT (3.00s)
    solver_timeout_test.go:42: read child pid: open /tmp/.../TestSolve_HardTimeout_FakeSolverIgnoringT.../001/child.pid: no such file or directory

Cause

internal/smt/solver_timeout_test.go:19 calls Solve with Timeout: time.Second against a fake solver script that writes its PID to a file and then sleeps. readChildPID (line 42) then reads that pidfile.

The test assumes the child process gets scheduled and writes its pidfile before the 1s solver timeout kills it. Under the parallel load of a full go test ./..., that assumption can lose: the child is killed before the write lands, the pidfile never exists, and readChildPID fails. Nothing in the test waits for the pidfile to appear.

This is a defect in the test, not in the hard-timeout mechanism it covers — Solve behaved correctly in every observed run (the status/elapsed/error assertions above line 42 all passed).

Why CI is green

CI runs the identical go test -timeout 300s ./... (.github/workflows/ci.yml:98) and dev is green at 263df3df8, so the runners' load profile happens to stay on the winning side of the race. That makes this a latent CI flake rather than a purely local annoyance — the same class the just-closed M-CI-FLAKE-SYSTEMIC-FIX sprint (#591#600) was about, and it is a survivor of it.

Suggested fix

Poll for the pidfile with a bounded deadline instead of assuming it exists by the time the solver timeout fires — or have the fake solver write its pidfile before doing anything else and have the test wait on that file with a bounded retry, failing loudly on expiry. internal/testutil's bounded helpers (added in #591) are the natural home for the wait.

Related: TestSolve_HardTimeout_FakeSolverIgnoringT is also one of the two tests already known to fail from a /tmp-rooted checkout, so it is sensitive to both tmp location and timing.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions