Skip to content

test: deflake TestCompareDynamic_ZeroAllocHotPath#340

Merged
matthyx merged 1 commit into
mainfrom
fix/deflake-zeroalloc-hotpath
Jun 26, 2026
Merged

test: deflake TestCompareDynamic_ZeroAllocHotPath#340
matthyx merged 1 commit into
mainfrom
fix/deflake-zeroalloc-hotpath

Conversation

@matthyx

@matthyx matthyx commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

TestCompareDynamic_ZeroAllocHotPath (pkg/registry/file/dynamicpathdetector/tests) is flaky. It was the cause of the intermittent pr-created / test failures (e.g. on #339, which is unrelated — it only touches summary-storage aggregation).

Root cause

The test measured allocations by diffing the process-global runtime.MemStats.Mallocs counter around a 10,000-iteration loop:

runtime.ReadMemStats(&before)
for i := 0; i < iters; i++ { _ = CompareDynamic(...) }
runtime.ReadMemStats(&after)
require.Equal(t, uint64(0), after.Mallocs-before.Mallocs)

Mallocs is process-wide, so a single allocation from a background runtime goroutine (GC assist, sysmon, the testing timer) landing inside the measurement window flips the delta to 1 and fails the assertion. The microsecond-scale window makes it rare but nonzero — the failure was observed flipping between different subtests across runs (literal_mismatch in CI, literal_exact_match locally), the signature of a flake rather than a regression.

Fix

Switch to testing.AllocsPerRun, which pins GOMAXPROCS(1) during measurement and integer-divides total mallocs by the run count. A stray sub-runs allocation now floors to 0 instead of flaking, while a genuine per-call allocation still yields ~1.0 and fails the zero-alloc contract. The contract is preserved; only the noise is removed.

Verification

  • 30/30 isolated runs green (previously ~PASS/PASS/FAIL/FAIL/PASS).
  • Full go test ./... suite green.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Updated a performance-oriented test to use a more reliable allocation check.
    • The zero-allocation assertion now uses per-run allocation measurement with clearer failure messaging.

@matthyx matthyx added the ai-assisted Created through Armosec AI tooling (armosec-shared-rules plugin) label Jun 26, 2026
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@matthyx, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 41 minutes and 36 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 49afe880-3669-45ae-995e-d4c9e76fcf81

📥 Commits

Reviewing files that changed from the base of the PR and between aa63382 and aabb0a8.

📒 Files selected for processing (1)
  • pkg/registry/file/dynamicpathdetector/tests/compare_dynamic_memoise_test.go
📝 Walkthrough

Walkthrough

The hot-path allocation check in one test was rewritten to use testing.AllocsPerRun with a zero-allocation assertion instead of comparing runtime.MemStats before and after repeated iterations.

Changes

Hot-path allocation test

Layer / File(s) Summary
Allocation assertion rewrite
pkg/registry/file/dynamicpathdetector/tests/compare_dynamic_memoise_test.go
TestCompareDynamic_ZeroAllocHotPath now measures allocations with testing.AllocsPerRun and asserts zero allocations with require.Zerof.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Poem

A bunny peeks at the hot-path run,
AllocsPerRun makes the counting fun.
No malloc crumbs in the meadow stay,
just zero hops and a tidy test today.
🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: deflaking the TestCompareDynamic_ZeroAllocHotPath test.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/deflake-zeroalloc-hotpath

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@matthyx matthyx force-pushed the fix/deflake-zeroalloc-hotpath branch from aa63382 to 415134b Compare June 26, 2026 11:13
The zero-allocation assertion measured allocations by diffing the
process-global runtime.MemStats.Mallocs counter around a 10k-iteration
loop. Mallocs is process-wide, so a single allocation from a background
runtime goroutine (GC assist, sysmon, the testing timer) landing inside
the measurement window flipped the delta to 1 and failed the assertion.
The microsecond-scale window made this rare but nonzero, producing
intermittent failures under the full `go test ./...` run (observed
flipping between different subtests across runs).

Switch to testing.AllocsPerRun, which pins GOMAXPROCS(1) during
measurement and integer-divides total mallocs by the run count. A stray
sub-run-count allocation now floors to 0 instead of flaking, while a
genuine per-call allocation still produces ~1.0 and fails the contract.
Verified 30/30 isolated runs green and the full module suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Docs-exempt: test-only change, no behavioral change
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
@matthyx matthyx force-pushed the fix/deflake-zeroalloc-hotpath branch from 415134b to aabb0a8 Compare June 26, 2026 11:23
@github-actions

Copy link
Copy Markdown

Summary:

  • License scan: failure
  • Credentials scan: failure
  • Vulnerabilities scan: failure
  • Unit test: success
  • Go linting: failure

@matthyx matthyx merged commit 335978f into main Jun 26, 2026
7 checks passed
@matthyx matthyx deleted the fix/deflake-zeroalloc-hotpath branch June 26, 2026 11:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-assisted Created through Armosec AI tooling (armosec-shared-rules plugin)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant