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