github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/merge_queue_test.go (about) 1 // Copyright 2018 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 "testing" 16 17 "github.com/cockroachdb/cockroach/pkg/config" 18 "github.com/cockroachdb/cockroach/pkg/config/zonepb" 19 "github.com/cockroachdb/cockroach/pkg/keys" 20 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/kvserverbase" 21 "github.com/cockroachdb/cockroach/pkg/roachpb" 22 "github.com/cockroachdb/cockroach/pkg/storage/enginepb" 23 "github.com/cockroachdb/cockroach/pkg/util/hlc" 24 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 25 "github.com/cockroachdb/cockroach/pkg/util/stop" 26 "github.com/gogo/protobuf/proto" 27 ) 28 29 func TestMergeQueueShouldQueue(t *testing.T) { 30 defer leaktest.AfterTest(t)() 31 32 ctx := context.Background() 33 testCtx := testContext{} 34 stopper := stop.NewStopper() 35 defer stopper.Stop(ctx) 36 testCtx.Start(t, stopper) 37 38 mq := newMergeQueue(testCtx.store, testCtx.store.DB(), testCtx.gossip) 39 kvserverbase.MergeQueueEnabled.Override(&testCtx.store.ClusterSettings().SV, true) 40 41 tableKey := func(i uint32) []byte { 42 return keys.SystemSQLCodec.TablePrefix(keys.MaxReservedDescID + i) 43 } 44 45 config.TestingSetZoneConfig(keys.MaxReservedDescID+1, *zonepb.NewZoneConfig()) 46 config.TestingSetZoneConfig(keys.MaxReservedDescID+2, *zonepb.NewZoneConfig()) 47 48 type testCase struct { 49 startKey, endKey []byte 50 minBytes int64 51 bytes int64 52 expShouldQ bool 53 expPriority float64 54 } 55 56 testCases := []testCase{ 57 // The last range of table 1 should not be mergeable because table 2 exists. 58 { 59 startKey: tableKey(1), 60 endKey: tableKey(2), 61 minBytes: 1, 62 }, 63 { 64 startKey: append(tableKey(1), 'z'), 65 endKey: tableKey(2), 66 minBytes: 1, 67 }, 68 69 // Unlike the last range of table 1, the last range of table 2 is mergeable 70 // because there is no table that follows. (In this test, the system only 71 // knows about tables on which TestingSetZoneConfig has been called.) 72 { 73 startKey: tableKey(2), 74 endKey: tableKey(3), 75 minBytes: 1, 76 expShouldQ: true, 77 expPriority: 1, 78 }, 79 { 80 startKey: append(tableKey(2), 'z'), 81 endKey: tableKey(3), 82 minBytes: 1, 83 expShouldQ: true, 84 expPriority: 1, 85 }, 86 87 // The last range is never mergeable. 88 { 89 startKey: tableKey(3), 90 endKey: roachpb.KeyMax, 91 minBytes: 1, 92 }, 93 { 94 startKey: append(tableKey(3), 'z'), 95 endKey: roachpb.KeyMax, 96 minBytes: 1, 97 }, 98 99 // An interior range of a table is not mergeable if it meets or exceeds the 100 // minimum byte threshold. 101 { 102 startKey: tableKey(1), 103 endKey: append(tableKey(1), 'a'), 104 minBytes: 1024, 105 bytes: 1024, 106 expShouldQ: false, 107 expPriority: 0, 108 }, 109 { 110 startKey: tableKey(1), 111 endKey: append(tableKey(1), 'a'), 112 minBytes: 1024, 113 bytes: 1024, 114 expShouldQ: false, 115 expPriority: 0, 116 }, 117 // Edge case: a minimum byte threshold of zero. This effectively disables 118 // the threshold, as an empty range is no longer considered mergeable. 119 { 120 startKey: tableKey(1), 121 endKey: append(tableKey(1), 'a'), 122 minBytes: 0, 123 bytes: 0, 124 expShouldQ: false, 125 expPriority: 0, 126 }, 127 128 // An interior range of a table is mergeable if it does not meet the minimum 129 // byte threshold. Its priority is inversely related to its size. 130 { 131 startKey: tableKey(1), 132 endKey: append(tableKey(1), 'a'), 133 minBytes: 1024, 134 bytes: 0, 135 expShouldQ: true, 136 expPriority: 1, 137 }, 138 { 139 startKey: tableKey(1), 140 endKey: append(tableKey(1), 'a'), 141 minBytes: 1024, 142 bytes: 768, 143 expShouldQ: true, 144 expPriority: 0.25, 145 }, 146 } 147 148 for _, tc := range testCases { 149 t.Run("", func(t *testing.T) { 150 repl := &Replica{} 151 repl.mu.state.Desc = &roachpb.RangeDescriptor{StartKey: tc.startKey, EndKey: tc.endKey} 152 repl.mu.state.Stats = &enginepb.MVCCStats{KeyBytes: tc.bytes} 153 zoneConfig := zonepb.DefaultZoneConfigRef() 154 zoneConfig.RangeMinBytes = proto.Int64(tc.minBytes) 155 repl.SetZoneConfig(zoneConfig) 156 shouldQ, priority := mq.shouldQueue(ctx, hlc.Timestamp{}, repl, config.NewSystemConfig(zoneConfig)) 157 if tc.expShouldQ != shouldQ { 158 t.Errorf("incorrect shouldQ: expected %v but got %v", tc.expShouldQ, shouldQ) 159 } 160 if tc.expPriority != priority { 161 t.Errorf("incorrect priority: expected %v but got %v", tc.expPriority, priority) 162 } 163 }) 164 } 165 }