github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/core/scc/lscc/lscc_noncc_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package lscc_test 8 9 import ( 10 "errors" 11 12 "github.com/golang/protobuf/proto" 13 "github.com/hyperledger/fabric/bccsp/sw" 14 "github.com/hyperledger/fabric/core/chaincode/lifecycle" 15 "github.com/hyperledger/fabric/core/common/ccprovider" 16 "github.com/hyperledger/fabric/core/scc/lscc" 17 "github.com/hyperledger/fabric/core/scc/lscc/mock" 18 . "github.com/onsi/ginkgo" 19 . "github.com/onsi/gomega" 20 ) 21 22 var _ = Describe("LSCC", func() { 23 var ( 24 l *lscc.SCC 25 fakeSupport *mock.FileSystemSupport 26 fakeCCPackage *mock.CCPackage 27 fakeSCCProvider *mock.SystemChaincodeProvider 28 fakeQueryExecutor *mock.QueryExecutor 29 ccData *ccprovider.ChaincodeData 30 ccDataBytes []byte 31 err error 32 ) 33 34 BeforeEach(func() { 35 fakeCCPackage = &mock.CCPackage{} 36 fakeCCPackage.GetChaincodeDataReturns(&ccprovider.ChaincodeData{ 37 InstantiationPolicy: []byte("instantiation-policy"), 38 }) 39 40 fakeSupport = &mock.FileSystemSupport{} 41 fakeSupport.GetChaincodeFromLocalStorageReturns(fakeCCPackage, nil) 42 43 fakeSCCProvider = &mock.SystemChaincodeProvider{} 44 fakeQueryExecutor = &mock.QueryExecutor{} 45 cryptoProvider, _ := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 46 47 l = &lscc.SCC{ 48 Support: fakeSupport, 49 SCCProvider: fakeSCCProvider, 50 BCCSP: cryptoProvider, 51 } 52 53 ccData = &ccprovider.ChaincodeData{ 54 Name: "chaincode-data-name", 55 Version: "version", 56 Escc: "escc", 57 Vscc: "vscc", 58 Policy: []byte("policy"), 59 Data: []byte("data"), 60 Id: []byte("id"), 61 InstantiationPolicy: []byte("instantiation-policy"), 62 } 63 64 ccDataBytes, err = proto.Marshal(ccData) 65 Expect(err).NotTo(HaveOccurred()) 66 67 fakeQueryExecutor = &mock.QueryExecutor{} 68 fakeQueryExecutor.GetStateReturns(ccDataBytes, nil) 69 }) 70 71 Describe("LegacySecurity", func() { 72 var ( 73 fakeCCPackage *mock.CCPackage 74 legacySecurity *lscc.LegacySecurity 75 ) 76 77 BeforeEach(func() { 78 fakeCCPackage = &mock.CCPackage{} 79 fakeCCPackage.GetChaincodeDataReturns(&ccprovider.ChaincodeData{ 80 InstantiationPolicy: []byte("instantiation-policy"), 81 }) 82 83 fakeSupport.GetChaincodeFromLocalStorageReturns(fakeCCPackage, nil) 84 85 legacySecurity = &lscc.LegacySecurity{ 86 Support: fakeSupport, 87 } 88 }) 89 90 It("returns nil if security checks are passed", func() { 91 err := legacySecurity.SecurityCheckLegacyChaincode(ccData) 92 Expect(err).NotTo(HaveOccurred()) 93 94 Expect(fakeCCPackage.ValidateCCCallCount()).To(Equal(1)) 95 Expect(fakeCCPackage.ValidateCCArgsForCall(0)).To(Equal(ccData)) 96 }) 97 98 Context("when cc package validation fails", func() { 99 BeforeEach(func() { 100 fakeCCPackage.ValidateCCReturns(errors.New("fake-validation-error")) 101 }) 102 103 It("returns an error", func() { 104 err := legacySecurity.SecurityCheckLegacyChaincode(ccData) 105 Expect(err).To(MatchError(lscc.InvalidCCOnFSError("fake-validation-error"))) 106 }) 107 }) 108 109 Context("when the instantiation policy doesn't match", func() { 110 BeforeEach(func() { 111 fakeCCPackage.GetChaincodeDataReturns(&ccprovider.ChaincodeData{ 112 InstantiationPolicy: []byte("bad-instantiation-policy"), 113 }) 114 }) 115 116 It("returns an error", func() { 117 err := legacySecurity.SecurityCheckLegacyChaincode(ccData) 118 Expect(err).To(MatchError("Instantiation policy mismatch for cc chaincode-data-name:version")) 119 }) 120 }) 121 }) 122 123 Describe("ChaincodeEndorsementInfo", func() { 124 It("retrieves the chaincode data from the state", func() { 125 chaincodeEndorsementInfo, err := l.ChaincodeEndorsementInfo("", "cc-name", fakeQueryExecutor) 126 Expect(err).NotTo(HaveOccurred()) 127 Expect(chaincodeEndorsementInfo).To(Equal(&lifecycle.ChaincodeEndorsementInfo{ 128 ChaincodeID: "chaincode-data-name:version", 129 Version: "version", 130 EndorsementPlugin: "escc", 131 })) 132 133 Expect(fakeQueryExecutor.GetStateCallCount()).To(Equal(1)) 134 namespace, key := fakeQueryExecutor.GetStateArgsForCall(0) 135 Expect(namespace).To(Equal("lscc")) 136 Expect(key).To(Equal("cc-name")) 137 }) 138 139 Context("when the state getter fails", func() { 140 BeforeEach(func() { 141 fakeQueryExecutor.GetStateReturns(nil, errors.New("fake-error")) 142 }) 143 144 It("returns the wrapped error", func() { 145 _, err := l.ChaincodeEndorsementInfo("", "cc-name", fakeQueryExecutor) 146 Expect(err).To(MatchError("could not retrieve state for chaincode cc-name: fake-error")) 147 }) 148 }) 149 150 Context("when the state getter does not find the key", func() { 151 BeforeEach(func() { 152 fakeQueryExecutor.GetStateReturns(nil, nil) 153 }) 154 155 It("returns an error", func() { 156 _, err := l.ChaincodeEndorsementInfo("", "cc-name", fakeQueryExecutor) 157 Expect(err).To(MatchError("chaincode cc-name not found")) 158 }) 159 }) 160 161 Context("when the state getter returns invalid data", func() { 162 BeforeEach(func() { 163 fakeQueryExecutor.GetStateReturns([]byte("garbage"), nil) 164 }) 165 166 It("wraps and returns the error", func() { 167 _, err := l.ChaincodeEndorsementInfo("", "cc-name", fakeQueryExecutor) 168 Expect(err).To(MatchError(MatchRegexp("chaincode cc-name has bad definition: proto:.*"))) 169 }) 170 }) 171 }) 172 173 Describe("ChaincodeDefinitionForValidation", func() { 174 BeforeEach(func() { 175 }) 176 177 It("retrieves the chaincode data from the state", func() { 178 vscc, policy, unexpectedErr, validationErr := l.ValidationInfo("", "cc-name", fakeQueryExecutor) 179 Expect(validationErr).NotTo(HaveOccurred()) 180 Expect(unexpectedErr).NotTo(HaveOccurred()) 181 Expect(vscc).To(Equal(ccData.Vscc)) 182 Expect(policy).To(Equal(ccData.Policy)) 183 184 Expect(fakeQueryExecutor.GetStateCallCount()).To(Equal(1)) 185 namespace, key := fakeQueryExecutor.GetStateArgsForCall(0) 186 Expect(namespace).To(Equal("lscc")) 187 Expect(key).To(Equal("cc-name")) 188 }) 189 190 Context("when the state getter fails", func() { 191 BeforeEach(func() { 192 fakeQueryExecutor.GetStateReturns(nil, errors.New("fake-error")) 193 }) 194 195 It("returns the wrapped error", func() { 196 _, _, unexpectedErr, validationErr := l.ValidationInfo("", "cc-name", fakeQueryExecutor) 197 Expect(unexpectedErr).To(MatchError("could not retrieve state for chaincode cc-name: fake-error")) 198 Expect(validationErr).NotTo(HaveOccurred()) 199 }) 200 }) 201 202 Context("when the state getter does not find the key", func() { 203 BeforeEach(func() { 204 fakeQueryExecutor.GetStateReturns(nil, nil) 205 }) 206 207 It("returns an error", func() { 208 _, _, unexpectedErr, validationErr := l.ValidationInfo("", "cc-name", fakeQueryExecutor) 209 Expect(unexpectedErr).NotTo(HaveOccurred()) 210 Expect(validationErr).To(MatchError("chaincode cc-name not found")) 211 }) 212 }) 213 214 Context("when the state getter returns invalid data", func() { 215 BeforeEach(func() { 216 fakeQueryExecutor.GetStateReturns([]byte("garbage"), nil) 217 }) 218 219 It("wraps and returns the error", func() { 220 _, _, unexpectedErr, validationErr := l.ValidationInfo("", "cc-name", fakeQueryExecutor) 221 Expect(validationErr).NotTo(HaveOccurred()) 222 Expect(unexpectedErr).To(MatchError(MatchRegexp("chaincode cc-name has bad definition: proto:.*"))) 223 }) 224 }) 225 }) 226 })