github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/core/chaincode/shim/shim_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 shim
    18  
    19  import (
    20  	"bytes"
    21  	"os"
    22  	"strconv"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	mockpeer "github.com/hyperledger/fabric/common/mocks/peer"
    28  	"github.com/hyperledger/fabric/common/util"
    29  	lproto "github.com/hyperledger/fabric/protos/ledger/queryresult"
    30  	pb "github.com/hyperledger/fabric/protos/peer"
    31  	"github.com/hyperledger/fabric/protos/utils"
    32  
    33  	"github.com/hyperledger/fabric/common/flogging"
    34  	"github.com/op/go-logging"
    35  	"github.com/spf13/viper"
    36  	"github.com/stretchr/testify/assert"
    37  )
    38  
    39  // shimTestCC example simple Chaincode implementation
    40  type shimTestCC struct {
    41  }
    42  
    43  func (t *shimTestCC) Init(stub ChaincodeStubInterface) pb.Response {
    44  	_, args := stub.GetFunctionAndParameters()
    45  	var A, B string    // Entities
    46  	var Aval, Bval int // Asset holdings
    47  	var err error
    48  
    49  	if len(args) != 4 {
    50  		return Error("Incorrect number of arguments. Expecting 4")
    51  	}
    52  
    53  	// Initialize the chaincode
    54  	A = args[0]
    55  	Aval, err = strconv.Atoi(args[1])
    56  	if err != nil {
    57  		return Error("Expecting integer value for asset holding")
    58  	}
    59  	B = args[2]
    60  	Bval, err = strconv.Atoi(args[3])
    61  	if err != nil {
    62  		return Error("Expecting integer value for asset holding")
    63  	}
    64  
    65  	// Write the state to the ledger
    66  	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
    67  	if err != nil {
    68  		return Error(err.Error())
    69  	}
    70  
    71  	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
    72  	if err != nil {
    73  		return Error(err.Error())
    74  	}
    75  
    76  	return Success(nil)
    77  }
    78  
    79  func (t *shimTestCC) Invoke(stub ChaincodeStubInterface) pb.Response {
    80  	function, args := stub.GetFunctionAndParameters()
    81  	if function == "invoke" {
    82  		// Make payment of X units from A to B
    83  		return t.invoke(stub, args)
    84  	} else if function == "delete" {
    85  		// Deletes an entity from its state
    86  		return t.delete(stub, args)
    87  	} else if function == "query" {
    88  		// the old "Query" is now implemtned in invoke
    89  		return t.query(stub, args)
    90  	} else if function == "cc2cc" {
    91  		return t.cc2cc(stub, args)
    92  	} else if function == "rangeq" {
    93  		return t.rangeq(stub, args)
    94  	} else if function == "historyq" {
    95  		return t.historyq(stub, args)
    96  	} else if function == "richq" {
    97  		return t.richq(stub, args)
    98  	}
    99  
   100  	return Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"")
   101  }
   102  
   103  // Transaction makes payment of X units from A to B
   104  func (t *shimTestCC) invoke(stub ChaincodeStubInterface, args []string) pb.Response {
   105  	var A, B string    // Entities
   106  	var Aval, Bval int // Asset holdings
   107  	var X int          // Transaction value
   108  	var err error
   109  
   110  	if len(args) != 3 {
   111  		return Error("Incorrect number of arguments. Expecting 3")
   112  	}
   113  
   114  	A = args[0]
   115  	B = args[1]
   116  
   117  	// Get the state from the ledger
   118  	// TODO: will be nice to have a GetAllState call to ledger
   119  	Avalbytes, err := stub.GetState(A)
   120  	if err != nil {
   121  		return Error("Failed to get state")
   122  	}
   123  	if Avalbytes == nil {
   124  		return Error("Entity not found")
   125  	}
   126  	Aval, _ = strconv.Atoi(string(Avalbytes))
   127  
   128  	Bvalbytes, err := stub.GetState(B)
   129  	if err != nil {
   130  		return Error("Failed to get state")
   131  	}
   132  	if Bvalbytes == nil {
   133  		return Error("Entity not found")
   134  	}
   135  	Bval, _ = strconv.Atoi(string(Bvalbytes))
   136  
   137  	// Perform the execution
   138  	X, err = strconv.Atoi(args[2])
   139  	if err != nil {
   140  		return Error("Invalid transaction amount, expecting a integer value")
   141  	}
   142  	Aval = Aval - X
   143  	Bval = Bval + X
   144  
   145  	// Write the state back to the ledger
   146  	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
   147  	if err != nil {
   148  		return Error(err.Error())
   149  	}
   150  
   151  	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
   152  	if err != nil {
   153  		return Error(err.Error())
   154  	}
   155  
   156  	return Success(nil)
   157  }
   158  
   159  // Deletes an entity from state
   160  func (t *shimTestCC) delete(stub ChaincodeStubInterface, args []string) pb.Response {
   161  	if len(args) != 1 {
   162  		return Error("Incorrect number of arguments. Expecting 1")
   163  	}
   164  
   165  	A := args[0]
   166  
   167  	// Delete the key from the state in ledger
   168  	err := stub.DelState(A)
   169  	if err != nil {
   170  		return Error("Failed to delete state")
   171  	}
   172  
   173  	return Success(nil)
   174  }
   175  
   176  // query callback representing the query of a chaincode
   177  func (t *shimTestCC) query(stub ChaincodeStubInterface, args []string) pb.Response {
   178  	var A string // Entities
   179  	var err error
   180  
   181  	if len(args) != 1 {
   182  		return Error("Incorrect number of arguments. Expecting name of the person to query")
   183  	}
   184  
   185  	A = args[0]
   186  
   187  	// Get the state from the ledger
   188  	Avalbytes, err := stub.GetState(A)
   189  	if err != nil {
   190  		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
   191  		return Error(jsonResp)
   192  	}
   193  
   194  	if Avalbytes == nil {
   195  		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
   196  		return Error(jsonResp)
   197  	}
   198  
   199  	return Success(Avalbytes)
   200  }
   201  
   202  // ccc2cc call
   203  func (t *shimTestCC) cc2cc(stub ChaincodeStubInterface, args []string) pb.Response {
   204  	if len(args) < 1 {
   205  		return Error("Invalid number of args for cc2cc. expecting at least 1")
   206  	}
   207  	return stub.InvokeChaincode(args[0], util.ToChaincodeArgs(args...), "")
   208  }
   209  
   210  // rangeq calls range query
   211  func (t *shimTestCC) rangeq(stub ChaincodeStubInterface, args []string) pb.Response {
   212  	if len(args) != 2 {
   213  		return Error("Incorrect number of arguments. Expecting keys for range query")
   214  	}
   215  
   216  	A := args[0]
   217  	B := args[0]
   218  
   219  	// Get the state from the ledger
   220  	resultsIterator, err := stub.GetStateByRange(A, B)
   221  	if err != nil {
   222  		return Error(err.Error())
   223  	}
   224  	defer resultsIterator.Close()
   225  
   226  	// buffer is a JSON array containing QueryResults
   227  	var buffer bytes.Buffer
   228  	buffer.WriteString("[")
   229  
   230  	bArrayMemberAlreadyWritten := false
   231  	for resultsIterator.HasNext() {
   232  		queryResponse, err := resultsIterator.Next()
   233  		if err != nil {
   234  			return Error(err.Error())
   235  		}
   236  		// Add a comma before array members, suppress it for the first array member
   237  		if bArrayMemberAlreadyWritten == true {
   238  			buffer.WriteString(",")
   239  		}
   240  		buffer.WriteString("{\"Key\":")
   241  		buffer.WriteString("\"")
   242  		buffer.WriteString(queryResponse.Key)
   243  		buffer.WriteString("\"")
   244  
   245  		buffer.WriteString(", \"Record\":")
   246  		// Record is a JSON object, so we write as-is
   247  		buffer.WriteString(string(queryResponse.Value))
   248  		buffer.WriteString("}")
   249  		bArrayMemberAlreadyWritten = true
   250  	}
   251  	buffer.WriteString("]")
   252  
   253  	return Success(buffer.Bytes())
   254  }
   255  
   256  // richq calls tichq query
   257  func (t *shimTestCC) richq(stub ChaincodeStubInterface, args []string) pb.Response {
   258  	if len(args) != 1 {
   259  		return Error("Incorrect number of arguments. Expecting keys for range query")
   260  	}
   261  
   262  	query := args[0]
   263  
   264  	// Get the state from the ledger
   265  	resultsIterator, err := stub.GetQueryResult(query)
   266  	if err != nil {
   267  		return Error(err.Error())
   268  	}
   269  	defer resultsIterator.Close()
   270  
   271  	// buffer is a JSON array containing QueryResults
   272  	var buffer bytes.Buffer
   273  	buffer.WriteString("[")
   274  
   275  	bArrayMemberAlreadyWritten := false
   276  	for resultsIterator.HasNext() {
   277  		queryResponse, err := resultsIterator.Next()
   278  		if err != nil {
   279  			return Error(err.Error())
   280  		}
   281  		// Add a comma before array members, suppress it for the first array member
   282  		if bArrayMemberAlreadyWritten == true {
   283  			buffer.WriteString(",")
   284  		}
   285  		buffer.WriteString("{\"Key\":")
   286  		buffer.WriteString("\"")
   287  		buffer.WriteString(queryResponse.Key)
   288  		buffer.WriteString("\"")
   289  
   290  		buffer.WriteString(", \"Record\":")
   291  		// Record is a JSON object, so we write as-is
   292  		buffer.WriteString(string(queryResponse.Value))
   293  		buffer.WriteString("}")
   294  		bArrayMemberAlreadyWritten = true
   295  	}
   296  	buffer.WriteString("]")
   297  
   298  	return Success(buffer.Bytes())
   299  }
   300  
   301  // rangeq calls range query
   302  func (t *shimTestCC) historyq(stub ChaincodeStubInterface, args []string) pb.Response {
   303  	if len(args) < 1 {
   304  		return Error("Incorrect number of arguments. Expecting 1")
   305  	}
   306  
   307  	key := args[0]
   308  
   309  	resultsIterator, err := stub.GetHistoryForKey(key)
   310  	if err != nil {
   311  		return Error(err.Error())
   312  	}
   313  	defer resultsIterator.Close()
   314  
   315  	var buffer bytes.Buffer
   316  	buffer.WriteString("[")
   317  
   318  	bArrayMemberAlreadyWritten := false
   319  	for resultsIterator.HasNext() {
   320  		response, err := resultsIterator.Next()
   321  		if err != nil {
   322  			return Error(err.Error())
   323  		}
   324  		// Add a comma before array members, suppress it for the first array member
   325  		if bArrayMemberAlreadyWritten == true {
   326  			buffer.WriteString(",")
   327  		}
   328  		buffer.WriteString("{\"TxId\":")
   329  		buffer.WriteString("\"")
   330  		buffer.WriteString(response.TxId)
   331  		buffer.WriteString("\"")
   332  
   333  		buffer.WriteString(", \"Value\":")
   334  		if response.IsDelete {
   335  			buffer.WriteString("null")
   336  		} else {
   337  			buffer.WriteString(string(response.Value))
   338  		}
   339  
   340  		buffer.WriteString(", \"IsDelete\":")
   341  		buffer.WriteString("\"")
   342  		buffer.WriteString(strconv.FormatBool(response.IsDelete))
   343  		buffer.WriteString("\"")
   344  
   345  		buffer.WriteString("}")
   346  		bArrayMemberAlreadyWritten = true
   347  	}
   348  	buffer.WriteString("]")
   349  
   350  	return Success(buffer.Bytes())
   351  }
   352  
   353  // Test Go shim functionality that can be tested outside of a real chaincode
   354  // context.
   355  
   356  // TestShimLogging simply tests that the APIs are working. These tests test
   357  // for correct control over the shim's logging object and the LogLevel
   358  // function.
   359  func TestShimLogging(t *testing.T) {
   360  	SetLoggingLevel(LogCritical)
   361  	if shimLoggingLevel != LogCritical {
   362  		t.Errorf("shimLoggingLevel is not LogCritical as expected")
   363  	}
   364  	if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
   365  		t.Errorf("The chaincodeLogger should not be enabled for DEBUG")
   366  	}
   367  	if !chaincodeLogger.IsEnabledFor(logging.CRITICAL) {
   368  		t.Errorf("The chaincodeLogger should be enabled for CRITICAL")
   369  	}
   370  	var level LoggingLevel
   371  	var err error
   372  	level, err = LogLevel("debug")
   373  	if err != nil {
   374  		t.Errorf("LogLevel(debug) failed")
   375  	}
   376  	if level != LogDebug {
   377  		t.Errorf("LogLevel(debug) did not return LogDebug")
   378  	}
   379  	level, err = LogLevel("INFO")
   380  	if err != nil {
   381  		t.Errorf("LogLevel(INFO) failed")
   382  	}
   383  	if level != LogInfo {
   384  		t.Errorf("LogLevel(INFO) did not return LogInfo")
   385  	}
   386  	level, err = LogLevel("Notice")
   387  	if err != nil {
   388  		t.Errorf("LogLevel(Notice) failed")
   389  	}
   390  	if level != LogNotice {
   391  		t.Errorf("LogLevel(Notice) did not return LogNotice")
   392  	}
   393  	level, err = LogLevel("WaRnInG")
   394  	if err != nil {
   395  		t.Errorf("LogLevel(WaRnInG) failed")
   396  	}
   397  	if level != LogWarning {
   398  		t.Errorf("LogLevel(WaRnInG) did not return LogWarning")
   399  	}
   400  	level, err = LogLevel("ERRor")
   401  	if err != nil {
   402  		t.Errorf("LogLevel(ERRor) failed")
   403  	}
   404  	if level != LogError {
   405  		t.Errorf("LogLevel(ERRor) did not return LogError")
   406  	}
   407  	level, err = LogLevel("critiCAL")
   408  	if err != nil {
   409  		t.Errorf("LogLevel(critiCAL) failed")
   410  	}
   411  	if level != LogCritical {
   412  		t.Errorf("LogLevel(critiCAL) did not return LogCritical")
   413  	}
   414  	level, err = LogLevel("foo")
   415  	if err == nil {
   416  		t.Errorf("LogLevel(foo) did not fail")
   417  	}
   418  	if level != LogError {
   419  		t.Errorf("LogLevel(foo) did not return LogError")
   420  	}
   421  }
   422  
   423  // TestChaincodeLogging tests the logging APIs for chaincodes.
   424  func TestChaincodeLogging(t *testing.T) {
   425  
   426  	// From start() - We can't call start() from this test
   427  	format := logging.MustStringFormatter("%{time:15:04:05.000} [%{module}] %{level:.4s} : %{message}")
   428  	backend := logging.NewLogBackend(os.Stderr, "", 0)
   429  	backendFormatter := logging.NewBackendFormatter(backend, format)
   430  	logging.SetBackend(backendFormatter).SetLevel(logging.Level(shimLoggingLevel), "shim")
   431  
   432  	foo := NewLogger("foo")
   433  	bar := NewLogger("bar")
   434  
   435  	foo.Debugf("Foo is debugging: %d", 10)
   436  	bar.Infof("Bar is informational? %s.", "Yes")
   437  	foo.Noticef("NOTE NOTE NOTE")
   438  	bar.Warningf("Danger, Danger %s %s", "Will", "Robinson!")
   439  	foo.Errorf("I'm sorry Dave, I'm afraid I can't do that.")
   440  	bar.Criticalf("PI is not equal to 3.14, we computed it as %.2f", 4.13)
   441  
   442  	bar.Debug("Foo is debugging:", 10)
   443  	foo.Info("Bar is informational?", "Yes.")
   444  	bar.Notice("NOTE NOTE NOTE")
   445  	foo.Warning("Danger, Danger", "Will", "Robinson!")
   446  	bar.Error("I'm sorry Dave, I'm afraid I can't do that.")
   447  	foo.Critical("PI is not equal to", 3.14, ", we computed it as", 4.13)
   448  
   449  	foo.SetLevel(LogWarning)
   450  	if foo.IsEnabledFor(LogDebug) {
   451  		t.Errorf("'foo' should not be enabled for LogDebug")
   452  	}
   453  	if !foo.IsEnabledFor(LogCritical) {
   454  		t.Errorf("'foo' should be enabled for LogCritical")
   455  	}
   456  	bar.SetLevel(LogCritical)
   457  	if bar.IsEnabledFor(LogDebug) {
   458  		t.Errorf("'bar' should not be enabled for LogDebug")
   459  	}
   460  	if !bar.IsEnabledFor(LogCritical) {
   461  		t.Errorf("'bar' should be enabled for LogCritical")
   462  	}
   463  }
   464  
   465  func TestNilEventName(t *testing.T) {
   466  	stub := ChaincodeStub{}
   467  	if err := stub.SetEvent("", []byte("event payload")); err == nil {
   468  		t.Error("Event name can not be nil string.")
   469  	}
   470  
   471  }
   472  
   473  type testCase struct {
   474  	name         string
   475  	ccLogLevel   string
   476  	shimLogLevel string
   477  }
   478  
   479  func TestSetupChaincodeLogging_shim(t *testing.T) {
   480  	var tc []testCase
   481  
   482  	tc = append(tc,
   483  		testCase{"ValidLevels", "debug", "warning"},
   484  		testCase{"EmptyLevels", "", ""},
   485  		testCase{"BadShimLevel", "debug", "war"},
   486  		testCase{"BadCCLevel", "deb", "notice"},
   487  		testCase{"EmptyShimLevel", "error", ""},
   488  		testCase{"EmptyCCLevel", "", "critical"},
   489  	)
   490  
   491  	assert := assert.New(t)
   492  
   493  	for i := 0; i < len(tc); i++ {
   494  		t.Run(tc[i].name, func(t *testing.T) {
   495  			viper.Set("chaincode.logging.level", tc[i].ccLogLevel)
   496  			viper.Set("chaincode.logging.shim", tc[i].shimLogLevel)
   497  
   498  			SetupChaincodeLogging()
   499  
   500  			_, ccErr := logging.LogLevel(tc[i].ccLogLevel)
   501  			_, shimErr := logging.LogLevel(tc[i].shimLogLevel)
   502  			if ccErr == nil {
   503  				assert.Equal(strings.ToUpper(tc[i].ccLogLevel), flogging.GetModuleLevel("ccLogger"), "Test case '%s' failed", tc[i].name)
   504  				if shimErr == nil {
   505  					assert.Equal(strings.ToUpper(tc[i].shimLogLevel), flogging.GetModuleLevel("shim"), "Test case '%s' failed", tc[i].name)
   506  				} else {
   507  					assert.Equal(strings.ToUpper(tc[i].ccLogLevel), flogging.GetModuleLevel("shim"), "Test case '%s' failed", tc[i].name)
   508  				}
   509  			} else {
   510  				assert.Equal(flogging.DefaultLevel(), flogging.GetModuleLevel("ccLogger"), "Test case '%s' failed", tc[i].name)
   511  				if shimErr == nil {
   512  					assert.Equal(strings.ToUpper(tc[i].shimLogLevel), flogging.GetModuleLevel("shim"), "Test case '%s' failed", tc[i].name)
   513  				} else {
   514  					assert.Equal(flogging.DefaultLevel(), flogging.GetModuleLevel("shim"), "Test case '%s' failed", tc[i].name)
   515  				}
   516  			}
   517  		})
   518  	}
   519  }
   520  
   521  //store the stream CC mappings here
   522  var mockPeerCCSupport = mockpeer.NewMockPeerSupport()
   523  
   524  func mockChaincodeStreamGetter(name string) (PeerChaincodeStream, error) {
   525  	return mockPeerCCSupport.GetCC(name)
   526  }
   527  
   528  func setupcc(name string, cc Chaincode) *mockpeer.MockCCComm {
   529  	viper.Set("chaincode.id.name", name)
   530  	send := make(chan *pb.ChaincodeMessage)
   531  	recv := make(chan *pb.ChaincodeMessage)
   532  	ccSide, _ := mockPeerCCSupport.AddCC(name, recv, send)
   533  	ccSide.SetPong(true)
   534  	return mockPeerCCSupport.GetCCMirror(name)
   535  }
   536  
   537  //assign this to done and failNow and keep using them
   538  func setuperror() chan error {
   539  	return make(chan error)
   540  }
   541  
   542  func processDone(t *testing.T, done chan error, expecterr bool) {
   543  	err := <-done
   544  	if expecterr != (err != nil) {
   545  		if err == nil {
   546  			t.Fatalf("Expected error but got success")
   547  		} else {
   548  			t.Fatalf("Expected success but got error %s", err)
   549  		}
   550  	}
   551  }
   552  
   553  //TestInvoke tests init and invoke along with many of the stub functions
   554  //such as get/put/del/range...
   555  func TestInvoke(t *testing.T) {
   556  	streamGetter = mockChaincodeStreamGetter
   557  	cc := &shimTestCC{}
   558  	//viper.Set("chaincode.logging.shim", "debug")
   559  	var err error
   560  	ccname := "shimTestCC"
   561  	peerSide := setupcc(ccname, cc)
   562  	defer mockPeerCCSupport.RemoveCC(ccname)
   563  	//start the shim+chaincode
   564  	go func() {
   565  		err = Start(cc)
   566  	}()
   567  
   568  	done := setuperror()
   569  
   570  	errorFunc := func(ind int, err error) {
   571  		done <- err
   572  	}
   573  
   574  	//start the mock peer
   575  	go func() {
   576  		respSet := &mockpeer.MockResponseSet{errorFunc, nil, []*mockpeer.MockResponse{
   577  			&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_REGISTER}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_REGISTERED}}}}
   578  		peerSide.SetResponses(respSet)
   579  		peerSide.SetKeepAlive(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_KEEPALIVE})
   580  		err = peerSide.Run()
   581  	}()
   582  
   583  	//wait for init
   584  	processDone(t, done, false)
   585  
   586  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_READY, Txid: "1"})
   587  
   588  	ci := &pb.ChaincodeInput{[][]byte{[]byte("init"), []byte("A"), []byte("100"), []byte("B"), []byte("200")}}
   589  	payload := utils.MarshalOrPanic(ci)
   590  	respSet := &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   591  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Txid: "2"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "2"}},
   592  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Txid: "2"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "2"}},
   593  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "2"}, nil}}}
   594  	peerSide.SetResponses(respSet)
   595  
   596  	//use the payload computed from prev init
   597  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INIT, Payload: payload, Txid: "2"})
   598  
   599  	//wait for done
   600  	processDone(t, done, false)
   601  
   602  	//good invoke
   603  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   604  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Txid: "3"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: []byte("100"), Txid: "3"}},
   605  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Txid: "3"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: []byte("200"), Txid: "3"}},
   606  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Txid: "3"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "3"}},
   607  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Txid: "3"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "3"}},
   608  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "3"}, nil}}}
   609  	peerSide.SetResponses(respSet)
   610  
   611  	ci = &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}}
   612  	payload = utils.MarshalOrPanic(ci)
   613  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "3"})
   614  
   615  	//wait for done
   616  	processDone(t, done, false)
   617  
   618  	//bad put
   619  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   620  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Txid: "3a"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: []byte("100"), Txid: "3a"}},
   621  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Txid: "3a"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: []byte("200"), Txid: "3a"}},
   622  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Txid: "3a"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Txid: "3a"}},
   623  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "3a"}, nil}}}
   624  	peerSide.SetResponses(respSet)
   625  
   626  	ci = &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}}
   627  	payload = utils.MarshalOrPanic(ci)
   628  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "3a"})
   629  
   630  	//wait for done
   631  	processDone(t, done, false)
   632  
   633  	//bad get
   634  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   635  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Txid: "3b"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Txid: "3b"}},
   636  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "3b"}, nil}}}
   637  	peerSide.SetResponses(respSet)
   638  
   639  	ci = &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}}
   640  	payload = utils.MarshalOrPanic(ci)
   641  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "3b"})
   642  
   643  	//wait for done
   644  	processDone(t, done, false)
   645  
   646  	//bad delete
   647  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   648  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_DEL_STATE, Txid: "4"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Txid: "4"}},
   649  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "4"}, nil}}}
   650  	peerSide.SetResponses(respSet)
   651  
   652  	ci = &pb.ChaincodeInput{[][]byte{[]byte("delete"), []byte("A")}}
   653  	payload = utils.MarshalOrPanic(ci)
   654  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "4"})
   655  
   656  	//wait for done
   657  	processDone(t, done, false)
   658  
   659  	//good delete
   660  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   661  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_DEL_STATE, Txid: "4a"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "4a"}},
   662  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "4a"}, nil}}}
   663  	peerSide.SetResponses(respSet)
   664  
   665  	ci = &pb.ChaincodeInput{[][]byte{[]byte("delete"), []byte("A")}}
   666  	payload = utils.MarshalOrPanic(ci)
   667  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "4a"})
   668  
   669  	//wait for done
   670  	processDone(t, done, false)
   671  
   672  	//bad invoke
   673  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   674  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "5"}, nil}}}
   675  	peerSide.SetResponses(respSet)
   676  
   677  	ci = &pb.ChaincodeInput{[][]byte{[]byte("badinvoke")}}
   678  	payload = utils.MarshalOrPanic(ci)
   679  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "5"})
   680  
   681  	//wait for done
   682  	processDone(t, done, false)
   683  
   684  	//range query
   685  
   686  	//create the response
   687  	rangeQueryResponse := &pb.QueryResponse{Results: []*pb.QueryResultBytes{
   688  		&pb.QueryResultBytes{ResultBytes: utils.MarshalOrPanic(&lproto.KV{"getputcc", "A", []byte("100")})},
   689  		&pb.QueryResultBytes{ResultBytes: utils.MarshalOrPanic(&lproto.KV{"getputcc", "B", []byte("200")})}},
   690  		HasMore: true}
   691  	rangeQPayload := utils.MarshalOrPanic(rangeQueryResponse)
   692  
   693  	//create the next response
   694  	rangeQueryNext := &pb.QueryResponse{Results: nil, HasMore: false}
   695  
   696  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   697  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE_BY_RANGE, Txid: "6"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: rangeQPayload, Txid: "6"}},
   698  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_NEXT, Txid: "6"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: utils.MarshalOrPanic(rangeQueryNext), Txid: "6"}},
   699  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_CLOSE, Txid: "6"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "6"}},
   700  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "6"}, nil}}}
   701  	peerSide.SetResponses(respSet)
   702  
   703  	ci = &pb.ChaincodeInput{[][]byte{[]byte("rangeq"), []byte("A"), []byte("B")}}
   704  	payload = utils.MarshalOrPanic(ci)
   705  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "6"})
   706  
   707  	//wait for done
   708  	processDone(t, done, false)
   709  
   710  	//error range query
   711  
   712  	//create the response
   713  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   714  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE_BY_RANGE, Txid: "6a"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: "6a"}},
   715  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "6a"}, nil}}}
   716  	peerSide.SetResponses(respSet)
   717  
   718  	ci = &pb.ChaincodeInput{[][]byte{[]byte("rangeq"), []byte("A"), []byte("B")}}
   719  	payload = utils.MarshalOrPanic(ci)
   720  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "6a"})
   721  
   722  	//wait for done
   723  	processDone(t, done, false)
   724  
   725  	//error range query next
   726  
   727  	//create the response
   728  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   729  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE_BY_RANGE, Txid: "6b"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: rangeQPayload, Txid: "6b"}},
   730  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_NEXT, Txid: "6b"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Txid: "6b"}},
   731  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_CLOSE, Txid: "6b"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "6b"}},
   732  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "6b"}, nil}}}
   733  	peerSide.SetResponses(respSet)
   734  
   735  	ci = &pb.ChaincodeInput{[][]byte{[]byte("rangeq"), []byte("A"), []byte("B")}}
   736  	payload = utils.MarshalOrPanic(ci)
   737  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "6b"})
   738  
   739  	//wait for done
   740  	processDone(t, done, false)
   741  
   742  	//error range query close
   743  
   744  	//create the response
   745  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   746  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE_BY_RANGE, Txid: "6c"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: rangeQPayload, Txid: "6c"}},
   747  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_NEXT, Txid: "6c"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Txid: "6c"}},
   748  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_CLOSE, Txid: "6c"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Txid: "6c"}},
   749  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "6c"}, nil}}}
   750  	peerSide.SetResponses(respSet)
   751  
   752  	ci = &pb.ChaincodeInput{[][]byte{[]byte("rangeq"), []byte("A"), []byte("B")}}
   753  	payload = utils.MarshalOrPanic(ci)
   754  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "6c"})
   755  
   756  	//wait for done
   757  	processDone(t, done, false)
   758  
   759  	//history query
   760  
   761  	//create the response
   762  	historyQueryResponse := &pb.QueryResponse{Results: []*pb.QueryResultBytes{
   763  		&pb.QueryResultBytes{ResultBytes: utils.MarshalOrPanic(&lproto.KeyModification{TxId: "6", Value: []byte("100")})}},
   764  		HasMore: true}
   765  	payload = utils.MarshalOrPanic(historyQueryResponse)
   766  
   767  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   768  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_HISTORY_FOR_KEY, Txid: "7"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payload, Txid: "7"}},
   769  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_NEXT, Txid: "7"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: utils.MarshalOrPanic(rangeQueryNext), Txid: "7"}},
   770  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_CLOSE, Txid: "7"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "7"}},
   771  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "7"}, nil}}}
   772  	peerSide.SetResponses(respSet)
   773  
   774  	ci = &pb.ChaincodeInput{[][]byte{[]byte("historyq"), []byte("A")}}
   775  	payload = utils.MarshalOrPanic(ci)
   776  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "7"})
   777  
   778  	//wait for done
   779  	processDone(t, done, false)
   780  
   781  	//error history query
   782  
   783  	//create the response
   784  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   785  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_HISTORY_FOR_KEY, Txid: "7a"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: "7a"}},
   786  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "7a"}, nil}}}
   787  	peerSide.SetResponses(respSet)
   788  
   789  	ci = &pb.ChaincodeInput{[][]byte{[]byte("historyq"), []byte("A")}}
   790  	payload = utils.MarshalOrPanic(ci)
   791  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "7a"})
   792  
   793  	//wait for done
   794  	processDone(t, done, false)
   795  
   796  	//query result
   797  
   798  	//create the response
   799  	getQRResp := &pb.QueryResponse{Results: []*pb.QueryResultBytes{
   800  		&pb.QueryResultBytes{ResultBytes: utils.MarshalOrPanic(&lproto.KV{"getputcc", "A", []byte("100")})},
   801  		&pb.QueryResultBytes{ResultBytes: utils.MarshalOrPanic(&lproto.KV{"getputcc", "B", []byte("200")})}},
   802  		HasMore: true}
   803  	getQRRespPayload := utils.MarshalOrPanic(getQRResp)
   804  
   805  	//create the next response
   806  	rangeQueryNext = &pb.QueryResponse{Results: nil, HasMore: false}
   807  
   808  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   809  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_QUERY_RESULT, Txid: "8"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: getQRRespPayload, Txid: "8"}},
   810  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_NEXT, Txid: "8"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: utils.MarshalOrPanic(rangeQueryNext), Txid: "8"}},
   811  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_CLOSE, Txid: "8"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "8"}},
   812  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "8"}, nil}}}
   813  	peerSide.SetResponses(respSet)
   814  
   815  	ci = &pb.ChaincodeInput{[][]byte{[]byte("richq"), []byte("A")}}
   816  	payload = utils.MarshalOrPanic(ci)
   817  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "8"})
   818  
   819  	//wait for done
   820  	processDone(t, done, false)
   821  
   822  	//query result error
   823  
   824  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   825  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_QUERY_RESULT, Txid: "8a"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: nil, Txid: "8a"}},
   826  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "8a"}, nil}}}
   827  	peerSide.SetResponses(respSet)
   828  
   829  	ci = &pb.ChaincodeInput{[][]byte{[]byte("richq"), []byte("A")}}
   830  	payload = utils.MarshalOrPanic(ci)
   831  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "8a"})
   832  
   833  	//wait for done
   834  	processDone(t, done, false)
   835  
   836  	time.Sleep(1 * time.Second)
   837  	peerSide.Quit()
   838  }
   839  
   840  func TestStartInProc(t *testing.T) {
   841  	streamGetter = mockChaincodeStreamGetter
   842  	cc := &shimTestCC{}
   843  	var err error
   844  	ccname := "shimTestCC"
   845  	peerSide := setupcc(ccname, cc)
   846  	defer mockPeerCCSupport.RemoveCC(ccname)
   847  
   848  	done := setuperror()
   849  
   850  	doneFunc := func(ind int, err error) {
   851  		done <- err
   852  	}
   853  
   854  	//start the mock peer
   855  	go func() {
   856  		respSet := &mockpeer.MockResponseSet{doneFunc, nil, []*mockpeer.MockResponse{
   857  			&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_REGISTER}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_REGISTERED}}}}
   858  		peerSide.SetResponses(respSet)
   859  		peerSide.SetKeepAlive(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_KEEPALIVE})
   860  		err = peerSide.Run()
   861  	}()
   862  
   863  	//start the shim+chaincode
   864  	go func() {
   865  		err = StartInProc([]string{"CORE_CHAINCODE_ID_NAME=shimTestCC", "CORE_CHAINCODE_LOGGING_SHIM=debug"}, nil, cc, peerSide.GetSendStream(), peerSide.GetRecvStream())
   866  	}()
   867  
   868  	//wait for init
   869  	processDone(t, done, false)
   870  
   871  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_READY, Txid: "1"})
   872  
   873  	time.Sleep(1 * time.Second)
   874  	peerSide.Quit()
   875  }
   876  
   877  func TestCC2CC(t *testing.T) {
   878  	streamGetter = mockChaincodeStreamGetter
   879  	cc := &shimTestCC{}
   880  	//viper.Set("chaincode.logging.shim", "debug")
   881  	var err error
   882  	ccname := "shimTestCC"
   883  	peerSide := setupcc(ccname, cc)
   884  	defer mockPeerCCSupport.RemoveCC(ccname)
   885  	//start the shim+chaincode
   886  	go func() {
   887  		err = Start(cc)
   888  	}()
   889  
   890  	done := setuperror()
   891  
   892  	errorFunc := func(ind int, err error) {
   893  		done <- err
   894  	}
   895  
   896  	//start the mock peer
   897  	go func() {
   898  		respSet := &mockpeer.MockResponseSet{errorFunc, nil, []*mockpeer.MockResponse{
   899  			&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_REGISTER}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_REGISTERED}}}}
   900  		peerSide.SetResponses(respSet)
   901  		peerSide.SetKeepAlive(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_KEEPALIVE})
   902  		err = peerSide.Run()
   903  	}()
   904  
   905  	//wait for init
   906  	processDone(t, done, false)
   907  
   908  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_READY, Txid: "1"})
   909  
   910  	ci := &pb.ChaincodeInput{[][]byte{[]byte("init"), []byte("A"), []byte("100"), []byte("B"), []byte("200")}}
   911  	payload := utils.MarshalOrPanic(ci)
   912  	respSet := &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   913  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Txid: "2"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "2"}},
   914  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Txid: "2"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "2"}},
   915  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "2"}, nil}}}
   916  	peerSide.SetResponses(respSet)
   917  
   918  	//use the payload computed from prev init
   919  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INIT, Payload: payload, Txid: "2"})
   920  
   921  	//wait for done
   922  	processDone(t, done, false)
   923  
   924  	//cc2cc
   925  	innerResp := utils.MarshalOrPanic(&pb.Response{Status: OK, Payload: []byte("CC2CC rocks")})
   926  	cc2ccresp := utils.MarshalOrPanic(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: innerResp})
   927  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   928  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INVOKE_CHAINCODE, Txid: "3"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: cc2ccresp, Txid: "3"}},
   929  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "3"}, nil}}}
   930  	peerSide.SetResponses(respSet)
   931  
   932  	ci = &pb.ChaincodeInput{[][]byte{[]byte("cc2cc"), []byte("othercc"), []byte("arg1"), []byte("arg2")}}
   933  	payload = utils.MarshalOrPanic(ci)
   934  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "3"})
   935  
   936  	//wait for done
   937  	processDone(t, done, false)
   938  
   939  	//error response cc2cc
   940  	respSet = &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{
   941  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INVOKE_CHAINCODE, Txid: "4"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: cc2ccresp, Txid: "4"}},
   942  		&mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "4"}, nil}}}
   943  	peerSide.SetResponses(respSet)
   944  
   945  	peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "4"})
   946  
   947  	//wait for done
   948  	processDone(t, done, false)
   949  
   950  	time.Sleep(1 * time.Second)
   951  	peerSide.Quit()
   952  }
   953  
   954  func TestRealPeerStream(t *testing.T) {
   955  	viper.Set("peer.address", "127.0.0.1:12345")
   956  	_, err := userChaincodeStreamGetter("fake")
   957  	assert.Error(t, err)
   958  }