test: add unit test for peering service
Steven Allen committed
May 25, 2020 at 20:02 UTC
fe2b289d3002ed11a1dbcc0521bc42d33f0d46ed
1 file changed
+134
-1
peering/peering_test.go
+134
-1
@@ -1,6 +1,139 @@
1
package peering
2
3
-import "testing"
3
+import (
4
+ "context"
5
+ "testing"
6
+ "time"
7
+
8
+ "github.com/libp2p/go-libp2p"
9
+ connmgr "github.com/libp2p/go-libp2p-connmgr"
10
+ "github.com/libp2p/go-libp2p-core/host"
11
+ "github.com/libp2p/go-libp2p-core/network"
12
+ "github.com/libp2p/go-libp2p-core/peer"
13
+
14
+ "github.com/stretchr/testify/require"
15
+)
16
+
17
+func newNode(ctx context.Context, t *testing.T) host.Host {
18
+ h, err := libp2p.New(
19
+ ctx,
20
+ libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0"),
21
+ // We'd like to set the connection manager low water to 0, but
22
+ // that would disable the connection manager.
23
+ libp2p.ConnectionManager(connmgr.NewConnManager(1, 100, 0)),
24
+ )
25
+ require.NoError(t, err)
26
+ return h
27
+}
28
29
func TestPeeringService(t *testing.T) {
30
+ ctx, cancel := context.WithCancel(context.Background())
31
+ defer cancel()
32
+
33
+ h1 := newNode(ctx, t)
34
+ ps1 := NewPeeringService(h1)
35
+
36
+ h2 := newNode(ctx, t)
37
+ h3 := newNode(ctx, t)
38
+ h4 := newNode(ctx, t)
39
+
40
+ // peer 1 -> 2
41
+ ps1.AddPeer(peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()})
42
+
43
+ // We haven't started so we shouldn't have any peers.
44
+ require.Never(t, func() bool {
45
+ return len(h1.Network().Peers()) > 0
46
+ }, 100*time.Millisecond, 1*time.Second, "expected host 1 to have no peers")
47
+
48
+ // Use p4 to take up the one slot we have in the connection manager.
49
+ for _, h := range []host.Host{h1, h2} {
50
+ require.NoError(t, h.Connect(ctx, peer.AddrInfo{ID: h4.ID(), Addrs: h4.Addrs()}))
51
+ h.ConnManager().TagPeer(h4.ID(), "sticky-peer", 1000)
52
+ }
53
+
54
+ // Now start.
55
+ require.NoError(t, ps1.Start())
56
+ // starting twice is fine.
57
+ require.NoError(t, ps1.Start())
58
+
59
+ // We should eventually connect.
60
+ require.Eventually(t, func() bool {
61
+ return h1.Network().Connectedness(h2.ID()) == network.Connected
62
+ }, 30*time.Second, 10*time.Millisecond)
63
+
64
+ // Now explicitly connect to p3.
65
+ require.NoError(t, h1.Connect(ctx, peer.AddrInfo{ID: h3.ID(), Addrs: h3.Addrs()}))
66
+ require.Eventually(t, func() bool {
67
+ return h1.Network().Connectedness(h2.ID()) == network.Connected
68
+ }, 30*time.Second, 100*time.Millisecond)
69
+
70
+ require.Len(t, h1.Network().Peers(), 3)
71
+
72
+ // force a disconnect
73
+ h1.ConnManager().TrimOpenConns(ctx)
74
+
75
+ // Should disconnect from p3.
76
+ require.Eventually(t, func() bool {
77
+ return h1.Network().Connectedness(h3.ID()) != network.Connected
78
+ }, 5*time.Second, 10*time.Millisecond)
79
+
80
+ // Should remain connected to p2
81
+ require.Never(t, func() bool {
82
+ return h1.Network().Connectedness(h2.ID()) != network.Connected
83
+ }, 5*time.Second, 1*time.Second)
84
+
85
+ // Now force h2 to disconnect (we have an asymmetric peering).
86
+ conns := h2.Network().ConnsToPeer(h1.ID())
87
+ require.NotEmpty(t, conns)
88
+ h2.ConnManager().TrimOpenConns(ctx)
89
+
90
+ // All conns to peer should eventually close.
91
+ for _, c := range conns {
92
+ require.Eventually(t, func() bool {
93
+ s, err := c.NewStream()
94
+ if s != nil {
95
+ _ = s.Reset()
96
+ }
97
+ return err != nil
98
+ }, 5*time.Second, 10*time.Millisecond)
99
+ }
100
+
101
+ // Should eventually re-connect.
102
+ require.Eventually(t, func() bool {
103
+ return h1.Network().Connectedness(h2.ID()) == network.Connected
104
+ }, 30*time.Second, 1*time.Second)
105
+
106
+ // Unprotect 2 from 1.
107
+ ps1.RemovePeer(h2.ID())
108
+
109
+ // Trim connections.
110
+ h1.ConnManager().TrimOpenConns(ctx)
111
+
112
+ // Should disconnect
113
+ require.Eventually(t, func() bool {
114
+ return h1.Network().Connectedness(h2.ID()) != network.Connected
115
+ }, 5*time.Second, 10*time.Millisecond)
116
+
117
+ // Should never reconnect.
118
+ require.Never(t, func() bool {
119
+ return h1.Network().Connectedness(h2.ID()) == network.Connected
120
+ }, 20*time.Second, 1*time.Second)
121
+
122
+ // Until added back
123
+ ps1.AddPeer(peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()})
124
+ ps1.AddPeer(peer.AddrInfo{ID: h3.ID(), Addrs: h3.Addrs()})
125
+ require.Eventually(t, func() bool {
126
+ return h1.Network().Connectedness(h2.ID()) == network.Connected
127
+ }, 30*time.Second, 1*time.Second)
128
+ require.Eventually(t, func() bool {
129
+ return h1.Network().Connectedness(h3.ID()) == network.Connected
130
+ }, 30*time.Second, 1*time.Second)
131
+
132
+ // Should be able to repeatedly stop.
133
+ require.NoError(t, ps1.Stop())
134
+ require.NoError(t, ps1.Stop())
135
+
136
+ // Adding and removing should work after stopping.
137
+ ps1.AddPeer(peer.AddrInfo{ID: h4.ID(), Addrs: h4.Addrs()})
138
+ ps1.RemovePeer(h2.ID())
139
}