tests: fix the data races in queueworker, recov and bufferqueue - #1479
tests: fix the data races in queueworker, recov and bufferqueue#1479dwin-gharibi wants to merge 1 commit into
Conversation
…ata races Signed-off-by: Dwin Gharibi <dwin.gharibi@email.kntu.ac.ir>
| got = true | ||
| got.Store(true) | ||
| }() | ||
|
|
There was a problem hiding this comment.
Minor (pre-existing, but this PR rewrites the test): this pre-Push check is timing-dependent — got.Load() is evaluated immediately after the goroutine is spawned, with no guarantee the goroutine has been scheduled yet. If BPop ever regresses to return immediately, the test can still pass: this check often runs before the goroutine stores true, and by the time done closes, if !got.Load() below also sees true. The done channel now reliably joins the goroutine (good), but the "should block when queue is empty" assertion is still not a strong check. (Also applies to the identical Cubelet copy.)
Review — PR #1479: tests: fix the data races in queueworker, recov and bufferqueueAI-generated review. Reviewed against the base branch tree ( Overall verdict: LGTM — approve. This is a test-only PR (5 files, +29/−12, no production code changed) that fixes real Change-by-change analysis1.
Verified against 2.
3. The watcher goroutine is joined via
This also resolves the "unreproducible in isolation" case the author describes: the fix is justified on the grounds of Minor observations (none blocking)
CI/portability notes
Conclusion: The PR does what it claims — removes three test-side data races, none in production code — with correct synchronization. Happy to approve; the inline note and the observations above are optional polish, not blockers. |
Closes #1478.
Motivation
go test -racefails in three packages because tests read state written by a goroutine withoutsynchronization. The production code is correct in all three cases; the tests are wrong.
These are part of what stands between the repo and a green
-racegate.What this changes
queueworker/queue_test.go—TestQueueBlock(CubeMaster and Cubelet copies)gotbecomes anatomic.Bool, and the test now waits on adonechannel closed by the goroutineinstead of sleeping for a fixed second:
gotBPopreturnsBPopnever returns, instead of reporting a confusing assertion failurerecov/runtime_test.go—TestGoWithRetryWithCrash(CubeMaster and Cubelet copies)int(panicTime)becomesint(atomic.LoadInt32(&panicTime)), matching theatomic.AddInt32thatproduction
HandleCrashuses to write it.bufferqueue/bufferqueue_test.go—TestQueueCheckTimestampPriority(CubeMaster only)The watcher goroutine is given a
watcherDonechannel and the test joins it viadefer, sot.Logfcan no longer run after the test function has returned.
No production code changed. No comment changes.
Per CONTRIBUTING's "one component per commit", this should land as two commits — one for CubeMaster, one
for Cubelet.
Testing
all under
-race -count=1, where master reports--- FAILplus aWARNING: DATA RACEforTestQueueBlockandTestGoWithRetryWithCrash.Module-wide
go test -race ./...in CubeMaster:The remaining 7 are the
localcacheproduction races, which are fixed on their own branch. The twochanges together take CubeMaster to 0.
On the bufferqueue one
I could not reproduce that race in five isolated runs of the package — it showed up only in a full
go test -race ./....bw.Workings()is correctlyatomic.LoadInt32, so the plausible cause is theunjoined goroutine touching
tafter the test returned, which is atestingmisuse regardless ofwhether the detector catches it on a given run. I fixed it on those grounds rather than claiming a
verified red/green, since I would rather say so than present an unproven fix as proven.
CI gates checked locally:
gofmt -lon all four packages — clean (fmt-check).go test -raceon all four — clean.