Skip to content

Commit 53e4d7e

Browse files
committed
swarm_test: support more transports for GenSwarm
Ideally, we should rewrite this to have the same semantics, opt into transports not opt out, as `libp2p.New`. But I need webtransport and webrtc support to write address inference tests for #3075 Depending on how disruptive this is to users, we can decide on whether to merge or drop this.
1 parent 2209ae0 commit 53e4d7e

File tree

3 files changed

+121
-15
lines changed

3 files changed

+121
-15
lines changed

p2p/net/swarm/swarm_notif_test.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
. "github.com/libp2p/go-libp2p/p2p/net/swarm"
1111

1212
ma "github.com/multiformats/go-multiaddr"
13+
manet "github.com/multiformats/go-multiaddr/net"
1314

1415
"github.com/stretchr/testify/require"
1516
)
@@ -93,11 +94,30 @@ func TestNotifications(t *testing.T) {
9394
}
9495
}
9596

97+
normalizeAddrs := func(a ma.Multiaddr, isLocal bool) ma.Multiaddr {
98+
x, _ := ma.SplitFunc(a, func(c ma.Component) bool {
99+
if c.Protocol().Code == ma.P_WEBTRANSPORT {
100+
return true
101+
}
102+
return false
103+
})
104+
if isLocal {
105+
if manet.IsIPUnspecified(x) {
106+
ip, rest := ma.SplitFirst(x)
107+
if ip.Protocol().Code == ma.P_IP4 {
108+
return ma.StringCast("/ip4/127.0.0.1").Encapsulate(rest)
109+
} else {
110+
return ma.StringCast("/ip6/::1").Encapsulate(rest)
111+
}
112+
}
113+
}
114+
return x
115+
}
96116
complement := func(c network.Conn) (*Swarm, *netNotifiee, *Conn) {
97117
for i, s := range swarms {
98118
for _, c2 := range s.Conns() {
99-
if c.LocalMultiaddr().Equal(c2.RemoteMultiaddr()) &&
100-
c2.LocalMultiaddr().Equal(c.RemoteMultiaddr()) {
119+
if normalizeAddrs(c.LocalMultiaddr(), true).Equal(normalizeAddrs(c2.RemoteMultiaddr(), false)) &&
120+
normalizeAddrs(c2.LocalMultiaddr(), true).Equal(normalizeAddrs(c.RemoteMultiaddr(), false)) {
101121
return s, notifiees[i], c2.(*Conn)
102122
}
103123
}

p2p/net/swarm/swarm_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,8 @@ func makeSwarms(t *testing.T, num int, opts ...Option) []*swarm.Swarm {
7979

8080
func connectSwarms(t *testing.T, ctx context.Context, swarms []*swarm.Swarm) {
8181
var wg sync.WaitGroup
82-
connect := func(s *swarm.Swarm, dst peer.ID, addr ma.Multiaddr) {
83-
// TODO: make a DialAddr func.
84-
s.Peerstore().AddAddr(dst, addr, peerstore.PermanentAddrTTL)
82+
connect := func(s *swarm.Swarm, dst peer.ID, addrs []ma.Multiaddr) {
83+
s.Peerstore().AddAddrs(dst, addrs, peerstore.TempAddrTTL)
8584
if _, err := s.DialPeer(ctx, dst); err != nil {
8685
t.Fatal("error swarm dialing to peer", err)
8786
}
@@ -92,7 +91,7 @@ func connectSwarms(t *testing.T, ctx context.Context, swarms []*swarm.Swarm) {
9291
for i, s1 := range swarms {
9392
for _, s2 := range swarms[i+1:] {
9493
wg.Add(1)
95-
connect(s1, s2.LocalPeer(), s2.ListenAddresses()[0]) // try the first.
94+
connect(s1, s2.LocalPeer(), s2.ListenAddresses())
9695
}
9796
}
9897
wg.Wait()

p2p/net/swarm/testing/testing.go

Lines changed: 96 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package testing
22

33
import (
44
"crypto/rand"
5+
"net"
56
"testing"
67
"time"
78

@@ -24,21 +25,26 @@ import (
2425
libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
2526
"github.com/libp2p/go-libp2p/p2p/transport/quicreuse"
2627
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
28+
libp2pwebrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc"
29+
libp2pwebtransport "github.com/libp2p/go-libp2p/p2p/transport/webtransport"
2730

2831
ma "github.com/multiformats/go-multiaddr"
32+
manet "github.com/multiformats/go-multiaddr/net"
2933
"github.com/quic-go/quic-go"
3034
"github.com/stretchr/testify/require"
3135
)
3236

3337
type config struct {
34-
disableReuseport bool
35-
dialOnly bool
36-
disableTCP bool
37-
disableQUIC bool
38-
connectionGater connmgr.ConnectionGater
39-
sk crypto.PrivKey
40-
swarmOpts []swarm.Option
41-
eventBus event.Bus
38+
disableReuseport bool
39+
dialOnly bool
40+
disableTCP bool
41+
disableQUIC bool
42+
disableWebTransport bool
43+
disableWebRTC bool
44+
connectionGater connmgr.ConnectionGater
45+
sk crypto.PrivKey
46+
swarmOpts []swarm.Option
47+
eventBus event.Bus
4248
clock
4349
}
4450

@@ -88,6 +94,16 @@ var OptDisableQUIC Option = func(_ testing.TB, c *config) {
8894
c.disableQUIC = true
8995
}
9096

97+
// OptDisableWebTransport disables WebTransport.
98+
var OptDisableWebTransport Option = func(_ testing.TB, c *config) {
99+
c.disableWebTransport = true
100+
}
101+
102+
// OptDisableWebRTC disables WebRTC.
103+
var OptDisableWebRTC Option = func(_ testing.TB, c *config) {
104+
c.disableWebRTC = true
105+
}
106+
91107
// OptConnGater configures the given connection gater on the test
92108
func OptConnGater(cg connmgr.ConnectionGater) Option {
93109
return func(_ testing.TB, c *config) {
@@ -175,8 +191,10 @@ func GenSwarm(t testing.TB, opts ...Option) *swarm.Swarm {
175191
}
176192
}
177193
}
194+
var quicListenAddr ma.Multiaddr
195+
var reuse *quicreuse.ConnManager
178196
if !cfg.disableQUIC {
179-
reuse, err := quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
197+
reuse, err = quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
180198
if err != nil {
181199
t.Fatal(err)
182200
}
@@ -191,6 +209,75 @@ func GenSwarm(t testing.TB, opts ...Option) *swarm.Swarm {
191209
if err := s.Listen(ma.StringCast("/ip4/127.0.0.1/udp/0/quic-v1")); err != nil {
192210
t.Fatal(err)
193211
}
212+
for _, a := range s.ListenAddresses() {
213+
if _, err := a.ValueForProtocol(ma.P_QUIC_V1); err == nil {
214+
quicListenAddr = a
215+
break
216+
}
217+
}
218+
}
219+
}
220+
if !cfg.disableWebTransport {
221+
if reuse == nil {
222+
reuse, err = quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
223+
if err != nil {
224+
t.Fatal(err)
225+
}
226+
}
227+
wtTransport, err := libp2pwebtransport.New(priv, nil, reuse, cfg.connectionGater, nil)
228+
if err != nil {
229+
t.Fatal(err)
230+
}
231+
if err := s.AddTransport(wtTransport); err != nil {
232+
t.Fatal(err)
233+
}
234+
if !cfg.dialOnly {
235+
listenAddr := ma.StringCast("/ip4/127.0.0.1/udp/0/quic-v1/webtransport")
236+
if quicListenAddr != nil {
237+
listenAddr = quicListenAddr.Encapsulate(ma.StringCast("/webtransport"))
238+
}
239+
if err := s.Listen(listenAddr); err != nil {
240+
t.Fatal(err)
241+
}
242+
}
243+
}
244+
245+
if !cfg.disableWebRTC {
246+
listenUDPFn := func(network string, laddr *net.UDPAddr) (net.PacketConn, error) {
247+
hasQuicAddrPortFor := func(network string, laddr *net.UDPAddr) bool {
248+
quicAddrPorts := map[string]struct{}{}
249+
for _, addr := range s.ListenAddresses() {
250+
if _, err := addr.ValueForProtocol(ma.P_QUIC_V1); err == nil {
251+
netw, addr, err := manet.DialArgs(addr)
252+
if err != nil {
253+
return false
254+
}
255+
quicAddrPorts[netw+"_"+addr] = struct{}{}
256+
}
257+
}
258+
_, ok := quicAddrPorts[network+"_"+laddr.String()]
259+
return ok
260+
}
261+
if hasQuicAddrPortFor(network, laddr) {
262+
return reuse.SharedNonQUICPacketConn(network, laddr)
263+
}
264+
return net.ListenUDP(network, laddr)
265+
}
266+
wrtcTransport, err := libp2pwebrtc.New(priv, nil, cfg.connectionGater, nil, listenUDPFn)
267+
if err != nil {
268+
t.Fatal(err)
269+
}
270+
if err := s.AddTransport(wrtcTransport); err != nil {
271+
t.Fatal(err)
272+
}
273+
if !cfg.dialOnly {
274+
listenAddr := ma.StringCast("/ip4/127.0.0.1/udp/0/webrtc-direct")
275+
if quicListenAddr != nil {
276+
listenAddr = quicListenAddr.Decapsulate(ma.StringCast("/quic-v1")).Encapsulate(ma.StringCast("/webrtc-direct"))
277+
}
278+
if err := s.Listen(listenAddr); err != nil {
279+
t.Fatal(err)
280+
}
194281
}
195282
}
196283
if !cfg.dialOnly {

0 commit comments

Comments
 (0)