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 }