From cd2f45fc7c5708e1c62572e855faffe629a3c09c Mon Sep 17 00:00:00 2001 From: Zachary Lowden Date: Sun, 1 Nov 2026 12:53:11 -0600 Subject: [PATCH] ci: give the Go suite a 20-minute per-package timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit go test's default timeout is 10 minutes per package. Under -race -cover, internal/api already takes 460-575 s on main's runs, and on a runner that was slower across every package (agentprovision 123 s vs 91 s) it passed 600 s and panicked mid-suite with nothing hung — three times on PR #393, and once on another PR before it. Locally that PR's api package was 362 s against main's 345 s, all tests passing, so the time was the runner's. A real hang still fails, at 20 minutes instead of 10. The pin in internal/modulegate/ci_verdict_steps_test.go is updated to the new line (watched red with the old pin against the new step). Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/ci.yml | 7 ++++++- internal/modulegate/ci_verdict_steps_test.go | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e520938e..b9474e17 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -212,10 +212,15 @@ jobs: # refuses the run unless each named test is IN it and PASSED, so the gate # cannot stop running quietly — a rename, a deletion or a build tag that # filters it out fails this step the same way a red walk does. + # + # ⚠ `-timeout 20m`, NOT go test's default 10m, which is PER PACKAGE: under + # -race -cover internal/api took 460-575 s on main's runs and passed 600 s + # on a runner that was slower across every package (agentprovision 123 s vs + # 91 s), panicking mid-suite with nothing hung. A real hang still fails here. - name: go test, and assert nothing skipped (one run) run: | set -o pipefail - go test -race -cover -json ./... | python3 -u tests/verdict.py --echo summary --require TestEveryRouteIsClassifiedForIsolation --require TestNoRouteLetsOneUserReachAnothersData --require TestAnotherUsersWritesNeverReachYourEventStream + go test -race -cover -timeout 20m -json ./... | python3 -u tests/verdict.py --echo summary --require TestEveryRouteIsClassifiedForIsolation --require TestNoRouteLetsOneUserReachAnothersData --require TestAnotherUsersWritesNeverReachYourEventStream # The e2e aggregate's leg binder (e2e/pick-legs.mjs) is an instrument # too: its choice and its refusals, each on a synthetic artifact tree. diff --git a/internal/modulegate/ci_verdict_steps_test.go b/internal/modulegate/ci_verdict_steps_test.go index d11283a5..85d947c3 100644 --- a/internal/modulegate/ci_verdict_steps_test.go +++ b/internal/modulegate/ci_verdict_steps_test.go @@ -30,7 +30,7 @@ import ( // --------------------------------------------------------------------------- var wantVerdictPipes = map[string]string{ - "test": "go test -race -cover -json ./... | python3 -u tests/verdict.py --echo summary" + + "test": "go test -race -cover -timeout 20m -json ./... | python3 -u tests/verdict.py --echo summary" + " --require TestEveryRouteIsClassifiedForIsolation --require TestNoRouteLetsOneUserReachAnothersData --require TestAnotherUsersWritesNeverReachYourEventStream", "ccd-tmux": "go test -tags tmuxit -race -run '^TestTmux' -json ./cmd/ccd/ | python3 -u tests/verdict.py --echo all", "mirror-tmux": "go test -tags tmuxit -race -run '^TestTmux' -json ./internal/mirror/ ./internal/mirrorhost/ | python3 -u tests/verdict.py --echo all",