github.com/koko1123/flow-go-1@v0.29.6/network/p2p/connection/peerManager_integration_test.go (about) 1 package connection_test 2 3 import ( 4 "context" 5 "testing" 6 "time" 7 8 "github.com/libp2p/go-libp2p/core/host" 9 "github.com/libp2p/go-libp2p/core/network" 10 "github.com/libp2p/go-libp2p/core/peer" 11 "github.com/libp2p/go-libp2p/core/peerstore" 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 15 "github.com/koko1123/flow-go-1/model/flow" 16 "github.com/koko1123/flow-go-1/module/irrecoverable" 17 "github.com/koko1123/flow-go-1/network/p2p" 18 "github.com/koko1123/flow-go-1/network/p2p/connection" 19 p2ptest "github.com/koko1123/flow-go-1/network/p2p/test" 20 "github.com/koko1123/flow-go-1/network/p2p/translator" 21 "github.com/koko1123/flow-go-1/network/p2p/utils" 22 "github.com/koko1123/flow-go-1/utils/unittest" 23 ) 24 25 // TestPeerManager_Integration tests the correctness of integration between PeerManager and Libp2pConnector over 26 // a fully connected topology. 27 // PeerManager should be able to connect to all peers using the connector, and must also tear down the connection to 28 // peers that are excluded from its identity provider. 29 func TestPeerManager_Integration(t *testing.T) { 30 count := 5 31 ctx, cancel := context.WithCancel(context.Background()) 32 33 signalerCtx := irrecoverable.NewMockSignalerContext(t, ctx) 34 35 // create nodes 36 nodes, identities := p2ptest.NodesFixture(t, unittest.IdentifierFixture(), "test_peer_manager", count) 37 38 p2ptest.StartNodes(t, signalerCtx, nodes, 100*time.Millisecond) 39 defer p2ptest.StopNodes(t, nodes, cancel, 100*time.Millisecond) 40 41 thisNode := nodes[0] 42 topologyPeers := identities[1:] 43 44 // adds address of all other nodes into the peer store of this node, so that it can dial them. 45 info, invalid := utils.PeerInfosFromIDs(topologyPeers) 46 require.Empty(t, invalid) 47 for _, i := range info { 48 thisNode.Host().Peerstore().SetAddrs(i.ID, i.Addrs, peerstore.PermanentAddrTTL) 49 } 50 51 // setup 52 connector, err := connection.NewLibp2pConnector(unittest.Logger(), thisNode.Host(), connection.ConnectionPruningEnabled) 53 require.NoError(t, err) 54 55 idTranslator, err := translator.NewFixedTableIdentityTranslator(identities) 56 require.NoError(t, err) 57 58 peerManager := connection.NewPeerManager(unittest.Logger(), connection.DefaultPeerUpdateInterval, connector) 59 peerManager.SetPeersProvider(func() peer.IDSlice { 60 // peerManager is furnished with a full topology that connects to all nodes 61 // in the topologyPeers. 62 peers := peer.IDSlice{} 63 for _, id := range topologyPeers { 64 peerId, err := idTranslator.GetPeerID(id.NodeID) 65 require.NoError(t, err) 66 peers = append(peers, peerId) 67 } 68 69 return peers 70 }) 71 72 // initially no node should be in peer store of this node. 73 require.Empty(t, thisNode.Host().Network().Peers()) 74 peerManager.ForceUpdatePeers(ctx) 75 time.Sleep(1 * time.Second) 76 // after a forced update all other nodes must be added to the peer store of this node. 77 require.Len(t, thisNode.Host().Network().Peers(), count-1) 78 // after a forced update there must be a connection between this node and other nodes 79 connectedToAll(t, thisNode.Host(), idTranslator, topologyPeers.NodeIDs()) 80 81 // kicks one node out of the othersIds; this imitates evicting, ejecting, or unstaking a node 82 evictedId := topologyPeers[0] // evicted one 83 topologyPeers = topologyPeers[1:] // updates otherIds list 84 peerManager.ForceUpdatePeers(ctx) 85 time.Sleep(1 * time.Second) 86 // after a forced update, the evicted one should be excluded from the peer store. 87 require.Len(t, thisNode.Host().Network().Peers(), count-2) 88 // there must be a connection between this node and other nodes (except evicted one). 89 connectedToAll(t, thisNode.Host(), idTranslator, topologyPeers.NodeIDs()) 90 91 // there must be no connection between this node and evicted one 92 peerId, err := idTranslator.GetPeerID(evictedId.NodeID) 93 require.NoError(t, err) 94 assert.Equal(t, thisNode.Host().Network().Connectedness(peerId), network.NotConnected) 95 } 96 97 // connectedToAll is a test helper that fails if there is no connection between this host and at least one of the 98 // nodes in "all". 99 func connectedToAll(t *testing.T, host host.Host, translator p2p.IDTranslator, all flow.IdentifierList) { 100 for _, id := range all { 101 peerId, err := translator.GetPeerID(id) 102 require.NoError(t, err) 103 assert.Equal(t, host.Network().Connectedness(peerId), network.Connected) 104 } 105 }