github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/common/ledger/blkstorage/fsblkstorage/blockfile_mgr_test.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 fsblkstorage 18 19 import ( 20 "fmt" 21 "testing" 22 23 "github.com/golang/protobuf/proto" 24 "github.com/hyperledger/fabric/common/ledger/testutil" 25 26 "github.com/hyperledger/fabric/protos/common" 27 putil "github.com/hyperledger/fabric/protos/utils" 28 ) 29 30 func TestBlockfileMgrBlockReadWrite(t *testing.T) { 31 env := newTestEnv(t, NewConf(testPath(), 0)) 32 defer env.Cleanup() 33 blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger") 34 defer blkfileMgrWrapper.close() 35 blocks := testutil.ConstructTestBlocks(t, 10) 36 blkfileMgrWrapper.addBlocks(blocks) 37 blkfileMgrWrapper.testGetBlockByHash(blocks) 38 blkfileMgrWrapper.testGetBlockByNumber(blocks, 0) 39 } 40 41 func TestBlockfileMgrCrashDuringWriting(t *testing.T) { 42 testBlockfileMgrCrashDuringWriting(t, 10, 2, 1000, 10) 43 testBlockfileMgrCrashDuringWriting(t, 10, 2, 1000, 1) 44 testBlockfileMgrCrashDuringWriting(t, 10, 2, 1000, 0) 45 testBlockfileMgrCrashDuringWriting(t, 0, 0, 1000, 10) 46 } 47 48 func testBlockfileMgrCrashDuringWriting(t *testing.T, numBlocksBeforeCheckpoint int, 49 numBlocksAfterCheckpoint int, numLastBlockBytes int, numPartialBytesToWrite int) { 50 env := newTestEnv(t, NewConf(testPath(), 0)) 51 defer env.Cleanup() 52 ledgerid := "testLedger" 53 blkfileMgrWrapper := newTestBlockfileWrapper(env, ledgerid) 54 bg := testutil.NewBlockGenerator(t) 55 blocksBeforeCP := bg.NextTestBlocks(numBlocksBeforeCheckpoint) 56 blkfileMgrWrapper.addBlocks(blocksBeforeCP) 57 currentCPInfo := blkfileMgrWrapper.blockfileMgr.cpInfo 58 cpInfo1 := &checkpointInfo{ 59 currentCPInfo.latestFileChunkSuffixNum, 60 currentCPInfo.latestFileChunksize, 61 currentCPInfo.isChainEmpty, 62 currentCPInfo.lastBlockNumber} 63 64 blocksAfterCP := bg.NextTestBlocks(numBlocksAfterCheckpoint) 65 blkfileMgrWrapper.addBlocks(blocksAfterCP) 66 cpInfo2 := blkfileMgrWrapper.blockfileMgr.cpInfo 67 68 // simulate a crash scenario 69 lastBlockBytes := []byte{} 70 encodedLen := proto.EncodeVarint(uint64(numLastBlockBytes)) 71 randomBytes := testutil.ConstructRandomBytes(t, numLastBlockBytes) 72 lastBlockBytes = append(lastBlockBytes, encodedLen...) 73 lastBlockBytes = append(lastBlockBytes, randomBytes...) 74 partialBytes := lastBlockBytes[:numPartialBytesToWrite] 75 blkfileMgrWrapper.blockfileMgr.currentFileWriter.append(partialBytes, true) 76 blkfileMgrWrapper.blockfileMgr.saveCurrentInfo(cpInfo1, true) 77 blkfileMgrWrapper.close() 78 79 // simulate a start after a crash 80 blkfileMgrWrapper = newTestBlockfileWrapper(env, ledgerid) 81 defer blkfileMgrWrapper.close() 82 cpInfo3 := blkfileMgrWrapper.blockfileMgr.cpInfo 83 testutil.AssertEquals(t, cpInfo3, cpInfo2) 84 85 // add fresh blocks after restart 86 blocksAfterRestart := bg.NextTestBlocks(2) 87 blkfileMgrWrapper.addBlocks(blocksAfterRestart) 88 allBlocks := []*common.Block{} 89 allBlocks = append(allBlocks, blocksBeforeCP...) 90 allBlocks = append(allBlocks, blocksAfterCP...) 91 allBlocks = append(allBlocks, blocksAfterRestart...) 92 testBlockfileMgrBlockIterator(t, blkfileMgrWrapper.blockfileMgr, 0, len(allBlocks)-1, allBlocks) 93 } 94 95 func TestBlockfileMgrBlockIterator(t *testing.T) { 96 env := newTestEnv(t, NewConf(testPath(), 0)) 97 defer env.Cleanup() 98 blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger") 99 defer blkfileMgrWrapper.close() 100 blocks := testutil.ConstructTestBlocks(t, 10) 101 blkfileMgrWrapper.addBlocks(blocks) 102 testBlockfileMgrBlockIterator(t, blkfileMgrWrapper.blockfileMgr, 0, 7, blocks[0:8]) 103 } 104 105 func testBlockfileMgrBlockIterator(t *testing.T, blockfileMgr *blockfileMgr, 106 firstBlockNum int, lastBlockNum int, expectedBlocks []*common.Block) { 107 itr, err := blockfileMgr.retrieveBlocks(uint64(firstBlockNum)) 108 defer itr.Close() 109 testutil.AssertNoError(t, err, "Error while getting blocks iterator") 110 numBlocksItrated := 0 111 for { 112 block, err := itr.Next() 113 testutil.AssertNoError(t, err, fmt.Sprintf("Error while getting block number [%d] from iterator", numBlocksItrated)) 114 testutil.AssertEquals(t, block.(*blockHolder).GetBlock(), expectedBlocks[numBlocksItrated]) 115 numBlocksItrated++ 116 if numBlocksItrated == lastBlockNum-firstBlockNum+1 { 117 break 118 } 119 } 120 testutil.AssertEquals(t, numBlocksItrated, lastBlockNum-firstBlockNum+1) 121 } 122 123 func TestBlockfileMgrBlockchainInfo(t *testing.T) { 124 env := newTestEnv(t, NewConf(testPath(), 0)) 125 defer env.Cleanup() 126 blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger") 127 defer blkfileMgrWrapper.close() 128 129 bcInfo := blkfileMgrWrapper.blockfileMgr.getBlockchainInfo() 130 testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{Height: 0, CurrentBlockHash: nil, PreviousBlockHash: nil}) 131 132 blocks := testutil.ConstructTestBlocks(t, 10) 133 blkfileMgrWrapper.addBlocks(blocks) 134 bcInfo = blkfileMgrWrapper.blockfileMgr.getBlockchainInfo() 135 testutil.AssertEquals(t, bcInfo.Height, uint64(10)) 136 } 137 138 func TestBlockfileMgrGetTxById(t *testing.T) { 139 env := newTestEnv(t, NewConf(testPath(), 0)) 140 defer env.Cleanup() 141 blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger") 142 defer blkfileMgrWrapper.close() 143 blocks := testutil.ConstructTestBlocks(t, 10) 144 blkfileMgrWrapper.addBlocks(blocks) 145 for _, blk := range blocks { 146 for j, txEnvelopeBytes := range blk.Data.Data { 147 // blockNum starts with 1 148 txID, err := extractTxID(blk.Data.Data[j]) 149 testutil.AssertNoError(t, err, "") 150 txEnvelopeFromFileMgr, err := blkfileMgrWrapper.blockfileMgr.retrieveTransactionByID(txID) 151 testutil.AssertNoError(t, err, "Error while retrieving tx from blkfileMgr") 152 txEnvelope, err := putil.GetEnvelopeFromBlock(txEnvelopeBytes) 153 testutil.AssertNoError(t, err, "Error while unmarshalling tx") 154 testutil.AssertEquals(t, txEnvelopeFromFileMgr, txEnvelope) 155 } 156 } 157 } 158 159 func TestBlockfileMgrGetTxByBlockNumTranNum(t *testing.T) { 160 env := newTestEnv(t, NewConf(testPath(), 0)) 161 defer env.Cleanup() 162 blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger") 163 defer blkfileMgrWrapper.close() 164 blocks := testutil.ConstructTestBlocks(t, 10) 165 blkfileMgrWrapper.addBlocks(blocks) 166 for blockIndex, blk := range blocks { 167 for tranIndex, txEnvelopeBytes := range blk.Data.Data { 168 // blockNum starts with 1, tranNum starts with 1 169 txEnvelopeFromFileMgr, err := blkfileMgrWrapper.blockfileMgr.retrieveTransactionByBlockNumTranNum(uint64(blockIndex), uint64(tranIndex+1)) 170 testutil.AssertNoError(t, err, "Error while retrieving tx from blkfileMgr") 171 txEnvelope, err := putil.GetEnvelopeFromBlock(txEnvelopeBytes) 172 testutil.AssertNoError(t, err, "Error while unmarshalling tx") 173 testutil.AssertEquals(t, txEnvelopeFromFileMgr, txEnvelope) 174 } 175 } 176 } 177 178 func TestBlockfileMgrRestart(t *testing.T) { 179 env := newTestEnv(t, NewConf(testPath(), 0)) 180 defer env.Cleanup() 181 ledgerid := "testLedger" 182 blkfileMgrWrapper := newTestBlockfileWrapper(env, ledgerid) 183 blocks := testutil.ConstructTestBlocks(t, 10) 184 blkfileMgrWrapper.addBlocks(blocks) 185 expectedHeight := uint64(10) 186 testutil.AssertEquals(t, blkfileMgrWrapper.blockfileMgr.getBlockchainInfo().Height, expectedHeight) 187 blkfileMgrWrapper.close() 188 189 blkfileMgrWrapper = newTestBlockfileWrapper(env, ledgerid) 190 defer blkfileMgrWrapper.close() 191 testutil.AssertEquals(t, int(blkfileMgrWrapper.blockfileMgr.cpInfo.lastBlockNumber), 9) 192 blkfileMgrWrapper.testGetBlockByHash(blocks) 193 testutil.AssertEquals(t, blkfileMgrWrapper.blockfileMgr.getBlockchainInfo().Height, expectedHeight) 194 } 195 196 func TestBlockfileMgrFileRolling(t *testing.T) { 197 blocks := testutil.ConstructTestBlocks(t, 200) 198 size := 0 199 for _, block := range blocks[:100] { 200 by, _, err := serializeBlock(block) 201 testutil.AssertNoError(t, err, "Error while serializing block") 202 blockBytesSize := len(by) 203 encodedLen := proto.EncodeVarint(uint64(blockBytesSize)) 204 size += blockBytesSize + len(encodedLen) 205 } 206 207 maxFileSie := int(0.75 * float64(size)) 208 env := newTestEnv(t, NewConf(testPath(), maxFileSie)) 209 defer env.Cleanup() 210 ledgerid := "testLedger" 211 blkfileMgrWrapper := newTestBlockfileWrapper(env, ledgerid) 212 blkfileMgrWrapper.addBlocks(blocks[:100]) 213 testutil.AssertEquals(t, blkfileMgrWrapper.blockfileMgr.cpInfo.latestFileChunkSuffixNum, 1) 214 blkfileMgrWrapper.testGetBlockByHash(blocks[:100]) 215 blkfileMgrWrapper.close() 216 217 blkfileMgrWrapper = newTestBlockfileWrapper(env, ledgerid) 218 defer blkfileMgrWrapper.close() 219 blkfileMgrWrapper.addBlocks(blocks[100:]) 220 testutil.AssertEquals(t, blkfileMgrWrapper.blockfileMgr.cpInfo.latestFileChunkSuffixNum, 2) 221 blkfileMgrWrapper.testGetBlockByHash(blocks[100:]) 222 } 223 224 func TestBlockfileMgrGetBlockByTxID(t *testing.T) { 225 env := newTestEnv(t, NewConf(testPath(), 0)) 226 defer env.Cleanup() 227 blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger") 228 defer blkfileMgrWrapper.close() 229 blocks := testutil.ConstructTestBlocks(t, 10) 230 blkfileMgrWrapper.addBlocks(blocks) 231 for _, blk := range blocks { 232 for j := range blk.Data.Data { 233 // blockNum starts with 1 234 txID, err := extractTxID(blk.Data.Data[j]) 235 testutil.AssertNoError(t, err, "") 236 237 blockFromFileMgr, err := blkfileMgrWrapper.blockfileMgr.retrieveBlockByTxID(txID) 238 testutil.AssertNoError(t, err, "Error while retrieving block from blkfileMgr") 239 testutil.AssertEquals(t, blockFromFileMgr, blk) 240 } 241 } 242 }