github.com/Hnampk/fabric@v2.1.1+incompatible/core/ledger/kvledger/benchmark/experiments/insert_txs_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package experiments
     8  
     9  import (
    10  	"fmt"
    11  	"sync"
    12  	"testing"
    13  
    14  	"github.com/hyperledger/fabric/common/util"
    15  	"github.com/hyperledger/fabric/core/ledger/kvledger/benchmark/chainmgmt"
    16  )
    17  
    18  // BenchmarkInsertTxs starts fresh chains and inserts the Key-values by simulating writes-only transactions
    19  // For each of the chains, this test launches the parallel clients (based on the configuration) and the clients
    20  // simulate and commit write-only transactions. The keys are divided among clients such that one key is written
    21  // only once and all the keys are inserted.
    22  //
    23  // For instance, if this benchmark is invoked with the following test parameters
    24  // -testParams=-NumChains=2, -NumParallelTxPerChain=2, -NumKVs=100
    25  // then client_1 on chain_1 will insert Key_1 to key_25 and client_2 on chain_1 will insert Key_26 to key_50
    26  // similarly client_3 on chain_2 will insert Key_1 to key_25 and client_4 on chain_2 will insert Key_26 to key_50
    27  // where, client_1 and client_2 run in parallel on chain_1 and client_3 and client_4 run in parallel on chain_2
    28  func BenchmarkInsertTxs(b *testing.B) {
    29  	if b.N != 1 {
    30  		panic(fmt.Errorf(`This benchmark should be called with N=1 only. Run this with more volume of data`))
    31  	}
    32  	testEnv := chainmgmt.InitTestEnv(conf.chainMgrConf, conf.batchConf, chainmgmt.ChainInitOpCreate)
    33  	for _, chain := range testEnv.Chains() {
    34  		go runInsertClientsForChain(chain)
    35  	}
    36  	testEnv.WaitForTestCompletion()
    37  }
    38  
    39  func runInsertClientsForChain(chain *chainmgmt.Chain) {
    40  	numKVsForChain := calculateShare(conf.dataConf.numKVs, conf.chainMgrConf.NumChains, int(chain.ID))
    41  	numClients := conf.txConf.numParallelTxsPerChain
    42  	wg := &sync.WaitGroup{}
    43  	wg.Add(numClients)
    44  	startKey := 0
    45  	for i := 0; i < numClients; i++ {
    46  		numKVsForClient := calculateShare(numKVsForChain, numClients, i)
    47  		endKey := startKey + numKVsForClient - 1
    48  		go runInsertClient(chain, startKey, endKey, wg)
    49  		startKey = endKey + 1
    50  	}
    51  	wg.Wait()
    52  	chain.Done()
    53  }
    54  
    55  func runInsertClient(chain *chainmgmt.Chain, startKey, endKey int, wg *sync.WaitGroup) {
    56  	numWritesPerTx := conf.txConf.numWritesPerTx
    57  	kvSize := conf.dataConf.kvSize
    58  	useJSON := conf.dataConf.useJSON
    59  
    60  	currentKey := startKey
    61  	for currentKey <= endKey {
    62  		simulator, err := chain.NewTxSimulator(util.GenerateUUID())
    63  		panicOnError(err)
    64  		for i := 0; i < numWritesPerTx; i++ {
    65  			if useJSON {
    66  				panicOnError(simulator.SetState(
    67  					chaincodeName, constructKey(currentKey), constructJSONValue(currentKey, kvSize)))
    68  			} else {
    69  				panicOnError(simulator.SetState(
    70  					chaincodeName, constructKey(currentKey), constructValue(currentKey, kvSize)))
    71  			}
    72  			currentKey++
    73  			if currentKey > endKey {
    74  				break
    75  			}
    76  		}
    77  		simulator.Done()
    78  		sr, err := simulator.GetTxSimulationResults()
    79  		panicOnError(err)
    80  		srBytes, err := sr.GetPubSimulationBytes()
    81  		panicOnError(err)
    82  		chain.SubmitTx(srBytes)
    83  	}
    84  	wg.Done()
    85  }