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  })