github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/split_queue_test.go (about) 1 // Copyright 2015 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package kvserver 12 13 import ( 14 "context" 15 "math" 16 "testing" 17 18 "github.com/cockroachdb/cockroach/pkg/config" 19 "github.com/cockroachdb/cockroach/pkg/config/zonepb" 20 "github.com/cockroachdb/cockroach/pkg/keys" 21 "github.com/cockroachdb/cockroach/pkg/roachpb" 22 "github.com/cockroachdb/cockroach/pkg/storage/enginepb" 23 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 24 "github.com/cockroachdb/cockroach/pkg/util/stop" 25 "github.com/gogo/protobuf/proto" 26 ) 27 28 // TestSplitQueueShouldQueue verifies shouldSplitRange method correctly 29 // combines splits in zone configs with the size of the range. 30 func TestSplitQueueShouldQueue(t *testing.T) { 31 defer leaktest.AfterTest(t)() 32 tc := testContext{} 33 stopper := stop.NewStopper() 34 defer stopper.Stop(context.Background()) 35 tc.Start(t, stopper) 36 37 // Set zone configs. 38 config.TestingSetZoneConfig(2000, zonepb.ZoneConfig{RangeMaxBytes: proto.Int64(32 << 20)}) 39 config.TestingSetZoneConfig(2002, zonepb.ZoneConfig{RangeMaxBytes: proto.Int64(32 << 20)}) 40 41 testCases := []struct { 42 start, end roachpb.RKey 43 bytes int64 44 maxBytes int64 45 shouldQ bool 46 priority float64 47 }{ 48 // No intersection, no bytes, no load. 49 {roachpb.RKeyMin, roachpb.RKey(keys.MetaMax), 0, 64 << 20, false, 0}, 50 // Intersection in zone, no bytes, no load. 51 {roachpb.RKey(keys.SystemSQLCodec.TablePrefix(2001)), roachpb.RKeyMax, 0, 64 << 20, true, 1}, 52 // Already split at largest ID, no load. 53 {roachpb.RKey(keys.SystemSQLCodec.TablePrefix(2002)), roachpb.RKeyMax, 0, 32 << 20, false, 0}, 54 // Multiple intersections, no bytes, no load. 55 {roachpb.RKeyMin, roachpb.RKeyMax, 0, 64 << 20, true, 1}, 56 // No intersection, max bytes, no load. 57 {roachpb.RKeyMin, roachpb.RKey(keys.MetaMax), 64 << 20, 64 << 20, false, 0}, 58 // No intersection, max bytes+1, no load. 59 {roachpb.RKeyMin, roachpb.RKey(keys.MetaMax), 64<<20 + 1, 64 << 20, true, 1}, 60 // No intersection, max bytes * 2 + 2, no load, should backpressure. 61 {roachpb.RKeyMin, roachpb.RKey(keys.MetaMax), 64<<21 + 2, 64 << 20, true, 52}, 62 // No intersection, max bytes * 4, no load, should not backpressure. 63 {roachpb.RKeyMin, roachpb.RKey(keys.MetaMax), 64 << 22, 64 << 20, true, 4}, 64 // Intersection, max bytes +1, no load. 65 {roachpb.RKey(keys.SystemSQLCodec.TablePrefix(2000)), roachpb.RKeyMax, 32<<20 + 1, 32 << 20, true, 2}, 66 // Split needed at table boundary, but no zone config, no load. 67 {roachpb.RKey(keys.SystemSQLCodec.TablePrefix(2001)), roachpb.RKeyMax, 32<<20 + 1, 64 << 20, true, 1}, 68 } 69 70 cfg := tc.gossip.GetSystemConfig() 71 if cfg == nil { 72 t.Fatal("config not set") 73 } 74 ctx := context.Background() 75 for i, test := range testCases { 76 // Create a replica for testing that is not hooked up to the store. This 77 // ensures that the store won't be mucking with our replica concurrently 78 // during testing (e.g. via the system config gossip update). 79 cpy := *tc.repl.Desc() 80 cpy.StartKey = test.start 81 cpy.EndKey = test.end 82 repl, err := newReplica(ctx, &cpy, tc.store, cpy.Replicas().Voters()[0].ReplicaID) 83 if err != nil { 84 t.Fatal(err) 85 } 86 87 repl.mu.Lock() 88 repl.mu.state.Stats = &enginepb.MVCCStats{KeyBytes: test.bytes} 89 repl.mu.Unlock() 90 zoneConfig := zonepb.DefaultZoneConfig() 91 zoneConfig.RangeMaxBytes = proto.Int64(test.maxBytes) 92 repl.SetZoneConfig(&zoneConfig) 93 94 // Testing using shouldSplitRange instead of shouldQueue to avoid using the splitFinder 95 // This tests the merge queue behavior too as a result. For splitFinder tests, 96 // see split/split_test.go. 97 shouldQ, priority := shouldSplitRange(repl.Desc(), repl.GetMVCCStats(), 98 repl.GetMaxBytes(), repl.ShouldBackpressureWrites(), cfg) 99 if shouldQ != test.shouldQ { 100 t.Errorf("%d: should queue expected %t; got %t", i, test.shouldQ, shouldQ) 101 } 102 if math.Abs(priority-test.priority) > 0.00001 { 103 t.Errorf("%d: priority expected %f; got %f", i, test.priority, priority) 104 } 105 } 106 }