github.com/lzy4123/fabric@v2.1.1+incompatible/core/chaincode/transaction_contexts_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package chaincode_test
     8  
     9  import (
    10  	pb "github.com/hyperledger/fabric-protos-go/peer"
    11  	"github.com/hyperledger/fabric/core/chaincode"
    12  	"github.com/hyperledger/fabric/core/chaincode/mock"
    13  	"github.com/hyperledger/fabric/core/common/ccprovider"
    14  	. "github.com/onsi/ginkgo"
    15  	. "github.com/onsi/gomega"
    16  )
    17  
    18  var _ = Describe("TransactionContexts", func() {
    19  	var txContexts *chaincode.TransactionContexts
    20  
    21  	BeforeEach(func() {
    22  		txContexts = chaincode.NewTransactionContexts()
    23  	})
    24  
    25  	Describe("Create", func() {
    26  		var (
    27  			signedProp               *pb.SignedProposal
    28  			proposal                 *pb.Proposal
    29  			fakeTxSimulator          *mock.TxSimulator
    30  			fakeHistoryQueryExecutor *mock.HistoryQueryExecutor
    31  
    32  			txParams *ccprovider.TransactionParams
    33  		)
    34  
    35  		BeforeEach(func() {
    36  			signedProp = &pb.SignedProposal{ProposalBytes: []byte("some-proposal-bytes")}
    37  			proposal = &pb.Proposal{Payload: []byte("some-payload-bytes")}
    38  			fakeTxSimulator = &mock.TxSimulator{}
    39  			fakeHistoryQueryExecutor = &mock.HistoryQueryExecutor{}
    40  
    41  			txParams = &ccprovider.TransactionParams{
    42  				ChannelID:            "channelID",
    43  				TxID:                 "transactionID",
    44  				SignedProp:           signedProp,
    45  				Proposal:             proposal,
    46  				TXSimulator:          fakeTxSimulator,
    47  				HistoryQueryExecutor: fakeHistoryQueryExecutor,
    48  			}
    49  		})
    50  
    51  		It("creates a new transaction context", func() {
    52  			txContext, err := txContexts.Create(txParams)
    53  			Expect(err).NotTo(HaveOccurred())
    54  
    55  			Expect(txContext.ChannelID).To(Equal("channelID"))
    56  			Expect(txContext.SignedProp).To(Equal(signedProp))
    57  			Expect(txContext.Proposal).To(Equal(proposal))
    58  			Expect(txContext.ResponseNotifier).NotTo(BeNil())
    59  			Expect(txContext.ResponseNotifier).NotTo(BeClosed())
    60  			Expect(txContext.TXSimulator).To(Equal(fakeTxSimulator))
    61  			Expect(txContext.HistoryQueryExecutor).To(Equal(fakeHistoryQueryExecutor))
    62  		})
    63  
    64  		It("keeps track of the created context", func() {
    65  			txContext, err := txContexts.Create(txParams)
    66  			Expect(err).NotTo(HaveOccurred())
    67  
    68  			c := txContexts.Get("channelID", "transactionID")
    69  			Expect(c).To(Equal(txContext))
    70  		})
    71  
    72  		Context("when the transaction context already exists", func() {
    73  			BeforeEach(func() {
    74  				_, err := txContexts.Create(txParams)
    75  				Expect(err).NotTo(HaveOccurred())
    76  			})
    77  
    78  			It("returns a meaningful error", func() {
    79  				_, err := txContexts.Create(txParams)
    80  				Expect(err).To(MatchError("txid: transactionID(channelID) exists"))
    81  			})
    82  		})
    83  	})
    84  
    85  	Describe("Get", func() {
    86  		var c1, c2 *chaincode.TransactionContext
    87  
    88  		BeforeEach(func() {
    89  			var err error
    90  			txParams1 := &ccprovider.TransactionParams{
    91  				ChannelID: "channelID1",
    92  				TxID:      "transactionID1",
    93  			}
    94  			c1, err = txContexts.Create(txParams1)
    95  			Expect(err).NotTo(HaveOccurred())
    96  
    97  			txParams2 := &ccprovider.TransactionParams{
    98  				ChannelID: "channelID1",
    99  				TxID:      "transactionID2",
   100  			}
   101  			c2, err = txContexts.Create(txParams2)
   102  			Expect(err).NotTo(HaveOccurred())
   103  		})
   104  
   105  		It("returns the correct transaction context", func() {
   106  			c := txContexts.Get("channelID1", "transactionID1")
   107  			Expect(c).To(Equal(c1))
   108  
   109  			c = txContexts.Get("channelID1", "transactionID2")
   110  			Expect(c).To(Equal(c2))
   111  
   112  			c = txContexts.Get("non-existent", "transactionID1")
   113  			Expect(c).To(BeNil())
   114  		})
   115  	})
   116  
   117  	Describe("Delete", func() {
   118  		BeforeEach(func() {
   119  			_, err := txContexts.Create(&ccprovider.TransactionParams{
   120  				ChannelID: "channelID2",
   121  				TxID:      "transactionID1",
   122  			})
   123  			Expect(err).NotTo(HaveOccurred())
   124  		})
   125  
   126  		It("removes transaction context", func() {
   127  			c := txContexts.Get("channelID2", "transactionID1")
   128  			Expect(c).NotTo(BeNil())
   129  
   130  			txContexts.Delete("channelID2", "transactionID1")
   131  
   132  			c = txContexts.Get("channelID2", "transactionID1")
   133  			Expect(c).To(BeNil())
   134  		})
   135  
   136  		Context("when the context doesn't exist", func() {
   137  			It("keeps calm and carries on", func() {
   138  				txContexts.Delete("not-existent", "transactionID1")
   139  			})
   140  		})
   141  	})
   142  
   143  	Describe("Close", func() {
   144  		var fakeIterators []*mock.QueryResultsIterator
   145  
   146  		BeforeEach(func() {
   147  			fakeIterators = make([]*mock.QueryResultsIterator, 6)
   148  			for i := 0; i < len(fakeIterators); i++ {
   149  				fakeIterators[i] = &mock.QueryResultsIterator{}
   150  			}
   151  
   152  			txContext, err := txContexts.Create(&ccprovider.TransactionParams{
   153  				ChannelID: "channelID",
   154  				TxID:      "transactionID",
   155  			})
   156  			Expect(err).NotTo(HaveOccurred())
   157  			txContext.InitializeQueryContext("key1", fakeIterators[0])
   158  			txContext.InitializeQueryContext("key2", fakeIterators[1])
   159  			txContext.InitializeQueryContext("key3", fakeIterators[2])
   160  
   161  			txContext2, err := txContexts.Create(&ccprovider.TransactionParams{
   162  				ChannelID: "channelID",
   163  				TxID:      "transactionID2",
   164  			})
   165  			Expect(err).NotTo(HaveOccurred())
   166  			txContext2.InitializeQueryContext("key1", fakeIterators[3])
   167  			txContext2.InitializeQueryContext("key2", fakeIterators[4])
   168  			txContext2.InitializeQueryContext("key3", fakeIterators[5])
   169  		})
   170  
   171  		It("closes all iterators in iterator map", func() {
   172  			for _, ri := range fakeIterators {
   173  				Expect(ri.CloseCallCount()).To(Equal(0))
   174  			}
   175  			txContexts.Close()
   176  			for _, ri := range fakeIterators {
   177  				Expect(ri.CloseCallCount()).To(Equal(1))
   178  			}
   179  		})
   180  
   181  		Context("when there are no contexts", func() {
   182  			BeforeEach(func() {
   183  				txContexts = chaincode.NewTransactionContexts()
   184  			})
   185  
   186  			It("keeps calm and carries on", func() {
   187  				txContexts.Close()
   188  			})
   189  		})
   190  
   191  		Context("when there is a context with no query iterators", func() {
   192  			BeforeEach(func() {
   193  				_, err := txContexts.Create(&ccprovider.TransactionParams{
   194  					ChannelID: "channelID",
   195  					TxID:      "no-query-iterators",
   196  				})
   197  				Expect(err).NotTo(HaveOccurred())
   198  			})
   199  
   200  			It("closes iterators associated with other contexts", func() {
   201  				txContexts.Close()
   202  				for _, ri := range fakeIterators {
   203  					Expect(ri.CloseCallCount()).To(Equal(1))
   204  				}
   205  			})
   206  		})
   207  	})
   208  })