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

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package queryutil_test
     8  
     9  import (
    10  	"errors"
    11  	"os"
    12  	"testing"
    13  
    14  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/privacyenabledstate"
    15  	"github.com/hechain20/hechain/core/ledger/util"
    16  
    17  	"github.com/hechain20/hechain/common/flogging"
    18  	commonledger "github.com/hechain20/hechain/common/ledger"
    19  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/queryutil"
    20  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/queryutil/mock"
    21  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/statedb"
    22  	statedbmock "github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/statedb/mock"
    23  	"github.com/hyperledger/fabric-protos-go/ledger/queryresult"
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  func TestMain(m *testing.M) {
    28  	flogging.ActivateSpec("util,statedb=debug")
    29  	os.Exit(m.Run())
    30  }
    31  
    32  func TestCombinerGetState(t *testing.T) {
    33  	batch1 := statedb.NewUpdateBatch()
    34  	batch1.Put("ns1", "key1", []byte("b1_value1"), nil)
    35  	batch1.Delete("ns1", "key2", nil)
    36  	batch1.Put("ns1", "key3", []byte("b1_value3"), nil)
    37  
    38  	batch2 := statedb.NewUpdateBatch()
    39  	batch2.Put("ns1", "key1", []byte("b2_value1"), nil)
    40  	batch2.Put("ns1", "key2", []byte("b2_value2"), nil)
    41  	batch2.Put("ns1", "key3", []byte("b2_value3"), nil)
    42  
    43  	batch3 := statedb.NewUpdateBatch()
    44  	batch3.Put("ns1", "key1", []byte("b3_value1"), nil)
    45  	batch3.Put("ns1", "key2", []byte("b3_value2"), nil)
    46  	batch3.Delete("ns1", "key3", nil)
    47  
    48  	combiner := &queryutil.QECombiner{
    49  		QueryExecuters: []queryutil.QueryExecuter{
    50  			&queryutil.UpdateBatchBackedQueryExecuter{UpdateBatch: batch1},
    51  			&queryutil.UpdateBatchBackedQueryExecuter{UpdateBatch: batch2},
    52  			&queryutil.UpdateBatchBackedQueryExecuter{UpdateBatch: batch3},
    53  		},
    54  	}
    55  
    56  	val, err := combiner.GetState("ns1", "key1")
    57  	require.NoError(t, err)
    58  	require.Equal(t, []byte("b1_value1"), val)
    59  
    60  	val, err = combiner.GetState("ns1", "key2")
    61  	require.NoError(t, err)
    62  	require.Nil(t, val)
    63  
    64  	val, err = combiner.GetState("ns1", "key3")
    65  	require.NoError(t, err)
    66  	require.Equal(t, []byte("b1_value3"), val)
    67  
    68  	combiner = &queryutil.QECombiner{
    69  		QueryExecuters: []queryutil.QueryExecuter{
    70  			&queryutil.UpdateBatchBackedQueryExecuter{UpdateBatch: batch3},
    71  			&queryutil.UpdateBatchBackedQueryExecuter{UpdateBatch: batch2},
    72  			&queryutil.UpdateBatchBackedQueryExecuter{UpdateBatch: batch1},
    73  		},
    74  	}
    75  	val, err = combiner.GetState("ns1", "key1")
    76  	require.NoError(t, err)
    77  	require.Equal(t, []byte("b3_value1"), val)
    78  
    79  	val, err = combiner.GetState("ns1", "key2")
    80  	require.NoError(t, err)
    81  	require.Equal(t, []byte("b3_value2"), val)
    82  
    83  	val, err = combiner.GetState("ns1", "key3")
    84  	require.NoError(t, err)
    85  	require.Nil(t, val)
    86  }
    87  
    88  func TestCombinerRangeScan(t *testing.T) {
    89  	batch1 := statedb.NewUpdateBatch()
    90  	batch1.Put("ns1", "key1", []byte("batch1_value1"), nil)
    91  	batch1.Delete("ns1", "key2", nil)
    92  	batch1.Put("ns1", "key3", []byte("batch1_value3"), nil)
    93  
    94  	batch2 := statedb.NewUpdateBatch()
    95  	batch2.Put("ns1", "key1", []byte("batch2_value1"), nil)
    96  	batch2.Put("ns1", "key2", []byte("batch2_value2"), nil)
    97  	batch2.Delete("ns1", "key3", nil)
    98  	batch2.Put("ns1", "key4", []byte("batch2_value4"), nil)
    99  
   100  	batch3 := statedb.NewUpdateBatch()
   101  	batch3.Put("ns1", "key0", []byte("batch3_value0"), nil)
   102  	batch3.Put("ns1", "key1", []byte("batch3_value1"), nil)
   103  	batch3.Put("ns1", "key2", []byte("batch3_value2"), nil)
   104  	batch3.Put("ns1", "key3", []byte("batch3_value3"), nil)
   105  	batch3.Put("ns1", "key4", []byte("batch3_value4"), nil)
   106  	batch3.Put("ns1", "key5", []byte("batch3_value5"), nil)
   107  
   108  	combiner := &queryutil.QECombiner{
   109  		QueryExecuters: []queryutil.QueryExecuter{
   110  			&queryutil.UpdateBatchBackedQueryExecuter{UpdateBatch: batch1},
   111  			&queryutil.UpdateBatchBackedQueryExecuter{UpdateBatch: batch2},
   112  			&queryutil.UpdateBatchBackedQueryExecuter{UpdateBatch: batch3},
   113  		},
   114  	}
   115  
   116  	itr, err := combiner.GetStateRangeScanIterator("ns1", "key1", "key4")
   117  	require.NoError(t, err)
   118  	expectedResults := []*queryresult.KV{
   119  		{Namespace: "ns1", Key: "key1", Value: []byte("batch1_value1")},
   120  		{Namespace: "ns1", Key: "key3", Value: []byte("batch1_value3")},
   121  	}
   122  	testutilCheckIteratorResults(t, itr, expectedResults)
   123  
   124  	itr, err = combiner.GetStateRangeScanIterator("ns1", "key0", "key6")
   125  	require.NoError(t, err)
   126  	expectedResults = []*queryresult.KV{
   127  		{Namespace: "ns1", Key: "key0", Value: []byte("batch3_value0")},
   128  		{Namespace: "ns1", Key: "key1", Value: []byte("batch1_value1")},
   129  		{Namespace: "ns1", Key: "key3", Value: []byte("batch1_value3")},
   130  		{Namespace: "ns1", Key: "key4", Value: []byte("batch2_value4")},
   131  		{Namespace: "ns1", Key: "key5", Value: []byte("batch3_value5")},
   132  	}
   133  	testutilCheckIteratorResults(t, itr, expectedResults)
   134  
   135  	combiner = &queryutil.QECombiner{
   136  		QueryExecuters: []queryutil.QueryExecuter{
   137  			&queryutil.UpdateBatchBackedQueryExecuter{UpdateBatch: batch3},
   138  			&queryutil.UpdateBatchBackedQueryExecuter{UpdateBatch: batch2},
   139  			&queryutil.UpdateBatchBackedQueryExecuter{UpdateBatch: batch1},
   140  		},
   141  	}
   142  	itr, err = combiner.GetStateRangeScanIterator("ns1", "key0", "key6")
   143  	require.NoError(t, err)
   144  	expectedResults = []*queryresult.KV{
   145  		{Namespace: "ns1", Key: "key0", Value: []byte("batch3_value0")},
   146  		{Namespace: "ns1", Key: "key1", Value: []byte("batch3_value1")},
   147  		{Namespace: "ns1", Key: "key2", Value: []byte("batch3_value2")},
   148  		{Namespace: "ns1", Key: "key3", Value: []byte("batch3_value3")},
   149  		{Namespace: "ns1", Key: "key4", Value: []byte("batch3_value4")},
   150  		{Namespace: "ns1", Key: "key5", Value: []byte("batch3_value5")},
   151  	}
   152  	testutilCheckIteratorResults(t, itr, expectedResults)
   153  }
   154  
   155  func TestGetStateError(t *testing.T) {
   156  	qe1 := &mock.QueryExecuter{}
   157  	qe1.GetStateReturns(&statedb.VersionedValue{Value: []byte("testValue")}, nil)
   158  	qe2 := &mock.QueryExecuter{}
   159  	qe2.GetStateReturns(nil, errors.New("Error for testing"))
   160  	combiner1 := &queryutil.QECombiner{
   161  		QueryExecuters: []queryutil.QueryExecuter{
   162  			qe1, qe2,
   163  		},
   164  	}
   165  	_, err := combiner1.GetState("ns", "key1")
   166  	require.NoError(t, err)
   167  
   168  	combiner2 := &queryutil.QECombiner{
   169  		QueryExecuters: []queryutil.QueryExecuter{
   170  			qe2, qe1,
   171  		},
   172  	}
   173  	_, err = combiner2.GetState("ns", "key1")
   174  	require.Error(t, err)
   175  }
   176  
   177  func TestGetRangeScanError(t *testing.T) {
   178  	itr1 := &statedbmock.ResultsIterator{}
   179  	itr1.NextReturns(
   180  		&statedb.VersionedKV{
   181  			CompositeKey:   &statedb.CompositeKey{Namespace: "ns", Key: "dummyKey"},
   182  			VersionedValue: &statedb.VersionedValue{Value: []byte("dummyVal")},
   183  		},
   184  		nil,
   185  	)
   186  
   187  	qe1 := &mock.QueryExecuter{}
   188  	qe1.GetStateRangeScanIteratorReturns(itr1, nil)
   189  	qe2 := &mock.QueryExecuter{}
   190  	qe2.GetStateRangeScanIteratorReturns(nil, errors.New("dummy error on getting the iterator"))
   191  	combiner := &queryutil.QECombiner{
   192  		QueryExecuters: []queryutil.QueryExecuter{
   193  			qe1, qe2,
   194  		},
   195  	}
   196  	_, err := combiner.GetStateRangeScanIterator("ns", "startKey", "endKey")
   197  	require.Error(t, err)
   198  }
   199  
   200  func TestGetRangeScanUnderlyingIteratorReturnsError(t *testing.T) {
   201  	itr1 := &statedbmock.ResultsIterator{}
   202  	itr1.NextReturns(
   203  		&statedb.VersionedKV{
   204  			CompositeKey:   &statedb.CompositeKey{Namespace: "ns", Key: "dummyKey"},
   205  			VersionedValue: &statedb.VersionedValue{Value: []byte("dummyVal")},
   206  		},
   207  		nil,
   208  	)
   209  
   210  	itr2 := &statedbmock.ResultsIterator{}
   211  	itr2.NextReturns(
   212  		nil,
   213  		errors.New("dummyErrorOnIteratorNext"),
   214  	)
   215  
   216  	qe1 := &mock.QueryExecuter{}
   217  	qe1.GetStateRangeScanIteratorReturns(itr1, nil)
   218  	qe2 := &mock.QueryExecuter{}
   219  	qe2.GetStateRangeScanIteratorReturns(itr2, nil)
   220  	combiner := &queryutil.QECombiner{
   221  		QueryExecuters: []queryutil.QueryExecuter{
   222  			qe1, qe2,
   223  		},
   224  	}
   225  	_, err := combiner.GetStateRangeScanIterator("ns", "startKey", "endKey")
   226  	require.Error(t, err)
   227  }
   228  
   229  func TestGetPrivateDataHash(t *testing.T) {
   230  	batch1 := privacyenabledstate.NewHashedUpdateBatch()
   231  	key1Hash := util.ComputeStringHash("key1")
   232  	key2Hash := util.ComputeStringHash("key2")
   233  	key3Hash := util.ComputeStringHash("key3")
   234  
   235  	batch1.Put("ns1", "coll1", key1Hash, []byte("b1_value1"), nil)
   236  	batch1.Delete("ns1", "coll1", key2Hash, nil)
   237  	batch1.Put("ns1", "coll1", key3Hash, []byte("b1_value3"), nil)
   238  
   239  	batch2 := privacyenabledstate.NewHashedUpdateBatch()
   240  	batch2.Put("ns1", "coll1", key1Hash, []byte("b2_value1"), nil)
   241  	batch2.Put("ns1", "coll1", key2Hash, []byte("b2_value2"), nil)
   242  	batch2.Put("ns1", "coll1", key3Hash, []byte("b2_value3"), nil)
   243  
   244  	batch3 := privacyenabledstate.NewHashedUpdateBatch()
   245  	batch3.Put("ns1", "coll1", key1Hash, []byte("b3_value1"), nil)
   246  	batch3.Put("ns1", "coll1", key2Hash, []byte("b3_value2"), nil)
   247  
   248  	combiner := &queryutil.QECombiner{
   249  		QueryExecuters: []queryutil.QueryExecuter{
   250  			&queryutil.UpdateBatchBackedQueryExecuter{HashUpdatesBatch: batch1},
   251  			&queryutil.UpdateBatchBackedQueryExecuter{HashUpdatesBatch: batch2},
   252  			&queryutil.UpdateBatchBackedQueryExecuter{HashUpdatesBatch: batch3},
   253  		},
   254  	}
   255  
   256  	val, err := combiner.GetPrivateDataHash("ns1", "coll1", "key1")
   257  	require.NoError(t, err)
   258  	require.Equal(t, []byte("b1_value1"), val)
   259  
   260  	val, err = combiner.GetPrivateDataHash("ns1", "coll1", "key2")
   261  	require.NoError(t, err)
   262  	require.Nil(t, val)
   263  
   264  	val, err = combiner.GetPrivateDataHash("ns1", "coll1", "key3")
   265  	require.NoError(t, err)
   266  	require.Equal(t, []byte("b1_value3"), val)
   267  
   268  	combiner = &queryutil.QECombiner{
   269  		QueryExecuters: []queryutil.QueryExecuter{
   270  			&queryutil.UpdateBatchBackedQueryExecuter{HashUpdatesBatch: batch3},
   271  			&queryutil.UpdateBatchBackedQueryExecuter{HashUpdatesBatch: batch2},
   272  			&queryutil.UpdateBatchBackedQueryExecuter{HashUpdatesBatch: batch1},
   273  		},
   274  	}
   275  	val, err = combiner.GetPrivateDataHash("ns1", "coll1", "key1")
   276  	require.NoError(t, err)
   277  	require.Equal(t, []byte("b3_value1"), val)
   278  
   279  	val, err = combiner.GetPrivateDataHash("ns1", "coll1", "key2")
   280  	require.NoError(t, err)
   281  	require.Equal(t, []byte("b3_value2"), val)
   282  
   283  	val, err = combiner.GetPrivateDataHash("ns1", "coll1", "key3")
   284  	require.NoError(t, err)
   285  	require.Equal(t, []byte("b2_value3"), val)
   286  }
   287  
   288  func TestGetPrivateDataHashError(t *testing.T) {
   289  	qe1 := &mock.QueryExecuter{}
   290  	qe1.GetPrivateDataHashReturns(&statedb.VersionedValue{Value: []byte("testValue")}, nil)
   291  	qe2 := &mock.QueryExecuter{}
   292  	qe2.GetPrivateDataHashReturns(nil, errors.New("Error for testing"))
   293  	combiner1 := &queryutil.QECombiner{
   294  		QueryExecuters: []queryutil.QueryExecuter{
   295  			qe1, qe2,
   296  		},
   297  	}
   298  	_, err := combiner1.GetPrivateDataHash("ns", "coll1", "key1")
   299  	require.NoError(t, err)
   300  
   301  	combiner2 := &queryutil.QECombiner{
   302  		QueryExecuters: []queryutil.QueryExecuter{
   303  			qe2, qe1,
   304  		},
   305  	}
   306  	_, err = combiner2.GetPrivateDataHash("ns", "coll1", "key1")
   307  	require.Error(t, err)
   308  }
   309  
   310  func testutilCheckIteratorResults(t *testing.T, itr commonledger.ResultsIterator, expectedResults []*queryresult.KV) {
   311  	results := []*queryresult.KV{}
   312  	for {
   313  		result, err := itr.Next()
   314  		require.NoError(t, err)
   315  		if result == nil {
   316  			break
   317  		}
   318  		results = append(results, result.(*queryresult.KV))
   319  	}
   320  	require.Equal(t, expectedResults, results)
   321  }