github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/kvledger/txmgmt/statedb/stateleveldb/stateleveldb_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package stateleveldb 8 9 import ( 10 "errors" 11 "testing" 12 13 "github.com/hechain20/hechain/core/ledger/internal/version" 14 "github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/statedb" 15 "github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/statedb/commontests" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestBasicRW(t *testing.T) { 20 env := NewTestVDBEnv(t) 21 defer env.Cleanup() 22 commontests.TestBasicRW(t, env.DBProvider) 23 } 24 25 func TestMultiDBBasicRW(t *testing.T) { 26 env := NewTestVDBEnv(t) 27 defer env.Cleanup() 28 commontests.TestMultiDBBasicRW(t, env.DBProvider) 29 } 30 31 func TestDeletes(t *testing.T) { 32 env := NewTestVDBEnv(t) 33 defer env.Cleanup() 34 commontests.TestDeletes(t, env.DBProvider) 35 } 36 37 func TestIterator(t *testing.T) { 38 env := NewTestVDBEnv(t) 39 defer env.Cleanup() 40 commontests.TestIterator(t, env.DBProvider) 41 t.Run("test-iter-error-path", func(t *testing.T) { 42 db, err := env.DBProvider.GetDBHandle("testiterator", nil) 43 require.NoError(t, err) 44 env.DBProvider.Close() 45 itr, err := db.GetStateRangeScanIterator("ns1", "", "") 46 require.EqualError(t, err, "internal leveldb error while obtaining db iterator: leveldb: closed") 47 require.Nil(t, itr) 48 }) 49 } 50 51 func TestDataKeyEncoding(t *testing.T) { 52 testDataKeyEncoding(t, "ledger1", "ns", "key") 53 testDataKeyEncoding(t, "ledger2", "ns", "") 54 } 55 56 func testDataKeyEncoding(t *testing.T, dbName string, ns string, key string) { 57 dataKey := encodeDataKey(ns, key) 58 t.Logf("dataKey=%#v", dataKey) 59 ns1, key1 := decodeDataKey(dataKey) 60 require.Equal(t, ns, ns1) 61 require.Equal(t, key, key1) 62 } 63 64 // TestQueryOnLevelDB tests queries on levelDB. 65 func TestQueryOnLevelDB(t *testing.T) { 66 env := NewTestVDBEnv(t) 67 defer env.Cleanup() 68 db, err := env.DBProvider.GetDBHandle("testquery", nil) 69 require.NoError(t, err) 70 require.NoError(t, db.Open()) 71 defer db.Close() 72 batch := statedb.NewUpdateBatch() 73 jsonValue1 := `{"asset_name": "marble1","color": "blue","size": 1,"owner": "tom"}` 74 batch.Put("ns1", "key1", []byte(jsonValue1), version.NewHeight(1, 1)) 75 76 savePoint := version.NewHeight(2, 22) 77 require.NoError(t, db.ApplyUpdates(batch, savePoint)) 78 79 // query for owner=jerry, use namespace "ns1" 80 // As queries are not supported in levelDB, call to ExecuteQuery() 81 // should return a error message 82 itr, err := db.ExecuteQuery("ns1", `{"selector":{"owner":"jerry"}}`) 83 require.Error(t, err, "ExecuteQuery not supported for leveldb") 84 require.Nil(t, itr) 85 } 86 87 func TestGetStateMultipleKeys(t *testing.T) { 88 env := NewTestVDBEnv(t) 89 defer env.Cleanup() 90 commontests.TestGetStateMultipleKeys(t, env.DBProvider) 91 } 92 93 func TestGetVersion(t *testing.T) { 94 env := NewTestVDBEnv(t) 95 defer env.Cleanup() 96 commontests.TestGetVersion(t, env.DBProvider) 97 } 98 99 func TestUtilityFunctions(t *testing.T) { 100 env := NewTestVDBEnv(t) 101 defer env.Cleanup() 102 103 db, err := env.DBProvider.GetDBHandle("testutilityfunctions", nil) 104 require.NoError(t, err) 105 106 require.True(t, env.DBProvider.BytesKeySupported()) 107 require.True(t, db.BytesKeySupported()) 108 109 // ValidateKeyValue should return nil for a valid key and value 110 require.NoError(t, db.ValidateKeyValue("testKey", []byte("testValue")), "leveldb should accept all key-values") 111 } 112 113 func TestValueAndMetadataWrites(t *testing.T) { 114 env := NewTestVDBEnv(t) 115 defer env.Cleanup() 116 commontests.TestValueAndMetadataWrites(t, env.DBProvider) 117 } 118 119 func TestPaginatedRangeQuery(t *testing.T) { 120 env := NewTestVDBEnv(t) 121 defer env.Cleanup() 122 commontests.TestPaginatedRangeQuery(t, env.DBProvider) 123 } 124 125 func TestRangeQuerySpecialCharacters(t *testing.T) { 126 env := NewTestVDBEnv(t) 127 defer env.Cleanup() 128 commontests.TestRangeQuerySpecialCharacters(t, env.DBProvider) 129 } 130 131 func TestApplyUpdatesWithNilHeight(t *testing.T) { 132 env := NewTestVDBEnv(t) 133 defer env.Cleanup() 134 commontests.TestApplyUpdatesWithNilHeight(t, env.DBProvider) 135 } 136 137 func TestDataExportImport(t *testing.T) { 138 // smaller batch size for testing to cover the boundary case of writing the final batch 139 maxDataImportBatchSize = 10 140 env := NewTestVDBEnv(t) 141 defer env.Cleanup() 142 commontests.TestDataExportImport( 143 t, 144 env.DBProvider, 145 ) 146 } 147 148 func TestFullScanIteratorErrorPropagation(t *testing.T) { 149 var env *TestVDBEnv 150 var cleanup func() 151 var vdbProvider *VersionedDBProvider 152 var vdb *versionedDB 153 154 initEnv := func() { 155 env = NewTestVDBEnv(t) 156 vdbProvider = env.DBProvider 157 db, err := vdbProvider.GetDBHandle("TestFullScanIteratorErrorPropagation", nil) 158 require.NoError(t, err) 159 vdb = db.(*versionedDB) 160 cleanup = func() { 161 env.Cleanup() 162 } 163 } 164 165 reInitEnv := func() { 166 env.Cleanup() 167 initEnv() 168 } 169 170 initEnv() 171 defer cleanup() 172 173 // error from function GetFullScanIterator 174 vdbProvider.Close() 175 _, err := vdb.GetFullScanIterator( 176 func(string) bool { 177 return false 178 }, 179 ) 180 require.Contains(t, err.Error(), "internal leveldb error while obtaining db iterator:") 181 182 // error from function Next 183 reInitEnv() 184 itr, err := vdb.GetFullScanIterator( 185 func(string) bool { 186 return false 187 }, 188 ) 189 require.NoError(t, err) 190 itr.Close() 191 _, err = itr.Next() 192 require.Contains(t, err.Error(), "internal leveldb error while retrieving data from db iterator:") 193 } 194 195 func TestImportStateErrorPropagation(t *testing.T) { 196 var env *TestVDBEnv 197 var cleanup func() 198 var vdbProvider *VersionedDBProvider 199 200 initEnv := func() { 201 env = NewTestVDBEnv(t) 202 vdbProvider = env.DBProvider 203 cleanup = func() { 204 env.Cleanup() 205 } 206 } 207 208 t.Run("error-reading-from-source", func(t *testing.T) { 209 initEnv() 210 defer cleanup() 211 212 err := vdbProvider.ImportFromSnapshot( 213 "test-db", 214 version.NewHeight(2, 2), 215 &dummyFullScanIter{ 216 err: errors.New("error while reading from source"), 217 }, 218 ) 219 220 require.EqualError(t, err, "error while reading from source") 221 }) 222 223 t.Run("error-writing-to-db", func(t *testing.T) { 224 initEnv() 225 defer cleanup() 226 227 vdbProvider.Close() 228 err := vdbProvider.ImportFromSnapshot("test-db", version.NewHeight(2, 2), 229 &dummyFullScanIter{ 230 kv: &statedb.VersionedKV{ 231 CompositeKey: &statedb.CompositeKey{ 232 Namespace: "ns", 233 Key: "key", 234 }, 235 VersionedValue: &statedb.VersionedValue{ 236 Value: []byte("value"), 237 Version: version.NewHeight(1, 1), 238 }, 239 }, 240 }, 241 ) 242 require.Contains(t, err.Error(), "error writing batch to leveldb") 243 }) 244 } 245 246 func TestDrop(t *testing.T) { 247 env := NewTestVDBEnv(t) 248 defer env.Cleanup() 249 250 checkDBsAfterDropFunc := func(channelName string) { 251 empty, err := env.DBProvider.dbProvider.GetDBHandle(channelName).IsEmpty() 252 require.NoError(t, err) 253 require.True(t, empty) 254 } 255 256 commontests.TestDrop(t, env.DBProvider, checkDBsAfterDropFunc) 257 } 258 259 func TestDropErrorPath(t *testing.T) { 260 env := NewTestVDBEnv(t) 261 defer env.Cleanup() 262 263 _, err := env.DBProvider.GetDBHandle("testdroperror", nil) 264 require.NoError(t, err) 265 266 env.DBProvider.Close() 267 require.EqualError(t, env.DBProvider.Drop("testdroperror"), "internal leveldb error while obtaining db iterator: leveldb: closed") 268 } 269 270 type dummyFullScanIter struct { 271 err error 272 kv *statedb.VersionedKV 273 } 274 275 func (d *dummyFullScanIter) Next() (*statedb.VersionedKV, error) { 276 return d.kv, d.err 277 } 278 279 func (d *dummyFullScanIter) Close() { 280 }