arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
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}