github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/kvledger/txmgmt/statedb/statecouchdb/cache_test.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package statecouchdb
     8  
     9  import (
    10  	"math/rand"
    11  	"testing"
    12  
    13  	"github.com/VictoriaMetrics/fastcache"
    14  	"github.com/golang/protobuf/proto"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  var sysNamespaces = []string{"lscc", "_lifecycle"}
    19  
    20  func TestNewCache(t *testing.T) {
    21  	c := newCache(32, sysNamespaces)
    22  	expectedCache := &cache{
    23  		sysCache:      fastcache.New(64 * 1024 * 1024),
    24  		usrCache:      fastcache.New(32 * 1024 * 1024),
    25  		sysNamespaces: sysNamespaces,
    26  	}
    27  	require.Equal(t, expectedCache, c)
    28  	require.True(t, c.enabled("lscc"))
    29  	require.True(t, c.enabled("_lifecycle"))
    30  	require.True(t, c.enabled("xyz"))
    31  
    32  	c = newCache(0, sysNamespaces)
    33  	expectedCache = &cache{
    34  		sysCache:      fastcache.New(64 * 1024 * 1024),
    35  		usrCache:      nil,
    36  		sysNamespaces: sysNamespaces,
    37  	}
    38  	require.Equal(t, expectedCache, c)
    39  	require.True(t, c.enabled("lscc"))
    40  	require.True(t, c.enabled("_lifecycle"))
    41  	require.False(t, c.enabled("xyz"))
    42  }
    43  
    44  func TestGetPutState(t *testing.T) {
    45  	cache := newCache(32, sysNamespaces)
    46  
    47  	// test GetState
    48  	v, err := cache.getState("ch1", "ns1", "k1")
    49  	require.NoError(t, err)
    50  	require.Nil(t, v)
    51  
    52  	// test PutState
    53  	expectedValue1 := &CacheValue{Value: []byte("value1")}
    54  	require.NoError(t, cache.putState("ch1", "ns1", "k1", expectedValue1))
    55  
    56  	v, err = cache.getState("ch1", "ns1", "k1")
    57  	require.NoError(t, err)
    58  	require.True(t, proto.Equal(expectedValue1, v))
    59  }
    60  
    61  func TestGetPutStateWithBigPayloadIfKeyDoesNotExist(t *testing.T) {
    62  	cache := newCache(32, sysNamespaces)
    63  
    64  	expectedValue := &CacheValue{Value: []byte("value")}
    65  	require.NoError(t, cache.putState("ch1", "ns1", "k1", expectedValue))
    66  	v, err := cache.getState("ch1", "ns1", "k1")
    67  	require.NoError(t, err)
    68  	require.True(t, proto.Equal(expectedValue, v))
    69  
    70  	// test PutState with BigPayload
    71  	token := make([]byte, (64*1024)+1)
    72  	rand.Read(token)
    73  	expectedValue1 := &CacheValue{Value: token}
    74  	require.NoError(t, cache.putState("ch1", "ns1", "k1", expectedValue1))
    75  
    76  	v, err = cache.getState("ch1", "ns1", "k1")
    77  	require.NoError(t, err)
    78  	// actually bigPayloads are not saved in cache, should return nil/nothing
    79  	require.Nil(t, v)
    80  }
    81  
    82  func TestUpdateStatesWithSingleSmallAndSingleBigPayloads(t *testing.T) {
    83  	cache := newCache(32, sysNamespaces)
    84  
    85  	expectedValue1 := &CacheValue{Value: []byte("value1")}
    86  	require.NoError(t, cache.putState("ch1", "ns1", "k1", expectedValue1))
    87  
    88  	expectedValue2 := &CacheValue{Value: []byte("value2")}
    89  	require.NoError(t, cache.putState("ch1", "ns1", "k2", expectedValue2))
    90  
    91  	v1, err := cache.getState("ch1", "ns1", "k1")
    92  	require.NoError(t, err)
    93  	require.True(t, proto.Equal(expectedValue1, v1))
    94  
    95  	v2, err := cache.getState("ch1", "ns1", "k2")
    96  	require.NoError(t, err)
    97  	require.True(t, proto.Equal(expectedValue2, v2))
    98  
    99  	token := make([]byte, (64*1024)+1)
   100  	rand.Read(token)
   101  
   102  	expectedValue3 := &CacheValue{Value: []byte("value3")}
   103  	expectedValue4 := &CacheValue{Value: token}
   104  
   105  	updates := cacheUpdates{
   106  		"ns1": cacheKVs{
   107  			"k1": expectedValue3,
   108  			"k2": expectedValue4,
   109  		},
   110  	}
   111  	require.NoError(t, cache.UpdateStates("ch1", updates))
   112  
   113  	v3, err := cache.getState("ch1", "ns1", "k1")
   114  	require.NoError(t, err)
   115  	require.True(t, proto.Equal(expectedValue3, v3))
   116  
   117  	v4, err := cache.getState("ch1", "ns1", "k2")
   118  	require.NoError(t, err)
   119  	require.Nil(t, v4)
   120  }
   121  
   122  func TestUpdateStates(t *testing.T) {
   123  	cache := newCache(32, sysNamespaces)
   124  
   125  	// create states for three namespaces (ns1, ns2, ns3)
   126  	// each with two keys (k1, k2)
   127  	expectedValue1 := &CacheValue{Value: []byte("value1")}
   128  	require.NoError(t, cache.putState("ch1", "ns1", "k1", expectedValue1))
   129  	expectedValue2 := &CacheValue{Value: []byte("value2")}
   130  	require.NoError(t, cache.putState("ch1", "ns1", "k2", expectedValue2))
   131  	expectedValue3 := &CacheValue{Value: []byte("value3")}
   132  	require.NoError(t, cache.putState("ch1", "ns2", "k1", expectedValue3))
   133  	expectedValue4 := &CacheValue{Value: []byte("value4")}
   134  	require.NoError(t, cache.putState("ch1", "ns2", "k2", expectedValue4))
   135  	expectedValue5 := &CacheValue{Value: []byte("value5")}
   136  	require.NoError(t, cache.putState("ch1", "ns3", "k1", expectedValue5))
   137  	expectedValue6 := &CacheValue{Value: []byte("value6")}
   138  	require.NoError(t, cache.putState("ch1", "ns3", "k2", expectedValue6))
   139  
   140  	v1, err := cache.getState("ch1", "ns1", "k1")
   141  	require.NoError(t, err)
   142  	require.True(t, proto.Equal(expectedValue1, v1))
   143  	v2, err := cache.getState("ch1", "ns1", "k2")
   144  	require.NoError(t, err)
   145  	require.True(t, proto.Equal(expectedValue2, v2))
   146  	v3, err := cache.getState("ch1", "ns2", "k1")
   147  	require.NoError(t, err)
   148  	require.True(t, proto.Equal(expectedValue3, v3))
   149  	v4, err := cache.getState("ch1", "ns2", "k2")
   150  	require.NoError(t, err)
   151  	require.True(t, proto.Equal(expectedValue4, v4))
   152  	v5, err := cache.getState("ch1", "ns3", "k1")
   153  	require.NoError(t, err)
   154  	require.True(t, proto.Equal(expectedValue5, v5))
   155  	v6, err := cache.getState("ch1", "ns3", "k2")
   156  	require.NoError(t, err)
   157  	require.True(t, proto.Equal(expectedValue6, v6))
   158  
   159  	// delete (ns2, k1), (ns3, k1), and (ns3, k2) while updating others.
   160  	// nil value represents a delete operation. A new entry (ns3, k3)
   161  	// is also being passed but would not get added to the cache as the
   162  	// entry does not exist in cache already.
   163  	expectedValue7 := &CacheValue{Value: []byte("value7")}
   164  	expectedValue8 := &CacheValue{Value: []byte("value8")}
   165  	expectedValue9 := &CacheValue{Value: []byte("value9")}
   166  	expectedValue10 := &CacheValue{Value: []byte("value10")}
   167  	updates := cacheUpdates{
   168  		"ns1": cacheKVs{
   169  			"k1": expectedValue7,
   170  			"k2": expectedValue8,
   171  		},
   172  		"ns2": cacheKVs{
   173  			"k1": nil,
   174  			"k2": expectedValue9,
   175  		},
   176  		"ns3": cacheKVs{
   177  			"k1": nil,
   178  			"k2": nil,
   179  			"k3": expectedValue10,
   180  		},
   181  	}
   182  
   183  	require.NoError(t, cache.UpdateStates("ch1", updates))
   184  
   185  	v7, err := cache.getState("ch1", "ns1", "k1")
   186  	require.NoError(t, err)
   187  	require.True(t, proto.Equal(expectedValue7, v7))
   188  
   189  	v8, err := cache.getState("ch1", "ns1", "k2")
   190  	require.NoError(t, err)
   191  	require.True(t, proto.Equal(expectedValue8, v8))
   192  
   193  	v9, err := cache.getState("ch1", "ns2", "k2")
   194  	require.NoError(t, err)
   195  	require.True(t, proto.Equal(expectedValue9, v9))
   196  
   197  	v, err := cache.getState("ch1", "ns2", "k1")
   198  	require.NoError(t, err)
   199  	require.Nil(t, v)
   200  	v, err = cache.getState("ch1", "ns3", "k1")
   201  	require.NoError(t, err)
   202  	require.Nil(t, v)
   203  	v, err = cache.getState("ch1", "ns3", "k2")
   204  	require.NoError(t, err)
   205  	require.Nil(t, v)
   206  	v, err = cache.getState("ch1", "ns3", "k3")
   207  	require.NoError(t, err)
   208  	require.Nil(t, v)
   209  }
   210  
   211  func TestCacheReset(t *testing.T) {
   212  	cache := newCache(32, sysNamespaces)
   213  
   214  	// create states for three namespaces (ns1, ns2, ns3)
   215  	// each with two keys (k1, k2)
   216  	expectedValue1 := &CacheValue{Value: []byte("value1")}
   217  	require.NoError(t, cache.putState("ch1", "ns1", "k1", expectedValue1))
   218  
   219  	expectedValue2 := &CacheValue{Value: []byte("value2")}
   220  	require.NoError(t, cache.putState("ch1", "ns2", "k1", expectedValue2))
   221  
   222  	expectedValue3 := &CacheValue{Value: []byte("value3")}
   223  	require.NoError(t, cache.putState("ch1", "lscc", "k1", expectedValue3))
   224  
   225  	v1, err := cache.getState("ch1", "ns1", "k1")
   226  	require.NoError(t, err)
   227  	require.True(t, proto.Equal(expectedValue1, v1))
   228  
   229  	v2, err := cache.getState("ch1", "ns2", "k1")
   230  	require.NoError(t, err)
   231  	require.True(t, proto.Equal(expectedValue2, v2))
   232  
   233  	v3, err := cache.getState("ch1", "lscc", "k1")
   234  	require.NoError(t, err)
   235  	require.True(t, proto.Equal(expectedValue3, v3))
   236  
   237  	cache.Reset()
   238  
   239  	v, err := cache.getState("ch1", "ns1", "k1")
   240  	require.NoError(t, err)
   241  	require.Nil(t, v)
   242  
   243  	v, err = cache.getState("ch1", "ns2", "k1")
   244  	require.NoError(t, err)
   245  	require.Nil(t, v)
   246  
   247  	v, err = cache.getState("ch1", "lscc", "k1")
   248  	require.NoError(t, err)
   249  	require.Nil(t, v)
   250  }
   251  
   252  func TestCacheUpdates(t *testing.T) {
   253  	u := make(cacheUpdates)
   254  	u.add("ns1", cacheKVs{
   255  		"k1": &CacheValue{Value: []byte("v1")},
   256  		"k2": &CacheValue{Value: []byte("v2")},
   257  	})
   258  
   259  	u.add("ns1", cacheKVs{
   260  		"k3": &CacheValue{Value: []byte("v1")},
   261  		"k4": &CacheValue{Value: []byte("v2")},
   262  	})
   263  
   264  	u.add("ns2", cacheKVs{
   265  		"k1": &CacheValue{Value: []byte("v1")},
   266  		"k2": &CacheValue{Value: []byte("v2")},
   267  	})
   268  
   269  	expectedCacheUpdates := cacheUpdates{
   270  		"ns1": cacheKVs{
   271  			"k1": &CacheValue{Value: []byte("v1")},
   272  			"k2": &CacheValue{Value: []byte("v2")},
   273  			"k3": &CacheValue{Value: []byte("v1")},
   274  			"k4": &CacheValue{Value: []byte("v2")},
   275  		},
   276  
   277  		"ns2": cacheKVs{
   278  			"k1": &CacheValue{Value: []byte("v1")},
   279  			"k2": &CacheValue{Value: []byte("v2")},
   280  		},
   281  	}
   282  
   283  	require.Equal(t, expectedCacheUpdates, u)
   284  }