test: Reduce test sleep durations in proxy, retry, and cache tests#103
test: Reduce test sleep durations in proxy, retry, and cache tests#103
Conversation
📝 WalkthroughWalkthroughReplaced fixed retry constants with timeout- and backoff-based constants; updated manifest push logic to use context-scoped timeouts and exponential backoff; adjusted test contexts and mock expectations to accept any context; shortened TTLs/sleeps in cache tests; added explicit Timeout option in retry test. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Snapshot WarningsEnsure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice. Scanned FilesNone |
There was a problem hiding this comment.
Pull request overview
Reduces overall Go test runtime by shortening long time.Sleep()-based waits in the slowest test suites (proxy manifest caching, retry timeouts, and cache TTL expiry), while keeping production behavior the same by default.
Changes:
- Added an explicit short timeout to the “always fails” retry test to avoid the default 60s wait.
- Reduced cache TTLs and corresponding sleeps in memory and redis cache tests.
- Made proxy manifest wait parameters test-overridable and updated proxy manifest cache sleeps accordingly.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/lib/retry/retry_test.go |
Reduces worst-case test duration by setting a 3s retry timeout for an always-failing case. |
src/lib/cache/redis/redis_test.go |
Shortens Redis cache expiration and sleep durations to speed up TTL-related tests. |
src/lib/cache/memory/memory_test.go |
Shortens in-memory cache expiration and sleep durations to speed up TTL-related tests. |
src/controller/proxy/manifestcache.go |
Updates sleep calls to work with new test-overridable interval variables. |
src/controller/proxy/manifestcache_test.go |
Overrides proxy manifest wait parameters to avoid minutes-long sleeps in the suite. |
src/controller/proxy/controller.go |
Converts manifest retry/sleep parameters from consts to vars so tests can override them. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/controller/proxy/manifestcache_test.go`:
- Around line 64-67: The test suite overrides package globals sleepIntervalSec,
maxManifestListWait, and maxManifestWait for faster tests but never restores
them; update the suite to save the original values before changing them (e.g.,
in SetupSuite or where they are set) and restore those originals in
TearDownSuite so other tests don't inherit the mutated timing configuration,
referencing the globals sleepIntervalSec, maxManifestListWait, maxManifestWait
and the test lifecycle method TearDownSuite.
In `@src/lib/cache/memory/memory_test.go`:
- Line 35: The suite-wide cache is created with a 1s TTL which causes flaky
failures under the race detector; instead, change the default in the TestSuite
setup (where suite.cache is assigned via cache.New and cache.Expiration) to a
much longer safe TTL (e.g., minutes) and reserve the 1s TTL only for tests that
specifically assert expiration by constructing a dedicated cache instance inside
those tests (call cache.New(..., cache.Expiration(time.Second)) locally). Update
any tests that rely on the global short TTL to create their own short-lived
cache so suite-wide timing is stable.
In `@src/lib/cache/redis/redis_test.go`:
- Line 35: The suite-wide use of a 1s TTL (suite.cache = cache.New("redis",
cache.Expiration(time.Second))) can cause race-mode flakiness; change the
suite-level initialization to use a much longer default TTL (e.g., time.Minute
or no expiration) and restrict cache.Expiration(time.Second) to only the tests
that assert expiration behavior (create per-test caches inside those
expiry-specific tests using cache.New with cache.Expiration(time.Second));
update references to suite.cache initialization in the setup helper (where
suite.cache is created) and ensure expiry tests construct their own short-TTL
caches instead of relying on suite.cache.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fed13a64-9d97-443c-981e-5c5446103597
📒 Files selected for processing (6)
src/controller/proxy/controller.gosrc/controller/proxy/manifestcache.gosrc/controller/proxy/manifestcache_test.gosrc/lib/cache/memory/memory_test.gosrc/lib/cache/redis/redis_test.gosrc/lib/retry/retry_test.go
There was a problem hiding this comment.
1 issue found across 6 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/controller/proxy/manifestcache_test.go">
<violation number="1" location="src/controller/proxy/manifestcache_test.go:65">
P2: Package-level globals (`sleepIntervalSec`, `maxManifestListWait`, `maxManifestWait`) are overridden in `SetupSuite` but never restored. This leaks modified timing configuration to any other tests in the `controller/proxy` package that run after this suite. Save the original values before overriding and restore them in `TearDownSuite`.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
7247f90 to
485fd64
Compare
The three slowest pure-unit-test packages account for 534s (>50%) of
total test execution time due to real time.Sleep() calls.
controller/proxy (421s → <1s):
Replace fixed sleep-poll loops in manifest cache with context-aware
exponential backoff. The retry loops now check first then wait
(instead of sleep-first), use select{} with ctx.Done() to respect
cancellation, and grow the interval from 1s to 30s max. Production
behavior is preserved with 10min/5min timeouts; tests use short
context deadlines.
lib/retry (75s → <1s):
Add a WithClock() option backed by benbjohnson/clock (already an
indirect dependency). Production callers are unchanged — they get
real time by default. Tests inject clock.NewMock() and advance time
instantly, eliminating all real sleeps.
lib/cache/memory (19s → <1s):
Add a WithClock() option to cache.Options, threaded into the memory
cache backend. The memory cache now uses clock.Now() instead of
time.Now() for TTL checks. Tests inject clock.NewMock() and advance
past TTL instantly — fully deterministic, zero wall-clock delay.
lib/cache/redis (19s → 6s):
Reduce TTL from 5s to 1s and sleep from 8s to 2s. Redis manages
its own TTL internally so clock injection isn't applicable.
Combined savings: ~528 seconds of test execution time.
Fixes #100
Signed-off-by: Vadim Bauer <vb@container-registry.com>
485fd64 to
555ffda
Compare
|
Preview images for this PR are available in
Verify a preview image: Verify SBOM attestation: |
Summary
benbjohnson/clock(already an indirect dependency) for deterministic time control inlib/retryandlib/cache/memorytestscontroller/proxywith context-aware exponential backoffRelated Issues
Fixes #100
Type of Change
test:)refactor:)Changes
controller/proxy— 421s → <1sReplace fixed
time.Sleep(20s)poll loops in manifest cache with context-aware exponential backoff.ctx.Done()Tests use short context deadlines (
200ms) instead of overriding constants.lib/retry— 75s → <1sAdd
WithClock(clock.Clock)option. Tests injectclock.NewMock()and advance time instantly. Production callers are unchanged —nilclock defaults to real time.lib/cache/memory— 19s → <1sAdd
WithClock(clock.Clock)option tocache.Options, threaded into the memory backend.time.Now()replaced withclock.Now(). Tests inject mock clock and advance past TTL instantly — fully deterministic.lib/cache/redis— 19s → 6sReduce TTL from 5s to 1s, sleep from 8s to 2s. Redis manages its own TTL so clock injection isn't applicable.
Production Code Side Effects
Five production files are modified. Here's why each is safe:
lib/retry/retry.go— No behavior changeClockfield toOptionsstructnil(all 25 existing callers),bclock.New()returns a real clockbclock.New().After()delegates totime.After(),.Sleep()totime.Sleep()lib/cache/options.go+lib/cache/memory/memory.go— No behavior changeClockfield toOptionsstructnil(all existing callers),clock.New()returns a real clockclock.New().Now()returnstime.Now()— identical behaviorcontroller/proxy/controller.go+manifestcache.go— Improved behaviorThe manifest cache retry loops run in a background goroutine detached from the HTTP request:
orm.Copy()returns avalueOnlyContextwhereDone()returnsnilandDeadline()returns zero. The goroutine is completely independent of the request lifecycle.Side effect analysis:
orm.Copy()context has no parent cancellation, soctx.Done()only fires from theWithTimeoutadded in new code. Equivalent to old iteration-count limit. No change in practice.Testing
controller/proxy— all tests pass (<1s)lib/retry— all tests pass with mock clock (<1s)lib/cache/memory— all tests pass with mock clock (<1s)-raceChecklist
git commit -s)