From 693b69353f6f358ac2b47b8afe78e3be186de78a Mon Sep 17 00:00:00 2001 From: Yahor Yuzefovich Date: Tue, 21 Oct 2025 18:10:54 +0000 Subject: [PATCH] storage: don't use global rand in test configs I was looking into a test timeout under race and saw one spot where we use the global rand under race. We have a few spots like this in the storage folder, so this commit fixes them. Release note: None --- pkg/storage/BUILD.bazel | 1 + pkg/storage/intent_interleaving_iter.go | 7 +++++-- pkg/storage/pebbleiter/BUILD.bazel | 1 + pkg/storage/pebbleiter/crdb_test_on.go | 13 ++++++++----- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/pkg/storage/BUILD.bazel b/pkg/storage/BUILD.bazel index ee6a628d3f2f..44ade067b0bf 100644 --- a/pkg/storage/BUILD.bazel +++ b/pkg/storage/BUILD.bazel @@ -85,6 +85,7 @@ go_library( "//pkg/util/metamorphic", "//pkg/util/mon", "//pkg/util/protoutil", + "//pkg/util/randutil", "//pkg/util/syncutil", "//pkg/util/sysutil", "//pkg/util/timeutil", diff --git a/pkg/storage/intent_interleaving_iter.go b/pkg/storage/intent_interleaving_iter.go index 793a4b21bf38..6cfea20436f9 100644 --- a/pkg/storage/intent_interleaving_iter.go +++ b/pkg/storage/intent_interleaving_iter.go @@ -17,6 +17,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/util" "github.com/cockroachdb/cockroach/pkg/util/protoutil" + "github.com/cockroachdb/cockroach/pkg/util/randutil" "github.com/cockroachdb/errors" "github.com/cockroachdb/pebble" ) @@ -1477,6 +1478,7 @@ func (i *intentInterleavingIter) assertInvariants() error { // changes to unsafe keys retrieved from MVCCIterators. type unsafeMVCCIterator struct { MVCCIterator + rng *rand.Rand keyBuf []byte rawKeyBuf []byte rawMVCCKeyBuf []byte @@ -1485,7 +1487,8 @@ type unsafeMVCCIterator struct { // gcassert:inline func maybeWrapInUnsafeIter(iter MVCCIterator) MVCCIterator { if util.RaceEnabled { - return &unsafeMVCCIterator{MVCCIterator: iter} + rng, _ := randutil.NewPseudoRand() + return &unsafeMVCCIterator{MVCCIterator: iter, rng: rng} } return iter } @@ -1547,7 +1550,7 @@ func (i *unsafeMVCCIterator) UnsafeRawMVCCKey() []byte { } func (i *unsafeMVCCIterator) mangleBufs() { - if rand.Intn(2) == 0 { + if i.rng.Intn(2) == 0 { for _, b := range [3][]byte{i.keyBuf, i.rawKeyBuf, i.rawMVCCKeyBuf} { for i := range b { b[i] = 0 diff --git a/pkg/storage/pebbleiter/BUILD.bazel b/pkg/storage/pebbleiter/BUILD.bazel index 7e90d4ec3747..2df2471c5580 100644 --- a/pkg/storage/pebbleiter/BUILD.bazel +++ b/pkg/storage/pebbleiter/BUILD.bazel @@ -14,6 +14,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/util", + "//pkg/util/randutil", "@com_github_cockroachdb_errors//:errors", "@com_github_cockroachdb_pebble//:pebble", ], diff --git a/pkg/storage/pebbleiter/crdb_test_on.go b/pkg/storage/pebbleiter/crdb_test_on.go index b96ead675f95..e82bdcc4b444 100644 --- a/pkg/storage/pebbleiter/crdb_test_on.go +++ b/pkg/storage/pebbleiter/crdb_test_on.go @@ -13,6 +13,7 @@ import ( "time" "github.com/cockroachdb/cockroach/pkg/util" + "github.com/cockroachdb/cockroach/pkg/util/randutil" "github.com/cockroachdb/errors" "github.com/cockroachdb/pebble" ) @@ -26,12 +27,14 @@ type Iterator = *assertionIter // MaybeWrap returns the provided Pebble iterator, wrapped with double close // detection. func MaybeWrap(iter *pebble.Iterator) Iterator { - return &assertionIter{Iterator: iter, closedCh: make(chan struct{})} + rng, _ := randutil.NewPseudoRand() + return &assertionIter{Iterator: iter, rng: rng, closedCh: make(chan struct{})} } // assertionIter wraps a *pebble.Iterator with assertion checking. type assertionIter struct { *pebble.Iterator + rng *rand.Rand closed bool closedCh chan struct{} // unsafeBufs hold buffers used for returning values with short lifetimes to @@ -243,11 +246,11 @@ func (i *assertionIter) PrevWithLimit(limit []byte) pebble.IterValidityState { // to the caller. This is used to ensure that the client respects the Pebble // iterator interface and the lifetimes of buffers it returns. func (i *assertionIter) maybeMangleBufs() { - if rand.Intn(2) == 0 { + if i.rng.Intn(2) == 0 { idx := i.unsafeBufs.idx zero(i.unsafeBufs.key[idx]) zero(i.unsafeBufs.val[idx]) - if rand.Intn(2) == 0 { + if i.rng.Intn(2) == 0 { // Switch to a new buffer for the next iterator position. i.unsafeBufs.idx = (i.unsafeBufs.idx + 1) % 2 } @@ -273,7 +276,7 @@ func (i *assertionIter) maybeSaveAndMangleRangeKeyBufs() { // Randomly zero them to ensure we catch bugs where they're reused. idx := i.rangeKeyBufs.idx mangleBuf := &i.rangeKeyBufs.bufs[idx] - if rand.Intn(2) == 0 { + if i.rng.Intn(2) == 0 { mangleBuf.mangle() } // If the new iterator position has range keys, copy them to our buffers. @@ -283,7 +286,7 @@ func (i *assertionIter) maybeSaveAndMangleRangeKeyBufs() { if _, hasRange := i.Iterator.HasPointAndRange(); !hasRange { return } - switchBuffers := rand.Intn(2) == 0 + switchBuffers := i.rng.Intn(2) == 0 if switchBuffers { // Switch to a new buffer for the new range key state. i.rangeKeyBufs.idx = (idx + 1) % 2