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