arnaucube
arnaucube/asmtPublic Self-hosted repository
asmt/db/db_test.go
db/db_test.goRaw
  1/**
  2 *  @file
  3 *  @copyright defined in aergo/LICENSE.txt
  4 */
  5package db
  6
  7import (
  8	"fmt"
  9	"io/ioutil"
 10	"log"
 11	"os"
 12	"strconv"
 13	"testing"
 14
 15	"github.com/stretchr/testify/assert"
 16)
 17
 18const (
 19	tmpDbTestKey1    = "tempkey1"
 20	tmpDbTestKey2    = "tempkey2"
 21	tmpDbTestStrVal1 = "val1"
 22	tmpDbTestStrVal2 = "val2"
 23	tmpDbTestIntVal1 = 1
 24	tmpDbTestIntVal2 = 2
 25)
 26
 27func createTmpDB(key ImplType) (dir string, db DB) {
 28	dir, err := ioutil.TempDir("", string(key))
 29	if err != nil {
 30		log.Fatal(err)
 31	}
 32
 33	db = NewDB(key, dir)
 34
 35	return
 36}
 37
 38func setInitData(db DB) {
 39	tx := db.NewTx()
 40
 41	tx.Set([]byte("1"), []byte("1"))
 42	tx.Set([]byte("2"), []byte("2"))
 43	tx.Set([]byte("3"), []byte("3"))
 44	tx.Set([]byte("4"), []byte("4"))
 45	tx.Set([]byte("5"), []byte("5"))
 46	tx.Set([]byte("6"), []byte("6"))
 47	tx.Set([]byte("7"), []byte("7"))
 48
 49	tx.Commit()
 50}
 51
 52func TestGetSetDeleteExist(t *testing.T) {
 53	// for each db implementation
 54	for key := range dbImpls {
 55		dir, db := createTmpDB(key)
 56
 57		// initial value of empty key must be empty byte
 58		assert.Empty(t, db.Get([]byte(tmpDbTestKey1)), db.Type())
 59		assert.False(t, db.Exist([]byte(tmpDbTestKey1)), db.Type())
 60
 61		// set value
 62		db.Set([]byte(tmpDbTestKey1), []byte(tmpDbTestStrVal1))
 63
 64		// check value set
 65		assert.Equal(t, tmpDbTestStrVal1, string(db.Get([]byte(tmpDbTestKey1))), db.Type())
 66		assert.True(t, db.Exist([]byte(tmpDbTestKey1)), db.Type())
 67
 68		// delete value
 69		db.Delete([]byte(tmpDbTestKey1))
 70
 71		// value must be erased
 72		assert.Empty(t, db.Get([]byte(tmpDbTestKey1)), db.Type())
 73		assert.False(t, db.Exist([]byte(tmpDbTestKey1)), db.Type())
 74
 75		db.Close()
 76		os.RemoveAll(dir)
 77	}
 78}
 79
 80func TestTransactionSet(t *testing.T) {
 81
 82	for key := range dbImpls {
 83		dir, db := createTmpDB(key)
 84
 85		// create a new writable tx
 86		tx := db.NewTx()
 87
 88		// set the value in the tx
 89		tx.Set([]byte(tmpDbTestKey1), []byte(tmpDbTestStrVal1))
 90		// the value will not visible at a db
 91		assert.Empty(t, db.Get([]byte(tmpDbTestKey1)), db.Type())
 92
 93		tx.Commit()
 94
 95		// after commit, the value visible from the db
 96		assert.Equal(t, tmpDbTestStrVal1, string(db.Get([]byte(tmpDbTestKey1))), db.Type())
 97
 98		db.Close()
 99		os.RemoveAll(dir)
100	}
101}
102
103func TestTransactionDiscard(t *testing.T) {
104
105	for key := range dbImpls {
106		dir, db := createTmpDB(key)
107
108		// create a new writable tx
109		tx := db.NewTx()
110		// discard test
111		tx = db.NewTx()
112		// set the value in the tx
113		tx.Set([]byte(tmpDbTestKey1), []byte(tmpDbTestStrVal2))
114
115		// discard tx
116		tx.Discard()
117
118		assert.Panics(t, func() { tx.Commit() }, "commit after discard is not allowed")
119
120		// after discard, the value must be reset at the db
121		assert.False(t, db.Exist([]byte(tmpDbTestKey1)), db.Type())
122
123		db.Close()
124		os.RemoveAll(dir)
125	}
126}
127
128func TestTransactionDelete(t *testing.T) {
129
130	for key := range dbImpls {
131		dir, db := createTmpDB(key)
132
133		// create a new writable tx
134		tx := db.NewTx()
135
136		// set the value in the tx
137		tx.Set([]byte(tmpDbTestKey1), []byte(tmpDbTestStrVal1))
138
139		// delete the value in the tx
140		tx.Delete([]byte(tmpDbTestKey1))
141
142		tx.Commit()
143
144		// after commit, chekc the value from the db
145		assert.Equal(t, "", string(db.Get([]byte(tmpDbTestKey1))), db.Type())
146
147		db.Close()
148		os.RemoveAll(dir)
149	}
150}
151
152func TestTransactionCommitTwice(t *testing.T) {
153	for key := range dbImpls {
154		dir, db := createTmpDB(key)
155
156		// create a new writable tx
157		tx := db.NewTx()
158
159		// a first commit will success
160		tx.Commit()
161
162		// a second commit will cause panic
163		assert.Panics(t, func() { tx.Commit() })
164
165		db.Close()
166		os.RemoveAll(dir)
167	}
168}
169
170func TestBulk(t *testing.T) {
171
172	for key := range dbImpls {
173		dir, db := createTmpDB(key)
174
175		// create a new Bulk instance
176		bulk := db.NewBulk()
177
178		// set the huge number of value in the bulk
179		for i := 0; i < 1000000; i++ {
180			bulk.Set([]byte(fmt.Sprintf("key%d", i)),
181				[]byte(tmpDbTestStrVal1))
182		}
183
184		bulk.Flush()
185
186		// after commit, the value visible from the db
187
188		for i := 0; i < 1000000; i++ {
189			assert.Equal(t, tmpDbTestStrVal1, string(db.Get([]byte(fmt.Sprintf("key%d", i)))), db.Type())
190		}
191
192		db.Close()
193		os.RemoveAll(dir)
194	}
195}
196
197func TestIter(t *testing.T) {
198
199	for key := range dbImpls {
200		dir, db := createTmpDB(key)
201
202		setInitData(db)
203
204		i := 1
205
206		for iter := db.Iterator(nil, nil); iter.Valid(); iter.Next() {
207			assert.EqualValues(t, strconv.Itoa(i), string(iter.Key()))
208			i++
209		}
210
211		db.Close()
212		os.RemoveAll(dir)
213	}
214}
215
216func TestRangeIter(t *testing.T) {
217
218	for key := range dbImpls {
219		dir, db := createTmpDB(key)
220
221		setInitData(db)
222
223		// test iteration 2 -> 5
224		i := 2
225		for iter := db.Iterator([]byte("2"), []byte("5")); iter.Valid(); iter.Next() {
226			assert.EqualValues(t, strconv.Itoa(i), string(iter.Key()))
227			assert.EqualValues(t, strconv.Itoa(i), string(iter.Value()))
228			i++
229		}
230		assert.EqualValues(t, i, 5)
231
232		// nil sames with []byte("0")
233		// test iteration 0 -> 5
234		i = 1
235		for iter := db.Iterator(nil, []byte("5")); iter.Valid(); iter.Next() {
236			assert.EqualValues(t, strconv.Itoa(i), string(iter.Key()))
237			assert.EqualValues(t, strconv.Itoa(i), string(iter.Value()))
238			i++
239		}
240		assert.EqualValues(t, i, 5)
241
242		db.Close()
243		os.RemoveAll(dir)
244	}
245}
246
247func TestReverseIter(t *testing.T) {
248
249	for key := range dbImpls {
250		dir, db := createTmpDB(key)
251
252		setInitData(db)
253
254		// test reverse iteration 5 <- 2
255		i := 5
256		for iter := db.Iterator([]byte("5"), []byte("2")); iter.Valid(); iter.Next() {
257			assert.EqualValues(t, strconv.Itoa(i), string(iter.Key()))
258			assert.EqualValues(t, strconv.Itoa(i), string(iter.Value()))
259			i--
260		}
261		assert.EqualValues(t, i, 2)
262
263		// nil sames with []byte("0")
264		// test reverse iteration 5 -> 0
265		i = 5
266		for iter := db.Iterator([]byte("5"), nil); iter.Valid(); iter.Next() {
267			assert.EqualValues(t, strconv.Itoa(i), string(iter.Key()))
268			assert.EqualValues(t, strconv.Itoa(i), string(iter.Value()))
269			i--
270		}
271		assert.EqualValues(t, i, 0)
272
273		db.Close()
274		os.RemoveAll(dir)
275	}
276}