github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/common/ledger/testutil/test_helper.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 testutil
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/golang/protobuf/proto"
    23  	"github.com/hyperledger/fabric/common/configtx/test"
    24  	"github.com/hyperledger/fabric/common/configtx/tool/provisional"
    25  	"github.com/hyperledger/fabric/common/util"
    26  	lutils "github.com/hyperledger/fabric/core/ledger/util"
    27  	"github.com/hyperledger/fabric/protos/common"
    28  	pb "github.com/hyperledger/fabric/protos/peer"
    29  	ptestutils "github.com/hyperledger/fabric/protos/testutils"
    30  	"github.com/hyperledger/fabric/protos/utils"
    31  
    32  	genesisconfig "github.com/hyperledger/fabric/common/configtx/tool/localconfig"
    33  )
    34  
    35  //BlockGenerator generates a series of blocks for testing
    36  type BlockGenerator struct {
    37  	blockNum     uint64
    38  	previousHash []byte
    39  	signTxs      bool
    40  	t            *testing.T
    41  }
    42  
    43  // NewBlockGenerator instantiates new BlockGenerator for testing
    44  func NewBlockGenerator(t *testing.T, ledgerID string, signTxs bool) (*BlockGenerator, *common.Block) {
    45  	gb, err := test.MakeGenesisBlock(ledgerID)
    46  	AssertNoError(t, err, "")
    47  	gb.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = lutils.NewTxValidationFlags(len(gb.Data.Data))
    48  	return &BlockGenerator{1, gb.GetHeader().Hash(), signTxs, t}, gb
    49  }
    50  
    51  // NextBlock constructs next block in sequence that includes a number of transactions - one per simulationResults
    52  func (bg *BlockGenerator) NextBlock(simulationResults [][]byte) *common.Block {
    53  	block := ConstructBlock(bg.t, bg.blockNum, bg.previousHash, simulationResults, bg.signTxs)
    54  	bg.blockNum++
    55  	bg.previousHash = block.Header.Hash()
    56  	return block
    57  }
    58  
    59  // NextTestBlock constructs next block in sequence block with 'numTx' number of transactions for testing
    60  func (bg *BlockGenerator) NextTestBlock(numTx int, txSize int) *common.Block {
    61  	simulationResults := [][]byte{}
    62  	for i := 0; i < numTx; i++ {
    63  		simulationResults = append(simulationResults, ConstructRandomBytes(bg.t, txSize))
    64  	}
    65  	return bg.NextBlock(simulationResults)
    66  }
    67  
    68  // NextTestBlocks constructs 'numBlocks' number of blocks for testing
    69  func (bg *BlockGenerator) NextTestBlocks(numBlocks int) []*common.Block {
    70  	blocks := []*common.Block{}
    71  	for i := 0; i < numBlocks; i++ {
    72  		blocks = append(blocks, bg.NextTestBlock(10, 100))
    73  	}
    74  	return blocks
    75  }
    76  
    77  // ConstructTransaction constructs a transaction for testing
    78  func ConstructTransaction(_ *testing.T, simulationResults []byte, sign bool) (*common.Envelope, string, error) {
    79  	ccid := &pb.ChaincodeID{
    80  		Name:    "foo",
    81  		Version: "v1",
    82  	}
    83  	//response := &pb.Response{Status: 200}
    84  	var txID string
    85  	var txEnv *common.Envelope
    86  	var err error
    87  	if sign {
    88  		txEnv, txID, err = ptestutils.ConstructSingedTxEnvWithDefaultSigner(util.GetTestChainID(), ccid, nil, simulationResults, nil, nil)
    89  	} else {
    90  		txEnv, txID, err = ptestutils.ConstructUnsingedTxEnv(util.GetTestChainID(), ccid, nil, simulationResults, nil, nil)
    91  	}
    92  	return txEnv, txID, err
    93  }
    94  
    95  // ConstructBlock constructs a single block
    96  func ConstructBlock(t *testing.T, blockNum uint64, previousHash []byte, simulationResults [][]byte, sign bool) *common.Block {
    97  	envs := []*common.Envelope{}
    98  	for i := 0; i < len(simulationResults); i++ {
    99  		env, _, err := ConstructTransaction(t, simulationResults[i], sign)
   100  		if err != nil {
   101  			t.Fatalf("ConstructTestTransaction failed, err %s", err)
   102  		}
   103  		envs = append(envs, env)
   104  	}
   105  	return newBlock(envs, blockNum, previousHash)
   106  }
   107  
   108  //ConstructTestBlock constructs a single block with random contents
   109  func ConstructTestBlock(t *testing.T, blockNum uint64, numTx int, txSize int) *common.Block {
   110  	simulationResults := [][]byte{}
   111  	for i := 0; i < numTx; i++ {
   112  		simulationResults = append(simulationResults, ConstructRandomBytes(t, txSize))
   113  	}
   114  	return ConstructBlock(t, blockNum, ConstructRandomBytes(t, 32), simulationResults, false)
   115  }
   116  
   117  // ConstructTestBlocks returns a series of blocks starting with blockNum=0.
   118  // The first block in the returned array is a config tx block that represents a genesis block
   119  func ConstructTestBlocks(t *testing.T, numBlocks int) []*common.Block {
   120  	bg, gb := NewBlockGenerator(t, util.GetTestChainID(), false)
   121  	blocks := []*common.Block{}
   122  	if numBlocks != 0 {
   123  		blocks = append(blocks, gb)
   124  	}
   125  	return append(blocks, bg.NextTestBlocks(numBlocks-1)...)
   126  }
   127  
   128  func newBlock(env []*common.Envelope, blockNum uint64, previousHash []byte) *common.Block {
   129  	block := common.NewBlock(blockNum, previousHash)
   130  	for i := 0; i < len(env); i++ {
   131  		txEnvBytes, _ := proto.Marshal(env[i])
   132  		block.Data.Data = append(block.Data.Data, txEnvBytes)
   133  	}
   134  	block.Header.DataHash = block.Data.Hash()
   135  	utils.InitBlockMetadata(block)
   136  
   137  	block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = lutils.NewTxValidationFlags(len(env))
   138  
   139  	return block
   140  }
   141  
   142  func MakeGenesisBlock() *common.Block {
   143  	genConf := genesisconfig.Load(genesisconfig.SampleInsecureProfile)
   144  	gb := provisional.New(genConf).GenesisBlock()
   145  	return gb
   146  }