Skip to content

test: make the test suite faster and sleep-free#3399

Merged
dgageot merged 3 commits into
docker:mainfrom
dgageot:test/faster-sleep-free-tests
Jul 2, 2026
Merged

test: make the test suite faster and sleep-free#3399
dgageot merged 3 commits into
docker:mainfrom
dgageot:test/faster-sleep-free-tests

Conversation

@dgageot

@dgageot dgageot commented Jul 1, 2026

Copy link
Copy Markdown
Member

The test suite contained 44 time.Sleep calls spread across 22 test files. These sleeps slowed every run, introduced timing-dependent flakiness on loaded CI machines, and gave no actual guarantee of ordering — a fast machine might still race past them. This change removes all of them, replacing each with a deterministic synchronization primitive appropriate to the situation.

Depending on the test, the replacement is a channel gate, require.Eventually, gotest.tools/poll.WaitOn, time.AfterFunc, a fake clock, or a backdated TTL entry. For the prompt-serialization test in pkg/tools/builtin/shell, a small production change was needed: askpass.go gained an atomic counter (promptArrivals) so the test can wait for a prompt to arrive rather than sleeping. The 429 rate-limit test in pkg/remote also dropped go-containerregistry's default retry backoff (which slept ~4.4 s total) in favour of a millisecond-scale backoff with the same retry count. The three remaining time.Sleep calls are fake-time advances inside testing/synctest bubbles and carry //nolint directives explaining why they are intentional. A forbidigo lint rule now bans time.Sleep in *_test.go files so the pattern cannot silently return.

Wall-clock speedups are most visible in the packages that leaned on sleep the most: pkg/runtime drops from ~9 s to ~3 s and pkg/server from ~5 s to ~2 s in isolation. The full suite was run with -race on all touched packages; golangci-lint and the new custom cop are clean.

dgageot added 3 commits July 2, 2026 00:05
newTestSession now injects a millisecond-scale backoff so the 429
rate-limit test no longer sleeps ~4.4s through go-containerregistry's
default 1s+3s retry delays.

Assisted-By: Claude (Anthropic)
Channels, require.Eventually, gotest.tools poll.WaitOn, fake clocks, and
backdated TTL entries replace every racy sleep in the test suite. A new
forbidigo rule in .golangci.yml bans time.Sleep in tests going forward;
the three remaining calls in source_loader_test.go are fake-time inside
synctest bubbles and carry nolint directives. One small production change:
askpass.go gains a promptWaiters counter so the serialization test can
sync without sleeping.

Assisted-By: Claude
@dgageot dgageot requested a review from a team as a code owner July 1, 2026 23:08

@docker-agent docker-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assessment: 🟢 APPROVE

This PR cleanly replaces 44 time.Sleep calls across 22 test files with deterministic synchronization primitives. No bugs were found in the changed code.

Key areas reviewed:

  • askpass.go production changepromptArrivals atomic.Int32 is correctly placed and used with atomic operations. No race conditions introduced.
  • Channel-based synchronization — All channels in elicitation, server, and supervisor tests are appropriately buffered or closed; no goroutine leaks or deadlocks detected.
  • require.Eventually / poll.WaitOn — Timeout values (1–2 s with ms polling) are reasonable for in-process test conditions.
  • Rate-limit retry backoffBackoff{Duration: time.Millisecond, Factor: 1, Steps: 3} correctly removes multi-second backoff while preserving retry-path coverage.
  • forbidigo lint rule — Correctly scoped to *_test.go files; prevents time.Sleep from silently re-entering the test suite.

The three intentional time.Sleep calls inside synctest bubbles with //nolint directives are appropriate and well-documented.

@aheritier aheritier added area/ci CI/CD workflows and pipeline area/testing Test infrastructure, CI/CD, test runners, evaluation kind/test Test-only changes labels Jul 1, 2026
@dgageot dgageot merged commit 6495c6e into docker:main Jul 2, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/ci CI/CD workflows and pipeline area/testing Test infrastructure, CI/CD, test runners, evaluation kind/test Test-only changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants