hermez-node/db/kvdb/kvdb_test.go
db/kvdb/kvdb_test.goRaw
1package kvdb
2
3import (
4 "fmt"
5 "io/ioutil"
6 "os"
7 "testing"
8
9 "github.com/hermeznetwork/hermez-node/common"
10 "github.com/stretchr/testify/assert"
11 "github.com/stretchr/testify/require"
12)
13
14func addTestKV(t *testing.T, db *KVDB, k, v []byte) {
15 tx, err := db.db.NewTx()
16 require.NoError(t, err)
17
18 err = tx.Put(k, v)
19 require.NoError(t, err)
20
21 err = tx.Commit()
22 require.NoError(t, err)
23}
24
25func printCheckpoints(t *testing.T, path string) {
26 files, err := ioutil.ReadDir(path)
27 require.NoError(t, err)
28
29 fmt.Println(path)
30 for _, f := range files {
31 fmt.Println(" " + f.Name())
32 }
33}
34
35func TestCheckpoints(t *testing.T) {
36 dir, err := ioutil.TempDir("", "sdb")
37 require.NoError(t, err)
38 defer require.NoError(t, os.RemoveAll(dir))
39
40 db, err := NewKVDB(Config{Path: dir, Keep: 128})
41 require.NoError(t, err)
42
43 // add test key-values
44 for i := 0; i < 10; i++ {
45 addTestKV(t, db, []byte{byte(i), byte(i)}, []byte{byte(i * 2), byte(i * 2)})
46 }
47
48 // do checkpoints and check that currentBatch is correct
49 err = db.MakeCheckpoint()
50 require.NoError(t, err)
51 cb, err := db.GetCurrentBatch()
52 require.NoError(t, err)
53 assert.Equal(t, common.BatchNum(1), cb)
54
55 for i := 1; i < 10; i++ {
56 err = db.MakeCheckpoint()
57 require.NoError(t, err)
58
59 cb, err = db.GetCurrentBatch()
60 require.NoError(t, err)
61 assert.Equal(t, common.BatchNum(i+1), cb)
62 }
63
64 // printCheckpoints(t, db.path)
65
66 // reset checkpoint
67 err = db.Reset(3)
68 require.NoError(t, err)
69
70 // check that reset can be repeated (as there exist the 'current' and
71 // 'BatchNum3', from where the 'current' is a copy)
72 err = db.Reset(3)
73 require.NoError(t, err)
74
75 printCheckpoints(t, db.cfg.Path)
76
77 // check that currentBatch is as expected after Reset
78 cb, err = db.GetCurrentBatch()
79 require.NoError(t, err)
80 assert.Equal(t, common.BatchNum(3), cb)
81
82 // advance one checkpoint and check that currentBatch is fine
83 err = db.MakeCheckpoint()
84 require.NoError(t, err)
85 cb, err = db.GetCurrentBatch()
86 require.NoError(t, err)
87 assert.Equal(t, common.BatchNum(4), cb)
88
89 err = db.DeleteCheckpoint(common.BatchNum(1))
90 require.NoError(t, err)
91 err = db.DeleteCheckpoint(common.BatchNum(2))
92 require.NoError(t, err)
93 err = db.DeleteCheckpoint(common.BatchNum(1)) // does not exist, should return err
94 assert.NotNil(t, err)
95 err = db.DeleteCheckpoint(common.BatchNum(2)) // does not exist, should return err
96 assert.NotNil(t, err)
97
98 // Create a new KVDB which will get Reset from the initial KVDB
99 dirLocal, err := ioutil.TempDir("", "ldb")
100 require.NoError(t, err)
101 defer require.NoError(t, os.RemoveAll(dirLocal))
102 ldb, err := NewKVDB(Config{Path: dirLocal, Keep: 128})
103 require.NoError(t, err)
104
105 // get checkpoint 4 from sdb (StateDB) to ldb (LocalStateDB)
106 err = ldb.ResetFromSynchronizer(4, db)
107 require.NoError(t, err)
108 // check that currentBatch is 4 after the Reset
109 cb, err = ldb.GetCurrentBatch()
110 require.NoError(t, err)
111 assert.Equal(t, common.BatchNum(4), cb)
112 // advance one checkpoint in ldb
113 err = ldb.MakeCheckpoint()
114 require.NoError(t, err)
115 cb, err = ldb.GetCurrentBatch()
116 require.NoError(t, err)
117 assert.Equal(t, common.BatchNum(5), cb)
118
119 // Create a 3rd KVDB which will get Reset from the initial KVDB
120 dirLocal2, err := ioutil.TempDir("", "ldb2")
121 require.NoError(t, err)
122 defer require.NoError(t, os.RemoveAll(dirLocal2))
123 ldb2, err := NewKVDB(Config{Path: dirLocal2, Keep: 128})
124 require.NoError(t, err)
125
126 // get checkpoint 4 from sdb (StateDB) to ldb (LocalStateDB)
127 err = ldb2.ResetFromSynchronizer(4, db)
128 require.NoError(t, err)
129 // check that currentBatch is 4 after the Reset
130 cb, err = ldb2.GetCurrentBatch()
131 require.NoError(t, err)
132 assert.Equal(t, common.BatchNum(4), cb)
133 // advance one checkpoint in ldb2
134 err = ldb2.MakeCheckpoint()
135 require.NoError(t, err)
136 cb, err = ldb2.GetCurrentBatch()
137 require.NoError(t, err)
138 assert.Equal(t, common.BatchNum(5), cb)
139
140 debug := false
141 if debug {
142 printCheckpoints(t, db.cfg.Path)
143 printCheckpoints(t, ldb.cfg.Path)
144 printCheckpoints(t, ldb2.cfg.Path)
145 }
146}
147
148func TestListCheckpoints(t *testing.T) {
149 dir, err := ioutil.TempDir("", "tmpdb")
150 require.NoError(t, err)
151 defer require.NoError(t, os.RemoveAll(dir))
152
153 db, err := NewKVDB(Config{Path: dir, Keep: 128})
154 require.NoError(t, err)
155
156 numCheckpoints := 16
157 // do checkpoints
158 for i := 0; i < numCheckpoints; i++ {
159 err = db.MakeCheckpoint()
160 require.NoError(t, err)
161 }
162 list, err := db.ListCheckpoints()
163 require.NoError(t, err)
164 assert.Equal(t, numCheckpoints, len(list))
165 assert.Equal(t, 1, list[0])
166 assert.Equal(t, numCheckpoints, list[len(list)-1])
167
168 numReset := 10
169 err = db.Reset(common.BatchNum(numReset))
170 require.NoError(t, err)
171 list, err = db.ListCheckpoints()
172 require.NoError(t, err)
173 assert.Equal(t, numReset, len(list))
174 assert.Equal(t, 1, list[0])
175 assert.Equal(t, numReset, list[len(list)-1])
176}
177
178func TestDeleteOldCheckpoints(t *testing.T) {
179 dir, err := ioutil.TempDir("", "tmpdb")
180 require.NoError(t, err)
181 defer require.NoError(t, os.RemoveAll(dir))
182
183 keep := 16
184 db, err := NewKVDB(Config{Path: dir, Keep: keep})
185 require.NoError(t, err)
186
187 numCheckpoints := 32
188 // do checkpoints and check that we never have more than `keep`
189 // checkpoints
190 for i := 0; i < numCheckpoints; i++ {
191 err = db.MakeCheckpoint()
192 require.NoError(t, err)
193 checkpoints, err := db.ListCheckpoints()
194 require.NoError(t, err)
195 assert.LessOrEqual(t, len(checkpoints), keep)
196 }
197}
198
199func TestGetCurrentIdx(t *testing.T) {
200 dir, err := ioutil.TempDir("", "tmpdb")
201 require.NoError(t, err)
202 defer require.NoError(t, os.RemoveAll(dir))
203
204 keep := 16
205 db, err := NewKVDB(Config{Path: dir, Keep: keep})
206 require.NoError(t, err)
207
208 idx, err := db.GetCurrentIdx()
209 require.NoError(t, err)
210 assert.Equal(t, common.Idx(255), idx)
211
212 db.Close()
213
214 db, err = NewKVDB(Config{Path: dir, Keep: keep})
215 require.NoError(t, err)
216
217 idx, err = db.GetCurrentIdx()
218 require.NoError(t, err)
219 assert.Equal(t, common.Idx(255), idx)
220
221 err = db.MakeCheckpoint()
222 require.NoError(t, err)
223
224 idx, err = db.GetCurrentIdx()
225 require.NoError(t, err)
226 assert.Equal(t, common.Idx(255), idx)
227
228 db.Close()
229
230 db, err = NewKVDB(Config{Path: dir, Keep: keep})
231 require.NoError(t, err)
232
233 idx, err = db.GetCurrentIdx()
234 require.NoError(t, err)
235 assert.Equal(t, common.Idx(255), idx)
236}