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 }