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 }