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