erigon-pulse/ethdb/abstract_test.go
Alex Sharov c5ffc971c5
[WIP] Badger v2 (#378)
* badger v2 investigation

* buf pool - use native New method and avoid double checks

* db.Open prototype

* db.Tx/Bucket/Cursor prototypes

* Chained config

* Item concept added

* save changes to test on master

* make hack resumable

* Design document v0

* Cursor concept

* less brackets syntax of cursor builder

* benchmarks

* cleanup fs

* test for context cancelations

* test for context cancelations

* test for cursor.Prefix option

* add ForEachKey method

* add ForEachKey method

* add naming explanation

* experiment of non-pointers cursor/bucket

* .Bucket() and .Cursor() doesn't returns error

* .Bucket() and .Cursor() doesn't returns error

* .Bucket() and .Cursor() doesn't returns error

* remove CursorOpts concept

* more test-cases

* simplify open api

* Tx, Bucket, Cursor - now are interfaces

* Tx, Bucket, Cursor - now are interfaces

* switch to interfaces

* rebase master

Co-authored-by: alex.sharov <alex.sharov@lazada.com>
2020-03-11 11:02:37 +00:00

258 lines
5.8 KiB
Go

package ethdb_test
import (
"context"
"errors"
"testing"
"time"
"github.com/ledgerwatch/turbo-geth/common"
"github.com/ledgerwatch/turbo-geth/common/dbutils"
"github.com/ledgerwatch/turbo-geth/ethdb"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestManagedTx(t *testing.T) {
ctx := context.Background()
t.Run("Bolt", func(t *testing.T) {
var db ethdb.DB
var errOpen error
db, errOpen = ethdb.NewBolt().InMem(true).Open(ctx)
assert.NoError(t, errOpen)
if err := db.Update(ctx, func(tx ethdb.Tx) error {
b := tx.Bucket(dbutils.AccountsBucket)
if err := b.Put([]byte("key1"), []byte("val1")); err != nil {
return err
}
if err := b.Put([]byte("key2"), []byte("val2")); err != nil {
return err
}
return nil
}); err != nil {
assert.NoError(t, err)
}
if err := db.View(ctx, func(tx ethdb.Tx) error {
b := tx.Bucket(dbutils.AccountsBucket)
c := b.Cursor().Prefetch(1000)
// b.Cursor().Prefetch(1000)
// c := tx.Bucket(dbutils.AccountsBucket).Cursor().Prefetch(1000)
for k, v, err := c.First(); k != nil || err != nil; k, v, err = c.Next() {
if err != nil {
return err
}
_ = v
}
for k, vSize, err := c.FirstKey(); k != nil || err != nil; k, vSize, err = c.NextKey() {
if err != nil {
return err
}
_ = vSize
}
for k, v, err := c.Seek([]byte("prefix")); k != nil || err != nil; k, v, err = c.Next() {
if err != nil {
return err
}
_ = v
}
return nil
}); err != nil {
assert.NoError(t, err)
}
})
t.Run("Badger", func(t *testing.T) {
var db ethdb.DB
var errOpen error
db, errOpen = ethdb.NewBadger().InMem(true).Open(ctx)
assert.NoError(t, errOpen)
if err := db.Update(ctx, func(tx ethdb.Tx) error {
b := tx.Bucket(dbutils.AccountsBucket)
if err := b.Put([]byte{0, 1}, []byte{1}); err != nil {
return err
}
if err := b.Put([]byte{0, 0, 1}, []byte{1}); err != nil {
return err
}
if err := b.Put([]byte{2}, []byte{1}); err != nil {
return err
}
if err := b.Put([]byte{1}, []byte{1}); err != nil {
return err
}
return nil
}); err != nil {
assert.NoError(t, err)
}
if err := db.View(ctx, func(tx ethdb.Tx) error {
b := tx.Bucket(dbutils.AccountsBucket)
//err := b.Iter().From(key).MatchBits(common.HashLength * 8).Walk()
//err := b.Cursor().From(key).MatchBits(common.HashLength * 8).Walk(func(k, v []byte) (bool, error) {
//})
//err := b.Cursor().From(key).MatchBits(common.HashLength * 8).Walk(func(k, v []byte) (bool, error) {
//})
//
//c, err := b.IterOpts().From(key).MatchBits(common.HashLength * 8).Iter()
//c, err := tx.Bucket(dbutil.AccountBucket).CursorOpts().From(key).Cursor()
//
//c, err := b.Cursor(b.CursorOpts().From(key).MatchBits(common.HashLength * 8))
c := b.Cursor()
for k, v, err := c.First(); k != nil || err != nil; k, v, err = c.Next() {
if err != nil {
return err
}
_ = v
}
for k, vSize, err := c.FirstKey(); k != nil || err != nil; k, vSize, err = c.NextKey() {
if err != nil {
return err
}
_ = vSize
}
for k, v, err := c.Seek([]byte("prefix")); k != nil || err != nil; k, v, err = c.Next() {
if err != nil {
return err
}
_ = v
}
k, _, err := c.First()
assert.NoError(t, err)
assert.Equal(t, []byte{0, 0, 1}, k)
k, _, err = c.Next()
assert.NoError(t, err)
assert.Equal(t, []byte{0, 1}, k)
k, _, err = c.Next()
assert.NoError(t, err)
assert.Equal(t, []byte{1}, k)
k, _, err = c.Next()
assert.NoError(t, err)
assert.Equal(t, []byte{2}, k)
return nil
}); err != nil {
assert.NoError(t, err)
}
})
}
func TestCancelTest(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Microsecond)
defer cancel()
var db ethdb.DB
var errOpen error
db, errOpen = ethdb.NewBolt().InMem(true).Open(ctx)
assert.NoError(t, errOpen)
if err := db.Update(ctx, func(tx ethdb.Tx) error {
b := tx.Bucket(dbutils.AccountsBucket)
if err := b.Put([]byte{1}, []byte{1}); err != nil {
return err
}
c := b.Cursor()
for {
for k, _, err := c.First(); k != nil || err != nil; k, _, err = c.Next() {
if err != nil {
return err
}
}
}
}); err != nil {
require.True(t, errors.Is(context.DeadlineExceeded, err))
}
}
func TestFilterTest(t *testing.T) {
ctx := context.Background()
var db ethdb.DB
var errOpen error
db, errOpen = ethdb.NewBolt().InMem(true).Open(ctx)
assert.NoError(t, errOpen)
if err := db.Update(ctx, func(tx ethdb.Tx) error {
b := tx.Bucket(dbutils.AccountsBucket)
if err := b.Put(common.FromHex("10"), []byte{1}); err != nil {
return err
}
if err := b.Put(common.FromHex("20"), []byte{1}); err != nil {
return nil
}
c := b.Cursor().Prefix(common.FromHex("2"))
counter := 0
for k, _, err := c.First(); k != nil || err != nil; k, _, err = c.Next() {
if err != nil {
return err
}
counter++
}
assert.Equal(t, 1, counter)
counter = 0
if err := c.Walk(func(_, _ []byte) (bool, error) {
counter++
return true, nil
}); err != nil {
return err
}
assert.Equal(t, 1, counter)
c = b.Cursor()
counter = 0
for k, _, err := c.First(); k != nil || err != nil; k, _, err = c.Next() {
if err != nil {
return err
}
counter++
}
assert.Equal(t, 2, counter)
counter = 0
if err := c.Walk(func(_, _ []byte) (bool, error) {
counter++
return true, nil
}); err != nil {
return err
}
assert.Equal(t, 2, counter)
return nil
}); err != nil {
require.NoError(t, err)
}
}
func TestUnmanagedTx(t *testing.T) {
ctx := context.Background()
t.Run("Bolt", func(t *testing.T) {
var db ethdb.DB
var errOpen error
db, errOpen = ethdb.NewBolt().InMem(true).Open(ctx)
assert.NoError(t, errOpen)
_ = db
// db.Begin()
})
}