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 }