github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/core/ledger/kvledger/txmgmt/txmgr/pkg_test.go (about) 1 /* 2 Copyright IBM Corp. 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/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/osdi23p228/fabric/common/flogging" 20 "github.com/osdi23p228/fabric/common/ledger/testutil" 21 "github.com/osdi23p228/fabric/core/ledger" 22 "github.com/osdi23p228/fabric/core/ledger/internal/version" 23 "github.com/osdi23p228/fabric/core/ledger/kvledger/bookkeeping" 24 "github.com/osdi23p228/fabric/core/ledger/kvledger/txmgmt/privacyenabledstate" 25 "github.com/osdi23p228/fabric/core/ledger/mock" 26 "github.com/osdi23p228/fabric/core/ledger/pvtdatapolicy" 27 btltestutil "github.com/osdi23p228/fabric/core/ledger/pvtdatapolicy/testutil" 28 "github.com/osdi23p228/fabric/core/ledger/util" 29 "github.com/osdi23p228/fabric/internal/pkg/txflags" 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 117 func (env *lockBasedEnv) getTxMgr() *LockBasedTxMgr { 118 return env.txmgr 119 } 120 121 func (env *lockBasedEnv) getVDB() *privacyenabledstate.DB { 122 return env.testDB 123 } 124 125 func (env *lockBasedEnv) cleanup() { 126 if env.dbInitialized { 127 env.txmgr.Shutdown() 128 env.testDBEnv.Cleanup() 129 env.testBookkeepingEnv.Cleanup() 130 env.dbInitialized = false 131 } 132 } 133 134 func (env *lockBasedEnv) stopExternalResource() { 135 env.testDBEnv.StopExternalResource() 136 } 137 138 //////////// txMgrTestHelper ///////////// 139 140 type txMgrTestHelper struct { 141 t *testing.T 142 txMgr *LockBasedTxMgr 143 bg *testutil.BlockGenerator 144 } 145 146 func newTxMgrTestHelper(t *testing.T, txMgr *LockBasedTxMgr) *txMgrTestHelper { 147 bg, _ := testutil.NewBlockGenerator(t, "testLedger", false) 148 return &txMgrTestHelper{t, txMgr, bg} 149 } 150 151 func (h *txMgrTestHelper) validateAndCommitRWSet(txRWSet *rwset.TxReadWriteSet) { 152 rwSetBytes, _ := proto.Marshal(txRWSet) 153 block := h.bg.NextBlock([][]byte{rwSetBytes}) 154 _, _, err := h.txMgr.ValidateAndPrepare(&ledger.BlockAndPvtData{Block: block, PvtData: nil}, true) 155 require.NoError(h.t, err) 156 txsFltr := txflags.ValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) 157 invalidTxNum := 0 158 for i := 0; i < len(block.Data.Data); i++ { 159 if txsFltr.IsInvalid(i) { 160 invalidTxNum++ 161 } 162 } 163 require.Equal(h.t, 0, invalidTxNum) 164 err = h.txMgr.Commit() 165 require.NoError(h.t, err) 166 } 167 168 func (h *txMgrTestHelper) checkRWsetInvalid(txRWSet *rwset.TxReadWriteSet) { 169 rwSetBytes, _ := proto.Marshal(txRWSet) 170 block := h.bg.NextBlock([][]byte{rwSetBytes}) 171 _, _, err := h.txMgr.ValidateAndPrepare(&ledger.BlockAndPvtData{Block: block, PvtData: nil}, true) 172 require.NoError(h.t, err) 173 txsFltr := txflags.ValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) 174 invalidTxNum := 0 175 for i := 0; i < len(block.Data.Data); i++ { 176 if txsFltr.IsInvalid(i) { 177 invalidTxNum++ 178 } 179 } 180 require.Equal(h.t, 1, invalidTxNum) 181 } 182 183 func populateCollConfigForTest(t *testing.T, txMgr *LockBasedTxMgr, nsColls []collConfigkey, ht *version.Height) { 184 m := map[string]*peer.CollectionConfigPackage{} 185 for _, nsColl := range nsColls { 186 ns, coll := nsColl.ns, nsColl.coll 187 pkg, ok := m[ns] 188 if !ok { 189 pkg = &peer.CollectionConfigPackage{} 190 m[ns] = pkg 191 } 192 sCollConfig := &peer.CollectionConfig_StaticCollectionConfig{ 193 StaticCollectionConfig: &peer.StaticCollectionConfig{ 194 Name: coll, 195 }, 196 } 197 pkg.Config = append(pkg.Config, &peer.CollectionConfig{Payload: sCollConfig}) 198 } 199 ccInfoProvider := &mock.DeployedChaincodeInfoProvider{} 200 ccInfoProvider.AllCollectionsConfigPkgStub = func(channelName, ccName string, qe ledger.SimpleQueryExecutor) (*peer.CollectionConfigPackage, error) { 201 fmt.Printf("retrieveing info for [%s] from [%s]\n", ccName, m) 202 return m[ccName], nil 203 } 204 txMgr.ccInfoProvider = ccInfoProvider 205 } 206 207 func testutilPopulateDB( 208 t *testing.T, txMgr *LockBasedTxMgr, ns string, 209 data []*queryresult.KV, pvtdataHashes []*testutilPvtdata, 210 version *version.Height, 211 ) { 212 updates := privacyenabledstate.NewUpdateBatch() 213 for _, kv := range data { 214 updates.PubUpdates.Put(ns, kv.Key, kv.Value, version) 215 } 216 for _, p := range pvtdataHashes { 217 updates.HashUpdates.Put(ns, p.coll, util.ComputeStringHash(p.key), util.ComputeHash(p.value), version) 218 } 219 txMgr.db.ApplyPrivacyAwareUpdates(updates, version) 220 } 221 222 type testutilPvtdata struct { 223 coll, key string 224 value []byte 225 }