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  }