github.com/ewagmig/fabric@v2.1.1+incompatible/core/chaincode/lifecycle/ledger_shim_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package lifecycle_test
     8  
     9  import (
    10  	"fmt"
    11  
    12  	. "github.com/onsi/ginkgo"
    13  	. "github.com/onsi/gomega"
    14  
    15  	"github.com/hyperledger/fabric-protos-go/ledger/queryresult"
    16  	"github.com/hyperledger/fabric/core/chaincode/lifecycle"
    17  	"github.com/hyperledger/fabric/core/chaincode/lifecycle/mock"
    18  )
    19  
    20  var _ = Describe("LedgerShims", func() {
    21  	var (
    22  		fakeStub *mock.ChaincodeStub
    23  	)
    24  
    25  	BeforeEach(func() {
    26  		fakeStub = &mock.ChaincodeStub{}
    27  	})
    28  
    29  	Describe("ChaincodePublicLedgerShim", func() {
    30  		var (
    31  			cls          *lifecycle.ChaincodePublicLedgerShim
    32  			fakeIterator *mock.StateIterator
    33  		)
    34  
    35  		BeforeEach(func() {
    36  			fakeIterator = &mock.StateIterator{}
    37  			fakeIterator.HasNextReturnsOnCall(0, true)
    38  			fakeIterator.HasNextReturnsOnCall(1, false)
    39  			fakeIterator.NextReturns(&queryresult.KV{
    40  				Key:   "fake-prefix-key",
    41  				Value: []byte("fake-value"),
    42  			}, nil)
    43  
    44  			fakeStub.GetStateByRangeReturns(fakeIterator, nil)
    45  
    46  			cls = &lifecycle.ChaincodePublicLedgerShim{
    47  				ChaincodeStubInterface: fakeStub,
    48  			}
    49  		})
    50  
    51  		Describe("GetStateRange", func() {
    52  			It("passes through to the stub", func() {
    53  				res, err := cls.GetStateRange("fake-prefix")
    54  				Expect(err).NotTo(HaveOccurred())
    55  				Expect(res).To(Equal(map[string][]byte{
    56  					"fake-prefix-key": []byte("fake-value"),
    57  				}))
    58  				Expect(fakeStub.GetStateByRangeCallCount()).To(Equal(1))
    59  				start, end := fakeStub.GetStateByRangeArgsForCall(0)
    60  				Expect(start).To(Equal("fake-prefix"))
    61  				Expect(end).To(Equal("fake-prefix\x7f"))
    62  			})
    63  
    64  			Context("when the iterator cannot be retrieved", func() {
    65  				BeforeEach(func() {
    66  					fakeStub.GetStateByRangeReturns(nil, fmt.Errorf("error-by-range"))
    67  				})
    68  
    69  				It("wraps and returns the error", func() {
    70  					_, err := cls.GetStateRange("fake-prefix")
    71  					Expect(err).To(MatchError("could not get state iterator: error-by-range"))
    72  
    73  				})
    74  			})
    75  
    76  			Context("when the iterator fails to iterate", func() {
    77  				BeforeEach(func() {
    78  					fakeIterator.NextReturns(nil, fmt.Errorf("fake-iterator-error"))
    79  				})
    80  
    81  				It("wraps and returns the error", func() {
    82  					_, err := cls.GetStateRange("fake-prefix")
    83  					Expect(err).To(MatchError("could not iterate over range: fake-iterator-error"))
    84  
    85  				})
    86  			})
    87  		})
    88  	})
    89  
    90  	Describe("ChaincodePrivateLedgerShim", func() {
    91  		var (
    92  			cls *lifecycle.ChaincodePrivateLedgerShim
    93  		)
    94  
    95  		BeforeEach(func() {
    96  			cls = &lifecycle.ChaincodePrivateLedgerShim{
    97  				Stub:       fakeStub,
    98  				Collection: "fake-collection",
    99  			}
   100  		})
   101  
   102  		Describe("GetStateRange", func() {
   103  			BeforeEach(func() {
   104  				fakeStub.GetPrivateDataByRangeReturns(&mock.StateIterator{}, nil)
   105  			})
   106  
   107  			It("passes through to the stub private function", func() {
   108  				res, err := cls.GetStateRange("fake-key")
   109  				Expect(err).NotTo(HaveOccurred())
   110  				Expect(res).To(BeEmpty())
   111  
   112  				Expect(fakeStub.GetPrivateDataByRangeCallCount()).To(Equal(1))
   113  				collection, start, end := fakeStub.GetPrivateDataByRangeArgsForCall(0)
   114  				Expect(collection).To(Equal("fake-collection"))
   115  				Expect(start).To(Equal("fake-key"))
   116  				Expect(end).To(Equal("fake-key\x7f"))
   117  			})
   118  
   119  			Context("when getting the state iterator fails", func() {
   120  				BeforeEach(func() {
   121  					fakeStub.GetPrivateDataByRangeReturns(nil, fmt.Errorf("fake-range-error"))
   122  				})
   123  
   124  				It("wraps and returns the error", func() {
   125  					_, err := cls.GetStateRange("fake-key")
   126  					Expect(err).To(MatchError("could not get state iterator: fake-range-error"))
   127  				})
   128  			})
   129  		})
   130  
   131  		Describe("GetState", func() {
   132  			BeforeEach(func() {
   133  				fakeStub.GetPrivateDataReturns([]byte("fake-value"), fmt.Errorf("fake-getstate-error"))
   134  			})
   135  
   136  			It("passes through to the stub private data implementation", func() {
   137  				res, err := cls.GetState("fake-key")
   138  				Expect(res).To(Equal([]byte("fake-value")))
   139  				Expect(err).To(MatchError(fmt.Errorf("fake-getstate-error")))
   140  				Expect(fakeStub.GetPrivateDataCallCount()).To(Equal(1))
   141  				collection, key := fakeStub.GetPrivateDataArgsForCall(0)
   142  				Expect(collection).To(Equal("fake-collection"))
   143  				Expect(key).To(Equal("fake-key"))
   144  			})
   145  		})
   146  
   147  		Describe("GetStateHash", func() {
   148  			BeforeEach(func() {
   149  				fakeStub.GetPrivateDataHashReturns([]byte("fake-hash"), fmt.Errorf("fake-error"))
   150  			})
   151  
   152  			It("passes through to the chaincode stub", func() {
   153  				res, err := cls.GetStateHash("fake-key")
   154  				Expect(res).To(Equal([]byte("fake-hash")))
   155  				Expect(err).To(MatchError("fake-error"))
   156  				Expect(fakeStub.GetPrivateDataHashCallCount()).To(Equal(1))
   157  				collection, key := fakeStub.GetPrivateDataHashArgsForCall(0)
   158  				Expect(collection).To(Equal("fake-collection"))
   159  				Expect(key).To(Equal("fake-key"))
   160  			})
   161  		})
   162  
   163  		Describe("PutState", func() {
   164  			BeforeEach(func() {
   165  				fakeStub.PutPrivateDataReturns(fmt.Errorf("fake-putstate-error"))
   166  			})
   167  
   168  			It("passes through to the stub private data implementation", func() {
   169  				err := cls.PutState("fake-key", []byte("fake-value"))
   170  				Expect(err).To(MatchError(fmt.Errorf("fake-putstate-error")))
   171  				Expect(fakeStub.PutPrivateDataCallCount()).To(Equal(1))
   172  				collection, key, value := fakeStub.PutPrivateDataArgsForCall(0)
   173  				Expect(collection).To(Equal("fake-collection"))
   174  				Expect(key).To(Equal("fake-key"))
   175  				Expect(value).To(Equal([]byte("fake-value")))
   176  			})
   177  		})
   178  
   179  		Describe("DelState", func() {
   180  			BeforeEach(func() {
   181  				fakeStub.DelPrivateDataReturns(fmt.Errorf("fake-delstate-error"))
   182  			})
   183  
   184  			It("passes through to the stub private data implementation", func() {
   185  				err := cls.DelState("fake-key")
   186  				Expect(err).To(MatchError(fmt.Errorf("fake-delstate-error")))
   187  				Expect(fakeStub.DelPrivateDataCallCount()).To(Equal(1))
   188  				collection, key := fakeStub.DelPrivateDataArgsForCall(0)
   189  				Expect(collection).To(Equal("fake-collection"))
   190  				Expect(key).To(Equal("fake-key"))
   191  			})
   192  		})
   193  	})
   194  
   195  	Describe("SimpleQueryExecutorShim", func() {
   196  		var (
   197  			sqes                    *lifecycle.SimpleQueryExecutorShim
   198  			fakeSimpleQueryExecutor *mock.SimpleQueryExecutor
   199  		)
   200  
   201  		BeforeEach(func() {
   202  			fakeSimpleQueryExecutor = &mock.SimpleQueryExecutor{}
   203  			sqes = &lifecycle.SimpleQueryExecutorShim{
   204  				Namespace:           "cc-namespace",
   205  				SimpleQueryExecutor: fakeSimpleQueryExecutor,
   206  			}
   207  		})
   208  
   209  		Describe("GetState", func() {
   210  			BeforeEach(func() {
   211  				fakeSimpleQueryExecutor.GetStateReturns([]byte("fake-state"), fmt.Errorf("fake-error"))
   212  			})
   213  
   214  			It("passes through to the query executor", func() {
   215  				res, err := sqes.GetState("fake-prefix")
   216  				Expect(res).To(Equal([]byte("fake-state")))
   217  				Expect(err).To(MatchError("fake-error"))
   218  			})
   219  		})
   220  
   221  		Describe("GetStateRange", func() {
   222  			var (
   223  				resItr *mock.ResultsIterator
   224  			)
   225  
   226  			BeforeEach(func() {
   227  				resItr = &mock.ResultsIterator{}
   228  				resItr.NextReturnsOnCall(0, &queryresult.KV{
   229  					Key:   "fake-key",
   230  					Value: []byte("key-value"),
   231  				}, nil)
   232  				fakeSimpleQueryExecutor.GetStateRangeScanIteratorReturns(resItr, nil)
   233  			})
   234  
   235  			It("passes through to the query executor", func() {
   236  				res, err := sqes.GetStateRange("fake-key")
   237  				Expect(err).NotTo(HaveOccurred())
   238  				Expect(res).To(Equal(map[string][]byte{
   239  					"fake-key": []byte("key-value"),
   240  				}))
   241  
   242  				Expect(fakeSimpleQueryExecutor.GetStateRangeScanIteratorCallCount()).To(Equal(1))
   243  				namespace, start, end := fakeSimpleQueryExecutor.GetStateRangeScanIteratorArgsForCall(0)
   244  				Expect(namespace).To(Equal("cc-namespace"))
   245  				Expect(start).To(Equal("fake-key"))
   246  				Expect(end).To(Equal("fake-key\x7f"))
   247  			})
   248  
   249  			Context("when the result iterator returns an error", func() {
   250  				BeforeEach(func() {
   251  					resItr.NextReturns(nil, fmt.Errorf("fake-error"))
   252  				})
   253  
   254  				It("returns the error", func() {
   255  					_, err := sqes.GetStateRange("fake-key")
   256  					Expect(err).To(MatchError("could not iterate over range: fake-error"))
   257  				})
   258  			})
   259  
   260  			Context("when getting the state iterator fails", func() {
   261  				BeforeEach(func() {
   262  					fakeSimpleQueryExecutor.GetStateRangeScanIteratorReturns(nil, fmt.Errorf("fake-range-error"))
   263  				})
   264  
   265  				It("wraps and returns the error", func() {
   266  					_, err := sqes.GetStateRange("fake-key")
   267  					Expect(err).To(MatchError("could not get state iterator: fake-range-error"))
   268  				})
   269  			})
   270  		})
   271  	})
   272  
   273  	Describe("PrivateQueryExecutorShim", func() {
   274  		var (
   275  			pqes                    *lifecycle.PrivateQueryExecutorShim
   276  			fakeSimpleQueryExecutor *mock.SimpleQueryExecutor
   277  		)
   278  
   279  		BeforeEach(func() {
   280  			fakeSimpleQueryExecutor = &mock.SimpleQueryExecutor{}
   281  			pqes = &lifecycle.PrivateQueryExecutorShim{
   282  				Namespace:  "cc-namespace",
   283  				Collection: "collection",
   284  				State:      fakeSimpleQueryExecutor,
   285  			}
   286  			fakeSimpleQueryExecutor.GetPrivateDataHashReturns([]byte("hash"), fmt.Errorf("fake-error"))
   287  		})
   288  
   289  		It("passes through to the underlying implementation", func() {
   290  			data, err := pqes.GetStateHash("key")
   291  			Expect(data).To(Equal([]byte("hash")))
   292  			Expect(err).To(MatchError("fake-error"))
   293  			Expect(fakeSimpleQueryExecutor.GetPrivateDataHashCallCount()).To(Equal(1))
   294  			namespace, collection, key := fakeSimpleQueryExecutor.GetPrivateDataHashArgsForCall(0)
   295  			Expect(namespace).To(Equal("cc-namespace"))
   296  			Expect(collection).To(Equal("collection"))
   297  			Expect(key).To(Equal("key"))
   298  		})
   299  	})
   300  })