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 }