github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/core/chaincode/concurrency_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 chaincode
    18  
    19  import (
    20  	"fmt"
    21  	"sync"
    22  	"testing"
    23  
    24  	"github.com/hyperledger/fabric/common/util"
    25  	"github.com/hyperledger/fabric/core/common/ccprovider"
    26  	pb "github.com/hyperledger/fabric/protos/peer"
    27  
    28  	"golang.org/x/net/context"
    29  )
    30  
    31  //TestExecuteConcurrentInvokes deploys newkeyperinvoke and runs 100 concurrent invokes
    32  //followed by concurrent 100 queries to validate
    33  func TestExecuteConcurrentInvokes(t *testing.T) {
    34  	//this test fails occasionally. FAB-1600 is opened to track this issue
    35  	//skip meanwhile so as to not block CI
    36  	t.Skip()
    37  	chainID := util.GetTestChainID()
    38  
    39  	lis, err := initPeer(chainID)
    40  	if err != nil {
    41  		t.Fail()
    42  		t.Logf("Error creating peer: %s", err)
    43  	}
    44  
    45  	defer finitPeer(lis, chainID)
    46  
    47  	var ctxt = context.Background()
    48  
    49  	url := "github.com/hyperledger/fabric/examples/ccchecker/chaincodes/newkeyperinvoke"
    50  
    51  	chaincodeID := &pb.ChaincodeID{Name: "nkpi", Path: url, Version: "0"}
    52  
    53  	args := util.ToChaincodeArgs("init", "")
    54  
    55  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}}
    56  
    57  	cccid := ccprovider.NewCCContext(chainID, "nkpi", "0", "", false, nil, nil)
    58  
    59  	defer theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
    60  
    61  	var nextBlockNumber uint64
    62  	_, err = deploy(ctxt, cccid, spec, nextBlockNumber)
    63  	nextBlockNumber++
    64  	if err != nil {
    65  		t.Fail()
    66  		t.Logf("Error initializing chaincode %s(%s)", chaincodeID, err)
    67  		return
    68  	}
    69  
    70  	var wg sync.WaitGroup
    71  
    72  	//run 100 invokes in parallel
    73  	numTrans := 100
    74  
    75  	results := make([][]byte, numTrans)
    76  	errs := make([]error, numTrans)
    77  
    78  	e := func(inv bool, qnum int) {
    79  		defer wg.Done()
    80  
    81  		newkey := fmt.Sprintf("%d", qnum)
    82  
    83  		var args [][]byte
    84  		if inv {
    85  			args = util.ToChaincodeArgs("put", newkey, newkey)
    86  		} else {
    87  			args = util.ToChaincodeArgs("get", newkey)
    88  		}
    89  
    90  		spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}}
    91  
    92  		//start with a new background
    93  		_, _, results[qnum], err = invoke(context.Background(), chainID, spec, nextBlockNumber, nil)
    94  
    95  		if err != nil {
    96  			errs[qnum] = fmt.Errorf("Error executing <%s>: %s", chaincodeID.Name, err)
    97  			return
    98  		}
    99  	}
   100  
   101  	wg.Add(numTrans)
   102  
   103  	//execute transactions concurrently.
   104  	for i := 0; i < numTrans; i++ {
   105  		go e(true, i)
   106  	}
   107  
   108  	wg.Wait()
   109  
   110  	for i := 0; i < numTrans; i++ {
   111  		if errs[i] != nil {
   112  			t.Fail()
   113  			t.Logf("Error invoking chaincode iter %d %s(%s)", i, chaincodeID.Name, errs[i])
   114  		}
   115  		if results[i] == nil || string(results[i]) != "OK" {
   116  			t.Fail()
   117  			t.Logf("Error concurrent invoke %d %s", i, chaincodeID.Name)
   118  			return
   119  		}
   120  	}
   121  
   122  	wg.Add(numTrans)
   123  
   124  	//execute queries concurrently.
   125  	for i := 0; i < numTrans; i++ {
   126  		go e(false, i)
   127  	}
   128  
   129  	wg.Wait()
   130  
   131  	for i := 0; i < numTrans; i++ {
   132  		if errs[i] != nil {
   133  			t.Fail()
   134  			t.Logf("Error querying chaincode iter %d %s(%s)", i, chaincodeID.Name, errs[i])
   135  			return
   136  		}
   137  		if results[i] == nil || string(results[i]) != fmt.Sprintf("%d", i) {
   138  			t.Fail()
   139  			if results[i] == nil {
   140  				t.Logf("Error concurrent query %d(%s)", i, chaincodeID.Name)
   141  			} else {
   142  				t.Logf("Error concurrent query %d(%s, %s, %v)", i, chaincodeID.Name, string(results[i]), results[i])
   143  			}
   144  			return
   145  		}
   146  	}
   147  }