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  }