github.com/celestiaorg/celestia-node@v0.15.0-beta.1/nodebuilder/p2p/p2p_test.go (about) 1 package p2p 2 3 import ( 4 "context" 5 "crypto/rand" 6 "testing" 7 "time" 8 9 "github.com/ipfs/go-datastore" 10 "github.com/libp2p/go-libp2p" 11 pubsub "github.com/libp2p/go-libp2p-pubsub" 12 libhost "github.com/libp2p/go-libp2p/core/host" 13 "github.com/libp2p/go-libp2p/core/metrics" 14 "github.com/libp2p/go-libp2p/core/network" 15 "github.com/libp2p/go-libp2p/core/protocol" 16 rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" 17 mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" 18 "github.com/stretchr/testify/assert" 19 "github.com/stretchr/testify/require" 20 ) 21 22 // TestP2PModule_Host tests P2P Module methods on 23 // the instance of Host. 24 func TestP2PModule_Host(t *testing.T) { 25 net, err := mocknet.FullMeshConnected(2) 26 require.NoError(t, err) 27 host, peer := net.Hosts()[0], net.Hosts()[1] 28 29 mgr := newModule(host, nil, nil, nil, nil) 30 31 ctx := context.Background() 32 33 // test all methods on `manager.host` 34 peers, err := mgr.Peers(ctx) 35 require.NoError(t, err) 36 assert.Equal(t, host.Network().Peers(), peers) 37 38 peerInfo, err := mgr.PeerInfo(ctx, peer.ID()) 39 require.NoError(t, err) 40 assert.Equal(t, libhost.InfoFromHost(peer).ID, peerInfo.ID) 41 42 connectedness, err := mgr.Connectedness(ctx, peer.ID()) 43 require.NoError(t, err) 44 assert.Equal(t, host.Network().Connectedness(peer.ID()), connectedness) 45 // now disconnect using manager and check for connectedness match again 46 assert.NoError(t, mgr.ClosePeer(ctx, peer.ID())) 47 connectedness, err = mgr.Connectedness(ctx, peer.ID()) 48 require.NoError(t, err) 49 assert.Equal(t, host.Network().Connectedness(peer.ID()), connectedness) 50 } 51 52 // TestP2PModule_ConnManager tests P2P Module methods on 53 // the Host's ConnManager. Note that this test is constructed differently 54 // than the one above because mocknet does not provide a ConnManager to its 55 // mock peers. 56 func TestP2PModule_ConnManager(t *testing.T) { 57 // make two full peers and connect them 58 host, err := libp2p.New() 59 require.NoError(t, err) 60 61 peer, err := libp2p.New() 62 require.NoError(t, err) 63 64 mgr := newModule(host, nil, nil, nil, nil) 65 66 ctx, cancel := context.WithCancel(context.Background()) 67 t.Cleanup(cancel) 68 69 err = mgr.Connect(ctx, *libhost.InfoFromHost(peer)) 70 require.NoError(t, err) 71 72 err = mgr.Protect(ctx, peer.ID(), "test") 73 require.NoError(t, err) 74 protected, err := mgr.IsProtected(ctx, peer.ID(), "test") 75 require.NoError(t, err) 76 assert.True(t, protected) 77 78 ok, err := mgr.Unprotect(ctx, peer.ID(), "test") 79 require.False(t, ok) 80 require.NoError(t, err) 81 protected, err = mgr.IsProtected(ctx, peer.ID(), "test") 82 require.NoError(t, err) 83 assert.False(t, protected) 84 } 85 86 // TestP2PModule_Autonat tests P2P Module methods on 87 // the node's instance of AutoNAT. 88 func TestP2PModule_Autonat(t *testing.T) { 89 host, err := libp2p.New(libp2p.EnableNATService()) 90 require.NoError(t, err) 91 92 mgr := newModule(host, nil, nil, nil, nil) 93 94 status, err := mgr.NATStatus(context.Background()) 95 assert.NoError(t, err) 96 assert.Equal(t, network.ReachabilityUnknown, status) 97 } 98 99 // TestP2PModule_Bandwidth tests P2P Module methods on 100 // the Host's bandwidth reporter. 101 func TestP2PModule_Bandwidth(t *testing.T) { 102 bw := metrics.NewBandwidthCounter() 103 host, err := libp2p.New(libp2p.BandwidthReporter(bw)) 104 require.NoError(t, err) 105 106 protoID := protocol.ID("test") 107 // define a buf size, so we know how many bytes to read 108 bufSize := 1000 109 110 // create a peer to connect to 111 peer, err := libp2p.New(libp2p.BandwidthReporter(bw)) 112 require.NoError(t, err) 113 114 // set stream handler on the host 115 host.SetStreamHandler(protoID, func(stream network.Stream) { 116 buf := make([]byte, bufSize) 117 _, err := stream.Read(buf) 118 require.NoError(t, err) 119 120 _, err = stream.Write(buf) 121 require.NoError(t, err) 122 }) 123 124 mgr := newModule(host, nil, nil, bw, nil) 125 126 ctx, cancel := context.WithCancel(context.Background()) 127 t.Cleanup(cancel) 128 129 // connect to the peer 130 err = mgr.Connect(ctx, *libhost.InfoFromHost(peer)) 131 require.NoError(t, err) 132 133 // check to ensure they're actually connected 134 connectedness, err := mgr.Connectedness(ctx, peer.ID()) 135 require.NoError(t, err) 136 require.Equal(t, network.Connected, connectedness) 137 138 // open stream with host 139 info, err := mgr.Info(ctx) 140 require.NoError(t, err) 141 stream, err := peer.NewStream(ctx, info.ID, protoID) 142 require.NoError(t, err) 143 144 // write to stream to increase bandwidth usage get some substantive 145 // data to read from the bandwidth counter 146 buf := make([]byte, bufSize) 147 _, err = rand.Read(buf) 148 require.NoError(t, err) 149 _, err = stream.Write(buf) 150 require.NoError(t, err) 151 152 _, err = stream.Read(buf) 153 require.NoError(t, err) 154 155 // has to be ~2 seconds for the metrics reporter to collect the stats 156 // in the background process 157 time.Sleep(time.Second * 2) 158 159 stats, err := mgr.BandwidthStats(ctx) 160 require.NoError(t, err) 161 assert.NotNil(t, stats) 162 163 peerStat, err := mgr.BandwidthForPeer(ctx, peer.ID()) 164 require.NoError(t, err) 165 assert.NotZero(t, peerStat.TotalIn) 166 assert.Greater(t, int(peerStat.TotalIn), bufSize) // should be slightly more than buf size due negotiations, etc 167 168 protoStat, err := mgr.BandwidthForProtocol(ctx, protoID) 169 require.NoError(t, err) 170 assert.NotZero(t, protoStat.TotalIn) 171 assert.Greater(t, int(protoStat.TotalIn), bufSize) // should be slightly more than buf size due negotiations, etc 172 } 173 174 // TestP2PModule_Pubsub tests P2P Module methods on 175 // the instance of pubsub. 176 func TestP2PModule_Pubsub(t *testing.T) { 177 net, err := mocknet.FullMeshConnected(5) 178 require.NoError(t, err) 179 180 host := net.Hosts()[0] 181 182 ctx, cancel := context.WithCancel(context.Background()) 183 t.Cleanup(cancel) 184 185 gs, err := pubsub.NewGossipSub(ctx, host) 186 require.NoError(t, err) 187 188 mgr := newModule(host, gs, nil, nil, nil) 189 190 topicStr := "test-topic" 191 192 topic, err := gs.Join(topicStr) 193 require.NoError(t, err) 194 195 // also join all peers on mocknet to topic 196 for _, p := range net.Hosts()[1:] { 197 newGs, err := pubsub.NewGossipSub(ctx, p) 198 require.NoError(t, err) 199 200 tp, err := newGs.Join(topicStr) 201 require.NoError(t, err) 202 _, err = tp.Subscribe() 203 require.NoError(t, err) 204 } 205 206 err = topic.Publish(ctx, []byte("test")) 207 require.NoError(t, err) 208 209 // give for some peers to properly join the topic (this is necessary 210 // anywhere where gossipsub is used in tests) 211 time.Sleep(1 * time.Second) 212 213 psPeers, err := mgr.PubSubPeers(context.Background(), topicStr) 214 require.NoError(t, err) 215 assert.Equal(t, len(topic.ListPeers()), len(psPeers)) 216 } 217 218 // TestP2PModule_ConnGater tests P2P Module methods on 219 // the instance of ConnectionGater. 220 func TestP2PModule_ConnGater(t *testing.T) { 221 gater, err := connectionGater(datastore.NewMapDatastore()) 222 require.NoError(t, err) 223 224 mgr := newModule(nil, nil, gater, nil, nil) 225 226 ctx := context.Background() 227 228 assert.NoError(t, mgr.BlockPeer(ctx, "badpeer")) 229 blocked, err := mgr.ListBlockedPeers(ctx) 230 require.NoError(t, err) 231 assert.Len(t, blocked, 1) 232 233 assert.NoError(t, mgr.UnblockPeer(ctx, "badpeer")) 234 blocked, err = mgr.ListBlockedPeers(ctx) 235 require.NoError(t, err) 236 assert.Len(t, blocked, 0) 237 } 238 239 // TestP2PModule_ResourceManager tests P2P Module methods on 240 // the resourceManager. 241 func TestP2PModule_ResourceManager(t *testing.T) { 242 rm, err := rcmgr.NewResourceManager(rcmgr.NewFixedLimiter(rcmgr.DefaultLimits.AutoScale())) 243 require.NoError(t, err) 244 245 mgr := newModule(nil, nil, nil, nil, rm) 246 247 state, err := mgr.ResourceState(context.Background()) 248 require.NoError(t, err) 249 250 assert.NotNil(t, state) 251 }