[test] Add tests for syncutil.GetOrCreate double-check locking path#5437
Draft
github-actions[bot] wants to merge 1 commit intomainfrom
Draft
[test] Add tests for syncutil.GetOrCreate double-check locking path#5437github-actions[bot] wants to merge 1 commit intomainfrom
github-actions[bot] wants to merge 1 commit intomainfrom
Conversation
Cover the double-check branch in syncutil.GetOrCreate (lines 27-28 of cache.go), which was previously uncovered at 92.3% → now 100%. The new test (TestGetOrCreate_DoubleCheckPreventsRedundantCreate) uses a deterministic coordination strategy: - Pre-hold the write lock before starting goroutines, forcing both to block at their first mu.RLock() call and guaranteeing both see a miss. - Release the write lock so both goroutines compete for read, then write. - Block the write-lock winner inside create() via a channel, giving the other goroutine time to queue on mu.Lock(). - Unblock create(), which triggers the double-check in the second goroutine. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Test Coverage Improvement: syncutil.GetOrCreate
Function Analyzed
internal/syncutilGetOrCreateWhy This Function?
GetOrCreateimplements the [double-check locking pattern]((en.wikipedia.org/redacted) for a generic cache with read-write mutex semantics. It's a core concurrency utility used throughout the codebase. Despite having several existing tests, the critical double-check branch (lines 27–28 ofcache.go) — which prevents redundantcreatecalls when two goroutines race for the write lock — was never executed during the test suite.This branch is the most important correctness invariant in the function: without it, two goroutines that both observe a cache miss could both call
create, which would be wrong.Root Cause of Missing Coverage
The existing
TestGetOrCreate_CreateCalledOncetest (100 goroutines) was too fast: by the time any goroutine finished creating and storing the value, the others would find it in the read lock check (line 18), not the double-check write lock path (line 27). The double-check is only reached when:Deterministic Test Strategy
The new test
TestGetOrCreate_DoubleCheckPreventsRedundantCreateuses precise goroutine coordination:mu.RLock(), guaranteeing both will see a cache miss once released.create()via a channel, giving the loser time to queue onmu.Lock().create()— the winner stores the value, the loser acquires the write lock, executes the double-check, finds the key, and returns without callingcreateagain.Tests Added
TestGetOrCreate_DoubleCheckPreventsRedundantCreate— deterministic test for the double-check locking pathcreateis called exactly once even under write-lock contention-race)Coverage Report
Test Execution
Generated by Test Coverage Improver
Next run will target the next most complex under-tested function
Warning
Firewall blocked 6 domains
The following domains were blocked by the firewall during workflow execution:
go.opentelemetry.iogo.yaml.ingolang.orggoogle.golang.orggopkg.inproxy.golang.orgSee Network Configuration for more information.