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  }