1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package mvcc
16
17 import (
18 "context"
19 "os"
20 "reflect"
21 "testing"
22 "time"
23
24 "go.etcd.io/etcd/pkg/v3/traceutil"
25 "go.etcd.io/etcd/server/v3/lease"
26 betesting "go.etcd.io/etcd/server/v3/mvcc/backend/testing"
27 "go.etcd.io/etcd/server/v3/mvcc/buckets"
28 "go.uber.org/zap"
29 "go.uber.org/zap/zaptest"
30 )
31
32 func TestScheduleCompaction(t *testing.T) {
33 revs := []revision{{1, 0}, {2, 0}, {3, 0}}
34
35 tests := []struct {
36 rev int64
37 keep map[revision]struct{}
38 wrevs []revision
39 }{
40
41 {
42 1,
43 nil,
44 revs[1:],
45 },
46
47 {
48 3,
49 nil,
50 nil,
51 },
52
53 {
54 1,
55 map[revision]struct{}{
56 {main: 1}: {},
57 },
58 revs,
59 },
60
61 {
62 3,
63 map[revision]struct{}{
64 {main: 2}: {},
65 {main: 3}: {},
66 },
67 revs[1:],
68 },
69 }
70 for i, tt := range tests {
71 b, tmpPath := betesting.NewDefaultTmpBackend(t)
72 s := NewStore(zaptest.NewLogger(t), b, &lease.FakeLessor{}, StoreConfig{})
73 fi := newFakeIndex()
74 fi.indexCompactRespc <- tt.keep
75 s.kvindex = fi
76
77 tx := s.b.BatchTx()
78
79 tx.Lock()
80 ibytes := newRevBytes()
81 for _, rev := range revs {
82 revToBytes(rev, ibytes)
83 tx.UnsafePut(buckets.Key, ibytes, []byte("bar"))
84 }
85 tx.Unlock()
86
87 _, err := s.scheduleCompaction(tt.rev, 0)
88 if err != nil {
89 t.Error(err)
90 }
91
92 tx.Lock()
93 for _, rev := range tt.wrevs {
94 revToBytes(rev, ibytes)
95 keys, _ := tx.UnsafeRange(buckets.Key, ibytes, nil, 0)
96 if len(keys) != 1 {
97 t.Errorf("#%d: range on %v = %d, want 1", i, rev, len(keys))
98 }
99 }
100 _, vals := tx.UnsafeRange(buckets.Meta, finishedCompactKeyName, nil, 0)
101 revToBytes(revision{main: tt.rev}, ibytes)
102 if w := [][]byte{ibytes}; !reflect.DeepEqual(vals, w) {
103 t.Errorf("#%d: vals on %v = %+v, want %+v", i, finishedCompactKeyName, vals, w)
104 }
105 tx.Unlock()
106
107 cleanup(s, b, tmpPath)
108 }
109 }
110
111 func TestCompactAllAndRestore(t *testing.T) {
112 b, tmpPath := betesting.NewDefaultTmpBackend(t)
113 s0 := NewStore(zap.NewExample(), b, &lease.FakeLessor{}, StoreConfig{})
114 defer os.Remove(tmpPath)
115
116 s0.Put([]byte("foo"), []byte("bar"), lease.NoLease)
117 s0.Put([]byte("foo"), []byte("bar1"), lease.NoLease)
118 s0.Put([]byte("foo"), []byte("bar2"), lease.NoLease)
119 s0.DeleteRange([]byte("foo"), nil)
120
121 rev := s0.Rev()
122
123 done, err := s0.Compact(traceutil.TODO(), rev)
124 if err != nil {
125 t.Fatal(err)
126 }
127
128 select {
129 case <-done:
130 case <-time.After(10 * time.Second):
131 t.Fatal("timeout waiting for compaction to finish")
132 }
133
134 err = s0.Close()
135 if err != nil {
136 t.Fatal(err)
137 }
138
139 s1 := NewStore(zap.NewExample(), b, &lease.FakeLessor{}, StoreConfig{})
140 if s1.Rev() != rev {
141 t.Errorf("rev = %v, want %v", s1.Rev(), rev)
142 }
143 _, err = s1.Range(context.TODO(), []byte("foo"), nil, RangeOptions{})
144 if err != nil {
145 t.Errorf("unexpect range error %v", err)
146 }
147 }
148
View as plain text