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

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package chaincode
     8  
     9  import (
    10  	"archive/tar"
    11  	"bytes"
    12  	"compress/gzip"
    13  	"errors"
    14  	"flag"
    15  	"fmt"
    16  	"io/ioutil"
    17  	"os"
    18  	"path/filepath"
    19  	"strings"
    20  	"sync"
    21  	"testing"
    22  	"time"
    23  
    24  	docker "github.com/fsouza/go-dockerclient"
    25  	"github.com/golang/protobuf/proto"
    26  	"github.com/hyperledger/fabric-chaincode-go/shim"
    27  	"github.com/hyperledger/fabric-protos-go/common"
    28  	plgr "github.com/hyperledger/fabric-protos-go/ledger/queryresult"
    29  	pb "github.com/hyperledger/fabric-protos-go/peer"
    30  	"github.com/hyperledger/fabric/bccsp/factory"
    31  	"github.com/hyperledger/fabric/bccsp/sw"
    32  	"github.com/hyperledger/fabric/common/crypto/tlsgen"
    33  	"github.com/hyperledger/fabric/common/flogging"
    34  	commonledger "github.com/hyperledger/fabric/common/ledger"
    35  	"github.com/hyperledger/fabric/common/metrics/disabled"
    36  	"github.com/hyperledger/fabric/common/policies"
    37  	"github.com/hyperledger/fabric/common/util"
    38  	"github.com/hyperledger/fabric/core/aclmgmt/resources"
    39  	"github.com/hyperledger/fabric/core/chaincode/accesscontrol"
    40  	"github.com/hyperledger/fabric/core/chaincode/lifecycle"
    41  	"github.com/hyperledger/fabric/core/chaincode/mock"
    42  	"github.com/hyperledger/fabric/core/chaincode/persistence"
    43  	"github.com/hyperledger/fabric/core/chaincode/platforms"
    44  	"github.com/hyperledger/fabric/core/chaincode/platforms/golang"
    45  	"github.com/hyperledger/fabric/core/common/ccprovider"
    46  	"github.com/hyperledger/fabric/core/config"
    47  	"github.com/hyperledger/fabric/core/container"
    48  	"github.com/hyperledger/fabric/core/container/ccintf"
    49  	"github.com/hyperledger/fabric/core/container/dockercontroller"
    50  	"github.com/hyperledger/fabric/core/ledger"
    51  	"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
    52  	"github.com/hyperledger/fabric/core/ledger/ledgermgmt/ledgermgmttest"
    53  	ledgermock "github.com/hyperledger/fabric/core/ledger/mock"
    54  	cut "github.com/hyperledger/fabric/core/ledger/util"
    55  	"github.com/hyperledger/fabric/core/peer"
    56  	"github.com/hyperledger/fabric/core/policy"
    57  	policymocks "github.com/hyperledger/fabric/core/policy/mocks"
    58  	"github.com/hyperledger/fabric/core/scc"
    59  	"github.com/hyperledger/fabric/core/scc/lscc"
    60  	"github.com/hyperledger/fabric/msp"
    61  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    62  	msptesttools "github.com/hyperledger/fabric/msp/mgmt/testtools"
    63  	"github.com/hyperledger/fabric/protoutil"
    64  	"github.com/spf13/viper"
    65  	"github.com/stretchr/testify/assert"
    66  )
    67  
    68  // CCContext is a legacy structure that was utilized heavily in the tests
    69  // so it has been preserved, even though it basically passes a name/version pair
    70  // alone.
    71  type CCContext struct {
    72  	Name    string
    73  	Version string
    74  }
    75  
    76  var globalBlockNum map[string]uint64
    77  
    78  type mockResultsIterator struct {
    79  	current int
    80  	kvs     []*plgr.KV
    81  }
    82  
    83  func (mri *mockResultsIterator) Next() (commonledger.QueryResult, error) {
    84  	if mri.current == len(mri.kvs) {
    85  		return nil, nil
    86  	}
    87  	kv := mri.kvs[mri.current]
    88  	mri.current = mri.current + 1
    89  
    90  	return kv, nil
    91  }
    92  
    93  func (mri *mockResultsIterator) Close() {
    94  	mri.current = len(mri.kvs)
    95  }
    96  
    97  type mockExecQuerySimulator struct {
    98  	txsim       ledger.TxSimulator
    99  	resultsIter map[string]map[string]*mockResultsIterator
   100  }
   101  
   102  func (meqe *mockExecQuerySimulator) GetHistoryForKey(namespace, query string) (commonledger.ResultsIterator, error) {
   103  	return meqe.commonQuery(namespace, query)
   104  }
   105  
   106  func (meqe *mockExecQuerySimulator) ExecuteQuery(namespace, query string) (commonledger.ResultsIterator, error) {
   107  	return meqe.commonQuery(namespace, query)
   108  }
   109  
   110  func (meqe *mockExecQuerySimulator) commonQuery(namespace, query string) (commonledger.ResultsIterator, error) {
   111  	if meqe.resultsIter == nil {
   112  		return nil, fmt.Errorf("query executor not initialized")
   113  	}
   114  	nsiter := meqe.resultsIter[namespace]
   115  	if nsiter == nil {
   116  		return nil, fmt.Errorf("namespace %v not found for %s", namespace, query)
   117  	}
   118  	iter := nsiter[query]
   119  	if iter == nil {
   120  		fmt.Printf("iter not found for query %s\n", query)
   121  	}
   122  	return iter, nil
   123  }
   124  
   125  func (meqe *mockExecQuerySimulator) SetState(namespace string, key string, value []byte) error {
   126  	if meqe.txsim == nil {
   127  		return fmt.Errorf("SetState txsimulator not initialed")
   128  	}
   129  	return meqe.txsim.SetState(namespace, key, value)
   130  }
   131  
   132  func (meqe *mockExecQuerySimulator) DeleteState(namespace string, key string) error {
   133  	if meqe.txsim == nil {
   134  		return fmt.Errorf("SetState txsimulator not initialed")
   135  	}
   136  	return meqe.txsim.DeleteState(namespace, key)
   137  }
   138  
   139  func (meqe *mockExecQuerySimulator) SetStateMultipleKeys(namespace string, kvs map[string][]byte) error {
   140  	if meqe.txsim == nil {
   141  		return fmt.Errorf("SetState txsimulator not initialed")
   142  	}
   143  	return meqe.txsim.SetStateMultipleKeys(namespace, kvs)
   144  }
   145  
   146  func (meqe *mockExecQuerySimulator) ExecuteUpdate(query string) error {
   147  	if meqe.txsim == nil {
   148  		return fmt.Errorf("SetState txsimulator not initialed")
   149  	}
   150  	return meqe.txsim.ExecuteUpdate(query)
   151  }
   152  
   153  func (meqe *mockExecQuerySimulator) GetTxSimulationResults() ([]byte, error) {
   154  	if meqe.txsim == nil {
   155  		return nil, fmt.Errorf("SetState txsimulator not initialed")
   156  	}
   157  	simRes, err := meqe.txsim.GetTxSimulationResults()
   158  	if err != nil {
   159  		return nil, err
   160  	}
   161  	return simRes.GetPubSimulationBytes()
   162  }
   163  
   164  //initialize peer and start up. If security==enabled, login as vp
   165  func initMockPeer(channelIDs ...string) (*peer.Peer, *ChaincodeSupport, func(), error) {
   166  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   167  	if err != nil {
   168  		panic(fmt.Sprintf("failed to create cryptoProvider: %s", err))
   169  	}
   170  
   171  	peerInstance := &peer.Peer{CryptoProvider: cryptoProvider}
   172  
   173  	tempdir, err := ioutil.TempDir("", "cc-support-test")
   174  	if err != nil {
   175  		panic(fmt.Sprintf("failed to create temporary directory: %s", err))
   176  	}
   177  
   178  	initializer := ledgermgmttest.NewInitializer(filepath.Join(tempdir, "ledgerData"))
   179  	peerInstance.LedgerMgr = ledgermgmt.NewLedgerMgr(initializer)
   180  
   181  	cleanup := func() {
   182  		peerInstance.LedgerMgr.Close()
   183  		os.RemoveAll(tempdir)
   184  	}
   185  
   186  	mockAclProvider := &mock.ACLProvider{}
   187  	ccprovider.SetChaincodesPath(tempdir)
   188  	ca, _ := tlsgen.NewCA()
   189  	certGenerator := accesscontrol.NewAuthenticator(ca)
   190  	globalConfig := GlobalConfig()
   191  	globalConfig.ExecuteTimeout = 1 * time.Second
   192  	globalConfig.InstallTimeout = 90 * time.Second
   193  	globalConfig.StartupTimeout = 10 * time.Second
   194  
   195  	buildRegistry := &container.BuildRegistry{}
   196  
   197  	client, err := docker.NewClientFromEnv()
   198  	if err != nil {
   199  		panic(err)
   200  	}
   201  
   202  	containerRouter := &container.Router{
   203  		DockerBuilder: &dockercontroller.DockerVM{
   204  			PlatformBuilder: &platforms.Builder{
   205  				Registry: platforms.NewRegistry(&golang.Platform{}),
   206  				Client:   client,
   207  			},
   208  		},
   209  		PackageProvider: &persistence.FallbackPackageLocator{
   210  			ChaincodePackageLocator: &persistence.ChaincodePackageLocator{},
   211  			LegacyCCPackageLocator:  &ccprovider.CCInfoFSImpl{GetHasher: cryptoProvider},
   212  		},
   213  	}
   214  
   215  	lsccImpl := &lscc.SCC{
   216  		BuiltinSCCs: map[string]struct{}{"lscc": {}},
   217  		Support: &lscc.SupportImpl{
   218  			GetMSPIDs: peerInstance.GetMSPIDs,
   219  		},
   220  		SCCProvider:      &lscc.PeerShim{Peer: peerInstance},
   221  		ACLProvider:      mockAclProvider,
   222  		GetMSPIDs:        peerInstance.GetMSPIDs,
   223  		PolicyChecker:    newPolicyChecker(peerInstance),
   224  		BCCSP:            cryptoProvider,
   225  		BuildRegistry:    buildRegistry,
   226  		ChaincodeBuilder: containerRouter,
   227  	}
   228  
   229  	ml := &mock.Lifecycle{}
   230  	ml.ChaincodeEndorsementInfoStub = func(_, name string, _ ledger.SimpleQueryExecutor) (*lifecycle.ChaincodeEndorsementInfo, error) {
   231  		switch name {
   232  		case "shimTestCC", "calledCC":
   233  			return &lifecycle.ChaincodeEndorsementInfo{
   234  				ChaincodeID: name + ":0",
   235  			}, nil
   236  		case "lscc":
   237  			return &lifecycle.ChaincodeEndorsementInfo{
   238  				ChaincodeID: "lscc.syscc",
   239  			}, nil
   240  		default:
   241  			return nil, errors.New("oh-bother-no-chaincode-info")
   242  		}
   243  	}
   244  
   245  	containerRuntime := &ContainerRuntime{
   246  		BuildRegistry:   buildRegistry,
   247  		ContainerRouter: containerRouter,
   248  	}
   249  	userRunsCC := true
   250  	metricsProviders := &disabled.Provider{}
   251  	chaincodeHandlerRegistry := NewHandlerRegistry(userRunsCC)
   252  	chaincodeLauncher := &RuntimeLauncher{
   253  		Metrics:        NewLaunchMetrics(metricsProviders),
   254  		Runtime:        containerRuntime,
   255  		Registry:       chaincodeHandlerRegistry,
   256  		StartupTimeout: globalConfig.StartupTimeout,
   257  		CACert:         ca.CertBytes(),
   258  		CertGenerator:  certGenerator,
   259  	}
   260  	if !globalConfig.TLSEnabled {
   261  		chaincodeLauncher.CertGenerator = nil
   262  	}
   263  	chaincodeSupport := &ChaincodeSupport{
   264  		ACLProvider:            mockAclProvider,
   265  		AppConfig:              peerInstance,
   266  		DeployedCCInfoProvider: &ledgermock.DeployedChaincodeInfoProvider{},
   267  		ExecuteTimeout:         globalConfig.ExecuteTimeout,
   268  		InstallTimeout:         globalConfig.InstallTimeout,
   269  		HandlerMetrics:         NewHandlerMetrics(metricsProviders),
   270  		HandlerRegistry:        chaincodeHandlerRegistry,
   271  		Keepalive:              globalConfig.Keepalive,
   272  		Launcher:               chaincodeLauncher,
   273  		Lifecycle:              ml,
   274  		Peer:                   peerInstance,
   275  		Runtime:                containerRuntime,
   276  		BuiltinSCCs:            map[string]struct{}{"lscc": {}},
   277  		TotalQueryLimit:        globalConfig.TotalQueryLimit,
   278  		UserRunsCC:             userRunsCC,
   279  	}
   280  
   281  	scc.DeploySysCC(lsccImpl, chaincodeSupport)
   282  
   283  	globalBlockNum = make(map[string]uint64, len(channelIDs))
   284  	for _, id := range channelIDs {
   285  		capabilities := &mock.ApplicationCapabilities{}
   286  		config := &mock.ApplicationConfig{}
   287  		config.CapabilitiesReturns(capabilities)
   288  		resources := &mock.Resources{}
   289  		resources.ApplicationConfigReturns(config, true)
   290  		if err := peer.CreateMockChannel(peerInstance, id, resources); err != nil {
   291  			cleanup()
   292  			return nil, nil, func() {}, err
   293  		}
   294  
   295  		// any channel other than the default testchannelid does not have a MSP set up -> create one
   296  		if id != "testchannelid" {
   297  			mspmgmt.XXXSetMSPManager(id, mspmgmt.GetManagerForChain("testchannelid"))
   298  		}
   299  		globalBlockNum[id] = 1
   300  	}
   301  
   302  	return peerInstance, chaincodeSupport, cleanup, nil
   303  }
   304  
   305  func finitMockPeer(peerInstance *peer.Peer, channelIDs ...string) {
   306  	for _, c := range channelIDs {
   307  		if lgr := peerInstance.GetLedger(c); lgr != nil {
   308  			lgr.Close()
   309  		}
   310  	}
   311  	ledgerPath := config.GetPath("peer.fileSystemPath")
   312  	os.RemoveAll(ledgerPath)
   313  	os.RemoveAll(filepath.Join(os.TempDir(), "hyperledger"))
   314  }
   315  
   316  //store the stream CC mappings here
   317  var mockPeerCCSupport = mock.NewMockPeerSupport()
   318  
   319  func setupcc(name string) (*mock.MockCCComm, *mock.MockCCComm) {
   320  	send := make(chan *pb.ChaincodeMessage)
   321  	recv := make(chan *pb.ChaincodeMessage)
   322  	peerSide, _ := mockPeerCCSupport.AddCC(name, recv, send)
   323  	peerSide.SetName("peer")
   324  	ccSide := mockPeerCCSupport.GetCCMirror(name)
   325  	ccSide.SetPong(true)
   326  	return peerSide, ccSide
   327  }
   328  
   329  //assign this to done and failNow and keep using them
   330  func setuperror() chan error {
   331  	return make(chan error)
   332  }
   333  
   334  func processDone(t *testing.T, done chan error, expecterr bool) {
   335  	var err error
   336  	if done != nil {
   337  		err = <-done
   338  	}
   339  	if expecterr != (err != nil) {
   340  		if err == nil {
   341  			t.Fatalf("Expected error but got success")
   342  		} else {
   343  			t.Fatalf("Expected success but got error %s", err)
   344  		}
   345  	}
   346  }
   347  
   348  func startTx(t *testing.T, peerInstance *peer.Peer, channelID string, cis *pb.ChaincodeInvocationSpec, txId string) (*ccprovider.TransactionParams, ledger.TxSimulator) {
   349  	creator := []byte([]byte("Alice"))
   350  	sprop, prop := protoutil.MockSignedEndorserProposalOrPanic(channelID, cis.ChaincodeSpec, creator, []byte("msg1"))
   351  	txsim, hqe, err := startTxSimulation(peerInstance, channelID, txId)
   352  	if err != nil {
   353  		t.Fatalf("getting txsimulator failed %s", err)
   354  	}
   355  
   356  	txParams := &ccprovider.TransactionParams{
   357  		ChannelID:            channelID,
   358  		TxID:                 txId,
   359  		Proposal:             prop,
   360  		SignedProp:           sprop,
   361  		TXSimulator:          txsim,
   362  		HistoryQueryExecutor: hqe,
   363  	}
   364  
   365  	return txParams, txsim
   366  }
   367  
   368  func endTx(t *testing.T, peerInstance *peer.Peer, txParams *ccprovider.TransactionParams, txsim ledger.TxSimulator, cis *pb.ChaincodeInvocationSpec) {
   369  	if err := endTxSimulationCIS(peerInstance, txParams.ChannelID, cis.ChaincodeSpec.ChaincodeId, txParams.TxID, txsim, []byte("invoke"), true, cis, globalBlockNum[txParams.ChannelID]); err != nil {
   370  		t.Fatalf("simulation failed with error %s", err)
   371  	}
   372  	globalBlockNum[txParams.ChannelID] = globalBlockNum[txParams.ChannelID] + 1
   373  }
   374  
   375  func execCC(t *testing.T, txParams *ccprovider.TransactionParams, ccSide *mock.MockCCComm, chaincodeName string, waitForERROR bool, expectExecErr bool, done chan error, cis *pb.ChaincodeInvocationSpec, respSet *mock.MockResponseSet, chaincodeSupport *ChaincodeSupport) error {
   376  	ccSide.SetResponses(respSet)
   377  
   378  	resp, _, err := chaincodeSupport.Execute(txParams, chaincodeName, cis.ChaincodeSpec.Input)
   379  	if err == nil && resp.Status != shim.OK {
   380  		err = errors.New(resp.Message)
   381  	}
   382  
   383  	if err == nil && expectExecErr {
   384  		t.Fatalf("expected error but succeeded")
   385  	} else if err != nil && !expectExecErr {
   386  		t.Fatalf("exec failed with %s", err)
   387  	}
   388  
   389  	//wait
   390  	processDone(t, done, waitForERROR)
   391  
   392  	return nil
   393  }
   394  
   395  //initialize cc support env and startup the chaincode
   396  func startCC(t *testing.T, channelID string, ccname string, chaincodeSupport *ChaincodeSupport) (*mock.MockCCComm, *mock.MockCCComm) {
   397  	peerSide, ccSide := setupcc(ccname)
   398  	defer mockPeerCCSupport.RemoveCC(ccname)
   399  
   400  	//register peer side with ccsupport
   401  	go func() {
   402  		chaincodeSupport.HandleChaincodeStream(peerSide)
   403  	}()
   404  
   405  	done := setuperror()
   406  
   407  	errorFunc := func(ind int, err error) {
   408  		done <- err
   409  	}
   410  
   411  	ccDone := make(chan struct{})
   412  	defer close(ccDone)
   413  
   414  	//start the mock peer
   415  	go func() {
   416  		respSet := &mock.MockResponseSet{
   417  			DoneFunc:  errorFunc,
   418  			ErrorFunc: nil,
   419  			Responses: []*mock.MockResponse{
   420  				{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_REGISTERED}, RespMsg: nil},
   421  				{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_READY}, RespMsg: nil},
   422  			},
   423  		}
   424  		ccSide.SetResponses(respSet)
   425  		ccSide.Run(ccDone)
   426  	}()
   427  
   428  	ccSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_REGISTER, Payload: protoutil.MarshalOrPanic(&pb.ChaincodeID{Name: ccname + ":0"}), Txid: "0", ChannelId: channelID})
   429  
   430  	//wait for init
   431  	processDone(t, done, false)
   432  
   433  	return peerSide, ccSide
   434  }
   435  
   436  func getTarGZ(t *testing.T, name string, contents []byte) []byte {
   437  	startTime := time.Now()
   438  	inputbuf := bytes.NewBuffer(nil)
   439  	gw := gzip.NewWriter(inputbuf)
   440  	tr := tar.NewWriter(gw)
   441  	size := int64(len(contents))
   442  
   443  	tr.WriteHeader(&tar.Header{Name: name, Size: size, ModTime: startTime, AccessTime: startTime, ChangeTime: startTime})
   444  	tr.Write(contents)
   445  	tr.Close()
   446  	gw.Close()
   447  	ioutil.WriteFile("/tmp/t.gz", inputbuf.Bytes(), 0644)
   448  	return inputbuf.Bytes()
   449  }
   450  
   451  // Deploy a chaincode - i.e., build and initialize.
   452  func deployCC(t *testing.T, txParams *ccprovider.TransactionParams, ccContext *CCContext, spec *pb.ChaincodeSpec, chaincodeSupport *ChaincodeSupport) {
   453  	// First build and get the deployment spec
   454  	code := getTarGZ(t, "src/dummy/dummy.go", []byte("code"))
   455  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: code}
   456  
   457  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   458  	assert.NoError(t, err)
   459  	ccinfoFSImpl := &ccprovider.CCInfoFSImpl{GetHasher: cryptoProvider}
   460  	_, err = ccinfoFSImpl.PutChaincode(cds)
   461  	assert.NoError(t, err)
   462  
   463  	b := protoutil.MarshalOrPanic(cds)
   464  
   465  	//wrap the deployment in an invocation spec to lscc...
   466  	lsccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: "lscc"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("deploy"), []byte(txParams.ChannelID), b}}}}
   467  
   468  	//write to lscc
   469  	if _, _, err := chaincodeSupport.Execute(txParams, "lscc", lsccSpec.ChaincodeSpec.Input); err != nil {
   470  		t.Fatalf("Error deploying chaincode %v (err: %s)", ccContext, err)
   471  	}
   472  }
   473  
   474  func initializeCC(t *testing.T, chainID, ccname string, ccSide *mock.MockCCComm, chaincodeSupport *ChaincodeSupport) error {
   475  	done := setuperror()
   476  
   477  	errorFunc := func(ind int, err error) {
   478  		done <- err
   479  	}
   480  
   481  	chaincodeID := &pb.ChaincodeID{Name: ccname, Version: "0"}
   482  	ci := &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("A"), []byte("100"), []byte("B"), []byte("200")}, Decorations: nil}
   483  	cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}}
   484  
   485  	txid := util.GenerateUUID()
   486  	txParams, txsim := startTx(t, chaincodeSupport.Peer, chainID, cis, txid)
   487  
   488  	//bad txid in response (should be "1"), should fail
   489  	resp := &mock.MockResponse{
   490  		RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION},
   491  		RespMsg: &pb.ChaincodeMessage{
   492  			Type:      pb.ChaincodeMessage_COMPLETED,
   493  			Payload:   protoutil.MarshalOrPanic(&pb.Response{Status: shim.OK, Payload: []byte("init succeeded")}),
   494  			Txid:      "unknowntxid",
   495  			ChannelId: chainID,
   496  		},
   497  	}
   498  	respSet := &mock.MockResponseSet{
   499  		DoneFunc:  errorFunc,
   500  		ErrorFunc: nil,
   501  		Responses: []*mock.MockResponse{resp},
   502  	}
   503  
   504  	execCC(t, txParams, ccSide, ccname, false, true, done, cis, respSet, chaincodeSupport)
   505  
   506  	//set the right TxID in response now
   507  	resp = &mock.MockResponse{
   508  		RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION},
   509  		RespMsg: &pb.ChaincodeMessage{
   510  			Type:      pb.ChaincodeMessage_COMPLETED,
   511  			Payload:   protoutil.MarshalOrPanic(&pb.Response{Status: shim.OK, Payload: []byte("init succeeded")}),
   512  			Txid:      txid,
   513  			ChannelId: chainID,
   514  		},
   515  	}
   516  	respSet = &mock.MockResponseSet{
   517  		DoneFunc:  errorFunc,
   518  		ErrorFunc: nil,
   519  		Responses: []*mock.MockResponse{resp},
   520  	}
   521  
   522  	//we are not going to reach the chaincode and so won't get a response from it. processDone will not
   523  	//be triggered by the chaincode stream.  We just expect an error from fabric. Hence pass nil for done
   524  	execCC(t, txParams, ccSide, "badccname", false, true, nil, cis, respSet, chaincodeSupport)
   525  
   526  	//---------try a successful init at last-------
   527  	//everything lined up
   528  	//    correct registered chaincode version
   529  	//    matching txid
   530  	//    txsim context
   531  	//    full response
   532  	//    correct block number for ending sim
   533  
   534  	respSet = &mock.MockResponseSet{
   535  		DoneFunc:  errorFunc,
   536  		ErrorFunc: nil,
   537  		Responses: []*mock.MockResponse{
   538  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Payload: protoutil.MarshalOrPanic(&pb.PutState{Collection: "", Key: "A", Value: []byte("100")}), Txid: txid, ChannelId: chainID}},
   539  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Payload: protoutil.MarshalOrPanic(&pb.PutState{Collection: "", Key: "B", Value: []byte("200")}), Txid: txid, ChannelId: chainID}},
   540  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: protoutil.MarshalOrPanic(&pb.Response{Status: shim.OK, Payload: []byte("OK")}), ChaincodeEvent: &pb.ChaincodeEvent{ChaincodeId: ccname}, Txid: txid, ChannelId: chainID}},
   541  		},
   542  	}
   543  
   544  	execCC(t, txParams, ccSide, ccname, false, false, done, cis, respSet, chaincodeSupport)
   545  
   546  	endTx(t, chaincodeSupport.Peer, txParams, txsim, cis)
   547  
   548  	return nil
   549  }
   550  
   551  func invokeCC(t *testing.T, chainID, ccname string, ccSide *mock.MockCCComm, chaincodeSupport *ChaincodeSupport) error {
   552  	done := setuperror()
   553  
   554  	errorFunc := func(ind int, err error) {
   555  		done <- err
   556  	}
   557  
   558  	chaincodeID := &pb.ChaincodeID{Name: ccname, Version: "0"}
   559  	ci := &pb.ChaincodeInput{Args: [][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}, Decorations: nil}
   560  	cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}}
   561  	txid := util.GenerateUUID()
   562  	txParams, txsim := startTx(t, chaincodeSupport.Peer, chainID, cis, txid)
   563  
   564  	respSet := &mock.MockResponseSet{
   565  		DoneFunc:  errorFunc,
   566  		ErrorFunc: nil,
   567  		Responses: []*mock.MockResponse{
   568  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Payload: protoutil.MarshalOrPanic(&pb.GetState{Collection: "", Key: "A"}), Txid: txid, ChannelId: chainID}},
   569  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Payload: protoutil.MarshalOrPanic(&pb.GetState{Collection: "", Key: "B"}), Txid: txid, ChannelId: chainID}},
   570  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Payload: protoutil.MarshalOrPanic(&pb.PutState{Collection: "", Key: "A", Value: []byte("90")}), Txid: txid, ChannelId: chainID}},
   571  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Payload: protoutil.MarshalOrPanic(&pb.PutState{Collection: "", Key: "B", Value: []byte("210")}), Txid: txid, ChannelId: chainID}},
   572  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Payload: protoutil.MarshalOrPanic(&pb.PutState{Collection: "", Key: "TODEL", Value: []byte("-to-be-deleted-")}), Txid: txid, ChannelId: chainID}},
   573  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: protoutil.MarshalOrPanic(&pb.Response{Status: shim.OK, Payload: []byte("OK")}), Txid: txid, ChannelId: chainID}},
   574  		},
   575  	}
   576  
   577  	execCC(t, txParams, ccSide, ccname, false, false, done, cis, respSet, chaincodeSupport)
   578  
   579  	//delete the extra var
   580  	respSet = &mock.MockResponseSet{
   581  		DoneFunc:  errorFunc,
   582  		ErrorFunc: nil,
   583  		Responses: []*mock.MockResponse{
   584  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Payload: protoutil.MarshalOrPanic(&pb.GetState{Collection: "", Key: "TODEL"}), Txid: "3", ChannelId: chainID}},
   585  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_DEL_STATE, Payload: protoutil.MarshalOrPanic(&pb.DelState{Collection: "", Key: "TODEL"}), Txid: "3", ChannelId: chainID}},
   586  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: protoutil.MarshalOrPanic(&pb.Response{Status: shim.OK, Payload: []byte("OK")}), Txid: "3", ChannelId: chainID}},
   587  		},
   588  	}
   589  
   590  	txParams.TxID = "3"
   591  	execCC(t, txParams, ccSide, ccname, false, false, done, cis, respSet, chaincodeSupport)
   592  
   593  	//get the extra var and delete it
   594  	respSet = &mock.MockResponseSet{
   595  		DoneFunc:  errorFunc,
   596  		ErrorFunc: nil,
   597  		Responses: []*mock.MockResponse{
   598  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Payload: protoutil.MarshalOrPanic(&pb.GetState{Collection: "", Key: "TODEL"}), Txid: "4", ChannelId: chainID}},
   599  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: protoutil.MarshalOrPanic(&pb.Response{Status: shim.ERROR, Message: "variable not found"}), Txid: "4", ChannelId: chainID}},
   600  		},
   601  	}
   602  
   603  	txParams.TxID = "4"
   604  	execCC(t, txParams, ccSide, ccname, false, true, done, cis, respSet, chaincodeSupport)
   605  
   606  	endTx(t, chaincodeSupport.Peer, txParams, txsim, cis)
   607  
   608  	return nil
   609  }
   610  
   611  func getQueryStateByRange(t *testing.T, collection, chainID, ccname string, ccSide *mock.MockCCComm, chaincodeSupport *ChaincodeSupport) error {
   612  	done := setuperror()
   613  	errorFunc := func(ind int, err error) {
   614  		done <- err
   615  	}
   616  
   617  	chaincodeID := &pb.ChaincodeID{Name: ccname, Version: "0"}
   618  	ci := &pb.ChaincodeInput{Args: [][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}, Decorations: nil}
   619  	cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}}
   620  	txid := util.GenerateUUID()
   621  	txParams, txsim := startTx(t, chaincodeSupport.Peer, chainID, cis, txid)
   622  
   623  	//create the response
   624  	queryStateNextFunc := func(reqMsg *pb.ChaincodeMessage) *pb.ChaincodeMessage {
   625  		qr := &pb.QueryResponse{}
   626  		proto.Unmarshal(reqMsg.Payload, qr)
   627  		return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_NEXT, Payload: protoutil.MarshalOrPanic(&pb.QueryStateNext{Id: qr.Id}), Txid: txid, ChannelId: chainID}
   628  	}
   629  	queryStateCloseFunc := func(reqMsg *pb.ChaincodeMessage) *pb.ChaincodeMessage {
   630  		qr := &pb.QueryResponse{}
   631  		proto.Unmarshal(reqMsg.Payload, qr)
   632  		return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_CLOSE, Payload: protoutil.MarshalOrPanic(&pb.QueryStateClose{Id: qr.Id}), Txid: txid, ChannelId: chainID}
   633  	}
   634  
   635  	var mkpeer []*mock.MockResponse
   636  
   637  	mkpeer = append(mkpeer, &mock.MockResponse{
   638  		RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION},
   639  		RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE_BY_RANGE, Payload: protoutil.MarshalOrPanic(&pb.GetStateByRange{Collection: collection, StartKey: "A", EndKey: "B"}), Txid: txid, ChannelId: chainID},
   640  	})
   641  
   642  	if collection == "" {
   643  		mkpeer = append(mkpeer, &mock.MockResponse{
   644  			RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE},
   645  			RespMsg: queryStateNextFunc,
   646  		})
   647  		mkpeer = append(mkpeer, &mock.MockResponse{
   648  			RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR},
   649  			RespMsg: queryStateCloseFunc,
   650  		})
   651  		mkpeer = append(mkpeer, &mock.MockResponse{
   652  			RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE},
   653  			RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: protoutil.MarshalOrPanic(&pb.Response{Status: shim.OK, Payload: []byte("OK")}), Txid: txid, ChannelId: chainID},
   654  		})
   655  	} else {
   656  		// Range queries on private data is not yet implemented.
   657  		mkpeer = append(mkpeer, &mock.MockResponse{
   658  			RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR},
   659  			RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: protoutil.MarshalOrPanic(&pb.Response{Status: shim.ERROR, Message: "Not Yet Supported"}), Txid: txid, ChannelId: chainID},
   660  		})
   661  	}
   662  
   663  	respSet := &mock.MockResponseSet{
   664  		DoneFunc:  errorFunc,
   665  		ErrorFunc: nil,
   666  		Responses: mkpeer,
   667  	}
   668  
   669  	if collection == "" {
   670  		execCC(t, txParams, ccSide, ccname, false, false, done, cis, respSet, chaincodeSupport)
   671  	} else {
   672  		execCC(t, txParams, ccSide, ccname, false, true, done, cis, respSet, chaincodeSupport)
   673  	}
   674  
   675  	endTx(t, chaincodeSupport.Peer, txParams, txsim, cis)
   676  
   677  	return nil
   678  }
   679  
   680  func cc2cc(t *testing.T, chainID, chainID2, ccname string, ccSide *mock.MockCCComm, chaincodeSupport *ChaincodeSupport) error {
   681  	calledCC := "calledCC"
   682  	//starts and registers the CC
   683  	_, calledCCSide := startCC(t, chainID2, calledCC, chaincodeSupport)
   684  	if calledCCSide == nil {
   685  		t.Fatalf("start up failed for called CC")
   686  	}
   687  	defer calledCCSide.Quit()
   688  
   689  	done := setuperror()
   690  
   691  	errorFunc := func(ind int, err error) {
   692  		done <- err
   693  	}
   694  
   695  	chaincodeID := &pb.ChaincodeID{Name: calledCC, Version: "0"}
   696  	ci := &pb.ChaincodeInput{Args: [][]byte{[]byte("deploycc")}, Decorations: nil}
   697  	cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}}
   698  	txid := util.GenerateUUID()
   699  	//first deploy the new cc to LSCC
   700  	txParams, txsim := startTx(t, chaincodeSupport.Peer, chainID, cis, txid)
   701  
   702  	ccContext := &CCContext{
   703  		Name:    calledCC,
   704  		Version: "0",
   705  	}
   706  
   707  	deployCC(t, txParams, ccContext, cis.ChaincodeSpec, chaincodeSupport)
   708  
   709  	//commit
   710  	endTx(t, chaincodeSupport.Peer, txParams, txsim, cis)
   711  
   712  	//now do the cc2cc
   713  	chaincodeID = &pb.ChaincodeID{Name: ccname, Version: "0"}
   714  	ci = &pb.ChaincodeInput{Args: [][]byte{[]byte("invokecc")}, Decorations: nil}
   715  	cis = &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}}
   716  	txid = util.GenerateUUID()
   717  	txParams, txsim = startTx(t, chaincodeSupport.Peer, chainID, cis, txid)
   718  
   719  	//call a callable system CC, a regular cc, a regular but different cc on a different chain, a regular but same cc on a different chain,  and an uncallable system cc and expect an error inthe last one
   720  	respSet := &mock.MockResponseSet{
   721  		DoneFunc:  errorFunc,
   722  		ErrorFunc: nil,
   723  		Responses: []*mock.MockResponse{
   724  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INVOKE_CHAINCODE, Payload: protoutil.MarshalOrPanic(&pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "lscc.syscc"}, Input: &pb.ChaincodeInput{Args: [][]byte{{}}}}), Txid: txid, ChannelId: chainID}},
   725  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INVOKE_CHAINCODE, Payload: protoutil.MarshalOrPanic(&pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "calledCC:0/" + chainID}, Input: &pb.ChaincodeInput{Args: [][]byte{{}}}}), Txid: txid, ChannelId: chainID}},
   726  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INVOKE_CHAINCODE, Payload: protoutil.MarshalOrPanic(&pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "calledCC:0/" + chainID2}, Input: &pb.ChaincodeInput{Args: [][]byte{{}}}}), Txid: txid, ChannelId: chainID}},
   727  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INVOKE_CHAINCODE, Payload: protoutil.MarshalOrPanic(&pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "vscc.syscc"}, Input: &pb.ChaincodeInput{Args: [][]byte{{}}}}), Txid: txid, ChannelId: chainID}},
   728  		},
   729  	}
   730  
   731  	respSet2 := &mock.MockResponseSet{
   732  		DoneFunc:  nil,
   733  		ErrorFunc: nil,
   734  		Responses: []*mock.MockResponse{
   735  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: protoutil.MarshalOrPanic(&pb.Response{Status: shim.OK, Payload: []byte("OK")}), Txid: txid, ChannelId: chainID}},
   736  		},
   737  	}
   738  	calledCCSide.SetResponses(respSet2)
   739  
   740  	execCC(t, txParams, ccSide, ccname, false, true, done, cis, respSet, chaincodeSupport)
   741  
   742  	endTx(t, chaincodeSupport.Peer, txParams, txsim, cis)
   743  
   744  	//finally lets try a Bad ACL with CC-calling-CC
   745  	chaincodeID = &pb.ChaincodeID{Name: ccname, Version: "0"}
   746  	ci = &pb.ChaincodeInput{Args: [][]byte{[]byte("invokecc")}, Decorations: nil}
   747  	cis = &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}}
   748  	txid = util.GenerateUUID()
   749  	txParams, txsim = startTx(t, chaincodeSupport.Peer, chainID, cis, txid)
   750  
   751  	mockAclProvider := chaincodeSupport.ACLProvider.(*mock.ACLProvider)
   752  	mockAclProvider.CheckACLStub = func(resource, channel string, _ interface{}) error {
   753  		if resource == resources.Peer_ChaincodeToChaincode && channel == chainID {
   754  			return errors.New("bad-acl-calling-cc")
   755  		}
   756  		return nil
   757  	}
   758  
   759  	//call regular cc but without ACL on called CC
   760  	respSet = &mock.MockResponseSet{
   761  		DoneFunc:  errorFunc,
   762  		ErrorFunc: nil,
   763  		Responses: []*mock.MockResponse{
   764  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INVOKE_CHAINCODE, Payload: protoutil.MarshalOrPanic(&pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "calledCC:0/" + chainID}, Input: &pb.ChaincodeInput{Args: [][]byte{{}}}}), Txid: txid, ChannelId: chainID}},
   765  		},
   766  	}
   767  
   768  	respSet2 = &mock.MockResponseSet{
   769  		DoneFunc:  nil,
   770  		ErrorFunc: nil,
   771  		Responses: []*mock.MockResponse{
   772  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: protoutil.MarshalOrPanic(&pb.Response{Status: shim.OK, Payload: []byte("OK")}), Txid: txid, ChannelId: chainID}},
   773  		},
   774  	}
   775  
   776  	calledCCSide.SetResponses(respSet2)
   777  
   778  	execCC(t, txParams, ccSide, ccname, false, true, done, cis, respSet, chaincodeSupport)
   779  
   780  	endTx(t, chaincodeSupport.Peer, txParams, txsim, cis)
   781  
   782  	return nil
   783  }
   784  
   785  func getQueryResult(t *testing.T, collection, chainID, ccname string, ccSide *mock.MockCCComm, chaincodeSupport *ChaincodeSupport) error {
   786  	done := setuperror()
   787  
   788  	errorFunc := func(ind int, err error) {
   789  		done <- err
   790  	}
   791  
   792  	chaincodeID := &pb.ChaincodeID{Name: ccname, Version: "0"}
   793  	ci := &pb.ChaincodeInput{Args: [][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}, Decorations: nil}
   794  	cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}}
   795  	txid := util.GenerateUUID()
   796  	txParams, txsim := startTx(t, chaincodeSupport.Peer, chainID, cis, txid)
   797  
   798  	kvs := make([]*plgr.KV, 1000)
   799  	for i := 0; i < 1000; i++ {
   800  		kvs[i] = &plgr.KV{Namespace: chainID, Key: fmt.Sprintf("%d", i), Value: []byte(fmt.Sprintf("%d", i))}
   801  	}
   802  
   803  	queryExec := &mockExecQuerySimulator{resultsIter: make(map[string]map[string]*mockResultsIterator)}
   804  	queryExec.resultsIter[ccname] = map[string]*mockResultsIterator{"goodquery": {kvs: kvs}}
   805  
   806  	queryExec.txsim = txParams.TXSimulator
   807  
   808  	//create the response
   809  	queryStateNextFunc := func(reqMsg *pb.ChaincodeMessage) *pb.ChaincodeMessage {
   810  		qr := &pb.QueryResponse{}
   811  		proto.Unmarshal(reqMsg.Payload, qr)
   812  		return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_NEXT, Payload: protoutil.MarshalOrPanic(&pb.QueryStateNext{Id: qr.Id}), Txid: txid, ChannelId: chainID}
   813  	}
   814  	queryStateCloseFunc := func(reqMsg *pb.ChaincodeMessage) *pb.ChaincodeMessage {
   815  		qr := &pb.QueryResponse{}
   816  		proto.Unmarshal(reqMsg.Payload, qr)
   817  		return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_CLOSE, Payload: protoutil.MarshalOrPanic(&pb.QueryStateClose{Id: qr.Id}), Txid: txid, ChannelId: chainID}
   818  	}
   819  
   820  	var mkpeer []*mock.MockResponse
   821  
   822  	mkpeer = append(mkpeer, &mock.MockResponse{
   823  		RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION},
   824  		RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_QUERY_RESULT, Payload: protoutil.MarshalOrPanic(&pb.GetQueryResult{Collection: "", Query: "goodquery"}), Txid: txid, ChannelId: chainID},
   825  	})
   826  
   827  	if collection == "" {
   828  		mkpeer = append(mkpeer, &mock.MockResponse{
   829  			RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE},
   830  			RespMsg: queryStateNextFunc,
   831  		})
   832  		mkpeer = append(mkpeer, &mock.MockResponse{
   833  			RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR},
   834  			RespMsg: queryStateCloseFunc,
   835  		})
   836  		mkpeer = append(mkpeer, &mock.MockResponse{
   837  			RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE},
   838  			RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: protoutil.MarshalOrPanic(&pb.Response{Status: shim.OK, Payload: []byte("OK")}), Txid: txid, ChannelId: chainID},
   839  		})
   840  	} else {
   841  		// Get query results on private data is not yet implemented.
   842  		mkpeer = append(mkpeer, &mock.MockResponse{
   843  			RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR},
   844  			RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: protoutil.MarshalOrPanic(&pb.Response{Status: shim.ERROR, Message: "Not Yet Supported"}), Txid: txid, ChannelId: chainID},
   845  		})
   846  	}
   847  
   848  	respSet := &mock.MockResponseSet{
   849  		DoneFunc:  errorFunc,
   850  		ErrorFunc: nil,
   851  		Responses: mkpeer,
   852  	}
   853  
   854  	if collection == "" {
   855  		execCC(t, txParams, ccSide, ccname, false, false, done, cis, respSet, chaincodeSupport)
   856  	} else {
   857  		execCC(t, txParams, ccSide, ccname, false, true, done, cis, respSet, chaincodeSupport)
   858  	}
   859  
   860  	endTx(t, chaincodeSupport.Peer, txParams, txsim, cis)
   861  
   862  	return nil
   863  }
   864  
   865  func getHistory(t *testing.T, chainID, ccname string, ccSide *mock.MockCCComm, chaincodeSupport *ChaincodeSupport) error {
   866  	done := setuperror()
   867  
   868  	errorFunc := func(ind int, err error) {
   869  		done <- err
   870  	}
   871  
   872  	chaincodeID := &pb.ChaincodeID{Name: ccname, Version: "0"}
   873  	ci := &pb.ChaincodeInput{Args: [][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}, Decorations: nil}
   874  	cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}}
   875  	txid := util.GenerateUUID()
   876  	txParams, txsim := startTx(t, chaincodeSupport.Peer, chainID, cis, txid)
   877  
   878  	kvs := make([]*plgr.KV, 1000)
   879  	for i := 0; i < 1000; i++ {
   880  		kvs[i] = &plgr.KV{Namespace: chainID, Key: fmt.Sprintf("%d", i), Value: []byte(fmt.Sprintf("%d", i))}
   881  	}
   882  
   883  	queryExec := &mockExecQuerySimulator{resultsIter: make(map[string]map[string]*mockResultsIterator)}
   884  	queryExec.resultsIter[ccname] = map[string]*mockResultsIterator{"goodquery": {kvs: kvs}}
   885  
   886  	queryExec.txsim = txParams.TXSimulator
   887  
   888  	//create the response
   889  	queryStateNextFunc := func(reqMsg *pb.ChaincodeMessage) *pb.ChaincodeMessage {
   890  		qr := &pb.QueryResponse{}
   891  		proto.Unmarshal(reqMsg.Payload, qr)
   892  		return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_NEXT, Payload: protoutil.MarshalOrPanic(&pb.QueryStateNext{Id: qr.Id}), Txid: txid}
   893  	}
   894  	queryStateCloseFunc := func(reqMsg *pb.ChaincodeMessage) *pb.ChaincodeMessage {
   895  		qr := &pb.QueryResponse{}
   896  		proto.Unmarshal(reqMsg.Payload, qr)
   897  		return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_CLOSE, Payload: protoutil.MarshalOrPanic(&pb.QueryStateClose{Id: qr.Id}), Txid: txid}
   898  	}
   899  
   900  	respSet := &mock.MockResponseSet{
   901  		DoneFunc:  errorFunc,
   902  		ErrorFunc: nil,
   903  		Responses: []*mock.MockResponse{
   904  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_HISTORY_FOR_KEY, Payload: protoutil.MarshalOrPanic(&pb.GetQueryResult{Query: "goodquery"}), Txid: txid, ChannelId: chainID}},
   905  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: queryStateNextFunc},
   906  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: queryStateNextFunc},
   907  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR}, RespMsg: queryStateCloseFunc},
   908  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: protoutil.MarshalOrPanic(&pb.Response{Status: shim.OK, Payload: []byte("OK")}), Txid: txid, ChannelId: chainID}},
   909  		},
   910  	}
   911  
   912  	execCC(t, txParams, ccSide, ccname, false, false, done, cis, respSet, chaincodeSupport)
   913  
   914  	endTx(t, chaincodeSupport.Peer, txParams, txsim, cis)
   915  
   916  	return nil
   917  }
   918  
   919  //success case
   920  func TestStartAndWaitSuccess(t *testing.T) {
   921  	handlerRegistry := NewHandlerRegistry(false)
   922  	fakeRuntime := &mock.Runtime{}
   923  	fakeRuntime.StartStub = func(_ string, _ *ccintf.PeerConnection) error {
   924  		handlerRegistry.Ready("testcc:0")
   925  		return nil
   926  	}
   927  
   928  	launcher := &RuntimeLauncher{
   929  		Runtime:        fakeRuntime,
   930  		Registry:       handlerRegistry,
   931  		StartupTimeout: 10 * time.Second,
   932  		Metrics:        NewLaunchMetrics(&disabled.Provider{}),
   933  	}
   934  
   935  	fakeStreamHandler := &mock.ChaincodeStreamHandler{}
   936  	//actual test - everythings good
   937  	err := launcher.Launch("testcc:0", fakeStreamHandler)
   938  	if err != nil {
   939  		t.Fatalf("expected success but failed with error %s", err)
   940  	}
   941  }
   942  
   943  //test timeout error
   944  func TestStartAndWaitTimeout(t *testing.T) {
   945  	fakeRuntime := &mock.Runtime{}
   946  	fakeRuntime.StartStub = func(_ string, _ *ccintf.PeerConnection) error {
   947  		time.Sleep(time.Second)
   948  		return nil
   949  	}
   950  
   951  	launcher := &RuntimeLauncher{
   952  		Runtime:        fakeRuntime,
   953  		Registry:       NewHandlerRegistry(false),
   954  		StartupTimeout: 500 * time.Millisecond,
   955  		Metrics:        NewLaunchMetrics(&disabled.Provider{}),
   956  	}
   957  
   958  	fakeStreamHandler := &mock.ChaincodeStreamHandler{}
   959  	//the actual test - timeout 1000 > 500
   960  	err := launcher.Launch("testcc:0", fakeStreamHandler)
   961  	if err == nil {
   962  		t.Fatalf("expected error but succeeded")
   963  	}
   964  }
   965  
   966  //test container return error
   967  func TestStartAndWaitLaunchError(t *testing.T) {
   968  	fakeRuntime := &mock.Runtime{}
   969  	fakeRuntime.StartStub = func(_ string, _ *ccintf.PeerConnection) error {
   970  		return errors.New("Bad lunch; upset stomach")
   971  	}
   972  
   973  	launcher := &RuntimeLauncher{
   974  		Runtime:        fakeRuntime,
   975  		Registry:       NewHandlerRegistry(false),
   976  		StartupTimeout: 10 * time.Second,
   977  		Metrics:        NewLaunchMetrics(&disabled.Provider{}),
   978  	}
   979  
   980  	fakeStreamHandler := &mock.ChaincodeStreamHandler{}
   981  	//actual test - container launch gives error
   982  	err := launcher.Launch("testcc:0", fakeStreamHandler)
   983  	if err == nil {
   984  		t.Fatalf("expected error but succeeded")
   985  	}
   986  	assert.EqualError(t, err, "error starting container: Bad lunch; upset stomach")
   987  }
   988  
   989  func TestGetTxContextFromHandler(t *testing.T) {
   990  	chnl := "test"
   991  	peerInstance, _, cleanup, err := initMockPeer(chnl)
   992  	assert.NoError(t, err, "failed to initialize mock peer")
   993  	defer cleanup()
   994  
   995  	h := Handler{
   996  		TXContexts:  NewTransactionContexts(),
   997  		BuiltinSCCs: map[string]struct{}{"lscc": {}},
   998  	}
   999  
  1000  	txid := "1"
  1001  	// test getTxContext for TEST channel, tx=1, msgType=IVNOKE_CHAINCODE and empty payload - empty payload => expect to return empty txContext
  1002  	txContext, _ := h.getTxContextForInvoke(chnl, "1", []byte(""), "[%s]No ledger context for %s. Sending %s", 12345, "TestCC", pb.ChaincodeMessage_ERROR)
  1003  	assert.Nil(t, txContext, "expected empty txContext for empty payload")
  1004  
  1005  	pldgr := peerInstance.GetLedger(chnl)
  1006  
  1007  	// prepare a payload and generate a TxContext in the handler to be used in the following getTxContextFroMessage with a normal UCC
  1008  	txCtxGenerated, payload := genNewPldAndCtxFromLdgr(t, "shimTestCC", chnl, txid, pldgr, &h)
  1009  
  1010  	// test getTxContext for TEST channel, tx=1, msgType=IVNOKE_CHAINCODE and non empty payload => must return a non empty txContext
  1011  	txContext, ccMsg := h.getTxContextForInvoke(chnl, txid, payload, "[%s]No ledger context for %s. Sending %s", 12345, pb.ChaincodeMessage_INVOKE_CHAINCODE, pb.ChaincodeMessage_ERROR)
  1012  	if txContext == nil || ccMsg != nil || txContext != txCtxGenerated {
  1013  		t.Fatalf("expected successful txContext for non empty payload and INVOKE_CHAINCODE msgType. triggerNextStateMsg: %s.", ccMsg)
  1014  	}
  1015  
  1016  	// test for another msgType (PUT_STATE) with the same payload ==> must return a non empty txContext
  1017  	txContext, ccMsg = h.getTxContextForInvoke(chnl, txid, payload, "[%s]No ledger context for %s. Sending %s", 12345, pb.ChaincodeMessage_PUT_STATE, pb.ChaincodeMessage_ERROR)
  1018  	if txContext == nil || ccMsg != nil || txContext != txCtxGenerated {
  1019  		t.Fatalf("expected successful txContext for non empty payload and PUT_STATE msgType. triggerNextStateMsg: %s.", ccMsg)
  1020  	}
  1021  
  1022  	// get a new txContext for our SCC tests
  1023  	txid = "2"
  1024  	// reset channel to "" to test getting a context for an SCC without a channel
  1025  	chnl = ""
  1026  	txCtxGenerated, payload = genNewPldAndCtxFromLdgr(t, "lscc", chnl, txid, pldgr, &h)
  1027  
  1028  	// test getting a TxContext with an SCC without a channel => expect to return a non empty txContext
  1029  	txContext, ccMsg = h.getTxContextForInvoke(chnl, txid, payload,
  1030  		"[%s]No ledger context for %s. Sending %s", 12345, pb.ChaincodeMessage_INVOKE_CHAINCODE, pb.ChaincodeMessage_ERROR)
  1031  	if txContext == nil || ccMsg != nil || txContext != txCtxGenerated {
  1032  		t.Fatalf("expected successful txContext for non empty payload and INVOKE_CHAINCODE msgType. triggerNextStateMsg: %s.", ccMsg)
  1033  	}
  1034  
  1035  	// now reset back to non empty channel and test with an SCC
  1036  	txid = "3"
  1037  	chnl = "TEST"
  1038  	txCtxGenerated, payload = genNewPldAndCtxFromLdgr(t, "lscc", chnl, txid, pldgr, &h)
  1039  
  1040  	// test getting a TxContext with an SCC with channel TEST => expect to return a non empty txContext
  1041  	txContext, ccMsg = h.getTxContextForInvoke(chnl, txid, payload,
  1042  		"[%s]No ledger context for %s. Sending %s", 12345, pb.ChaincodeMessage_INVOKE_CHAINCODE, pb.ChaincodeMessage_ERROR)
  1043  	if txContext == nil || ccMsg != nil || txContext != txCtxGenerated {
  1044  		t.Fatalf("expected successful txContext for non empty payload and INVOKE_CHAINCODE msgType. triggerNextStateMsg: %s.", ccMsg)
  1045  	}
  1046  
  1047  	// now test getting a context with an empty channel and a UCC instead of an SCC
  1048  	txid = "4"
  1049  	chnl = ""
  1050  	txCtxGenerated, payload = genNewPldAndCtxFromLdgr(t, "shimTestCC", chnl, txid, pldgr, &h)
  1051  	// test getting a TxContext with an SCC with channel TEST => expect to return a non empty txContext
  1052  	txContext, ccMsg = h.getTxContextForInvoke(chnl, txid, payload,
  1053  		"[%s]No ledger context for %s. Sending %s", 12345, pb.ChaincodeMessage_INVOKE_CHAINCODE, pb.ChaincodeMessage_ERROR)
  1054  	if txContext == nil || ccMsg != nil || txContext != txCtxGenerated {
  1055  		t.Fatalf("expected successful txContext for non empty payload and INVOKE_CHAINCODE msgType. triggerNextStateMsg: %s.", ccMsg)
  1056  	}
  1057  
  1058  	// new test getting a context with an empty channel without the ledger creating a new context for a UCC
  1059  	txid = "5"
  1060  	payload = genNewPld(t, "shimTestCC")
  1061  	// test getting a TxContext with an SCC with channel TEST => expect to return a non empty txContext
  1062  	txContext, ccMsg = h.getTxContextForInvoke(chnl, txid, payload,
  1063  		"[%s]No ledger context for %s. Sending %s", 12345, pb.ChaincodeMessage_INVOKE_CHAINCODE, pb.ChaincodeMessage_ERROR)
  1064  	if txContext != nil || ccMsg == nil {
  1065  		t.Fatal("expected nil txContext for non empty payload and INVOKE_CHAINCODE msgType without the ledger generating a TxContext . unexpected non nil tcContext")
  1066  	}
  1067  
  1068  	// test same scenario as above but for an SCC this time
  1069  	txid = "6"
  1070  	payload = genNewPld(t, "lscc")
  1071  	// test getting a TxContext with an SCC with channel TEST => expect to return a non empty txContext
  1072  	txContext, ccMsg = h.getTxContextForInvoke(chnl, txid, payload,
  1073  		"[%s]No ledger context for %s. Sending %s", 12345, pb.ChaincodeMessage_INVOKE_CHAINCODE, pb.ChaincodeMessage_ERROR)
  1074  	if txContext != nil || ccMsg == nil {
  1075  		t.Fatal("expected nil txContext for non empty payload and INVOKE_CHAINCODE msgType without the ledger generating a TxContext . unexpected non nil tcContext")
  1076  	}
  1077  }
  1078  
  1079  func genNewPldAndCtxFromLdgr(t *testing.T, ccName string, chnl string, txid string, pldgr ledger.PeerLedger, h *Handler) (*TransactionContext, []byte) {
  1080  	// create a new TxSimulator for the received txid
  1081  	txsim, err := pldgr.NewTxSimulator(txid)
  1082  	if err != nil {
  1083  		t.Fatalf("failed to create TxSimulator %s", err)
  1084  	}
  1085  	txParams := &ccprovider.TransactionParams{
  1086  		TxID:        txid,
  1087  		ChannelID:   chnl,
  1088  		TXSimulator: txsim,
  1089  		NamespaceID: ccName,
  1090  	}
  1091  	newTxCtxt, err := h.TXContexts.Create(txParams)
  1092  	if err != nil {
  1093  		t.Fatalf("Error creating TxContext by the handler for cc %s and channel '%s': %s", ccName, chnl, err)
  1094  	}
  1095  	if newTxCtxt == nil {
  1096  		t.Fatalf("Error creating TxContext: newTxCtxt created by the handler is nil for cc %s and channel '%s'.", ccName, chnl)
  1097  	}
  1098  	// build a new cds and payload for the CC called ccName
  1099  	payload := genNewPld(t, ccName)
  1100  	return newTxCtxt, payload
  1101  }
  1102  
  1103  func genNewPld(t *testing.T, ccName string) []byte {
  1104  	// build a new cds and payload for the CC called ccName
  1105  	chaincodeID := &pb.ChaincodeID{Name: ccName, Version: "0"}
  1106  	ci := &pb.ChaincodeInput{Args: [][]byte{[]byte("deploycc")}, Decorations: nil}
  1107  	cds := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}
  1108  	payload, err := proto.Marshal(cds)
  1109  	if err != nil {
  1110  		t.Fatalf("failed to marshal CDS %s", err)
  1111  	}
  1112  	return payload
  1113  }
  1114  
  1115  func cc2SameCC(t *testing.T, chainID, chainID2, ccname string, ccSide *mock.MockCCComm, chaincodeSupport *ChaincodeSupport) {
  1116  	//first deploy the CC on chainID2
  1117  	chaincodeID := &pb.ChaincodeID{Name: ccname, Version: "0"}
  1118  	ci := &pb.ChaincodeInput{Args: [][]byte{[]byte("deploycc")}, Decorations: nil}
  1119  	cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}}
  1120  
  1121  	txid := util.GenerateUUID()
  1122  	txParams, txsim := startTx(t, chaincodeSupport.Peer, chainID2, cis, txid)
  1123  
  1124  	ccContext := &CCContext{
  1125  		Name:    ccname,
  1126  		Version: "0",
  1127  	}
  1128  
  1129  	deployCC(t, txParams, ccContext, cis.ChaincodeSpec, chaincodeSupport)
  1130  
  1131  	//commit
  1132  	endTx(t, chaincodeSupport.Peer, txParams, txsim, cis)
  1133  
  1134  	done := setuperror()
  1135  
  1136  	errorFunc := func(ind int, err error) {
  1137  		done <- err
  1138  	}
  1139  
  1140  	//now for the test - call the same cc on a different channel(should succeed), call the same cc on the same channel(should fail)
  1141  	//Note the error "Another request pending for this Txid. Cannot process." in the logs under TX "cctosamecctx"
  1142  	ci = &pb.ChaincodeInput{Args: [][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}, Decorations: nil}
  1143  	cis = &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}}
  1144  	txid = util.GenerateUUID()
  1145  	txParams, txsim = startTx(t, chaincodeSupport.Peer, chainID, cis, txid)
  1146  
  1147  	txid = "cctosamecctx"
  1148  	respSet := &mock.MockResponseSet{
  1149  		DoneFunc:  errorFunc,
  1150  		ErrorFunc: nil,
  1151  		Responses: []*mock.MockResponse{
  1152  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INVOKE_CHAINCODE, Payload: protoutil.MarshalOrPanic(&pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: ccname + ":0/" + chainID2}, Input: &pb.ChaincodeInput{Args: [][]byte{{}}}}), Txid: txid, ChannelId: chainID}},
  1153  			{RecvMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE}, RespMsg: &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INVOKE_CHAINCODE, Payload: protoutil.MarshalOrPanic(&pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: ccname + ":0/" + chainID}, Input: &pb.ChaincodeInput{Args: [][]byte{{}}}}), Txid: txid, ChannelId: chainID}},
  1154  		},
  1155  	}
  1156  
  1157  	execCC(t, txParams, ccSide, ccname, false, true, done, cis, respSet, chaincodeSupport)
  1158  
  1159  	endTx(t, chaincodeSupport.Peer, txParams, txsim, cis)
  1160  }
  1161  
  1162  func TestCCFramework(t *testing.T) {
  1163  	//register 2 channels
  1164  	chainID := "mockchainid"
  1165  	chainID2 := "secondchain"
  1166  	peerInstance, chaincodeSupport, cleanup, err := initMockPeer(chainID, chainID2)
  1167  	if err != nil {
  1168  		t.Fatalf("%s", err)
  1169  	}
  1170  	defer cleanup()
  1171  	defer finitMockPeer(peerInstance, chainID, chainID2)
  1172  	//create a chaincode
  1173  	ccname := "shimTestCC"
  1174  
  1175  	//starts and registers the CC
  1176  	_, ccSide := startCC(t, chainID, ccname, chaincodeSupport)
  1177  	if ccSide == nil {
  1178  		t.Fatalf("start up failed")
  1179  	}
  1180  	defer ccSide.Quit()
  1181  
  1182  	//call's init and does some PUT (after doing some negative testing)
  1183  	initializeCC(t, chainID, ccname, ccSide, chaincodeSupport)
  1184  
  1185  	//chaincode support should not allow dups
  1186  	handler := &Handler{chaincodeID: ccname + ":0", BuiltinSCCs: chaincodeSupport.BuiltinSCCs}
  1187  	if err := chaincodeSupport.HandlerRegistry.Register(handler); err == nil {
  1188  		t.Fatalf("expected re-register to fail")
  1189  	}
  1190  
  1191  	//call's init and does some PUT (after doing some negative testing)
  1192  	initializeCC(t, chainID2, ccname, ccSide, chaincodeSupport)
  1193  
  1194  	//call's invoke and do some GET
  1195  	invokeCC(t, chainID, ccname, ccSide, chaincodeSupport)
  1196  
  1197  	//call's query state range
  1198  	getQueryStateByRange(t, "", chainID, ccname, ccSide, chaincodeSupport)
  1199  
  1200  	//call's cc2cc on the same chaincode only call to chainID2 should succeed
  1201  	cc2SameCC(t, chainID, chainID2, ccname, ccSide, chaincodeSupport)
  1202  
  1203  	//call's cc2cc (variation with syscc calls)
  1204  	cc2cc(t, chainID, chainID2, ccname, ccSide, chaincodeSupport)
  1205  	// reset mock
  1206  	chaincodeSupport.ACLProvider = &mock.ACLProvider{}
  1207  
  1208  	//call's query result
  1209  	getQueryResult(t, "", chainID, ccname, ccSide, chaincodeSupport)
  1210  
  1211  	//call's history result
  1212  	getHistory(t, chainID, ccname, ccSide, chaincodeSupport)
  1213  
  1214  	ccSide.Quit()
  1215  }
  1216  
  1217  func TestExecuteTimeout(t *testing.T) {
  1218  	_, cs, cleanup, err := initMockPeer("testchannel")
  1219  	assert.NoError(t, err)
  1220  	defer cleanup()
  1221  
  1222  	tests := []struct {
  1223  		executeTimeout  time.Duration
  1224  		installTimeout  time.Duration
  1225  		namespace       string
  1226  		command         string
  1227  		expectedTimeout time.Duration
  1228  	}{
  1229  		{
  1230  			executeTimeout:  time.Second,
  1231  			installTimeout:  time.Minute,
  1232  			namespace:       "lscc",
  1233  			command:         "install",
  1234  			expectedTimeout: time.Minute,
  1235  		},
  1236  		{
  1237  			executeTimeout:  time.Minute,
  1238  			installTimeout:  time.Second,
  1239  			namespace:       "lscc",
  1240  			command:         "install",
  1241  			expectedTimeout: time.Minute,
  1242  		},
  1243  		{
  1244  			executeTimeout:  time.Second,
  1245  			installTimeout:  time.Minute,
  1246  			namespace:       "_lifecycle",
  1247  			command:         "InstallChaincode",
  1248  			expectedTimeout: time.Minute,
  1249  		},
  1250  		{
  1251  			executeTimeout:  time.Minute,
  1252  			installTimeout:  time.Second,
  1253  			namespace:       "_lifecycle",
  1254  			command:         "InstallChaincode",
  1255  			expectedTimeout: time.Minute,
  1256  		},
  1257  		{
  1258  			executeTimeout:  time.Second,
  1259  			installTimeout:  time.Minute,
  1260  			namespace:       "_lifecycle",
  1261  			command:         "anything",
  1262  			expectedTimeout: time.Second,
  1263  		},
  1264  		{
  1265  			executeTimeout:  time.Second,
  1266  			installTimeout:  time.Minute,
  1267  			namespace:       "lscc",
  1268  			command:         "anything",
  1269  			expectedTimeout: time.Second,
  1270  		},
  1271  		{
  1272  			executeTimeout:  time.Second,
  1273  			installTimeout:  time.Minute,
  1274  			namespace:       "anything",
  1275  			command:         "",
  1276  			expectedTimeout: time.Second,
  1277  		},
  1278  	}
  1279  	for _, tt := range tests {
  1280  		t.Run(tt.namespace+"_"+tt.command, func(t *testing.T) {
  1281  			cs.ExecuteTimeout = tt.executeTimeout
  1282  			cs.InstallTimeout = tt.installTimeout
  1283  			input := &pb.ChaincodeInput{Args: util.ToChaincodeArgs(tt.command)}
  1284  
  1285  			result := cs.executeTimeout(tt.namespace, input)
  1286  			assert.Equalf(t, tt.expectedTimeout, result, "want %s, got %s", tt.expectedTimeout, result)
  1287  		})
  1288  	}
  1289  }
  1290  
  1291  func TestMaxDuration(t *testing.T) {
  1292  	tests := []struct {
  1293  		durations []time.Duration
  1294  		expected  time.Duration
  1295  	}{
  1296  		{
  1297  			durations: []time.Duration{},
  1298  			expected:  time.Duration(0),
  1299  		},
  1300  		{
  1301  			durations: []time.Duration{time.Second, time.Hour, time.Minute},
  1302  			expected:  time.Hour,
  1303  		},
  1304  		{
  1305  			durations: []time.Duration{-time.Second},
  1306  			expected:  time.Duration(0),
  1307  		},
  1308  	}
  1309  	for _, tt := range tests {
  1310  		result := maxDuration(tt.durations...)
  1311  		assert.Equalf(t, tt.expected, result, "want %s got %s", tt.expected, result)
  1312  	}
  1313  }
  1314  
  1315  func startTxSimulation(peerInstance *peer.Peer, channelID string, txid string) (ledger.TxSimulator, ledger.HistoryQueryExecutor, error) {
  1316  	lgr := peerInstance.GetLedger(channelID)
  1317  	txsim, err := lgr.NewTxSimulator(txid)
  1318  	if err != nil {
  1319  		return nil, nil, err
  1320  	}
  1321  	historyQueryExecutor, err := lgr.NewHistoryQueryExecutor()
  1322  	if err != nil {
  1323  		return nil, nil, err
  1324  	}
  1325  
  1326  	return txsim, historyQueryExecutor, nil
  1327  }
  1328  
  1329  func endTxSimulationCIS(peerInstance *peer.Peer, channelID string, ccid *pb.ChaincodeID, txid string, txsim ledger.TxSimulator, payload []byte, commit bool, cis *pb.ChaincodeInvocationSpec, blockNumber uint64) error {
  1330  	// get serialized version of the signer
  1331  	ss, err := signer.Serialize()
  1332  	if err != nil {
  1333  		return err
  1334  	}
  1335  
  1336  	// get a proposal - we need it to get a transaction
  1337  	prop, returnedTxid, err := protoutil.CreateProposalFromCISAndTxid(txid, common.HeaderType_ENDORSER_TRANSACTION, channelID, cis, ss)
  1338  	if err != nil {
  1339  		return err
  1340  	}
  1341  	if returnedTxid != txid {
  1342  		return errors.New("txids are not same")
  1343  	}
  1344  
  1345  	return endTxSimulation(peerInstance, channelID, ccid, txsim, payload, commit, prop, blockNumber)
  1346  }
  1347  
  1348  //getting a crash from ledger.Commit when doing concurrent invokes
  1349  //It is likely intentional that ledger.Commit is serial (ie, the real
  1350  //Committer will invoke this serially on each block). Mimic that here
  1351  //by forcing serialization of the ledger.Commit call.
  1352  //
  1353  //NOTE-this should NOT have any effect on the older serial tests.
  1354  //This affects only the tests in concurrent_test.go which call these
  1355  //concurrently (100 concurrent invokes followed by 100 concurrent queries)
  1356  var _commitLock_ sync.Mutex
  1357  
  1358  func endTxSimulation(peerInstance *peer.Peer, channelID string, ccid *pb.ChaincodeID, txsim ledger.TxSimulator, _ []byte, commit bool, prop *pb.Proposal, blockNumber uint64) error {
  1359  	txsim.Done()
  1360  	if lgr := peerInstance.GetLedger(channelID); lgr != nil {
  1361  		if commit {
  1362  			var txSimulationResults *ledger.TxSimulationResults
  1363  			var txSimulationBytes []byte
  1364  			var err error
  1365  
  1366  			txsim.Done()
  1367  
  1368  			//get simulation results
  1369  			if txSimulationResults, err = txsim.GetTxSimulationResults(); err != nil {
  1370  				return err
  1371  			}
  1372  			if txSimulationBytes, err = txSimulationResults.GetPubSimulationBytes(); err != nil {
  1373  				return err
  1374  			}
  1375  			// assemble a (signed) proposal response message
  1376  			resp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &pb.Response{Status: 200},
  1377  				txSimulationBytes, nil, ccid, signer)
  1378  			if err != nil {
  1379  				return err
  1380  			}
  1381  
  1382  			// get the envelope
  1383  			env, err := protoutil.CreateSignedTx(prop, signer, resp)
  1384  			if err != nil {
  1385  				return err
  1386  			}
  1387  
  1388  			envBytes, err := protoutil.GetBytesEnvelope(env)
  1389  			if err != nil {
  1390  				return err
  1391  			}
  1392  
  1393  			//create the block with 1 transaction
  1394  			bcInfo, err := lgr.GetBlockchainInfo()
  1395  			if err != nil {
  1396  				return err
  1397  			}
  1398  			block := protoutil.NewBlock(blockNumber, bcInfo.CurrentBlockHash)
  1399  			block.Data.Data = [][]byte{envBytes}
  1400  			txsFilter := cut.NewTxValidationFlagsSetValue(len(block.Data.Data), pb.TxValidationCode_VALID)
  1401  			block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter
  1402  
  1403  			//commit the block
  1404  
  1405  			//see comment on _commitLock_
  1406  			_commitLock_.Lock()
  1407  			defer _commitLock_.Unlock()
  1408  
  1409  			blockAndPvtData := &ledger.BlockAndPvtData{
  1410  				Block:   block,
  1411  				PvtData: make(ledger.TxPvtDataMap),
  1412  			}
  1413  
  1414  			// All tests are performed with just one transaction in a block.
  1415  			// Hence, we can simiplify the procedure of constructing the
  1416  			// block with private data. There is not enough need to
  1417  			// add more than one transaction in a block for testing chaincode
  1418  			// API.
  1419  
  1420  			// ASSUMPTION: Only one transaction in a block.
  1421  			seqInBlock := uint64(0)
  1422  
  1423  			if txSimulationResults.PvtSimulationResults != nil {
  1424  				blockAndPvtData.PvtData[seqInBlock] = &ledger.TxPvtData{
  1425  					SeqInBlock: seqInBlock,
  1426  					WriteSet:   txSimulationResults.PvtSimulationResults,
  1427  				}
  1428  			}
  1429  
  1430  			if err := lgr.CommitLegacy(blockAndPvtData, &ledger.CommitOptions{}); err != nil {
  1431  				return err
  1432  			}
  1433  		}
  1434  	}
  1435  
  1436  	return nil
  1437  }
  1438  
  1439  func TestMain(m *testing.M) {
  1440  	var err error
  1441  
  1442  	msptesttools.LoadMSPSetupForTesting()
  1443  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1444  	if err != nil {
  1445  		fmt.Printf("Initialize cryptoProvider bccsp failed: %s", err)
  1446  		os.Exit(-1)
  1447  		return
  1448  	}
  1449  	signer, err = mspmgmt.GetLocalMSP(cryptoProvider).GetDefaultSigningIdentity()
  1450  	if err != nil {
  1451  		fmt.Print("Could not initialize msp/signer")
  1452  		os.Exit(-1)
  1453  		return
  1454  	}
  1455  
  1456  	setupTestConfig()
  1457  	flogging.ActivateSpec("chaincode=debug")
  1458  	os.Exit(m.Run())
  1459  }
  1460  
  1461  func setupTestConfig() {
  1462  	flag.Parse()
  1463  
  1464  	// Now set the configuration file
  1465  	viper.SetEnvPrefix("CORE")
  1466  	viper.AutomaticEnv()
  1467  	replacer := strings.NewReplacer(".", "_")
  1468  	viper.SetEnvKeyReplacer(replacer)
  1469  	viper.SetConfigName("chaincodetest") // name of config file (without extension)
  1470  	viper.AddConfigPath("./")            // path to look for the config file in
  1471  	err := viper.ReadInConfig()          // Find and read the config file
  1472  	if err != nil {                      // Handle errors reading the config file
  1473  		panic(fmt.Errorf("Fatal error config file: %s \n", err))
  1474  	}
  1475  
  1476  	// Init the BCCSP
  1477  	err = factory.InitFactories(nil)
  1478  	if err != nil {
  1479  		panic(fmt.Errorf("Could not initialize BCCSP Factories [%s]", err))
  1480  	}
  1481  }
  1482  
  1483  var signer msp.SigningIdentity
  1484  
  1485  func newPolicyChecker(peerInstance *peer.Peer) policy.PolicyChecker {
  1486  	return policy.NewPolicyChecker(
  1487  		policies.PolicyManagerGetterFunc(peerInstance.GetPolicyManager),
  1488  		&policymocks.MockIdentityDeserializer{
  1489  			Identity: []byte("Admin"),
  1490  			Msg:      []byte("msg1"),
  1491  		},
  1492  		&policymocks.MockMSPPrincipalGetter{Principal: []byte("Admin")},
  1493  	)
  1494  }