github.com/kaituanwang/hyperledger@v2.0.1+incompatible/core/handlers/validation/builtin/default_validation_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package builtin 8 9 import ( 10 "testing" 11 12 "github.com/hyperledger/fabric-protos-go/common" 13 commonerrors "github.com/hyperledger/fabric/common/errors" 14 "github.com/hyperledger/fabric/core/committer/txvalidator/plugin" 15 . "github.com/hyperledger/fabric/core/handlers/validation/api" 16 vmocks "github.com/hyperledger/fabric/core/handlers/validation/builtin/mocks" 17 "github.com/hyperledger/fabric/core/handlers/validation/builtin/v12/mocks" 18 v20mocks "github.com/hyperledger/fabric/core/handlers/validation/builtin/v20/mocks" 19 "github.com/pkg/errors" 20 "github.com/stretchr/testify/assert" 21 "github.com/stretchr/testify/mock" 22 ) 23 24 func TestInit(t *testing.T) { 25 factory := &DefaultValidationFactory{} 26 defValidation := factory.New() 27 28 identityDeserializer := &mocks.IdentityDeserializer{} 29 capabilities := &mocks.Capabilities{} 30 stateFetcher := &mocks.StateFetcher{} 31 polEval := &mocks.PolicyEvaluator{} 32 colRes := &v20mocks.CollectionResources{} 33 34 assert.Equal(t, "stateFetcher not passed in init", defValidation.Init(identityDeserializer, capabilities, polEval, colRes).Error()) 35 assert.Equal(t, "identityDeserializer not passed in init", defValidation.Init(capabilities, stateFetcher, polEval, colRes).Error()) 36 assert.Equal(t, "capabilities not passed in init", defValidation.Init(identityDeserializer, stateFetcher, polEval, colRes).Error()) 37 assert.Equal(t, "policy fetcher not passed in init", defValidation.Init(identityDeserializer, capabilities, stateFetcher, colRes).Error()) 38 assert.Equal(t, "collection resources not passed in init", defValidation.Init(identityDeserializer, capabilities, stateFetcher, polEval).Error()) 39 40 fullDeps := []Dependency{identityDeserializer, capabilities, stateFetcher, polEval, colRes} 41 assert.NoError(t, defValidation.Init(fullDeps...)) 42 } 43 44 func TestErrorConversion(t *testing.T) { 45 validator := &vmocks.TransactionValidator{} 46 capabilities := &mocks.Capabilities{} 47 validation := &DefaultValidation{ 48 TxValidatorV1_2: validator, 49 Capabilities: capabilities, 50 } 51 block := &common.Block{ 52 Header: &common.BlockHeader{}, 53 Data: &common.BlockData{ 54 Data: [][]byte{{}}, 55 }, 56 } 57 58 capabilities.On("V2_0Validation").Return(false) 59 capabilities.On("V1_3Validation").Return(false) 60 capabilities.On("V1_2Validation").Return(true) 61 62 // Scenario I: An error that isn't *commonerrors.ExecutionFailureError or *commonerrors.VSCCEndorsementPolicyError 63 // should cause a panic 64 validator.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(errors.New("bla bla")).Once() 65 assert.Panics(t, func() { 66 validation.Validate(block, "", 0, 0, plugin.SerializedPolicy("policy")) 67 }) 68 69 // Scenario II: Non execution errors are returned as is 70 validator.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&commonerrors.VSCCEndorsementPolicyError{Err: errors.New("foo")}).Once() 71 err := validation.Validate(block, "", 0, 0, plugin.SerializedPolicy("policy")) 72 assert.Equal(t, (&commonerrors.VSCCEndorsementPolicyError{Err: errors.New("foo")}).Error(), err.Error()) 73 74 // Scenario III: Execution errors are converted to the plugin error type 75 validator.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&commonerrors.VSCCExecutionFailureError{Err: errors.New("bar")}).Once() 76 err = validation.Validate(block, "", 0, 0, plugin.SerializedPolicy("policy")) 77 assert.Equal(t, &ExecutionFailureError{Reason: "bar"}, err) 78 79 // Scenario IV: No errors are forwarded 80 validator.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() 81 assert.NoError(t, validation.Validate(block, "", 0, 0, plugin.SerializedPolicy("policy"))) 82 } 83 84 func TestValidateBadInput(t *testing.T) { 85 validator := &vmocks.TransactionValidator{} 86 validation := &DefaultValidation{ 87 TxValidatorV1_2: validator, 88 } 89 90 // Scenario I: Nil block 91 validator.On("Validate", mock.Anything, mock.Anything).Return(nil).Once() 92 err := validation.Validate(nil, "", 0, 0, plugin.SerializedPolicy("policy")) 93 assert.Equal(t, "empty block", err.Error()) 94 95 block := &common.Block{ 96 Header: &common.BlockHeader{}, 97 Data: &common.BlockData{ 98 Data: [][]byte{{}}, 99 }, 100 } 101 // Scenario II: Block with 1 transaction, but position is at 1 also 102 validator.On("Validate", mock.Anything, mock.Anything).Return(nil).Once() 103 err = validation.Validate(block, "", 1, 0, plugin.SerializedPolicy("policy")) 104 assert.Equal(t, "block has only 1 transactions, but requested tx at position 1", err.Error()) 105 106 // Scenario III: Block without header 107 validator.On("Validate", mock.Anything, mock.Anything).Return(nil).Once() 108 err = validation.Validate(&common.Block{ 109 Data: &common.BlockData{ 110 Data: [][]byte{{}}, 111 }, 112 }, "", 0, 0, plugin.SerializedPolicy("policy")) 113 assert.Equal(t, "no block header", err.Error()) 114 115 // Scenario IV: No serialized policy passed 116 assert.Panics(t, func() { 117 validator.On("Validate", mock.Anything, mock.Anything).Return(nil).Once() 118 err = validation.Validate(&common.Block{ 119 Header: &common.BlockHeader{}, 120 Data: &common.BlockData{ 121 Data: [][]byte{{}}, 122 }, 123 }, "", 0, 0) 124 }) 125 126 // Scenario V: Policy passed isn't a serialized policy 127 assert.Panics(t, func() { 128 validator.On("Validate", mock.Anything, mock.Anything).Return(nil).Once() 129 err = validation.Validate(&common.Block{ 130 Header: &common.BlockHeader{}, 131 Data: &common.BlockData{ 132 Data: [][]byte{{}}, 133 }, 134 }, "", 0, 0, []byte("policy")) 135 }) 136 137 }