github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/common/ledger/blkstorage/block_stream_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  	"testing"
    11  
    12  	"github.com/golang/protobuf/proto"
    13  	"github.com/hyperledger/fabric-protos-go/common"
    14  	"github.com/osdi23p228/fabric/common/ledger/testutil"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func TestBlockfileStream(t *testing.T) {
    19  	testBlockfileStream(t, 0)
    20  	testBlockfileStream(t, 1)
    21  	testBlockfileStream(t, 10)
    22  }
    23  
    24  func testBlockfileStream(t *testing.T, numBlocks int) {
    25  	env := newTestEnv(t, NewConf(testPath(), 0))
    26  	defer env.Cleanup()
    27  	ledgerid := "testledger"
    28  	w := newTestBlockfileWrapper(env, ledgerid)
    29  	blocks := testutil.ConstructTestBlocks(t, numBlocks)
    30  	w.addBlocks(blocks)
    31  	w.close()
    32  
    33  	s, err := newBlockfileStream(w.blockfileMgr.rootDir, 0, 0)
    34  	defer s.close()
    35  	require.NoError(t, err, "Error in constructing blockfile stream")
    36  
    37  	blockCount := 0
    38  	for {
    39  		blockBytes, err := s.nextBlockBytes()
    40  		require.NoError(t, err, "Error in getting next block")
    41  		if blockBytes == nil {
    42  			break
    43  		}
    44  		blockCount++
    45  	}
    46  	// After the stream has been exhausted, both blockBytes and err should be nil
    47  	blockBytes, err := s.nextBlockBytes()
    48  	require.Nil(t, blockBytes)
    49  	require.NoError(t, err, "Error in getting next block after exhausting the file")
    50  	require.Equal(t, numBlocks, blockCount)
    51  }
    52  
    53  func TestBlockFileStreamUnexpectedEOF(t *testing.T) {
    54  	partialBlockBytes := []byte{}
    55  	dummyBlockBytes := testutil.ConstructRandomBytes(t, 100)
    56  	lenBytes := proto.EncodeVarint(uint64(len(dummyBlockBytes)))
    57  	partialBlockBytes = append(partialBlockBytes, lenBytes...)
    58  	partialBlockBytes = append(partialBlockBytes, dummyBlockBytes...)
    59  	testBlockFileStreamUnexpectedEOF(t, 10, partialBlockBytes[:1])
    60  	testBlockFileStreamUnexpectedEOF(t, 10, partialBlockBytes[:2])
    61  	testBlockFileStreamUnexpectedEOF(t, 10, partialBlockBytes[:5])
    62  	testBlockFileStreamUnexpectedEOF(t, 10, partialBlockBytes[:20])
    63  }
    64  
    65  func testBlockFileStreamUnexpectedEOF(t *testing.T, numBlocks int, partialBlockBytes []byte) {
    66  	env := newTestEnv(t, NewConf(testPath(), 0))
    67  	defer env.Cleanup()
    68  	w := newTestBlockfileWrapper(env, "testLedger")
    69  	blockfileMgr := w.blockfileMgr
    70  	blocks := testutil.ConstructTestBlocks(t, numBlocks)
    71  	w.addBlocks(blocks)
    72  	blockfileMgr.currentFileWriter.append(partialBlockBytes, true)
    73  	w.close()
    74  	s, err := newBlockfileStream(blockfileMgr.rootDir, 0, 0)
    75  	defer s.close()
    76  	require.NoError(t, err, "Error in constructing blockfile stream")
    77  
    78  	for i := 0; i < numBlocks; i++ {
    79  		blockBytes, err := s.nextBlockBytes()
    80  		require.NotNil(t, blockBytes)
    81  		require.NoError(t, err, "Error in getting next block")
    82  	}
    83  	blockBytes, err := s.nextBlockBytes()
    84  	require.Nil(t, blockBytes)
    85  	require.Exactly(t, ErrUnexpectedEndOfBlockfile, err)
    86  }
    87  
    88  func TestBlockStream(t *testing.T) {
    89  	testBlockStream(t, 1)
    90  	testBlockStream(t, 2)
    91  	testBlockStream(t, 10)
    92  }
    93  
    94  func testBlockStream(t *testing.T, numFiles int) {
    95  	ledgerID := "testLedger"
    96  	env := newTestEnv(t, NewConf(testPath(), 0))
    97  	defer env.Cleanup()
    98  	w := newTestBlockfileWrapper(env, ledgerID)
    99  	defer w.close()
   100  	blockfileMgr := w.blockfileMgr
   101  
   102  	numBlocksInEachFile := 10
   103  	bg, gb := testutil.NewBlockGenerator(t, ledgerID, false)
   104  	w.addBlocks([]*common.Block{gb})
   105  	for i := 0; i < numFiles; i++ {
   106  		numBlocks := numBlocksInEachFile
   107  		if i == 0 {
   108  			// genesis block already added so adding one less block
   109  			numBlocks = numBlocksInEachFile - 1
   110  		}
   111  		blocks := bg.NextTestBlocks(numBlocks)
   112  		w.addBlocks(blocks)
   113  		blockfileMgr.moveToNextFile()
   114  	}
   115  	s, err := newBlockStream(blockfileMgr.rootDir, 0, 0, numFiles-1)
   116  	defer s.close()
   117  	require.NoError(t, err, "Error in constructing new block stream")
   118  	blockCount := 0
   119  	for {
   120  		blockBytes, err := s.nextBlockBytes()
   121  		require.NoError(t, err, "Error in getting next block")
   122  		if blockBytes == nil {
   123  			break
   124  		}
   125  		blockCount++
   126  	}
   127  	// After the stream has been exhausted, both blockBytes and err should be nil
   128  	blockBytes, err := s.nextBlockBytes()
   129  	require.Nil(t, blockBytes)
   130  	require.NoError(t, err, "Error in getting next block after exhausting the file")
   131  	require.Equal(t, numFiles*numBlocksInEachFile, blockCount)
   132  }