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