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 }