github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/core/endorser/endorser_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package endorser
    18  
    19  import (
    20  	"flag"
    21  	"fmt"
    22  	"io/ioutil"
    23  	"net"
    24  	"os"
    25  	"runtime"
    26  	"strings"
    27  	"testing"
    28  	"time"
    29  
    30  	"path/filepath"
    31  
    32  	"errors"
    33  
    34  	"github.com/golang/protobuf/proto"
    35  	"github.com/hyperledger/fabric/bccsp/factory"
    36  	mockpolicies "github.com/hyperledger/fabric/common/mocks/policies"
    37  	"github.com/hyperledger/fabric/common/policies"
    38  	"github.com/hyperledger/fabric/common/util"
    39  	"github.com/hyperledger/fabric/core/chaincode"
    40  	"github.com/hyperledger/fabric/core/common/ccprovider"
    41  	"github.com/hyperledger/fabric/core/config"
    42  	"github.com/hyperledger/fabric/core/container"
    43  	"github.com/hyperledger/fabric/core/peer"
    44  	syscc "github.com/hyperledger/fabric/core/scc"
    45  	"github.com/hyperledger/fabric/core/testutil"
    46  	"github.com/hyperledger/fabric/msp"
    47  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    48  	"github.com/hyperledger/fabric/msp/mgmt/testtools"
    49  	"github.com/hyperledger/fabric/protos/common"
    50  	pb "github.com/hyperledger/fabric/protos/peer"
    51  	pbutils "github.com/hyperledger/fabric/protos/utils"
    52  	"github.com/spf13/viper"
    53  	"golang.org/x/net/context"
    54  	"google.golang.org/grpc"
    55  
    56  	"github.com/stretchr/testify/assert"
    57  	"google.golang.org/grpc/credentials"
    58  )
    59  
    60  var endorserServer pb.EndorserServer
    61  var signer msp.SigningIdentity
    62  
    63  type testEnvironment struct {
    64  	tempDir  string
    65  	listener net.Listener
    66  }
    67  
    68  //initialize peer and start up. If security==enabled, login as vp
    69  func initPeer(chainID string) (*testEnvironment, error) {
    70  	//start clean
    71  	// finitPeer(nil)
    72  	var opts []grpc.ServerOption
    73  	if viper.GetBool("peer.tls.enabled") {
    74  		creds, err := credentials.NewServerTLSFromFile(config.GetPath("peer.tls.cert.file"), config.GetPath("peer.tls.key.file"))
    75  		if err != nil {
    76  			return nil, fmt.Errorf("Failed to generate credentials %v", err)
    77  		}
    78  		opts = []grpc.ServerOption{grpc.Creds(creds)}
    79  	}
    80  	grpcServer := grpc.NewServer(opts...)
    81  
    82  	tempDir := newTempDir()
    83  	viper.Set("peer.fileSystemPath", filepath.Join(tempDir, "hyperledger", "production"))
    84  
    85  	peerAddress, err := peer.GetLocalAddress()
    86  	if err != nil {
    87  		return nil, fmt.Errorf("Error obtaining peer address: %s", err)
    88  	}
    89  	lis, err := net.Listen("tcp", peerAddress)
    90  	if err != nil {
    91  		return nil, fmt.Errorf("Error starting peer listener %s", err)
    92  	}
    93  
    94  	//initialize ledger
    95  	peer.MockInitialize()
    96  
    97  	mspGetter := func(cid string) []string {
    98  		return []string{"DEFAULT"}
    99  	}
   100  
   101  	peer.MockSetMSPIDGetter(mspGetter)
   102  
   103  	getPeerEndpoint := func() (*pb.PeerEndpoint, error) {
   104  		return &pb.PeerEndpoint{Id: &pb.PeerID{Name: "testpeer"}, Address: peerAddress}, nil
   105  	}
   106  
   107  	ccStartupTimeout := time.Duration(30000) * time.Millisecond
   108  	pb.RegisterChaincodeSupportServer(grpcServer, chaincode.NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout))
   109  
   110  	syscc.RegisterSysCCs()
   111  
   112  	if err = peer.MockCreateChain(chainID); err != nil {
   113  		closeListenerAndSleep(lis)
   114  		return nil, err
   115  	}
   116  
   117  	syscc.DeploySysCCs(chainID)
   118  
   119  	go grpcServer.Serve(lis)
   120  
   121  	return &testEnvironment{tempDir: tempDir, listener: lis}, nil
   122  }
   123  
   124  func finitPeer(tev *testEnvironment) {
   125  	closeListenerAndSleep(tev.listener)
   126  	os.RemoveAll(tev.tempDir)
   127  }
   128  
   129  func closeListenerAndSleep(l net.Listener) {
   130  	if l != nil {
   131  		l.Close()
   132  		time.Sleep(2 * time.Second)
   133  	}
   134  }
   135  
   136  // getInvokeProposal gets the proposal for the chaincode invocation
   137  // Currently supported only for Invokes
   138  // It returns the proposal and the transaction id associated to the proposal
   139  func getInvokeProposal(cis *pb.ChaincodeInvocationSpec, chainID string, creator []byte) (*pb.Proposal, string, error) {
   140  	return pbutils.CreateChaincodeProposal(common.HeaderType_ENDORSER_TRANSACTION, chainID, cis, creator)
   141  }
   142  
   143  // getInvokeProposalOverride allows to get a proposal for the chaincode invocation
   144  // overriding transaction id and nonce which are by default auto-generated.
   145  // It returns the proposal and the transaction id associated to the proposal
   146  func getInvokeProposalOverride(txid string, cis *pb.ChaincodeInvocationSpec, chainID string, nonce, creator []byte) (*pb.Proposal, string, error) {
   147  	return pbutils.CreateChaincodeProposalWithTxIDNonceAndTransient(txid, common.HeaderType_ENDORSER_TRANSACTION, chainID, cis, nonce, creator, nil)
   148  }
   149  
   150  func getDeployProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte) (*pb.Proposal, error) {
   151  	return getDeployOrUpgradeProposal(cds, chainID, creator, false)
   152  }
   153  
   154  func getUpgradeProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte) (*pb.Proposal, error) {
   155  	return getDeployOrUpgradeProposal(cds, chainID, creator, true)
   156  }
   157  
   158  //getDeployOrUpgradeProposal gets the proposal for the chaincode deploy or upgrade
   159  //the payload is a ChaincodeDeploymentSpec
   160  func getDeployOrUpgradeProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte, upgrade bool) (*pb.Proposal, error) {
   161  	//we need to save off the chaincode as we have to instantiate with nil CodePackage
   162  	var err error
   163  	if err = ccprovider.PutChaincodeIntoFS(cds); err != nil {
   164  		return nil, err
   165  	}
   166  
   167  	cds.CodePackage = nil
   168  
   169  	b, err := proto.Marshal(cds)
   170  	if err != nil {
   171  		return nil, err
   172  	}
   173  
   174  	var propType string
   175  	if upgrade {
   176  		propType = "upgrade"
   177  	} else {
   178  		propType = "deploy"
   179  	}
   180  	sccver := util.GetSysCCVersion()
   181  	//wrap the deployment in an invocation spec to lscc...
   182  	lsccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: "lscc", Version: sccver}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte(propType), []byte(chainID), b}}}}
   183  
   184  	//...and get the proposal for it
   185  	var prop *pb.Proposal
   186  	if prop, _, err = getInvokeProposal(lsccSpec, chainID, creator); err != nil {
   187  		return nil, err
   188  	}
   189  
   190  	return prop, nil
   191  }
   192  
   193  func getSignedProposal(prop *pb.Proposal, signer msp.SigningIdentity) (*pb.SignedProposal, error) {
   194  	propBytes, err := pbutils.GetBytesProposal(prop)
   195  	if err != nil {
   196  		return nil, err
   197  	}
   198  
   199  	signature, err := signer.Sign(propBytes)
   200  	if err != nil {
   201  		return nil, err
   202  	}
   203  
   204  	return &pb.SignedProposal{ProposalBytes: propBytes, Signature: signature}, nil
   205  }
   206  
   207  func getDeploymentSpec(context context.Context, spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) {
   208  	codePackageBytes, err := container.GetChaincodePackageBytes(spec)
   209  	if err != nil {
   210  		return nil, err
   211  	}
   212  	chaincodeDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes}
   213  	return chaincodeDeploymentSpec, nil
   214  }
   215  
   216  func deploy(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec)) (*pb.ProposalResponse, *pb.Proposal, error) {
   217  	return deployOrUpgrade(endorserServer, chainID, spec, f, false)
   218  }
   219  
   220  func upgrade(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec)) (*pb.ProposalResponse, *pb.Proposal, error) {
   221  	return deployOrUpgrade(endorserServer, chainID, spec, f, true)
   222  }
   223  
   224  func deployOrUpgrade(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec), upgrade bool) (*pb.ProposalResponse, *pb.Proposal, error) {
   225  	var err error
   226  	var depSpec *pb.ChaincodeDeploymentSpec
   227  
   228  	ctxt := context.Background()
   229  	depSpec, err = getDeploymentSpec(ctxt, spec)
   230  	if err != nil {
   231  		return nil, nil, err
   232  	}
   233  
   234  	if f != nil {
   235  		f(depSpec)
   236  	}
   237  
   238  	creator, err := signer.Serialize()
   239  	if err != nil {
   240  		return nil, nil, err
   241  	}
   242  
   243  	var prop *pb.Proposal
   244  	if upgrade {
   245  		prop, err = getUpgradeProposal(depSpec, chainID, creator)
   246  	} else {
   247  		prop, err = getDeployProposal(depSpec, chainID, creator)
   248  	}
   249  	if err != nil {
   250  		return nil, nil, err
   251  	}
   252  
   253  	var signedProp *pb.SignedProposal
   254  	signedProp, err = getSignedProposal(prop, signer)
   255  	if err != nil {
   256  		return nil, nil, err
   257  	}
   258  
   259  	var resp *pb.ProposalResponse
   260  	resp, err = endorserServer.ProcessProposal(context.Background(), signedProp)
   261  
   262  	return resp, prop, err
   263  }
   264  
   265  func invoke(chainID string, spec *pb.ChaincodeSpec) (*pb.Proposal, *pb.ProposalResponse, string, []byte, error) {
   266  	invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
   267  
   268  	creator, err := signer.Serialize()
   269  	if err != nil {
   270  		return nil, nil, "", nil, err
   271  	}
   272  
   273  	var prop *pb.Proposal
   274  	prop, txID, err := getInvokeProposal(invocation, chainID, creator)
   275  	if err != nil {
   276  		return nil, nil, "", nil, fmt.Errorf("Error creating proposal  %s: %s\n", spec.ChaincodeId, err)
   277  	}
   278  
   279  	nonce, err := pbutils.GetNonce(prop)
   280  	if err != nil {
   281  		return nil, nil, "", nil, fmt.Errorf("Failed getting nonce  %s: %s\n", spec.ChaincodeId, err)
   282  	}
   283  
   284  	var signedProp *pb.SignedProposal
   285  	signedProp, err = getSignedProposal(prop, signer)
   286  	if err != nil {
   287  		return nil, nil, "", nil, err
   288  	}
   289  
   290  	resp, err := endorserServer.ProcessProposal(context.Background(), signedProp)
   291  	if err != nil {
   292  		return nil, nil, "", nil, err
   293  	}
   294  
   295  	return prop, resp, txID, nonce, err
   296  }
   297  
   298  func invokeWithOverride(txid string, chainID string, spec *pb.ChaincodeSpec, nonce []byte) (*pb.ProposalResponse, error) {
   299  	invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
   300  
   301  	creator, err := signer.Serialize()
   302  	if err != nil {
   303  		return nil, err
   304  	}
   305  
   306  	var prop *pb.Proposal
   307  	prop, _, err = getInvokeProposalOverride(txid, invocation, chainID, nonce, creator)
   308  	if err != nil {
   309  		return nil, fmt.Errorf("Error creating proposal with override  %s %s: %s\n", txid, spec.ChaincodeId, err)
   310  	}
   311  
   312  	var signedProp *pb.SignedProposal
   313  	signedProp, err = getSignedProposal(prop, signer)
   314  	if err != nil {
   315  		return nil, err
   316  	}
   317  
   318  	resp, err := endorserServer.ProcessProposal(context.Background(), signedProp)
   319  	if err != nil {
   320  		return nil, fmt.Errorf("Error endorsing %s %s: %s\n", txid, spec.ChaincodeId, err)
   321  	}
   322  
   323  	return resp, err
   324  }
   325  
   326  func deleteChaincodeOnDisk(chaincodeID string) {
   327  	os.RemoveAll(filepath.Join(config.GetPath("peer.fileSystemPath"), "chaincodes", chaincodeID))
   328  }
   329  
   330  //begin tests. Note that we rely upon the system chaincode and peer to be created
   331  //once and be used for all the tests. In order to avoid dependencies / collisions
   332  //due to deployed chaincodes, trying to use different chaincodes for different
   333  //tests
   334  
   335  //TestDeploy deploy chaincode example01
   336  func TestDeploy(t *testing.T) {
   337  	chainID := util.GetTestChainID()
   338  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "ex01", Path: "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}}
   339  	defer deleteChaincodeOnDisk("ex01.0")
   340  
   341  	cccid := ccprovider.NewCCContext(chainID, "ex01", "0", "", false, nil, nil)
   342  
   343  	_, _, err := deploy(endorserServer, chainID, spec, nil)
   344  	if err != nil {
   345  		t.Fail()
   346  		t.Logf("Deploy-error in deploy %s", err)
   347  		chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   348  		return
   349  	}
   350  	chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   351  }
   352  
   353  //REMOVE WHEN JAVA CC IS ENABLED
   354  func TestJavaDeploy(t *testing.T) {
   355  	chainID := util.GetTestChainID()
   356  	//pretend this is a java CC (type 4)
   357  	spec := &pb.ChaincodeSpec{Type: 4, ChaincodeId: &pb.ChaincodeID{Name: "javacc", Path: "../../examples/chaincode/java/chaincode_example02", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}}
   358  	defer deleteChaincodeOnDisk("javacc.0")
   359  
   360  	cccid := ccprovider.NewCCContext(chainID, "javacc", "0", "", false, nil, nil)
   361  
   362  	_, _, err := deploy(endorserServer, chainID, spec, nil)
   363  	if err == nil {
   364  		t.Fail()
   365  		t.Logf("expected java CC deploy to fail")
   366  		chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   367  		return
   368  	}
   369  	chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   370  }
   371  
   372  //TestRedeploy - deploy two times, second time should fail but example02 should remain deployed
   373  func TestRedeploy(t *testing.T) {
   374  	chainID := util.GetTestChainID()
   375  
   376  	//invalid arguments
   377  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "ex02", Path: "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}}
   378  
   379  	defer deleteChaincodeOnDisk("ex02.0")
   380  
   381  	cccid := ccprovider.NewCCContext(chainID, "ex02", "0", "", false, nil, nil)
   382  
   383  	_, _, err := deploy(endorserServer, chainID, spec, nil)
   384  	if err != nil {
   385  		t.Fail()
   386  		t.Logf("error in endorserServer.ProcessProposal %s", err)
   387  		chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   388  		return
   389  	}
   390  
   391  	deleteChaincodeOnDisk("ex02.0")
   392  
   393  	//second time should not fail as we are just simulating
   394  	_, _, err = deploy(endorserServer, chainID, spec, nil)
   395  	if err != nil {
   396  		t.Fail()
   397  		t.Logf("error in endorserServer.ProcessProposal %s", err)
   398  		chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   399  		return
   400  	}
   401  	chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   402  }
   403  
   404  // TestDeployAndInvoke deploys and invokes chaincode_example01
   405  func TestDeployAndInvoke(t *testing.T) {
   406  	chainID := util.GetTestChainID()
   407  	var ctxt = context.Background()
   408  
   409  	url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01"
   410  	chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01", Version: "0"}
   411  
   412  	defer deleteChaincodeOnDisk("ex01.0")
   413  
   414  	args := []string{"10"}
   415  
   416  	f := "init"
   417  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   418  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   419  
   420  	cccid := ccprovider.NewCCContext(chainID, "ex01", "0", "", false, nil, nil)
   421  
   422  	resp, prop, err := deploy(endorserServer, chainID, spec, nil)
   423  	chaincodeID1 := spec.ChaincodeId.Name
   424  	if err != nil {
   425  		t.Fail()
   426  		t.Logf("Error deploying <%s>: %s", chaincodeID1, err)
   427  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   428  		return
   429  	}
   430  	var nextBlockNumber uint64 = 1 // first block needs to be block number = 1. Genesis block is block 0
   431  	err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber)
   432  	if err != nil {
   433  		t.Fail()
   434  		t.Logf("Error committing deploy <%s>: %s", chaincodeID1, err)
   435  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   436  		return
   437  	}
   438  
   439  	f = "invoke"
   440  	invokeArgs := append([]string{f}, args...)
   441  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   442  	prop, resp, txid, nonce, err := invoke(chainID, spec)
   443  	if err != nil {
   444  		t.Fail()
   445  		t.Logf("Error invoking transaction: %s", err)
   446  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   447  		return
   448  	}
   449  	// Commit invoke
   450  	nextBlockNumber++
   451  	err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber)
   452  	if err != nil {
   453  		t.Fail()
   454  		t.Logf("Error committing first invoke <%s>: %s", chaincodeID1, err)
   455  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   456  		return
   457  	}
   458  
   459  	// Now test for an invalid TxID
   460  	f = "invoke"
   461  	invokeArgs = append([]string{f}, args...)
   462  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   463  	_, err = invokeWithOverride("invalid_tx_id", chainID, spec, nonce)
   464  	if err == nil {
   465  		t.Fail()
   466  		t.Log("Replay attack protection faild. Transaction with invalid txid passed")
   467  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   468  		return
   469  	}
   470  
   471  	// Now test for duplicated TxID
   472  	f = "invoke"
   473  	invokeArgs = append([]string{f}, args...)
   474  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   475  	_, err = invokeWithOverride(txid, chainID, spec, nonce)
   476  	if err == nil {
   477  		t.Fail()
   478  		t.Log("Replay attack protection faild. Transaction with duplicaged txid passed")
   479  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   480  		return
   481  	}
   482  
   483  	// Test chaincode endorsement failure when invalid function name supplied
   484  	f = "invokeinvalid"
   485  	invokeArgs = append([]string{f}, args...)
   486  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   487  	prop, resp, txid, nonce, err = invoke(chainID, spec)
   488  	if err == nil {
   489  		t.Fail()
   490  		t.Logf("expecting fabric to report error from chaincode failure")
   491  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   492  		return
   493  	} else if _, ok := err.(*chaincodeError); !ok {
   494  		t.Fail()
   495  		t.Logf("expecting chaincode error but found %v", err)
   496  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   497  		return
   498  	}
   499  
   500  	if resp != nil {
   501  		assert.Equal(t, int32(500), resp.Response.Status, "Unexpected response status")
   502  	}
   503  
   504  	t.Logf("Invoke test passed")
   505  
   506  	chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   507  }
   508  
   509  // TestUpgradeAndInvoke deploys chaincode_example01, upgrade it with chaincode_example02, then invoke it
   510  func TestDeployAndUpgrade(t *testing.T) {
   511  	chainID := util.GetTestChainID()
   512  	var ctxt = context.Background()
   513  
   514  	url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01"
   515  	url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
   516  	chaincodeID1 := &pb.ChaincodeID{Path: url1, Name: "upgradeex01", Version: "0"}
   517  	chaincodeID2 := &pb.ChaincodeID{Path: url2, Name: "upgradeex01", Version: "1"}
   518  
   519  	defer deleteChaincodeOnDisk("upgradeex01.0")
   520  	defer deleteChaincodeOnDisk("upgradeex01.1")
   521  
   522  	f := "init"
   523  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   524  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID1, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   525  
   526  	cccid1 := ccprovider.NewCCContext(chainID, "upgradeex01", "0", "", false, nil, nil)
   527  	cccid2 := ccprovider.NewCCContext(chainID, "upgradeex01", "1", "", false, nil, nil)
   528  
   529  	resp, prop, err := deploy(endorserServer, chainID, spec, nil)
   530  
   531  	chaincodeName := spec.ChaincodeId.Name
   532  	if err != nil {
   533  		t.Fail()
   534  		chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}})
   535  		chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}})
   536  		t.Logf("Error deploying <%s>: %s", chaincodeName, err)
   537  		return
   538  	}
   539  
   540  	var nextBlockNumber uint64 = 3 // something above created block 0
   541  	err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber)
   542  	if err != nil {
   543  		t.Fail()
   544  		chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}})
   545  		chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}})
   546  		t.Logf("Error committing <%s>: %s", chaincodeName, err)
   547  		return
   548  	}
   549  
   550  	argsUpgrade := util.ToChaincodeArgs(f, "a", "150", "b", "300")
   551  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID2, Input: &pb.ChaincodeInput{Args: argsUpgrade}}
   552  	_, _, err = upgrade(endorserServer, chainID, spec, nil)
   553  	if err != nil {
   554  		t.Fail()
   555  		chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}})
   556  		chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}})
   557  		t.Logf("Error upgrading <%s>: %s", chaincodeName, err)
   558  		return
   559  	}
   560  
   561  	t.Logf("Upgrade test passed")
   562  
   563  	chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}})
   564  	chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}})
   565  }
   566  
   567  // TestWritersACLFail deploys a chaincode and then tries to invoke it;
   568  // however we inject a special policy for writers to simulate
   569  // the scenario in which the creator of this proposal is not among
   570  // the writers for the chain
   571  func TestWritersACLFail(t *testing.T) {
   572  	//skip pending FAB-2457 fix
   573  	t.Skip()
   574  	chainID := util.GetTestChainID()
   575  	var ctxt = context.Background()
   576  
   577  	url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01"
   578  	chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01-fail", Version: "0"}
   579  
   580  	defer deleteChaincodeOnDisk("ex01-fail.0")
   581  
   582  	args := []string{"10"}
   583  
   584  	f := "init"
   585  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   586  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   587  
   588  	cccid := ccprovider.NewCCContext(chainID, "ex01-fail", "0", "", false, nil, nil)
   589  
   590  	resp, prop, err := deploy(endorserServer, chainID, spec, nil)
   591  	chaincodeID1 := spec.ChaincodeId.Name
   592  	if err != nil {
   593  		t.Fail()
   594  		t.Logf("Error deploying <%s>: %s", chaincodeID1, err)
   595  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   596  		return
   597  	}
   598  	var nextBlockNumber uint64 = 3 // The tests that ran before this test created blocks 0-2
   599  	err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber)
   600  	if err != nil {
   601  		t.Fail()
   602  		t.Logf("Error committing deploy <%s>: %s", chaincodeID1, err)
   603  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   604  		return
   605  	}
   606  
   607  	// here we inject a reject policy for writers
   608  	// to simulate the scenario in which the invoker
   609  	// is not authorized to issue this proposal
   610  	rejectpolicy := &mockpolicies.Policy{
   611  		Err: errors.New("The creator of this proposal does not fulfil the writers policy of this chain"),
   612  	}
   613  	pm := peer.GetPolicyManager(chainID)
   614  	pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{policies.ChannelApplicationWriters: rejectpolicy}
   615  
   616  	f = "invoke"
   617  	invokeArgs := append([]string{f}, args...)
   618  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   619  	prop, resp, _, _, err = invoke(chainID, spec)
   620  	if err == nil {
   621  		t.Fail()
   622  		t.Logf("Invocation should have failed")
   623  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   624  		return
   625  	}
   626  
   627  	t.Logf("TestWritersACLFail passed")
   628  
   629  	chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   630  }
   631  
   632  // TestAdminACLFail deploys tried to deploy a chaincode;
   633  // however we inject a special policy for admins to simulate
   634  // the scenario in which the creator of this proposal is not among
   635  // the admins for the chain
   636  func TestAdminACLFail(t *testing.T) {
   637  	//skip pending FAB-2457 fix
   638  	t.Skip()
   639  	chainID := util.GetTestChainID()
   640  
   641  	// here we inject a reject policy for admins
   642  	// to simulate the scenario in which the invoker
   643  	// is not authorized to issue this proposal
   644  	rejectpolicy := &mockpolicies.Policy{
   645  		Err: errors.New("The creator of this proposal does not fulfil the writers policy of this chain"),
   646  	}
   647  	pm := peer.GetPolicyManager(chainID)
   648  	pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{policies.ChannelApplicationAdmins: rejectpolicy}
   649  
   650  	var ctxt = context.Background()
   651  
   652  	url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01"
   653  	chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01-fail1", Version: "0"}
   654  
   655  	defer deleteChaincodeOnDisk("ex01-fail1.0")
   656  
   657  	f := "init"
   658  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   659  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   660  
   661  	cccid := ccprovider.NewCCContext(chainID, "ex01-fail1", "0", "", false, nil, nil)
   662  
   663  	_, _, err := deploy(endorserServer, chainID, spec, nil)
   664  	if err == nil {
   665  		t.Fail()
   666  		t.Logf("Deploying chaincode should have failed!")
   667  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   668  		return
   669  	}
   670  
   671  	t.Logf("TestATestAdminACLFailCLFail passed")
   672  
   673  	chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   674  }
   675  
   676  // TestInvokeSccFail makes sure that invoking a system chaincode fails
   677  func TestInvokeSccFail(t *testing.T) {
   678  	chainID := util.GetTestChainID()
   679  
   680  	chaincodeID := &pb.ChaincodeID{Name: "escc"}
   681  	args := util.ToChaincodeArgs("someFunc", "someArg")
   682  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}}
   683  	_, _, _, _, err := invoke(chainID, spec)
   684  	if err == nil {
   685  		t.Logf("Invoking escc should have failed!")
   686  		t.Fail()
   687  		return
   688  	}
   689  }
   690  
   691  func newTempDir() string {
   692  	tempDir, err := ioutil.TempDir("", "fabric-")
   693  	if err != nil {
   694  		panic(err)
   695  	}
   696  	return tempDir
   697  }
   698  
   699  func TestMain(m *testing.M) {
   700  	setupTestConfig()
   701  
   702  	chainID := util.GetTestChainID()
   703  	tev, err := initPeer(chainID)
   704  	if err != nil {
   705  		os.Exit(-1)
   706  		fmt.Printf("Could not initialize tests")
   707  		finitPeer(tev)
   708  		return
   709  	}
   710  
   711  	endorserServer = NewEndorserServer()
   712  
   713  	// setup the MSP manager so that we can sign/verify
   714  	err = msptesttools.LoadMSPSetupForTesting()
   715  	if err != nil {
   716  		fmt.Printf("Could not initialize msp/signer, err %s", err)
   717  		finitPeer(tev)
   718  		os.Exit(-1)
   719  		return
   720  	}
   721  	signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()
   722  	if err != nil {
   723  		fmt.Printf("Could not initialize msp/signer")
   724  		finitPeer(tev)
   725  		os.Exit(-1)
   726  		return
   727  	}
   728  
   729  	retVal := m.Run()
   730  
   731  	finitPeer(tev)
   732  
   733  	os.Exit(retVal)
   734  }
   735  
   736  func setupTestConfig() {
   737  	flag.Parse()
   738  
   739  	// Now set the configuration file
   740  	viper.SetEnvPrefix("CORE")
   741  	viper.AutomaticEnv()
   742  	replacer := strings.NewReplacer(".", "_")
   743  	viper.SetEnvKeyReplacer(replacer)
   744  	viper.SetConfigName("endorser_test") // name of config file (without extension)
   745  	viper.AddConfigPath("./")            // path to look for the config file in
   746  	err := viper.ReadInConfig()          // Find and read the config file
   747  	if err != nil {                      // Handle errors reading the config file
   748  		panic(fmt.Errorf("Fatal error config file: %s \n", err))
   749  	}
   750  
   751  	testutil.SetupTestLogging()
   752  
   753  	// Set the number of maxprocs
   754  	runtime.GOMAXPROCS(viper.GetInt("peer.gomaxprocs"))
   755  
   756  	// Init the BCCSP
   757  	var bccspConfig *factory.FactoryOpts
   758  	err = viper.UnmarshalKey("peer.BCCSP", &bccspConfig)
   759  	if err != nil {
   760  		bccspConfig = nil
   761  	}
   762  
   763  	msp.SetupBCCSPKeystoreConfig(bccspConfig, viper.GetString("peer.mspConfigPath")+"/keystore")
   764  
   765  	err = factory.InitFactories(bccspConfig)
   766  	if err != nil {
   767  		panic(fmt.Errorf("Could not initialize BCCSP Factories [%s]", err))
   768  	}
   769  }