github.com/iotexproject/iotex-core@v1.14.1-rc1/db/db_bolt_test.go (about) 1 // Copyright (c) 2019 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package db 7 8 import ( 9 "context" 10 "fmt" 11 "math/rand" 12 "syscall" 13 "testing" 14 15 "github.com/pkg/errors" 16 "github.com/stretchr/testify/require" 17 18 "github.com/iotexproject/iotex-core/db/batch" 19 "github.com/iotexproject/iotex-core/testutil" 20 ) 21 22 func TestBoltDB_NilDB_DoesNotPanic(t *testing.T) { 23 r := require.New(t) 24 25 cfg := DefaultConfig 26 kv := NewBoltDB(cfg) 27 28 // ensure all methods return the error instead of panicking if the db is nil. 29 r.Equal(kv.BucketExists("namespace"), false) 30 31 _, _, err := kv.Filter("namespace", func(k, v []byte) bool { 32 return true 33 }, []byte("minKey"), []byte("maxKey")) 34 r.Errorf(err, "db hasn't started") 35 36 _, err = kv.Get("namespace", []byte("test")) 37 r.Errorf(err, "db hasn't started") 38 39 _, err = kv.GetBucketByPrefix([]byte("namespace")) 40 r.Errorf(err, "db hasn't started") 41 _, err = kv.GetKeyByPrefix([]byte("namespace"), []byte("prefix")) 42 r.Errorf(err, "db hasn't started") 43 44 r.Errorf(kv.Delete("test", []byte("key")), "db hasn't started") 45 r.Errorf(kv.Purge([]byte("name"), 123), "db hasn't started") 46 r.Errorf(kv.Insert([]byte("name"), 123, []byte("value")), "db hasn't started") 47 r.Errorf(kv.Put("test", []byte("key"), []byte("value")), "db hasn't started") 48 r.Errorf(kv.Remove([]byte("name"), 123), "db hasn't started") 49 r.Errorf(kv.WriteBatch(batch.NewBatch()), "db hasn't started") 50 51 _, err = kv.Range("namespace", []byte("key"), 0) 52 r.Errorf(err, "db hasn't started") 53 54 _, err = kv.SeekNext([]byte("key"), 12) 55 r.Errorf(err, "db hasn't started") 56 57 _, err = kv.SeekPrev([]byte("key"), 12) 58 r.Errorf(err, "db hasn't started") 59 } 60 61 func TestBucketExists(t *testing.T) { 62 r := require.New(t) 63 testPath, err := testutil.PathOfTempFile("test-bucket") 64 r.NoError(err) 65 defer func() { 66 testutil.CleanupPath(testPath) 67 }() 68 69 cfg := DefaultConfig 70 cfg.DbPath = testPath 71 kv := NewBoltDB(cfg) 72 ctx := context.Background() 73 r.NoError(kv.Start(ctx)) 74 defer kv.Stop(ctx) 75 r.False(kv.BucketExists("name")) 76 r.NoError(kv.Put("name", []byte("key"), []byte{})) 77 r.True(kv.BucketExists("name")) 78 v, err := kv.Get("name", []byte("key")) 79 r.NoError(err) 80 r.Equal([]byte{}, v) 81 } 82 83 func TestDiskfullErr(t *testing.T) { 84 err := fmt.Errorf("write /run/data/chain.db: %w", syscall.ENOSPC) 85 require.True(t, errors.Is(err, syscall.ENOSPC)) 86 } 87 88 func BenchmarkBoltDB_Get(b *testing.B) { 89 runBenchmark := func(b *testing.B, size int) { 90 path, err := testutil.PathOfTempFile("boltdb") 91 require.NoError(b, err) 92 defer testutil.CleanupPath(path) 93 db := BoltDB{ 94 path: path, 95 config: DefaultConfig, 96 } 97 db.Start(context.Background()) 98 defer db.Stop(context.Background()) 99 100 key := []byte("key") 101 data := make([]byte, size) 102 for i := range data { 103 data[i] = byte(rand.Int()) 104 } 105 require.NoError(b, db.Put("ns", key, data)) 106 107 b.ResetTimer() 108 for n := 0; n < b.N; n++ { 109 b.StartTimer() 110 _, err := db.Get("ns", key) 111 b.StopTimer() 112 require.NoError(b, err) 113 } 114 } 115 116 b.Run("100", func(b *testing.B) { 117 runBenchmark(b, 100) 118 }) 119 b.Run("10000", func(b *testing.B) { 120 runBenchmark(b, 100) 121 }) 122 b.Run("1000000", func(b *testing.B) { 123 runBenchmark(b, 100) 124 }) 125 }