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  }