github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/common/ledger/blkstorage/pkg_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  	"io/ioutil"
    11  	"math"
    12  	"os"
    13  	"testing"
    14  
    15  	"github.com/golang/protobuf/proto"
    16  	"github.com/hyperledger/fabric-protos-go/common"
    17  	"github.com/hyperledger/fabric-protos-go/peer"
    18  	"github.com/osdi23p228/fabric/common/flogging"
    19  	"github.com/osdi23p228/fabric/common/metrics"
    20  	"github.com/osdi23p228/fabric/common/metrics/disabled"
    21  	"github.com/osdi23p228/fabric/protoutil"
    22  	"github.com/stretchr/testify/assert"
    23  	"github.com/stretchr/testify/require"
    24  )
    25  
    26  func TestMain(m *testing.M) {
    27  	flogging.ActivateSpec("blkstorage=debug")
    28  	os.Exit(m.Run())
    29  }
    30  
    31  func testPath() string {
    32  	if path, err := ioutil.TempDir("", "blkstorage-"); err != nil {
    33  		panic(err)
    34  	} else {
    35  		return path
    36  	}
    37  }
    38  
    39  type testEnv struct {
    40  	t        testing.TB
    41  	provider *BlockStoreProvider
    42  }
    43  
    44  var attrsToIndex = []IndexableAttr{
    45  	IndexableAttrBlockHash,
    46  	IndexableAttrBlockNum,
    47  	IndexableAttrTxID,
    48  	IndexableAttrBlockNumTranNum,
    49  }
    50  
    51  func newTestEnv(t testing.TB, conf *Conf) *testEnv {
    52  	return newTestEnvWithMetricsProvider(t, conf, &disabled.Provider{})
    53  }
    54  
    55  func newTestEnvWithMetricsProvider(t testing.TB, conf *Conf, metricsProvider metrics.Provider) *testEnv {
    56  	return newTestEnvSelectiveIndexing(t, conf, attrsToIndex, metricsProvider)
    57  }
    58  
    59  func newTestEnvSelectiveIndexing(t testing.TB, conf *Conf, attrsToIndex []IndexableAttr, metricsProvider metrics.Provider) *testEnv {
    60  	indexConfig := &IndexConfig{AttrsToIndex: attrsToIndex}
    61  	p, err := NewProvider(conf, indexConfig, metricsProvider)
    62  	assert.NoError(t, err)
    63  	return &testEnv{t, p}
    64  }
    65  
    66  func (env *testEnv) Cleanup() {
    67  	env.provider.Close()
    68  	env.removeFSPath()
    69  }
    70  
    71  func (env *testEnv) removeFSPath() {
    72  	fsPath := env.provider.conf.blockStorageDir
    73  	os.RemoveAll(fsPath)
    74  }
    75  
    76  type testBlockfileMgrWrapper struct {
    77  	t            testing.TB
    78  	blockfileMgr *blockfileMgr
    79  }
    80  
    81  func newTestBlockfileWrapper(env *testEnv, ledgerid string) *testBlockfileMgrWrapper {
    82  	blkStore, err := env.provider.Open(ledgerid)
    83  	assert.NoError(env.t, err)
    84  	return &testBlockfileMgrWrapper{env.t, blkStore.fileMgr}
    85  }
    86  
    87  func (w *testBlockfileMgrWrapper) addBlocks(blocks []*common.Block) {
    88  	for _, blk := range blocks {
    89  		err := w.blockfileMgr.addBlock(blk)
    90  		assert.NoError(w.t, err, "Error while adding block to blockfileMgr")
    91  	}
    92  }
    93  
    94  func (w *testBlockfileMgrWrapper) testGetBlockByHash(blocks []*common.Block, expectedErr error) {
    95  	for i, block := range blocks {
    96  		hash := protoutil.BlockHeaderHash(block.Header)
    97  		b, err := w.blockfileMgr.retrieveBlockByHash(hash)
    98  		if expectedErr != nil {
    99  			assert.Error(w.t, err, expectedErr.Error())
   100  			continue
   101  		}
   102  		assert.NoError(w.t, err, "Error while retrieving [%d]th block from blockfileMgr", i)
   103  		assert.Equal(w.t, block, b)
   104  	}
   105  }
   106  
   107  func (w *testBlockfileMgrWrapper) testGetBlockByNumber(blocks []*common.Block, startingNum uint64, expectedErr error) {
   108  	for i := 0; i < len(blocks); i++ {
   109  		b, err := w.blockfileMgr.retrieveBlockByNumber(startingNum + uint64(i))
   110  		if expectedErr != nil {
   111  			assert.Equal(w.t, err.Error(), expectedErr.Error())
   112  			continue
   113  		}
   114  		assert.NoError(w.t, err, "Error while retrieving [%d]th block from blockfileMgr", i)
   115  		assert.Equal(w.t, blocks[i], b)
   116  	}
   117  	// test getting the last block
   118  	b, err := w.blockfileMgr.retrieveBlockByNumber(math.MaxUint64)
   119  	iLastBlock := len(blocks) - 1
   120  	assert.NoError(w.t, err, "Error while retrieving last block from blockfileMgr")
   121  	assert.Equal(w.t, blocks[iLastBlock], b)
   122  }
   123  
   124  func (w *testBlockfileMgrWrapper) testGetBlockByTxID(blocks []*common.Block, expectedErr error) {
   125  	for i, block := range blocks {
   126  		for _, txEnv := range block.Data.Data {
   127  			txID, err := protoutil.GetOrComputeTxIDFromEnvelope(txEnv)
   128  			assert.NoError(w.t, err)
   129  			b, err := w.blockfileMgr.retrieveBlockByTxID(txID)
   130  			if expectedErr != nil {
   131  				assert.Equal(w.t, err.Error(), expectedErr.Error())
   132  				continue
   133  			}
   134  			assert.NoError(w.t, err, "Error while retrieving [%d]th block from blockfileMgr", i)
   135  			assert.Equal(w.t, block, b)
   136  		}
   137  	}
   138  }
   139  
   140  func (w *testBlockfileMgrWrapper) testGetTransactionByTxID(txID string, expectedEnvelope []byte, expectedErr error) {
   141  	envelope, err := w.blockfileMgr.retrieveTransactionByID(txID)
   142  	if expectedErr != nil {
   143  		assert.Equal(w.t, err.Error(), expectedErr.Error())
   144  		return
   145  	}
   146  	actualEnvelope, err := proto.Marshal(envelope)
   147  	assert.NoError(w.t, err)
   148  	assert.Equal(w.t, expectedEnvelope, actualEnvelope)
   149  }
   150  
   151  func (w *testBlockfileMgrWrapper) testGetMultipleDataByTxID(
   152  	txID string,
   153  	expectedData []*expectedBlkTxValidationCode,
   154  ) {
   155  	rangescan := constructTxIDRangeScan(txID)
   156  	itr, err := w.blockfileMgr.db.GetIterator(rangescan.startKey, rangescan.stopKey)
   157  	require := require.New(w.t)
   158  	require.NoError(err)
   159  	defer itr.Release()
   160  
   161  	fetchedData := []*expectedBlkTxValidationCode{}
   162  	for itr.Next() {
   163  		v := &TxIDIndexValue{}
   164  		require.NoError(proto.Unmarshal(itr.Value(), v))
   165  
   166  		blkFLP := &fileLocPointer{}
   167  		require.NoError(blkFLP.unmarshal(v.BlkLocation))
   168  		blk, err := w.blockfileMgr.fetchBlock(blkFLP)
   169  		require.NoError(err)
   170  
   171  		txFLP := &fileLocPointer{}
   172  		require.NoError(txFLP.unmarshal(v.TxLocation))
   173  		txEnv, err := w.blockfileMgr.fetchTransactionEnvelope(txFLP)
   174  		require.NoError(err)
   175  
   176  		fetchedData = append(fetchedData, &expectedBlkTxValidationCode{
   177  			blk:            blk,
   178  			txEnv:          txEnv,
   179  			validationCode: peer.TxValidationCode(v.TxValidationCode),
   180  		})
   181  	}
   182  	require.Equal(expectedData, fetchedData)
   183  }
   184  
   185  func (w *testBlockfileMgrWrapper) close() {
   186  	w.blockfileMgr.close()
   187  }
   188  
   189  type expectedBlkTxValidationCode struct {
   190  	blk            *common.Block
   191  	txEnv          *common.Envelope
   192  	validationCode peer.TxValidationCode
   193  }