github.com/iotexproject/iotex-core@v1.14.1-rc1/state/factory/workingsetstore_test.go (about)

     1  // Copyright (c) 2022 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 factory
     7  
     8  import (
     9  	"bytes"
    10  	"context"
    11  	"encoding/hex"
    12  	"testing"
    13  
    14  	"github.com/iotexproject/iotex-core/action/protocol"
    15  	"github.com/iotexproject/iotex-core/db"
    16  	"github.com/iotexproject/iotex-core/db/batch"
    17  	"github.com/iotexproject/iotex-core/pkg/util/byteutil"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func TestStateDBWorkingSetStore(t *testing.T) {
    22  	require := require.New(t)
    23  	ctx := context.Background()
    24  	view := protocol.View{}
    25  	inMemStore := db.NewMemKVStore()
    26  	flusher, err := db.NewKVStoreFlusher(inMemStore, batch.NewCachedBatch())
    27  	require.NoError(err)
    28  	store := newStateDBWorkingSetStore(view, flusher, true)
    29  	require.NotNil(store)
    30  	require.NoError(store.Start(ctx))
    31  	name := "name"
    32  	viewValue := "value"
    33  	namespace := "namespace"
    34  	key1 := []byte("key1")
    35  	value1 := []byte("value1")
    36  	key2 := []byte("key2")
    37  	value2 := []byte("value2")
    38  	key3 := []byte("key3")
    39  	value3 := []byte("value3")
    40  	t.Run("test view", func(t *testing.T) {
    41  		_, err := store.ReadView(name)
    42  		require.Error(err)
    43  		require.NoError(store.WriteView(name, viewValue))
    44  		valueInView, err := store.ReadView(name)
    45  		require.NoError(err)
    46  		require.Equal(valueInView, viewValue)
    47  	})
    48  	t.Run("test kvstore feature", func(t *testing.T) {
    49  		_, err := store.Get(namespace, key1)
    50  		require.Error(err)
    51  		require.NoError(store.Delete(namespace, key1))
    52  		require.NoError(store.Put(namespace, key1, value1))
    53  		valueInStore, err := store.Get(namespace, key1)
    54  		require.NoError(err)
    55  		require.True(bytes.Equal(value1, valueInStore))
    56  		sn1 := store.Snapshot()
    57  		require.NoError(store.Put(namespace, key2, value2))
    58  		valueInStore, err = store.Get(namespace, key2)
    59  		require.NoError(err)
    60  		require.True(bytes.Equal(value2, valueInStore))
    61  		store.Snapshot()
    62  		require.NoError(store.Put(namespace, key3, value3))
    63  		valueInStore, err = store.Get(namespace, key3)
    64  		require.NoError(err)
    65  		require.True(bytes.Equal(value3, valueInStore))
    66  		valuesInStore, err := store.States(namespace, [][]byte{key1, key2, key3})
    67  		require.Equal(3, len(valuesInStore))
    68  		require.True(bytes.Equal(value1, valuesInStore[0]))
    69  		require.True(bytes.Equal(value2, valuesInStore[1]))
    70  		require.True(bytes.Equal(value3, valuesInStore[2]))
    71  		t.Run("test digest", func(t *testing.T) {
    72  			h := store.Digest()
    73  			require.Equal("e1f83be0a44ae601061724990036b8a40edbf81cffc639657c9bb2c5d384defa", hex.EncodeToString(h[:]))
    74  		})
    75  		sn3 := store.Snapshot()
    76  		require.NoError(store.Delete(namespace, key1))
    77  		_, err = store.Get(namespace, key1)
    78  		require.Error(err)
    79  		valuesInStore, err = store.States(namespace, [][]byte{key1, key2, key3})
    80  		require.Equal(3, len(valuesInStore))
    81  		require.Nil(valuesInStore[0])
    82  		require.True(bytes.Equal(value2, valuesInStore[1]))
    83  		require.True(bytes.Equal(value3, valuesInStore[2]))
    84  		require.NoError(store.RevertSnapshot(sn3))
    85  		valueInStore, err = store.Get(namespace, key1)
    86  		require.NoError(err)
    87  		require.NoError(store.RevertSnapshot(sn1))
    88  		require.True(bytes.Equal(value1, valueInStore))
    89  		_, err = store.Get(namespace, key2)
    90  		require.Error(err)
    91  	})
    92  	t.Run("finalize & commit", func(t *testing.T) {
    93  		height := uint64(100)
    94  		_, err := store.Get(AccountKVNamespace, []byte(CurrentHeightKey))
    95  		require.Error(err)
    96  		_, err = inMemStore.Get(AccountKVNamespace, []byte(CurrentHeightKey))
    97  		require.Error(err)
    98  		require.NoError(store.Finalize(height))
    99  		heightInStore, err := store.Get(AccountKVNamespace, []byte(CurrentHeightKey))
   100  		require.NoError(err)
   101  		require.True(bytes.Equal(heightInStore, byteutil.Uint64ToBytes(height)))
   102  		_, err = inMemStore.Get(AccountKVNamespace, []byte(CurrentHeightKey))
   103  		require.Error(err)
   104  		require.NoError(store.Commit())
   105  		heightInStore, err = inMemStore.Get(AccountKVNamespace, []byte(CurrentHeightKey))
   106  		require.NoError(err)
   107  		require.True(bytes.Equal(heightInStore, byteutil.Uint64ToBytes(height)))
   108  	})
   109  	require.NoError(store.Stop(ctx))
   110  }
   111  
   112  func TestFactoryWorkingSetStore(t *testing.T) {
   113  	// TODO: add unit test for factory working set store
   114  }