github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/peer/peer_test.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package peer
     8  
     9  import (
    10  	"fmt"
    11  	"io/ioutil"
    12  	"math/rand"
    13  	"os"
    14  	"path/filepath"
    15  	"runtime"
    16  	"testing"
    17  	"time"
    18  
    19  	"github.com/hechain20/hechain/common/channelconfig"
    20  
    21  	"github.com/hechain20/hechain/bccsp/sw"
    22  	configtxtest "github.com/hechain20/hechain/common/configtx/test"
    23  	"github.com/hechain20/hechain/common/crypto/tlsgen"
    24  	"github.com/hechain20/hechain/common/metrics/disabled"
    25  	"github.com/hechain20/hechain/core/committer/txvalidator/plugin"
    26  	"github.com/hechain20/hechain/core/deliverservice"
    27  	validation "github.com/hechain20/hechain/core/handlers/validation/api"
    28  	"github.com/hechain20/hechain/core/ledger"
    29  	"github.com/hechain20/hechain/core/ledger/ledgermgmt"
    30  	"github.com/hechain20/hechain/core/ledger/ledgermgmt/ledgermgmttest"
    31  	ledgermocks "github.com/hechain20/hechain/core/ledger/mock"
    32  	"github.com/hechain20/hechain/core/transientstore"
    33  	"github.com/hechain20/hechain/gossip/gossip"
    34  	gossipmetrics "github.com/hechain20/hechain/gossip/metrics"
    35  	"github.com/hechain20/hechain/gossip/privdata"
    36  	gossipservice "github.com/hechain20/hechain/gossip/service"
    37  	peergossip "github.com/hechain20/hechain/internal/peer/gossip"
    38  	"github.com/hechain20/hechain/internal/peer/gossip/mocks"
    39  	"github.com/hechain20/hechain/internal/pkg/comm"
    40  	"github.com/hechain20/hechain/msp/mgmt"
    41  	msptesttools "github.com/hechain20/hechain/msp/mgmt/testtools"
    42  	"github.com/hyperledger/fabric-protos-go/common"
    43  	pb "github.com/hyperledger/fabric-protos-go/peer"
    44  	"github.com/stretchr/testify/require"
    45  	"google.golang.org/grpc"
    46  )
    47  
    48  func TestMain(m *testing.M) {
    49  	msptesttools.LoadMSPSetupForTesting()
    50  	rc := m.Run()
    51  	os.Exit(rc)
    52  }
    53  
    54  func NewTestPeer(t *testing.T) (*Peer, func()) {
    55  	tempdir, err := ioutil.TempDir("", "peer-test")
    56  	require.NoError(t, err, "failed to create temporary directory")
    57  
    58  	// Initialize gossip service
    59  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    60  	require.NoError(t, err)
    61  	signer, err := mgmt.GetLocalMSP(cryptoProvider).GetDefaultSigningIdentity()
    62  	require.NoError(t, err)
    63  
    64  	localMSP := mgmt.GetLocalMSP(cryptoProvider)
    65  	deserManager := peergossip.NewDeserializersManager(localMSP)
    66  	messageCryptoService := peergossip.NewMCS(
    67  		&mocks.ChannelPolicyManagerGetter{},
    68  		signer,
    69  		deserManager,
    70  		cryptoProvider,
    71  	)
    72  	secAdv := peergossip.NewSecurityAdvisor(deserManager)
    73  	defaultSecureDialOpts := func() []grpc.DialOption { return []grpc.DialOption{grpc.WithInsecure()} }
    74  	gossipConfig, err := gossip.GlobalConfig("localhost:0", nil)
    75  	require.NoError(t, err)
    76  
    77  	gossipService, err := gossipservice.New(
    78  		signer,
    79  		gossipmetrics.NewGossipMetrics(&disabled.Provider{}),
    80  		"localhost:0",
    81  		grpc.NewServer(),
    82  		messageCryptoService,
    83  		secAdv,
    84  		defaultSecureDialOpts,
    85  		nil,
    86  		gossipConfig,
    87  		&gossipservice.ServiceConfig{},
    88  		&privdata.PrivdataConfig{},
    89  		&deliverservice.DeliverServiceConfig{
    90  			ReConnectBackoffThreshold:   deliverservice.DefaultReConnectBackoffThreshold,
    91  			ReconnectTotalTimeThreshold: deliverservice.DefaultReConnectTotalTimeThreshold,
    92  		},
    93  	)
    94  	require.NoError(t, err, "failed to create gossip service")
    95  
    96  	ledgerMgr, err := constructLedgerMgrWithTestDefaults(filepath.Join(tempdir, "ledgersData"))
    97  	require.NoError(t, err, "failed to create ledger manager")
    98  
    99  	require.NoError(t, err)
   100  	transientStoreProvider, err := transientstore.NewStoreProvider(
   101  		filepath.Join(tempdir, "transientstore"),
   102  	)
   103  	require.NoError(t, err)
   104  	peerInstance := &Peer{
   105  		GossipService:  gossipService,
   106  		StoreProvider:  transientStoreProvider,
   107  		LedgerMgr:      ledgerMgr,
   108  		CryptoProvider: cryptoProvider,
   109  	}
   110  
   111  	cleanup := func() {
   112  		ledgerMgr.Close()
   113  		os.RemoveAll(tempdir)
   114  	}
   115  	return peerInstance, cleanup
   116  }
   117  
   118  func TestInitialize(t *testing.T) {
   119  	peerInstance, cleanup := NewTestPeer(t)
   120  	defer cleanup()
   121  
   122  	org1CA, err := tlsgen.NewCA()
   123  	require.NoError(t, err)
   124  	org1Server1KeyPair, err := org1CA.NewServerCertKeyPair("localhost", "127.0.0.1", "::1")
   125  	require.NoError(t, err)
   126  
   127  	serverConfig := comm.ServerConfig{
   128  		SecOpts: comm.SecureOptions{
   129  			UseTLS:            true,
   130  			Certificate:       org1Server1KeyPair.Cert,
   131  			Key:               org1Server1KeyPair.Key,
   132  			ServerRootCAs:     [][]byte{org1CA.CertBytes()},
   133  			RequireClientCert: true,
   134  		},
   135  	}
   136  
   137  	server, err := comm.NewGRPCServer("localhost:0", serverConfig)
   138  	require.NoError(t, err, "failed to create gRPC server")
   139  
   140  	peerInstance.Initialize(
   141  		nil,
   142  		server,
   143  		plugin.MapBasedMapper(map[string]validation.PluginFactory{}),
   144  		&ledgermocks.DeployedChaincodeInfoProvider{},
   145  		nil,
   146  		nil,
   147  		runtime.NumCPU(),
   148  	)
   149  	require.Equal(t, peerInstance.server, server)
   150  }
   151  
   152  func TestCreateChannel(t *testing.T) {
   153  	peerInstance, cleanup := NewTestPeer(t)
   154  	defer cleanup()
   155  
   156  	var initArg string
   157  	peerInstance.Initialize(
   158  		func(cid string) { initArg = cid },
   159  		nil,
   160  		plugin.MapBasedMapper(map[string]validation.PluginFactory{}),
   161  		&ledgermocks.DeployedChaincodeInfoProvider{},
   162  		nil,
   163  		nil,
   164  		runtime.NumCPU(),
   165  	)
   166  
   167  	testChannelID := fmt.Sprintf("mytestchannelid-%d", rand.Int())
   168  	block, err := configtxtest.MakeGenesisBlock(testChannelID)
   169  	if err != nil {
   170  		fmt.Printf("Failed to create a config block, err %s\n", err)
   171  		t.FailNow()
   172  	}
   173  
   174  	err = peerInstance.CreateChannel(testChannelID, block, &ledgermocks.DeployedChaincodeInfoProvider{}, nil, nil)
   175  	if err != nil {
   176  		t.Fatalf("failed to create chain %s", err)
   177  	}
   178  
   179  	require.Equal(t, testChannelID, initArg)
   180  
   181  	// Correct ledger
   182  	ledger := peerInstance.GetLedger(testChannelID)
   183  	if ledger == nil {
   184  		t.Fatalf("failed to get correct ledger")
   185  	}
   186  
   187  	// Get config block from ledger
   188  	block, err = ConfigBlockFromLedger(ledger)
   189  	require.NoError(t, err, "Failed to get config block from ledger")
   190  	require.NotNil(t, block, "Config block should not be nil")
   191  	require.Equal(t, uint64(0), block.Header.Number, "config block should have been block 0")
   192  
   193  	// Bad ledger
   194  	ledger = peerInstance.GetLedger("BogusChain")
   195  	if ledger != nil {
   196  		t.Fatalf("got a bogus ledger")
   197  	}
   198  
   199  	// Correct PolicyManager
   200  	pmgr := peerInstance.GetPolicyManager(testChannelID)
   201  	if pmgr == nil {
   202  		t.Fatal("failed to get PolicyManager")
   203  	}
   204  
   205  	// Bad PolicyManager
   206  	pmgr = peerInstance.GetPolicyManager("BogusChain")
   207  	if pmgr != nil {
   208  		t.Fatal("got a bogus PolicyManager")
   209  	}
   210  
   211  	channels := peerInstance.GetChannelsInfo()
   212  	if len(channels) != 1 {
   213  		t.Fatalf("incorrect number of channels")
   214  	}
   215  }
   216  
   217  func TestCreateChannelBySnapshot(t *testing.T) {
   218  	peerInstance, cleanup := NewTestPeer(t)
   219  	defer cleanup()
   220  
   221  	var initArg string
   222  	waitCh := make(chan struct{})
   223  	peerInstance.Initialize(
   224  		func(cid string) {
   225  			<-waitCh
   226  			initArg = cid
   227  		},
   228  		nil,
   229  		plugin.MapBasedMapper(map[string]validation.PluginFactory{}),
   230  		&ledgermocks.DeployedChaincodeInfoProvider{},
   231  		nil,
   232  		nil,
   233  		runtime.NumCPU(),
   234  	)
   235  
   236  	testChannelID := "createchannelbysnapshot"
   237  
   238  	// create a temp dir to store snapshot
   239  	tempdir, err := ioutil.TempDir("", testChannelID)
   240  	require.NoError(t, err)
   241  	defer os.Remove(tempdir)
   242  
   243  	snapshotDir := ledgermgmttest.CreateSnapshotWithGenesisBlock(t, tempdir, testChannelID, &ConfigTxProcessor{})
   244  	err = peerInstance.CreateChannelFromSnapshot(snapshotDir, &ledgermocks.DeployedChaincodeInfoProvider{}, nil, nil)
   245  	require.NoError(t, err)
   246  
   247  	expectedStatus := &pb.JoinBySnapshotStatus{InProgress: true, BootstrappingSnapshotDir: snapshotDir}
   248  	require.Equal(t, expectedStatus, peerInstance.JoinBySnaphotStatus())
   249  
   250  	// write a msg to waitCh to unblock channel init func
   251  	waitCh <- struct{}{}
   252  
   253  	// wait until ledger creation is done
   254  	ledgerCreationDone := func() bool {
   255  		return !peerInstance.JoinBySnaphotStatus().InProgress
   256  	}
   257  	require.Eventually(t, ledgerCreationDone, time.Minute, time.Second)
   258  
   259  	// verify channel init func is called
   260  	require.Equal(t, testChannelID, initArg)
   261  
   262  	// verify ledger created
   263  	ledger := peerInstance.GetLedger(testChannelID)
   264  	require.NotNil(t, ledger)
   265  
   266  	bcInfo, err := ledger.GetBlockchainInfo()
   267  	require.NoError(t, err)
   268  	require.Equal(t, uint64(1), bcInfo.GetHeight())
   269  
   270  	expectedStatus = &pb.JoinBySnapshotStatus{InProgress: false, BootstrappingSnapshotDir: ""}
   271  	require.Equal(t, expectedStatus, peerInstance.JoinBySnaphotStatus())
   272  
   273  	// Bad ledger
   274  	ledger = peerInstance.GetLedger("BogusChain")
   275  	require.Nil(t, ledger)
   276  
   277  	// Correct PolicyManager
   278  	pmgr := peerInstance.GetPolicyManager(testChannelID)
   279  	require.NotNil(t, pmgr)
   280  
   281  	// Bad PolicyManager
   282  	pmgr = peerInstance.GetPolicyManager("BogusChain")
   283  	require.Nil(t, pmgr)
   284  
   285  	channels := peerInstance.GetChannelsInfo()
   286  	require.Equal(t, 1, len(channels))
   287  }
   288  
   289  func TestDeliverSupportManager(t *testing.T) {
   290  	peerInstance, cleanup := NewTestPeer(t)
   291  	defer cleanup()
   292  
   293  	manager := &DeliverChainManager{Peer: peerInstance}
   294  
   295  	chainSupport := manager.GetChain("fake")
   296  	require.Nil(t, chainSupport, "chain support should be nil")
   297  
   298  	peerInstance.channels = map[string]*Channel{"testchain": {}}
   299  	chainSupport = manager.GetChain("testchain")
   300  	require.NotNil(t, chainSupport, "chain support should not be nil")
   301  }
   302  
   303  func TestConfigCallback(t *testing.T) {
   304  	peerInstance, cleanup := NewTestPeer(t)
   305  	defer cleanup()
   306  
   307  	var callbackInvoked bool
   308  	peerInstance.AddConfigCallbacks(func(bundle *channelconfig.Bundle) {
   309  		callbackInvoked = true
   310  		orderer, exists := bundle.OrdererConfig()
   311  		require.True(t, exists)
   312  		require.NotEmpty(t, orderer.Organizations()["SampleOrg"].Endpoints)
   313  	})
   314  
   315  	peerInstance.Initialize(
   316  		nil,
   317  		nil,
   318  		plugin.MapBasedMapper(map[string]validation.PluginFactory{}),
   319  		&ledgermocks.DeployedChaincodeInfoProvider{},
   320  		nil,
   321  		nil,
   322  		runtime.NumCPU(),
   323  	)
   324  
   325  	testChannelID := fmt.Sprintf("mytestchannelid-%d", rand.Int())
   326  	block, err := configtxtest.MakeGenesisBlock(testChannelID)
   327  	require.NoError(t, err)
   328  
   329  	// We expect the callback to be invoked when the channel is created
   330  	require.False(t, callbackInvoked)
   331  
   332  	err = peerInstance.CreateChannel(testChannelID, block, &ledgermocks.DeployedChaincodeInfoProvider{}, nil, nil)
   333  	require.NoError(t, err)
   334  
   335  	// the callback should have been invoked
   336  	require.True(t, callbackInvoked)
   337  }
   338  
   339  func constructLedgerMgrWithTestDefaults(ledgersDataDir string) (*ledgermgmt.LedgerMgr, error) {
   340  	ledgerInitializer := ledgermgmttest.NewInitializer(ledgersDataDir)
   341  
   342  	ledgerInitializer.CustomTxProcessors = map[common.HeaderType]ledger.CustomTxProcessor{
   343  		common.HeaderType_CONFIG: &ConfigTxProcessor{},
   344  	}
   345  	ledgerInitializer.Config.HistoryDBConfig = &ledger.HistoryDBConfig{
   346  		Enabled: true,
   347  	}
   348  	return ledgermgmt.NewLedgerMgr(ledgerInitializer), nil
   349  }
   350  
   351  // SetServer sets the gRPC server for the peer.
   352  // It should only be used in peer/pkg_test.
   353  func (p *Peer) SetServer(server *comm.GRPCServer) {
   354  	p.server = server
   355  }