github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/common/ledger/blkstorage/fsblkstorage/blocks_itr_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  	"sync"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/hyperledger/fabric/common/ledger/testutil"
    25  	"github.com/hyperledger/fabric/protos/common"
    26  )
    27  
    28  func TestBlocksItrBlockingNext(t *testing.T) {
    29  	env := newTestEnv(t, NewConf(testPath(), 0))
    30  	defer env.Cleanup()
    31  	blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger")
    32  	defer blkfileMgrWrapper.close()
    33  	blkfileMgr := blkfileMgrWrapper.blockfileMgr
    34  
    35  	blocks := testutil.ConstructTestBlocks(t, 10)
    36  	blkfileMgrWrapper.addBlocks(blocks[:5])
    37  
    38  	itr, err := blkfileMgr.retrieveBlocks(1)
    39  	defer itr.Close()
    40  	testutil.AssertNoError(t, err, "")
    41  	doneChan := make(chan bool)
    42  	go testIterateAndVerify(t, itr, blocks[1:], doneChan)
    43  	for {
    44  		if itr.blockNumToRetrieve == 5 {
    45  			break
    46  		}
    47  		time.Sleep(time.Millisecond * 10)
    48  	}
    49  	testAppendBlocks(blkfileMgrWrapper, blocks[5:7])
    50  	blkfileMgr.moveToNextFile()
    51  	time.Sleep(time.Millisecond * 10)
    52  	testAppendBlocks(blkfileMgrWrapper, blocks[7:])
    53  	<-doneChan
    54  }
    55  
    56  func TestBlockItrClose(t *testing.T) {
    57  	env := newTestEnv(t, NewConf(testPath(), 0))
    58  	defer env.Cleanup()
    59  	blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger")
    60  	defer blkfileMgrWrapper.close()
    61  	blkfileMgr := blkfileMgrWrapper.blockfileMgr
    62  
    63  	blocks := testutil.ConstructTestBlocks(t, 5)
    64  	blkfileMgrWrapper.addBlocks(blocks)
    65  
    66  	itr, err := blkfileMgr.retrieveBlocks(1)
    67  	testutil.AssertNoError(t, err, "")
    68  
    69  	bh, _ := itr.Next()
    70  	testutil.AssertNotNil(t, bh)
    71  	itr.Close()
    72  
    73  	bh, err = itr.Next()
    74  	testutil.AssertNoError(t, err, "")
    75  	testutil.AssertNil(t, bh)
    76  }
    77  
    78  func TestBlockItrCloseWithoutRetrieve(t *testing.T) {
    79  	env := newTestEnv(t, NewConf(testPath(), 0))
    80  	defer env.Cleanup()
    81  	blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger")
    82  	defer blkfileMgrWrapper.close()
    83  	blkfileMgr := blkfileMgrWrapper.blockfileMgr
    84  	blocks := testutil.ConstructTestBlocks(t, 5)
    85  	blkfileMgrWrapper.addBlocks(blocks)
    86  
    87  	itr, err := blkfileMgr.retrieveBlocks(2)
    88  	testutil.AssertNoError(t, err, "")
    89  	itr.Close()
    90  }
    91  
    92  func TestCloseMultipleItrsWaitForFutureBlock(t *testing.T) {
    93  	env := newTestEnv(t, NewConf(testPath(), 0))
    94  	defer env.Cleanup()
    95  	blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger")
    96  	defer blkfileMgrWrapper.close()
    97  	blkfileMgr := blkfileMgrWrapper.blockfileMgr
    98  	blocks := testutil.ConstructTestBlocks(t, 10)
    99  	blkfileMgrWrapper.addBlocks(blocks[:5])
   100  
   101  	wg := &sync.WaitGroup{}
   102  	wg.Add(2)
   103  	itr1, err := blkfileMgr.retrieveBlocks(7)
   104  	testutil.AssertNoError(t, err, "")
   105  	// itr1 does not retrieve any block because it closes before new blocks are added
   106  	go iterateInBackground(t, itr1, 9, wg, []uint64{})
   107  
   108  	itr2, err := blkfileMgr.retrieveBlocks(8)
   109  	testutil.AssertNoError(t, err, "")
   110  	// itr2 retrieves two blocks 8 and 9. Because it started waiting for 8 and quits at 9
   111  	go iterateInBackground(t, itr2, 9, wg, []uint64{8, 9})
   112  
   113  	// sleep for the background iterators to get started
   114  	time.Sleep(2 * time.Second)
   115  	itr1.Close()
   116  	blkfileMgrWrapper.addBlocks(blocks[5:])
   117  	wg.Wait()
   118  }
   119  
   120  func iterateInBackground(t *testing.T, itr *blocksItr, quitAfterBlkNum uint64, wg *sync.WaitGroup, expectedBlockNums []uint64) {
   121  	defer wg.Done()
   122  	retrievedBlkNums := []uint64{}
   123  	defer func() { testutil.AssertEquals(t, retrievedBlkNums, expectedBlockNums) }()
   124  
   125  	for {
   126  		blk, err := itr.Next()
   127  		testutil.AssertNoError(t, err, "")
   128  		if blk == nil {
   129  			return
   130  		}
   131  		blkNum := blk.(*common.Block).Header.Number
   132  		retrievedBlkNums = append(retrievedBlkNums, blkNum)
   133  		t.Logf("blk.Num=%d", blk.(*common.Block).Header.Number)
   134  		if blkNum == quitAfterBlkNum {
   135  			return
   136  		}
   137  	}
   138  }
   139  
   140  func testIterateAndVerify(t *testing.T, itr *blocksItr, blocks []*common.Block, doneChan chan bool) {
   141  	blocksIterated := 0
   142  	for {
   143  		t.Logf("blocksIterated: %v", blocksIterated)
   144  		block, err := itr.Next()
   145  		testutil.AssertNoError(t, err, "")
   146  		testutil.AssertEquals(t, block, blocks[blocksIterated])
   147  		blocksIterated++
   148  		if blocksIterated == len(blocks) {
   149  			break
   150  		}
   151  	}
   152  	doneChan <- true
   153  }
   154  
   155  func testAppendBlocks(blkfileMgrWrapper *testBlockfileMgrWrapper, blocks []*common.Block) {
   156  	blkfileMgrWrapper.addBlocks(blocks)
   157  }