diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f53233663..119f258b11 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -325,7 +325,12 @@ jobs: # -p 2 permits concurrent compilation/testing in rest on the public # 4-vCPU / 16-GB runner, leaving headroom for the linker. tui3 and # session use four shards; codeaf runs its suite without sharding. - ./scripts/touched-verdict.sh run --base "$BASE" --shards 4 --report "$TMPDIR/$LEG.json" $PACKAGES + # CODEAF'S ONE TEST BINARY GETS 25 MINUTES, AND ONLY IT. Sharding cmd/codeaf + # was tried and its sharded runs failed (#1734), and its serial suite measured + # 1065 s (17.8 min) on this runner on 2026-11-03, over the Makefile's 15m, so + # every test after the cut went unchecked. The other legs pass no --timeout and + # keep the Makefile's 15m. Drop this once the suite is back under 15 minutes. + ./scripts/touched-verdict.sh run --base "$BASE" --shards 4 ${{ matrix.leg == 'codeaf' && '--timeout 25m' || '' }} --report "$TMPDIR/$LEG.json" $PACKAGES - uses: actions/upload-artifact@v4 if: always() with: diff --git a/cmd/codeaf/appworkstreams_conformance_test.go b/cmd/codeaf/appworkstreams_conformance_test.go index e3cb621e43..c236c94605 100644 --- a/cmd/codeaf/appworkstreams_conformance_test.go +++ b/cmd/codeaf/appworkstreams_conformance_test.go @@ -1294,10 +1294,33 @@ func workstreamWireError(t *testing.T, contract *workstreamWireContract, files m } } -// Hold a writer on a separate handle to the same real store. The backend must -// exhaust the normal busy timeout and translate that refusal on the wire. +// Hold a real writer on a second handle to the same store. Shorten only the +// backend's lock wait to 200 ms on its single connection so the case proves the +// real SQLITE_BUSY -> ErrBusy -> wire "busy" path without waiting ten seconds. +// Production keeps internal/workspace's 10-second wait. The refusal still says +// "(waited 10s)" because storeError uses that constant; conformance checks the +// code and a non-empty message, not that text. func workstreamWireHoldWriter(t *testing.T, backend *appBackend) func() { t.Helper() + if backend.collections == nil { + t.Fatal("busy fixture must seed the backend's collections store before holding a writer") + } + const workstreamBusyTimeoutMS = 200 + if err := backend.collections.Write(context.Background(), func(tx *sql.Tx) error { + _, err := tx.Exec(fmt.Sprintf("PRAGMA busy_timeout = %d", workstreamBusyTimeoutMS)) + return err + }); err != nil { + t.Fatalf("set backend busy timeout: %v", err) + } + var ms int + if err := backend.collections.Read(context.Background(), func(tx *sql.Tx, _ int) error { + return tx.QueryRow("PRAGMA busy_timeout").Scan(&ms) + }); err != nil { + t.Fatalf("read backend busy timeout: %v", err) + } + if ms != workstreamBusyTimeoutMS { + t.Fatalf("backend busy timeout = %d ms, want %d ms", ms, workstreamBusyTimeoutMS) + } other, err := workspace.Open(backend.collectionsPath) if err != nil { t.Fatal(err) diff --git a/docs/changes/unreleased/2296-codeaf-leg-finishes-in-ci.md b/docs/changes/unreleased/2296-codeaf-leg-finishes-in-ci.md new file mode 100644 index 0000000000..43ebe1f0cd --- /dev/null +++ b/docs/changes/unreleased/2296-codeaf-leg-finishes-in-ci.md @@ -0,0 +1,11 @@ +--- +kind: internal +title: The cmd/codeaf touched leg gets a 25-minute timeout; the conformance busy case waits 200 ms +pr: 2296 +surface: [build] +invalidates: [] +--- + +The package's serial suite measured 17.8 minutes on the CI runner, over the +15-minute timeout, so tests after the cut went unchecked. Only the codeaf leg +changes; the other legs keep 15 minutes. diff --git a/docs/rules/ci.md b/docs/rules/ci.md index 26957c0922..0430a2e3d1 100644 --- a/docs/rules/ci.md +++ b/docs/rules/ci.md @@ -15,6 +15,9 @@ root-module packages. Module changes select the whole tree; changes without Go or module edits select no package leg. Tests run fresh with `-count=1` in separate chat, session, command and remaining-package jobs. Heavy packages are sharded from one compiled test binary, with a 15-minute timeout per shard. +`cmd/codeaf` runs unsharded in its own leg; its serial suite measured 17.8 +minutes on 2026-11-03, so that leg alone passes a 25-minute package timeout. +Drop this exception once the suite is back under 15 minutes. ## Local verification