github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/test/tools/LTE/experiments/readwrite_txs_test.go (about) 1 /* 2 Copyright IBM Corp. 2017 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 experiments 18 19 import ( 20 "fmt" 21 "math/rand" 22 "sync" 23 "testing" 24 "time" 25 26 "github.com/hyperledger/fabric/test/tools/LTE/chainmgmt" 27 "github.com/hyperledger/fabric/test/tools/LTE/common" 28 ) 29 30 // BenchmarkReadWriteTxs opens the existing chains and modifies the Key-values by simulating read-write transactions 31 // For each of the chains, this test launches the parallel clients (based on the configuration) and the clients 32 // simulate and commit read-write transactions. This test assumes the pre-populated chain by previously running 33 // BenchmarkInsertTxs. Each transaction simultated by this benchmark randomly selects a configurable number of keys 34 // and modifies their values 35 // 36 // For instance, if this benchmark is invoked with the following test parameters 37 // -testParams=-NumChains=2, -NumParallelTxPerChain=2, -NumKVs=100, -NumTotalTx=200 38 // then client_1, and client_2 both execute 50 transactions on chain_1 in parallel. Similarly, 39 // client_3, and client_4 both execute 50 transactions on chain_2 in parallel 40 // In each of the transactions executed by any client, the transaction expects 41 // and modifies any key(s) between Key_1 to key_50 (because, total keys are to be 100 across two chains) 42 func BenchmarkReadWriteTxs(b *testing.B) { 43 if b.N != 1 { 44 panic(fmt.Errorf(`This benchmark should be called with N=1 only. Run this with more volume of data`)) 45 } 46 testEnv := chainmgmt.InitTestEnv(conf.chainMgrConf, conf.batchConf, chainmgmt.ChainInitOpOpen) 47 for _, chain := range testEnv.Chains() { 48 go runReadWriteClientsForChain(chain) 49 } 50 testEnv.WaitForTestCompletion() 51 } 52 53 func runReadWriteClientsForChain(chain *chainmgmt.Chain) { 54 numClients := conf.txConf.numParallelTxsPerChain 55 numTxForChain := calculateShare(conf.txConf.numTotalTxs, conf.chainMgrConf.NumChains, int(chain.ID)) 56 wg := &sync.WaitGroup{} 57 wg.Add(numClients) 58 for i := 0; i < numClients; i++ { 59 numTxForClient := calculateShare(numTxForChain, numClients, i) 60 randomNumGen := rand.New(rand.NewSource(int64(time.Now().Nanosecond()) + int64(chain.ID))) 61 go runReadWriteClient(chain, randomNumGen, numTxForClient, wg) 62 } 63 wg.Wait() 64 chain.Done() 65 } 66 67 func runReadWriteClient(chain *chainmgmt.Chain, rand *rand.Rand, numTx int, wg *sync.WaitGroup) { 68 numKeysPerTx := conf.txConf.numKeysInEachTx 69 maxKeyNumber := calculateShare(conf.dataConf.numKVs, conf.chainMgrConf.NumChains, int(chain.ID)) 70 71 for i := 0; i < numTx; i++ { 72 simulator, err := chain.NewTxSimulator() 73 common.PanicOnError(err) 74 for i := 0; i < numKeysPerTx; i++ { 75 keyNumber := rand.Intn(maxKeyNumber) 76 key := constructKey(keyNumber) 77 value, err := simulator.GetState(chaincodeName, key) 78 common.PanicOnError(err) 79 if !verifyValue(keyNumber, value) { 80 panic(fmt.Errorf("Value %s is not expected for key number %d", value, keyNumber)) 81 } 82 common.PanicOnError(simulator.SetState(chaincodeName, key, value)) 83 } 84 simulator.Done() 85 sr, err := simulator.GetTxSimulationResults() 86 common.PanicOnError(err) 87 chain.SubmitTx(sr) 88 } 89 wg.Done() 90 }