代码拉取完成,页面将自动刷新
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package tests
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/bccsp"
"github.com/hyperledger/fabric/bccsp/sw"
"github.com/hyperledger/fabric/common/ledger/blkstorage/fsblkstorage"
"github.com/hyperledger/fabric/common/ledger/util"
"github.com/hyperledger/fabric/common/metrics/disabled"
"github.com/hyperledger/fabric/core/chaincode/lifecycle"
"github.com/hyperledger/fabric/core/common/privdata"
"github.com/hyperledger/fabric/core/container/externalbuilder"
"github.com/hyperledger/fabric/core/ledger"
"github.com/hyperledger/fabric/core/ledger/kvledger"
"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
corepeer "github.com/hyperledger/fabric/core/peer"
"github.com/hyperledger/fabric/core/scc/lscc"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/msp/mgmt"
"github.com/hyperledger/fabric/protoutil"
"github.com/stretchr/testify/assert"
)
type rebuildable uint8
const (
rebuildableStatedb rebuildable = 1
rebuildableBlockIndex rebuildable = 2
rebuildableConfigHistory rebuildable = 4
rebuildableHistoryDB rebuildable = 8
rebuildableBookkeeper rebuildable = 16
)
type env struct {
assert *assert.Assertions
initializer *ledgermgmt.Initializer
ledgerMgr *ledgermgmt.LedgerMgr
}
func newEnv(t *testing.T) *env {
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
assert.NoError(t, err)
return newEnvWithInitializer(t, &ledgermgmt.Initializer{
Hasher: cryptoProvider,
EbMetadataProvider: &externalbuilder.MetadataProvider{
DurablePath: "testdata",
},
})
}
func newEnvWithInitializer(t *testing.T, initializer *ledgermgmt.Initializer) *env {
populateMissingsWithTestDefaults(t, initializer)
return &env{
assert: assert.New(t),
initializer: initializer,
}
}
func (e *env) cleanup() {
if e.ledgerMgr != nil {
e.ledgerMgr.Close()
}
// Ignore RemoveAll error because when a test mounts a dir to a couchdb container,
// the mounted dir cannot be deleted in CI builds. This has no impact to CI because it gets a new VM for each build.
// When running the test locally (macOS and linux VM), the mounted dirs are deleted without any error.
os.RemoveAll(e.initializer.Config.RootFSPath)
}
func (e *env) closeAllLedgersAndDrop(flags rebuildable) {
if e.ledgerMgr != nil {
e.ledgerMgr.Close()
}
defer e.initLedgerMgmt()
if flags&rebuildableBlockIndex == rebuildableBlockIndex {
indexPath := e.getBlockIndexDBPath()
logger.Infof("Deleting blockstore indexdb path [%s]", indexPath)
e.verifyNonEmptyDirExists(indexPath)
e.assert.NoError(os.RemoveAll(indexPath))
}
if flags&rebuildableStatedb == rebuildableStatedb {
statedbPath := e.getLevelstateDBPath()
logger.Infof("Deleting statedb path [%s]", statedbPath)
e.verifyNonEmptyDirExists(statedbPath)
e.assert.NoError(os.RemoveAll(statedbPath))
}
if flags&rebuildableConfigHistory == rebuildableConfigHistory {
configHistoryPath := e.getConfigHistoryDBPath()
logger.Infof("Deleting configHistory db path [%s]", configHistoryPath)
e.verifyNonEmptyDirExists(configHistoryPath)
e.assert.NoError(os.RemoveAll(configHistoryPath))
}
if flags&rebuildableBookkeeper == rebuildableBookkeeper {
bookkeeperPath := e.getBookkeeperDBPath()
logger.Infof("Deleting bookkeeper db path [%s]", bookkeeperPath)
e.verifyNonEmptyDirExists(bookkeeperPath)
e.assert.NoError(os.RemoveAll(bookkeeperPath))
}
if flags&rebuildableHistoryDB == rebuildableHistoryDB {
historyPath := e.getHistoryDBPath()
logger.Infof("Deleting history db path [%s]", historyPath)
e.verifyNonEmptyDirExists(historyPath)
e.assert.NoError(os.RemoveAll(historyPath))
}
e.verifyRebuilableDoesNotExist(flags)
}
func (e *env) verifyRebuilablesExist(flags rebuildable) {
if flags&rebuildableBlockIndex == rebuildableBlockIndex {
e.verifyNonEmptyDirExists(e.getBlockIndexDBPath())
}
if flags&rebuildableStatedb == rebuildableStatedb {
e.verifyNonEmptyDirExists(e.getLevelstateDBPath())
}
if flags&rebuildableConfigHistory == rebuildableConfigHistory {
e.verifyNonEmptyDirExists(e.getConfigHistoryDBPath())
}
if flags&rebuildableBookkeeper == rebuildableBookkeeper {
e.verifyNonEmptyDirExists(e.getBookkeeperDBPath())
}
if flags&rebuildableHistoryDB == rebuildableHistoryDB {
e.verifyNonEmptyDirExists(e.getHistoryDBPath())
}
}
func (e *env) verifyRebuilableDoesNotExist(flags rebuildable) {
if flags&rebuildableStatedb == rebuildableStatedb {
e.verifyDirDoesNotExist(e.getLevelstateDBPath())
}
if flags&rebuildableBlockIndex == rebuildableBlockIndex {
e.verifyDirDoesNotExist(e.getBlockIndexDBPath())
}
if flags&rebuildableConfigHistory == rebuildableConfigHistory {
e.verifyDirDoesNotExist(e.getConfigHistoryDBPath())
}
if flags&rebuildableBookkeeper == rebuildableBookkeeper {
e.verifyDirDoesNotExist(e.getBookkeeperDBPath())
}
if flags&rebuildableHistoryDB == rebuildableHistoryDB {
e.verifyDirDoesNotExist(e.getHistoryDBPath())
}
}
func (e *env) verifyNonEmptyDirExists(path string) {
empty, err := util.DirEmpty(path)
e.assert.NoError(err)
e.assert.False(empty)
}
func (e *env) verifyDirDoesNotExist(path string) {
exists, _, err := util.FileExists(path)
e.assert.NoError(err)
e.assert.False(exists)
}
func (e *env) initLedgerMgmt() {
e.ledgerMgr = ledgermgmt.NewLedgerMgr(e.initializer)
}
func (e *env) closeLedgerMgmt() {
e.ledgerMgr.Close()
}
func (e *env) getLedgerRootPath() string {
return e.initializer.Config.RootFSPath
}
func (e *env) getLevelstateDBPath() string {
return kvledger.StateDBPath(e.initializer.Config.RootFSPath)
}
func (e *env) getBlockIndexDBPath() string {
return filepath.Join(kvledger.BlockStorePath(e.initializer.Config.RootFSPath), fsblkstorage.IndexDir)
}
func (e *env) getConfigHistoryDBPath() string {
return kvledger.ConfigHistoryDBPath(e.initializer.Config.RootFSPath)
}
func (e *env) getHistoryDBPath() string {
return kvledger.HistoryDBPath(e.initializer.Config.RootFSPath)
}
func (e *env) getBookkeeperDBPath() string {
return kvledger.BookkeeperDBPath(e.initializer.Config.RootFSPath)
}
func populateMissingsWithTestDefaults(t *testing.T, initializer *ledgermgmt.Initializer) {
if initializer.CustomTxProcessors == nil {
initializer.CustomTxProcessors = map[common.HeaderType]ledger.CustomTxProcessor{}
}
if initializer.DeployedChaincodeInfoProvider == nil {
initializer.DeployedChaincodeInfoProvider = &lscc.DeployedCCInfoProvider{}
}
if initializer.MembershipInfoProvider == nil {
identityDeserializerFactory := func(chainID string) msp.IdentityDeserializer {
return mgmt.GetManagerForChain(chainID)
}
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
assert.NoError(t, err)
mspID := "test-mspid"
membershipInfoProvider := privdata.NewMembershipInfoProvider(mspID, createSelfSignedData(cryptoProvider), identityDeserializerFactory)
initializer.MembershipInfoProvider = membershipInfoProvider
}
if initializer.MetricsProvider == nil {
initializer.MetricsProvider = &disabled.Provider{}
}
if initializer.Config == nil {
rootPath, err := ioutil.TempDir("/tmp", "ledgersData")
if err != nil {
t.Fatalf("Failed to create root directory: %s", err)
}
initializer.Config = &ledger.Config{
RootFSPath: rootPath,
}
}
if initializer.Config.StateDBConfig == nil {
initializer.Config.StateDBConfig = &ledger.StateDBConfig{
StateDatabase: "goleveldb",
}
}
if initializer.Config.HistoryDBConfig == nil {
initializer.Config.HistoryDBConfig = &ledger.HistoryDBConfig{
Enabled: true,
}
}
if initializer.Config.PrivateDataConfig == nil {
initializer.Config.PrivateDataConfig = &ledger.PrivateDataConfig{
MaxBatchSize: 5000,
BatchesInterval: 1000,
PurgeInterval: 100,
}
}
}
func createSelfSignedData(cryptoProvider bccsp.BCCSP) protoutil.SignedData {
sID := mgmt.GetLocalSigningIdentityOrPanic(cryptoProvider)
msg := make([]byte, 32)
sig, err := sID.Sign(msg)
if err != nil {
logger.Panicf("Failed creating self signed data because message signing failed: %v", err)
}
peerIdentity, err := sID.Serialize()
if err != nil {
logger.Panicf("Failed creating self signed data because peer identity couldn't be serialized: %v", err)
}
return protoutil.SignedData{
Data: msg,
Signature: sig,
Identity: peerIdentity,
}
}
// deployedCCInfoProviderWrapper is a wrapper type that overrides ChaincodeImplicitCollections
type deployedCCInfoProviderWrapper struct {
*lifecycle.ValidatorCommitter
orgMSPIDs []string
}
// AllCollectionsConfigPkg overrides the same method in lifecycle.AllCollectionsConfigPkg.
// It is basically a copy of lifecycle.AllCollectionsConfigPkg and invokes ImplicitCollections in the wrapper.
// This method is called when the unit test code gets private data code path.
func (dc *deployedCCInfoProviderWrapper) AllCollectionsConfigPkg(channelName, chaincodeName string, qe ledger.SimpleQueryExecutor) (*peer.CollectionConfigPackage, error) {
chaincodeInfo, err := dc.ChaincodeInfo(channelName, chaincodeName, qe)
if err != nil {
return nil, err
}
explicitCollectionConfigPkg := chaincodeInfo.ExplicitCollectionConfigPkg
implicitCollections, _ := dc.ImplicitCollections(channelName, "", nil)
var combinedColls []*peer.CollectionConfig
if explicitCollectionConfigPkg != nil {
combinedColls = append(combinedColls, explicitCollectionConfigPkg.Config...)
}
for _, implicitColl := range implicitCollections {
c := &peer.CollectionConfig{}
c.Payload = &peer.CollectionConfig_StaticCollectionConfig{StaticCollectionConfig: implicitColl}
combinedColls = append(combinedColls, c)
}
return &peer.CollectionConfigPackage{
Config: combinedColls,
}, nil
}
// ImplicitCollections overrides the same method in lifecycle.ValidatorCommitter.
// It constructs static collection config using known mspids from the sample ledger.
// This method is called when the unit test code gets collection configuration.
func (dc *deployedCCInfoProviderWrapper) ImplicitCollections(channelName, chaincodeName string, qe ledger.SimpleQueryExecutor) ([]*peer.StaticCollectionConfig, error) {
collConfigs := make([]*peer.StaticCollectionConfig, 0, len(dc.orgMSPIDs))
for _, mspID := range dc.orgMSPIDs {
collConfigs = append(collConfigs, dc.ValidatorCommitter.GenerateImplicitCollectionForOrg(mspID))
}
return collConfigs, nil
}
func createDeployedCCInfoProvider(orgMSPIDs []string) ledger.DeployedChaincodeInfoProvider {
deployedCCInfoProvider := &lifecycle.ValidatorCommitter{
CoreConfig: &corepeer.Config{},
Resources: &lifecycle.Resources{
Serializer: &lifecycle.Serializer{},
},
LegacyDeployedCCInfoProvider: &lscc.DeployedCCInfoProvider{},
}
return &deployedCCInfoProviderWrapper{
ValidatorCommitter: deployedCCInfoProvider,
orgMSPIDs: orgMSPIDs,
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。