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