// newTestRangeSet creates a new range set that has the count number of ranges. func newTestRangeSet(count int, t *testing.T) *testRangeSet { rs := &testRangeSet{replicasByKey: btree.New(64 /* degree */)} for i := 0; i < count; i++ { desc := &roachpb.RangeDescriptor{ RangeID: roachpb.RangeID(i), StartKey: roachpb.RKey(fmt.Sprintf("%03d", i)), EndKey: roachpb.RKey(fmt.Sprintf("%03d", i+1)), } // Initialize the range stat so the scanner can use it. repl := &Replica{ RangeID: desc.RangeID, } repl.mu.TimedMutex = syncutil.MakeTimedMutex(defaultMuLogger) repl.cmdQMu.TimedMutex = syncutil.MakeTimedMutex(defaultMuLogger) repl.mu.state.Stats = enginepb.MVCCStats{ KeyBytes: 1, ValBytes: 2, KeyCount: 1, LiveCount: 1, } if err := repl.setDesc(desc); err != nil { t.Fatal(err) } if exRngItem := rs.replicasByKey.ReplaceOrInsert(repl); exRngItem != nil { t.Fatalf("failed to insert range %s", repl) } } return rs }
func TestTimedMutex(t *testing.T) { var msgs []string printf := func(ctx context.Context, innerMsg string, args ...interface{}) { formatted := fmt.Sprintf(innerMsg, args...) msgs = append(msgs, formatted) } var numMeasurements int record := func(time.Duration) { numMeasurements++ } { cb := syncutil.ThresholdLogger( context.Background(), time.Nanosecond, printf, record, ) // Should fire. tm := syncutil.MakeTimedMutex(cb) tm.Lock() time.Sleep(2 * time.Nanosecond) tm.Unlock() re := regexp.MustCompile(`mutex held by .*TestTimedMutex for .* \(\>1ns\):`) if len(msgs) != 1 || !re.MatchString(msgs[0]) { t.Fatalf("mutex did not warn as expected: %+v", msgs) } if numMeasurements != 1 { t.Fatalf("expected one measurement, not %d", numMeasurements) } } numMeasurements = 0 msgs = nil { cb := syncutil.ThresholdLogger( context.Background(), time.Duration(math.MaxInt64), printf, record, ) tm := syncutil.MakeTimedMutex(cb) const num = 10 for i := 0; i < num; i++ { tm.Lock() // Avoid staticcheck complaining about empty critical section. time.Sleep(time.Nanosecond) tm.Unlock() } if len(msgs) != 0 { t.Fatalf("mutex warned erroneously: %+v", msgs) } if numMeasurements != num { t.Fatalf("expected %d measurements not %d", num, numMeasurements) } } }
func TestAssertHeld(t *testing.T) { tm := syncutil.MakeTimedMutex(nil) // The normal, successful case. tm.Lock() tm.AssertHeld() tm.Unlock() func() { defer func() { if r := recover(); r == nil { t.Fatal("did not get expected panic") } else if a, e := r.(string), "mutex is not locked"; a != e { t.Fatalf("got %q, expected %q", a, e) } }() tm.AssertHeld() }() }
func newRaftScheduler( ambient log.AmbientContext, metrics *StoreMetrics, processor raftProcessor, numWorkers int, ) *raftScheduler { s := &raftScheduler{ processor: processor, numWorkers: numWorkers, } muLogger := syncutil.ThresholdLogger( ambient.AnnotateCtx(context.Background()), defaultReplicaMuWarnThreshold, func(ctx context.Context, msg string, args ...interface{}) { log.Warningf(ctx, "raftScheduler.mu: "+msg, args...) }, func(t time.Duration) { if metrics != nil { metrics.MuSchedulerNanos.RecordValue(t.Nanoseconds()) } }, ) s.mu.TimedMutex = syncutil.MakeTimedMutex(muLogger) s.mu.cond = sync.NewCond(&s.mu.TimedMutex) s.mu.state = make(map[roachpb.RangeID]raftScheduleState) return s }