github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/common/ledger/blkstorage/fsblkstorage/blockfile_helper_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package fsblkstorage
     8  
     9  import (
    10  	"io/ioutil"
    11  	"os"
    12  	"testing"
    13  
    14  	"github.com/golang/protobuf/proto"
    15  	"github.com/hyperledger/fabric/common/ledger/testutil"
    16  	"github.com/hyperledger/fabric/common/ledger/util"
    17  	"github.com/stretchr/testify/assert"
    18  )
    19  
    20  func TestConstructCheckpointInfoFromBlockFiles(t *testing.T) {
    21  	testPath := "/tmp/tests/fabric/common/ledger/blkstorage/fsblkstorage"
    22  	ledgerid := "testLedger"
    23  	conf := NewConf(testPath, 0)
    24  	blkStoreDir := conf.getLedgerBlockDir(ledgerid)
    25  	env := newTestEnv(t, conf)
    26  	util.CreateDirIfMissing(blkStoreDir)
    27  	defer env.Cleanup()
    28  
    29  	// checkpoint constructed on an empty block folder should return CPInfo with isChainEmpty: true
    30  	cpInfo, err := constructCheckpointInfoFromBlockFiles(blkStoreDir)
    31  	assert.NoError(t, err)
    32  	assert.Equal(t, &checkpointInfo{isChainEmpty: true, lastBlockNumber: 0, latestFileChunksize: 0, latestFileChunkSuffixNum: 0}, cpInfo)
    33  
    34  	w := newTestBlockfileWrapper(env, ledgerid)
    35  	defer w.close()
    36  	blockfileMgr := w.blockfileMgr
    37  	bg, gb := testutil.NewBlockGenerator(t, ledgerid, false)
    38  
    39  	// Add a few blocks and verify that cpinfo derived from filesystem should be same as from the blockfile manager
    40  	blockfileMgr.addBlock(gb)
    41  	for _, blk := range bg.NextTestBlocks(3) {
    42  		blockfileMgr.addBlock(blk)
    43  	}
    44  	checkCPInfoFromFile(t, blkStoreDir, blockfileMgr.cpInfo)
    45  
    46  	// Move the chain to new file and check cpinfo derived from file system
    47  	blockfileMgr.moveToNextFile()
    48  	checkCPInfoFromFile(t, blkStoreDir, blockfileMgr.cpInfo)
    49  
    50  	// Add a few blocks that would go to new file and verify that cpinfo derived from filesystem should be same as from the blockfile manager
    51  	for _, blk := range bg.NextTestBlocks(3) {
    52  		blockfileMgr.addBlock(blk)
    53  	}
    54  	checkCPInfoFromFile(t, blkStoreDir, blockfileMgr.cpInfo)
    55  
    56  	// Write a partial block (to simulate a crash) and verify that cpinfo derived from filesystem should be same as from the blockfile manager
    57  	lastTestBlk := bg.NextTestBlocks(1)[0]
    58  	blockBytes, _, err := serializeBlock(lastTestBlk)
    59  	assert.NoError(t, err)
    60  	partialByte := append(proto.EncodeVarint(uint64(len(blockBytes))), blockBytes[len(blockBytes)/2:]...)
    61  	blockfileMgr.currentFileWriter.append(partialByte, true)
    62  	checkCPInfoFromFile(t, blkStoreDir, blockfileMgr.cpInfo)
    63  
    64  	// Close the block storage, drop the index and restart and verify
    65  	cpInfoBeforeClose := blockfileMgr.cpInfo
    66  	w.close()
    67  	env.provider.Close()
    68  	indexFolder := conf.getIndexDir()
    69  	assert.NoError(t, os.RemoveAll(indexFolder))
    70  
    71  	env = newTestEnv(t, conf)
    72  	w = newTestBlockfileWrapper(env, ledgerid)
    73  	blockfileMgr = w.blockfileMgr
    74  	assert.Equal(t, cpInfoBeforeClose, blockfileMgr.cpInfo)
    75  
    76  	lastBlkIndexed, err := blockfileMgr.index.getLastBlockIndexed()
    77  	assert.NoError(t, err)
    78  	assert.Equal(t, uint64(6), lastBlkIndexed)
    79  
    80  	// Add the last block again after start and check cpinfo again
    81  	assert.NoError(t, blockfileMgr.addBlock(lastTestBlk))
    82  	checkCPInfoFromFile(t, blkStoreDir, blockfileMgr.cpInfo)
    83  }
    84  
    85  func TestBinarySearchBlockFileNum(t *testing.T) {
    86  	blockStoreRootDir := testPath()
    87  	blocks := testutil.ConstructTestBlocks(t, 100)
    88  	maxFileSie := int(0.1 * float64(testutilEstimateTotalSizeOnDisk(t, blocks)))
    89  	env := newTestEnv(t, NewConf(blockStoreRootDir, maxFileSie))
    90  	defer env.Cleanup()
    91  	blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger")
    92  	blkfileMgr := blkfileMgrWrapper.blockfileMgr
    93  
    94  	blkfileMgrWrapper.addBlocks(blocks)
    95  
    96  	ledgerDir := (&Conf{blockStorageDir: blockStoreRootDir}).getLedgerBlockDir("testLedger")
    97  	files, err := ioutil.ReadDir(ledgerDir)
    98  	assert.NoError(t, err)
    99  	assert.Len(t, files, 11)
   100  
   101  	for i := uint64(0); i < 100; i++ {
   102  		fileNum, err := binarySearchFileNumForBlock(ledgerDir, i)
   103  		assert.NoError(t, err)
   104  		locFromIndex, err := blkfileMgr.index.getBlockLocByBlockNum(i)
   105  		assert.NoError(t, err)
   106  		expectedFileNum := locFromIndex.fileSuffixNum
   107  		assert.Equal(t, expectedFileNum, fileNum)
   108  	}
   109  }
   110  
   111  func checkCPInfoFromFile(t *testing.T, blkStoreDir string, expectedCPInfo *checkpointInfo) {
   112  	cpInfo, err := constructCheckpointInfoFromBlockFiles(blkStoreDir)
   113  	assert.NoError(t, err)
   114  	assert.Equal(t, expectedCPInfo, cpInfo)
   115  }