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 }