github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/kvledger/txmgmt/txmgr/pkg_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package txmgr 8 9 import ( 10 "fmt" 11 "os" 12 "testing" 13 14 "github.com/golang/protobuf/proto" 15 "github.com/hechain20/hechain/common/flogging" 16 "github.com/hechain20/hechain/common/ledger/testutil" 17 "github.com/hechain20/hechain/core/ledger" 18 "github.com/hechain20/hechain/core/ledger/internal/version" 19 "github.com/hechain20/hechain/core/ledger/kvledger/bookkeeping" 20 "github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/privacyenabledstate" 21 "github.com/hechain20/hechain/core/ledger/mock" 22 "github.com/hechain20/hechain/core/ledger/pvtdatapolicy" 23 btltestutil "github.com/hechain20/hechain/core/ledger/pvtdatapolicy/testutil" 24 "github.com/hechain20/hechain/core/ledger/util" 25 "github.com/hechain20/hechain/internal/pkg/txflags" 26 "github.com/hyperledger/fabric-protos-go/common" 27 "github.com/hyperledger/fabric-protos-go/ledger/queryresult" 28 "github.com/hyperledger/fabric-protos-go/ledger/rwset" 29 "github.com/hyperledger/fabric-protos-go/peer" 30 "github.com/stretchr/testify/require" 31 ) 32 33 func TestMain(m *testing.M) { 34 flogging.ActivateSpec( 35 "lockbasedtxmgr,statevalidator,statebasedval,statecouchdb,valimpl,pvtstatepurgemgmt,valinternal=debug", 36 ) 37 exitCode := m.Run() 38 for _, testEnv := range testEnvs { 39 testEnv.stopExternalResource() 40 } 41 os.Exit(exitCode) 42 } 43 44 type testEnv interface { 45 cleanup() 46 getName() string 47 getTxMgr() *LockBasedTxMgr 48 getVDB() *privacyenabledstate.DB 49 init(t *testing.T, testLedgerID string, btlPolicy pvtdatapolicy.BTLPolicy) 50 stopExternalResource() 51 } 52 53 const ( 54 levelDBtestEnvName = "levelDB_LockBasedTxMgr" 55 couchDBtestEnvName = "couchDB_LockBasedTxMgr" 56 ) 57 58 // Tests will be run against each environment in this array 59 // For example, to skip CouchDB tests, remove the entry for couch environment 60 var testEnvs = []testEnv{ 61 &lockBasedEnv{name: levelDBtestEnvName, testDBEnv: &privacyenabledstate.LevelDBTestEnv{}}, 62 &lockBasedEnv{name: couchDBtestEnvName, testDBEnv: &privacyenabledstate.CouchDBTestEnv{}}, 63 } 64 65 var testEnvsMap = map[string]testEnv{ 66 levelDBtestEnvName: testEnvs[0], 67 couchDBtestEnvName: testEnvs[1], 68 } 69 70 ///////////// LevelDB Environment ////////////// 71 72 type lockBasedEnv struct { 73 dbInitialized bool 74 name string 75 t testing.TB 76 testBookkeepingEnv *bookkeeping.TestEnv 77 testDB *privacyenabledstate.DB 78 testDBEnv privacyenabledstate.TestEnv 79 txmgr *LockBasedTxMgr 80 } 81 82 func (env *lockBasedEnv) getName() string { 83 return env.name 84 } 85 86 func (env *lockBasedEnv) init(t *testing.T, testLedgerID string, btlPolicy pvtdatapolicy.BTLPolicy) { 87 var err error 88 env.t = t 89 if env.dbInitialized == false { 90 env.testDBEnv.Init(t) 91 env.dbInitialized = true 92 } 93 env.testDB = env.testDBEnv.GetDBHandle(testLedgerID) 94 require.NoError(t, err) 95 if btlPolicy == nil { 96 btlPolicy = btltestutil.SampleBTLPolicy( 97 map[[2]string]uint64{}, 98 ) 99 } 100 env.testBookkeepingEnv = bookkeeping.NewTestEnv(t) 101 102 txmgrInitializer := &Initializer{ 103 LedgerID: testLedgerID, 104 DB: env.testDB, 105 StateListeners: nil, 106 BtlPolicy: btlPolicy, 107 BookkeepingProvider: env.testBookkeepingEnv.TestProvider, 108 CCInfoProvider: &mock.DeployedChaincodeInfoProvider{}, 109 CustomTxProcessors: nil, 110 HashFunc: testHashFunc, 111 } 112 env.txmgr, err = NewLockBasedTxMgr(txmgrInitializer) 113 require.NoError(t, err) 114 } 115 116 func (env *lockBasedEnv) getTxMgr() *LockBasedTxMgr { 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 *LockBasedTxMgr 142 bg *testutil.BlockGenerator 143 } 144 145 func newTxMgrTestHelper(t *testing.T, txMgr *LockBasedTxMgr) *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 require.NoError(h.t, err) 155 txsFltr := txflags.ValidationFlags(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 require.Equal(h.t, 0, invalidTxNum) 163 err = h.txMgr.Commit() 164 require.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 require.NoError(h.t, err) 172 txsFltr := txflags.ValidationFlags(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 require.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 require.NoError(t, txMgr.db.ApplyPrivacyAwareUpdates(updates, version)) 219 } 220 221 type testutilPvtdata struct { 222 coll, key string 223 value []byte 224 }