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  }