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

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package fsblkstorage
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"testing"
    13  
    14  	"github.com/hyperledger/fabric-protos-go/common"
    15  	"github.com/hyperledger/fabric-protos-go/peer"
    16  	"github.com/hyperledger/fabric/common/ledger/blkstorage"
    17  	"github.com/hyperledger/fabric/common/ledger/testutil"
    18  	"github.com/hyperledger/fabric/core/ledger/util"
    19  	"github.com/hyperledger/fabric/protoutil"
    20  	"github.com/stretchr/testify/assert"
    21  	"github.com/stretchr/testify/require"
    22  )
    23  
    24  func TestMultipleBlockStores(t *testing.T) {
    25  	tempdir := testPath()
    26  	defer os.RemoveAll(tempdir)
    27  
    28  	env := newTestEnv(t, NewConf(tempdir, 0))
    29  	provider := env.provider
    30  	defer provider.Close()
    31  
    32  	subdirs, err := provider.List()
    33  	require.NoError(t, err)
    34  	require.Empty(t, subdirs)
    35  
    36  	store1, err := provider.OpenBlockStore("ledger1")
    37  	require.NoError(t, err)
    38  	defer store1.Shutdown()
    39  	store2, err := provider.CreateBlockStore("ledger2")
    40  	require.NoError(t, err)
    41  	defer store2.Shutdown()
    42  
    43  	blocks1 := testutil.ConstructTestBlocks(t, 5)
    44  	for _, b := range blocks1 {
    45  		err := store1.AddBlock(b)
    46  		require.NoError(t, err)
    47  	}
    48  
    49  	blocks2 := testutil.ConstructTestBlocks(t, 10)
    50  	for _, b := range blocks2 {
    51  		err := store2.AddBlock(b)
    52  		require.NoError(t, err)
    53  	}
    54  	checkBlocks(t, blocks1, store1)
    55  	checkBlocks(t, blocks2, store2)
    56  	checkWithWrongInputs(t, store1, 5)
    57  	checkWithWrongInputs(t, store2, 10)
    58  
    59  	store1.Shutdown()
    60  	store2.Shutdown()
    61  	provider.Close()
    62  
    63  	// Reopen provider
    64  	newenv := newTestEnv(t, NewConf(tempdir, 0))
    65  	newprovider := newenv.provider
    66  	defer newprovider.Close()
    67  
    68  	subdirs, err = newprovider.List()
    69  	require.NoError(t, err)
    70  	require.Len(t, subdirs, 2)
    71  
    72  	newstore1, err := newprovider.OpenBlockStore("ledger1")
    73  	require.NoError(t, err)
    74  	defer newstore1.Shutdown()
    75  	newstore2, err := newprovider.CreateBlockStore("ledger2")
    76  	require.NoError(t, err)
    77  	defer newstore2.Shutdown()
    78  
    79  	checkBlocks(t, blocks1, newstore1)
    80  	checkBlocks(t, blocks2, newstore2)
    81  	checkWithWrongInputs(t, newstore1, 5)
    82  	checkWithWrongInputs(t, newstore2, 10)
    83  }
    84  
    85  func checkBlocks(t *testing.T, expectedBlocks []*common.Block, store blkstorage.BlockStore) {
    86  	bcInfo, _ := store.GetBlockchainInfo()
    87  	assert.Equal(t, uint64(len(expectedBlocks)), bcInfo.Height)
    88  	assert.Equal(t, protoutil.BlockHeaderHash(expectedBlocks[len(expectedBlocks)-1].GetHeader()), bcInfo.CurrentBlockHash)
    89  
    90  	itr, _ := store.RetrieveBlocks(0)
    91  	for i := 0; i < len(expectedBlocks); i++ {
    92  		block, _ := itr.Next()
    93  		assert.Equal(t, expectedBlocks[i], block)
    94  	}
    95  
    96  	for blockNum := 0; blockNum < len(expectedBlocks); blockNum++ {
    97  		block := expectedBlocks[blockNum]
    98  		flags := util.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
    99  		retrievedBlock, _ := store.RetrieveBlockByNumber(uint64(blockNum))
   100  		assert.Equal(t, block, retrievedBlock)
   101  
   102  		retrievedBlock, _ = store.RetrieveBlockByHash(protoutil.BlockHeaderHash(block.Header))
   103  		assert.Equal(t, block, retrievedBlock)
   104  
   105  		for txNum := 0; txNum < len(block.Data.Data); txNum++ {
   106  			txEnvBytes := block.Data.Data[txNum]
   107  			txEnv, _ := protoutil.GetEnvelopeFromBlock(txEnvBytes)
   108  			txid, err := protoutil.GetOrComputeTxIDFromEnvelope(txEnvBytes)
   109  			assert.NoError(t, err)
   110  
   111  			retrievedBlock, _ := store.RetrieveBlockByTxID(txid)
   112  			assert.Equal(t, block, retrievedBlock)
   113  
   114  			retrievedTxEnv, _ := store.RetrieveTxByID(txid)
   115  			assert.Equal(t, txEnv, retrievedTxEnv)
   116  
   117  			retrievedTxEnv, _ = store.RetrieveTxByBlockNumTranNum(uint64(blockNum), uint64(txNum))
   118  			assert.Equal(t, txEnv, retrievedTxEnv)
   119  
   120  			retrievedTxValCode, err := store.RetrieveTxValidationCodeByTxID(txid)
   121  			assert.NoError(t, err)
   122  			assert.Equal(t, flags.Flag(txNum), retrievedTxValCode)
   123  		}
   124  	}
   125  }
   126  
   127  func checkWithWrongInputs(t *testing.T, store blkstorage.BlockStore, numBlocks int) {
   128  	block, err := store.RetrieveBlockByHash([]byte("non-existent-hash"))
   129  	assert.Nil(t, block)
   130  	assert.Equal(t, blkstorage.ErrNotFoundInIndex, err)
   131  
   132  	block, err = store.RetrieveBlockByTxID("non-existent-txid")
   133  	assert.Nil(t, block)
   134  	assert.Equal(t, blkstorage.ErrNotFoundInIndex, err)
   135  
   136  	tx, err := store.RetrieveTxByID("non-existent-txid")
   137  	assert.Nil(t, tx)
   138  	assert.Equal(t, blkstorage.ErrNotFoundInIndex, err)
   139  
   140  	tx, err = store.RetrieveTxByBlockNumTranNum(uint64(numBlocks+1), uint64(0))
   141  	assert.Nil(t, tx)
   142  	assert.Equal(t, blkstorage.ErrNotFoundInIndex, err)
   143  
   144  	txCode, err := store.RetrieveTxValidationCodeByTxID("non-existent-txid")
   145  	assert.Equal(t, peer.TxValidationCode(-1), txCode)
   146  	assert.Equal(t, blkstorage.ErrNotFoundInIndex, err)
   147  }
   148  
   149  func TestBlockStoreProvider(t *testing.T) {
   150  	env := newTestEnv(t, NewConf(testPath(), 0))
   151  	defer env.Cleanup()
   152  
   153  	provider := env.provider
   154  	storeNames, err := provider.List()
   155  	assert.NoError(t, err)
   156  	assert.Empty(t, storeNames)
   157  
   158  	var stores []blkstorage.BlockStore
   159  	numStores := 10
   160  	for i := 0; i < numStores; i++ {
   161  		store, _ := provider.OpenBlockStore(constructLedgerid(i))
   162  		defer store.Shutdown()
   163  		stores = append(stores, store)
   164  	}
   165  	assert.Equal(t, numStores, len(stores))
   166  
   167  	storeNames, err = provider.List()
   168  	assert.NoError(t, err)
   169  	assert.Equal(t, numStores, len(storeNames))
   170  
   171  	for i := 0; i < numStores; i++ {
   172  		exists, err := provider.Exists(constructLedgerid(i))
   173  		assert.NoError(t, err)
   174  		assert.Equal(t, true, exists)
   175  	}
   176  
   177  	exists, err := provider.Exists(constructLedgerid(numStores + 1))
   178  	assert.NoError(t, err)
   179  	assert.Equal(t, false, exists)
   180  
   181  }
   182  
   183  func constructLedgerid(id int) string {
   184  	return fmt.Sprintf("ledger_%d", id)
   185  }