Skip to content

test: make the suite race-clean and order-independent - #57

Merged
sre-helmcode merged 1 commit into
mainfrom
fix/test-race-order-55
Oct 14, 2026
Merged

sre-helmcode merged 1 commit into
mainfrom
fix/test-race-order-55

Conversation

@sre-helmcode

Copy link
Copy Markdown
Contributor

Fixes #55

What and why

Two pre-existing test-only defects surfaced by the Opus QA of #54:

  1. Race on time.Local (TestTriggersJSONAndTokens and any other runWrite caller, plus TestBYOKGoldenViews). The tests swapped time.Local to UTC per test, while net/http server goroutines (including keep-alive ones left from earlier tests) read it via time.Now(). Now time.Local = time.UTC is set once in TestMain, before any test or goroutine starts.
  2. Order dependence (TestSecretsSetRetriesWithTheSameIdempotencyKey). TestSecretsSetWithoutRetryFailsOnALostAnswer set createAttempts = 1 before runWrite snapshotted it, so runWrite's cleanup "restored" 1 and the retry test later saw no retry (EOF). Now it uses swap(t, &createAttempts, 1).

Global-state audit (cmd package)

  • New swap[T](t, *T, v) helper (set + restore via t.Cleanup) used for every package var tests override: runsBaseURL, writeStdin, writeStdinTTY, writeStdout, writeStderr, createAttempts, openTUI. Removes hand-written save/restore blocks that restored hard-coded values instead of the previous ones.
  • execute (the shared cobra tree runner) now resets every flag before running and again on cleanup, and clears args/out/err. Tests that drove rootCmd by hand and reset runOpts/flags manually (TestVersionPrintsOneLine, TestContradictoryWorktreeFlagsSayWhatIsWrong, TestCobraRefusalsExit64OnRunCommands) now go through it.
  • Already correct and left as is: env (t.Setenv everywhere, no os.Setenv), apiBaseURL/logoutWarnings/keepToolsFlag/tokenFileFlag/cancelWindow/loginVerifyURL/logoutTimeout/runHermesConfig (restored via cleanup/defer), runs/phase-2 flag vars (resetRunsFlags/resetPhase2Flags at start and end), os.Stdout/os.Stdin swaps (restored in cleanup/defer). No http.DefaultClient mutation, no t.Parallel anywhere.

CI

go test ./... -> go test -race -shuffle=on ./... on ubuntu and macos. The full suite takes ~10 s locally under -race. A shuffle failure prints its -test.shuffle seed for reproduction.

Test evidence (local, darwin/arm64)

  • Before: go test -race ./... -> DATA RACE (runWrite / TestBYOKGoldenViews vs net/http.(*conn).setState); go test -shuffle=on ./... failed 4/5 runs on TestSecretsSetRetriesWithTheSameIdempotencyKey.
  • After: go test -race -count=3 ./... ok; go test -shuffle=on -count=5 ./... ok; go test -race -shuffle=on ./... ok; the four previously failing seeds now pass; 10 more random shuffles of ./cmd ok. go vet and gofmt -l clean.

Deploy notes

Test-only change. No VERSION / tui.Version bump, no release.

🤖 Generated with Claude Code

- Pin time.Local to UTC once in TestMain instead of swapping it per test:
  the swap raced with time.Now() in net/http servers (runWrite,
  TestBYOKGoldenViews).
- Add a generic swap helper (set + restore via t.Cleanup) and use it for
  package vars tests override (writeStdin, writeStdinTTY, writeStdout,
  writeStderr, runsBaseURL, createAttempts, openTUI).
- TestSecretsSetWithoutRetryFailsOnALostAnswer set createAttempts=1 before
  runWrite snapshotted it, so the "restore" kept 1 and broke
  TestSecretsSetRetriesWithTheSameIdempotencyKey whenever it ran later.
- execute resets the shared cobra tree's flags before running and again on
  cleanup; tests that drove rootCmd by hand now go through it.
- CI runs go test -race -shuffle=on.

Fixes #55

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sre-helmcode
sre-helmcode merged commit b3aea03 into main Oct 14, 2026
6 checks passed
sre-helmcode pushed a commit that referenced this pull request Oct 20, 2026
Brings #50, #51, #52, #53, #54, #56 and #57 onto the new structure:

- mimo-v2.6-flash, qwen3.8-flash at 1M, and the Codex model catalogue:
  the writer changes go to internal/tools, the catalogue and its
  embedded prompt to internal/tools/codexprompt.
- BYOK runs, secrets and automation writes, and notifications: the
  commands go to internal/cli and hang off NewRootCmd; their goldens
  to internal/cli/testdata.
- The --json contract test counts the commands with a --json of their
  own, not the one every command inherits from the root.
- The embedded Codex prompt is Apache-2.0: its NOTICE and licence are
  now in THIRD-PARTY-NOTICES.txt.
- Messages without em dashes, and the new code lint-clean.
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.

Tests: race on time.Local in runWrite helper; TestSecretsSetRetriesWithTheSameIdempotencyKey order-dependent

2 participants