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 assert.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 assert.NoError(t, os.RemoveAll(dir))
39
40 db, err := NewKVDB(dir, 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 assert.NoError(t, err)
51 cb, err := db.GetCurrentBatch()
52 assert.NoError(t, err)
53 assert.Equal(t, common.BatchNum(1), cb)
54
55 for i := 1; i < 10; i++ {
56 err = db.MakeCheckpoint()
57 assert.NoError(t, err)
58
59 cb, err = db.GetCurrentBatch()
60 assert.NoError(t, err)
61 assert.Equal(t, common.BatchNum(i+1), cb)
62 }
63
64 // printCheckpoints(t, sdb.path)
65
66 // reset checkpoint
67 err = db.Reset(3)
68 assert.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 // check that currentBatch is as expected after Reset
76 cb, err = db.GetCurrentBatch()
77 assert.NoError(t, err)
78 assert.Equal(t, common.BatchNum(3), cb)
79
80 // advance one checkpoint and check that currentBatch is fine
81 err = db.MakeCheckpoint()
82 assert.NoError(t, err)
83 cb, err = db.GetCurrentBatch()
84 assert.NoError(t, err)
85 assert.Equal(t, common.BatchNum(4), cb)
86
87 err = db.DeleteCheckpoint(common.BatchNum(1))
88 assert.NoError(t, err)
89 err = db.DeleteCheckpoint(common.BatchNum(2))
90 assert.NoError(t, err)
91 err = db.DeleteCheckpoint(common.BatchNum(1)) // does not exist, should return err
92 assert.NotNil(t, err)
93 err = db.DeleteCheckpoint(common.BatchNum(2)) // does not exist, should return err
94 assert.NotNil(t, err)
95
96 // Create a new KVDB which will get Reset from the initial KVDB
97 dirLocal, err := ioutil.TempDir("", "ldb")
98 require.NoError(t, err)
99 defer assert.NoError(t, os.RemoveAll(dirLocal))
100 ldb, err := NewKVDB(dirLocal, 128)
101 assert.NoError(t, err)
102
103 // get checkpoint 4 from sdb (StateDB) to ldb (LocalStateDB)
104 err = ldb.ResetFromSynchronizer(4, db)
105 assert.NoError(t, err)
106 // check that currentBatch is 4 after the Reset
107 cb, err = ldb.GetCurrentBatch()
108 assert.NoError(t, err)
109 assert.Equal(t, common.BatchNum(4), cb)
110 // advance one checkpoint in ldb
111 err = ldb.MakeCheckpoint()
112 assert.NoError(t, err)
113 cb, err = ldb.GetCurrentBatch()
114 assert.NoError(t, err)
115 assert.Equal(t, common.BatchNum(5), cb)
116
117 // Create a 3rd KVDB which will get Reset from the initial KVDB
118 dirLocal2, err := ioutil.TempDir("", "ldb2")
119 require.NoError(t, err)
120 defer assert.NoError(t, os.RemoveAll(dirLocal2))
121 ldb2, err := NewKVDB(dirLocal2, 128)
122 assert.NoError(t, err)
123
124 // get checkpoint 4 from sdb (StateDB) to ldb (LocalStateDB)
125 err = ldb2.ResetFromSynchronizer(4, db)
126 assert.NoError(t, err)
127 // check that currentBatch is 4 after the Reset
128 cb, err = ldb2.GetCurrentBatch()
129 assert.NoError(t, err)
130 assert.Equal(t, common.BatchNum(4), cb)
131 // advance one checkpoint in ldb2
132 err = ldb2.MakeCheckpoint()
133 assert.NoError(t, err)
134 cb, err = ldb2.GetCurrentBatch()
135 assert.NoError(t, err)
136 assert.Equal(t, common.BatchNum(5), cb)
137
138 debug := false
139 if debug {
140 printCheckpoints(t, db.path)
141 printCheckpoints(t, ldb.path)
142 printCheckpoints(t, ldb2.path)
143 }
144}
145
146func TestListCheckpoints(t *testing.T) {
147 dir, err := ioutil.TempDir("", "tmpdb")
148 require.NoError(t, err)
149 defer assert.NoError(t, os.RemoveAll(dir))
150
151 db, err := NewKVDB(dir, 128)
152 require.NoError(t, err)
153
154 numCheckpoints := 16
155 // do checkpoints
156 for i := 0; i < numCheckpoints; i++ {
157 err = db.MakeCheckpoint()
158 require.NoError(t, err)
159 }
160 list, err := db.ListCheckpoints()
161 require.NoError(t, err)
162 assert.Equal(t, numCheckpoints, len(list))
163 assert.Equal(t, 1, list[0])
164 assert.Equal(t, numCheckpoints, list[len(list)-1])
165
166 numReset := 10
167 err = db.Reset(common.BatchNum(numReset))
168 require.NoError(t, err)
169 list, err = db.ListCheckpoints()
170 require.NoError(t, err)
171 assert.Equal(t, numReset, len(list))
172 assert.Equal(t, 1, list[0])
173 assert.Equal(t, numReset, list[len(list)-1])
174}
175
176func TestDeleteOldCheckpoints(t *testing.T) {
177 dir, err := ioutil.TempDir("", "tmpdb")
178 require.NoError(t, err)
179 defer assert.NoError(t, os.RemoveAll(dir))
180
181 keep := 16
182 db, err := NewKVDB(dir, keep)
183 require.NoError(t, err)
184
185 numCheckpoints := 32
186 // do checkpoints and check that we never have more than `keep`
187 // checkpoints
188 for i := 0; i < numCheckpoints; i++ {
189 err = db.MakeCheckpoint()
190 require.NoError(t, err)
191 checkpoints, err := db.ListCheckpoints()
192 require.NoError(t, err)
193 assert.LessOrEqual(t, len(checkpoints), keep)
194 }
195}