github.com/defanghe/fabric@v2.1.1+incompatible/core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr/pkg_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package lockbasedtxmgr 8 9 import ( 10 "fmt" 11 "os" 12 "testing" 13 14 "github.com/golang/protobuf/proto" 15 "github.com/hyperledger/fabric-protos-go/common" 16 "github.com/hyperledger/fabric-protos-go/ledger/queryresult" 17 "github.com/hyperledger/fabric-protos-go/ledger/rwset" 18 "github.com/hyperledger/fabric-protos-go/peer" 19 "github.com/hyperledger/fabric/bccsp/sw" 20 "github.com/hyperledger/fabric/common/flogging" 21 "github.com/hyperledger/fabric/common/ledger/testutil" 22 "github.com/hyperledger/fabric/core/ledger" 23 "github.com/hyperledger/fabric/core/ledger/kvledger/bookkeeping" 24 "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/privacyenabledstate" 25 "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/txmgr" 26 "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/version" 27 "github.com/hyperledger/fabric/core/ledger/mock" 28 "github.com/hyperledger/fabric/core/ledger/pvtdatapolicy" 29 btltestutil "github.com/hyperledger/fabric/core/ledger/pvtdatapolicy/testutil" 30 "github.com/hyperledger/fabric/core/ledger/util" 31 "github.com/stretchr/testify/assert" 32 ) 33 34 func TestMain(m *testing.M) { 35 flogging.ActivateSpec( 36 "lockbasedtxmgr,statevalidator,statebasedval,statecouchdb,valimpl,pvtstatepurgemgmt,valinternal=debug", 37 ) 38 exitCode := m.Run() 39 for _, testEnv := range testEnvs { 40 testEnv.stopExternalResource() 41 } 42 os.Exit(exitCode) 43 } 44 45 type testEnv interface { 46 cleanup() 47 getName() string 48 getTxMgr() txmgr.TxMgr 49 getVDB() privacyenabledstate.DB 50 init(t *testing.T, testLedgerID string, btlPolicy pvtdatapolicy.BTLPolicy) 51 stopExternalResource() 52 } 53 54 const ( 55 levelDBtestEnvName = "levelDB_LockBasedTxMgr" 56 couchDBtestEnvName = "couchDB_LockBasedTxMgr" 57 ) 58 59 // Tests will be run against each environment in this array 60 // For example, to skip CouchDB tests, remove the entry for couch environment 61 var testEnvs = []testEnv{ 62 &lockBasedEnv{name: levelDBtestEnvName, testDBEnv: &privacyenabledstate.LevelDBCommonStorageTestEnv{}}, 63 &lockBasedEnv{name: couchDBtestEnvName, testDBEnv: &privacyenabledstate.CouchDBCommonStorageTestEnv{}}, 64 } 65 66 var testEnvsMap = map[string]testEnv{ 67 levelDBtestEnvName: testEnvs[0], 68 couchDBtestEnvName: testEnvs[1], 69 } 70 71 ///////////// LevelDB Environment ////////////// 72 73 type lockBasedEnv struct { 74 dbInitialized bool 75 name string 76 t testing.TB 77 testBookkeepingEnv *bookkeeping.TestEnv 78 testDB privacyenabledstate.DB 79 testDBEnv privacyenabledstate.TestEnv 80 txmgr txmgr.TxMgr 81 } 82 83 func (env *lockBasedEnv) getName() string { 84 return env.name 85 } 86 87 func (env *lockBasedEnv) init(t *testing.T, testLedgerID string, btlPolicy pvtdatapolicy.BTLPolicy) { 88 var err error 89 env.t = t 90 if env.dbInitialized == false { 91 env.testDBEnv.Init(t) 92 env.dbInitialized = true 93 } 94 env.testDB = env.testDBEnv.GetDBHandle(testLedgerID) 95 assert.NoError(t, err) 96 if btlPolicy == nil { 97 btlPolicy = btltestutil.SampleBTLPolicy( 98 map[[2]string]uint64{}, 99 ) 100 } 101 env.testBookkeepingEnv = bookkeeping.NewTestEnv(t) 102 103 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 104 assert.NoError(t, err) 105 env.txmgr, err = NewLockBasedTxMgr( 106 testLedgerID, env.testDB, nil, 107 btlPolicy, env.testBookkeepingEnv.TestProvider, 108 &mock.DeployedChaincodeInfoProvider{}, 109 nil, 110 cryptoProvider, 111 ) 112 assert.NoError(t, err) 113 114 } 115 116 func (env *lockBasedEnv) getTxMgr() txmgr.TxMgr { 117 return env.txmgr 118 } 119 120 func (env *lockBasedEnv) getVDB() privacyenabledstate.DB { 121 return env.testDB 122 } 123 124 func (env *lockBasedEnv) cleanup() { 125 if env.dbInitialized { 126 env.txmgr.Shutdown() 127 env.testDBEnv.Cleanup() 128 env.testBookkeepingEnv.Cleanup() 129 env.dbInitialized = false 130 } 131 } 132 133 func (env *lockBasedEnv) stopExternalResource() { 134 env.testDBEnv.StopExternalResource() 135 } 136 137 //////////// txMgrTestHelper ///////////// 138 139 type txMgrTestHelper struct { 140 t *testing.T 141 txMgr txmgr.TxMgr 142 bg *testutil.BlockGenerator 143 } 144 145 func newTxMgrTestHelper(t *testing.T, txMgr txmgr.TxMgr) *txMgrTestHelper { 146 bg, _ := testutil.NewBlockGenerator(t, "testLedger", false) 147 return &txMgrTestHelper{t, txMgr, bg} 148 } 149 150 func (h *txMgrTestHelper) validateAndCommitRWSet(txRWSet *rwset.TxReadWriteSet) { 151 rwSetBytes, _ := proto.Marshal(txRWSet) 152 block := h.bg.NextBlock([][]byte{rwSetBytes}) 153 _, _, err := h.txMgr.ValidateAndPrepare(&ledger.BlockAndPvtData{Block: block, PvtData: nil}, true) 154 assert.NoError(h.t, err) 155 txsFltr := util.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) 156 invalidTxNum := 0 157 for i := 0; i < len(block.Data.Data); i++ { 158 if txsFltr.IsInvalid(i) { 159 invalidTxNum++ 160 } 161 } 162 assert.Equal(h.t, 0, invalidTxNum) 163 err = h.txMgr.Commit() 164 assert.NoError(h.t, err) 165 } 166 167 func (h *txMgrTestHelper) checkRWsetInvalid(txRWSet *rwset.TxReadWriteSet) { 168 rwSetBytes, _ := proto.Marshal(txRWSet) 169 block := h.bg.NextBlock([][]byte{rwSetBytes}) 170 _, _, err := h.txMgr.ValidateAndPrepare(&ledger.BlockAndPvtData{Block: block, PvtData: nil}, true) 171 assert.NoError(h.t, err) 172 txsFltr := util.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) 173 invalidTxNum := 0 174 for i := 0; i < len(block.Data.Data); i++ { 175 if txsFltr.IsInvalid(i) { 176 invalidTxNum++ 177 } 178 } 179 assert.Equal(h.t, 1, invalidTxNum) 180 } 181 182 func populateCollConfigForTest(t *testing.T, txMgr *LockBasedTxMgr, nsColls []collConfigkey, ht *version.Height) { 183 m := map[string]*peer.CollectionConfigPackage{} 184 for _, nsColl := range nsColls { 185 ns, coll := nsColl.ns, nsColl.coll 186 pkg, ok := m[ns] 187 if !ok { 188 pkg = &peer.CollectionConfigPackage{} 189 m[ns] = pkg 190 } 191 sCollConfig := &peer.CollectionConfig_StaticCollectionConfig{ 192 StaticCollectionConfig: &peer.StaticCollectionConfig{ 193 Name: coll, 194 }, 195 } 196 pkg.Config = append(pkg.Config, &peer.CollectionConfig{Payload: sCollConfig}) 197 } 198 ccInfoProvider := &mock.DeployedChaincodeInfoProvider{} 199 ccInfoProvider.AllCollectionsConfigPkgStub = func(channelName, ccName string, qe ledger.SimpleQueryExecutor) (*peer.CollectionConfigPackage, error) { 200 fmt.Printf("retrieveing info for [%s] from [%s]\n", ccName, m) 201 return m[ccName], nil 202 } 203 txMgr.ccInfoProvider = ccInfoProvider 204 } 205 206 func testutilPopulateDB( 207 t *testing.T, txMgr *LockBasedTxMgr, ns string, 208 data []*queryresult.KV, pvtdataHashes []*testutilPvtdata, 209 version *version.Height, 210 ) { 211 updates := privacyenabledstate.NewUpdateBatch() 212 for _, kv := range data { 213 updates.PubUpdates.Put(ns, kv.Key, kv.Value, version) 214 } 215 for _, p := range pvtdataHashes { 216 updates.HashUpdates.Put(ns, p.coll, util.ComputeStringHash(p.key), util.ComputeHash(p.value), version) 217 } 218 txMgr.db.ApplyPrivacyAwareUpdates(updates, version) 219 } 220 221 type testutilPvtdata struct { 222 coll, key string 223 value []byte 224 }