Skip to content

Commit

Permalink
swarm_test: support more transports for GenSwarm
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sukunrt committed Dec 30, 2024
1 parent 2209ae0 commit 53e4d7e
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 15 deletions.
24 changes: 22 additions & 2 deletions p2p/net/swarm/swarm_notif_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
. "github.com/libp2p/go-libp2p/p2p/net/swarm"

ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"

"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -93,11 +94,30 @@ func TestNotifications(t *testing.T) {
}
}

normalizeAddrs := func(a ma.Multiaddr, isLocal bool) ma.Multiaddr {
x, _ := ma.SplitFunc(a, func(c ma.Component) bool {
if c.Protocol().Code == ma.P_WEBTRANSPORT {
return true
}
return false
})
if isLocal {
if manet.IsIPUnspecified(x) {
ip, rest := ma.SplitFirst(x)
if ip.Protocol().Code == ma.P_IP4 {
return ma.StringCast("/ip4/127.0.0.1").Encapsulate(rest)
} else {
return ma.StringCast("/ip6/::1").Encapsulate(rest)
}
}
}
return x
}
complement := func(c network.Conn) (*Swarm, *netNotifiee, *Conn) {
for i, s := range swarms {
for _, c2 := range s.Conns() {
if c.LocalMultiaddr().Equal(c2.RemoteMultiaddr()) &&
c2.LocalMultiaddr().Equal(c.RemoteMultiaddr()) {
if normalizeAddrs(c.LocalMultiaddr(), true).Equal(normalizeAddrs(c2.RemoteMultiaddr(), false)) &&
normalizeAddrs(c2.LocalMultiaddr(), true).Equal(normalizeAddrs(c.RemoteMultiaddr(), false)) {
return s, notifiees[i], c2.(*Conn)
}
}
Expand Down
7 changes: 3 additions & 4 deletions p2p/net/swarm/swarm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,8 @@ func makeSwarms(t *testing.T, num int, opts ...Option) []*swarm.Swarm {

func connectSwarms(t *testing.T, ctx context.Context, swarms []*swarm.Swarm) {
var wg sync.WaitGroup
connect := func(s *swarm.Swarm, dst peer.ID, addr ma.Multiaddr) {
// TODO: make a DialAddr func.
s.Peerstore().AddAddr(dst, addr, peerstore.PermanentAddrTTL)
connect := func(s *swarm.Swarm, dst peer.ID, addrs []ma.Multiaddr) {
s.Peerstore().AddAddrs(dst, addrs, peerstore.TempAddrTTL)
if _, err := s.DialPeer(ctx, dst); err != nil {
t.Fatal("error swarm dialing to peer", err)
}
Expand All @@ -92,7 +91,7 @@ func connectSwarms(t *testing.T, ctx context.Context, swarms []*swarm.Swarm) {
for i, s1 := range swarms {
for _, s2 := range swarms[i+1:] {
wg.Add(1)
connect(s1, s2.LocalPeer(), s2.ListenAddresses()[0]) // try the first.
connect(s1, s2.LocalPeer(), s2.ListenAddresses())
}
}
wg.Wait()
Expand Down
105 changes: 96 additions & 9 deletions p2p/net/swarm/testing/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package testing

import (
"crypto/rand"
"net"
"testing"
"time"

Expand All @@ -24,21 +25,26 @@ import (
libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
"github.com/libp2p/go-libp2p/p2p/transport/quicreuse"
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
libp2pwebrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc"
libp2pwebtransport "github.com/libp2p/go-libp2p/p2p/transport/webtransport"

ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"
"github.com/quic-go/quic-go"
"github.com/stretchr/testify/require"
)

type config struct {
disableReuseport bool
dialOnly bool
disableTCP bool
disableQUIC bool
connectionGater connmgr.ConnectionGater
sk crypto.PrivKey
swarmOpts []swarm.Option
eventBus event.Bus
disableReuseport bool
dialOnly bool
disableTCP bool
disableQUIC bool
disableWebTransport bool
disableWebRTC bool
connectionGater connmgr.ConnectionGater
sk crypto.PrivKey
swarmOpts []swarm.Option
eventBus event.Bus
clock
}

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

// OptDisableWebTransport disables WebTransport.
var OptDisableWebTransport Option = func(_ testing.TB, c *config) {
c.disableWebTransport = true
}

// OptDisableWebRTC disables WebRTC.
var OptDisableWebRTC Option = func(_ testing.TB, c *config) {
c.disableWebRTC = true
}

// OptConnGater configures the given connection gater on the test
func OptConnGater(cg connmgr.ConnectionGater) Option {
return func(_ testing.TB, c *config) {
Expand Down Expand Up @@ -175,8 +191,10 @@ func GenSwarm(t testing.TB, opts ...Option) *swarm.Swarm {
}
}
}
var quicListenAddr ma.Multiaddr
var reuse *quicreuse.ConnManager
if !cfg.disableQUIC {
reuse, err := quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
reuse, err = quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
if err != nil {
t.Fatal(err)
}
Expand All @@ -191,6 +209,75 @@ func GenSwarm(t testing.TB, opts ...Option) *swarm.Swarm {
if err := s.Listen(ma.StringCast("/ip4/127.0.0.1/udp/0/quic-v1")); err != nil {
t.Fatal(err)
}
for _, a := range s.ListenAddresses() {
if _, err := a.ValueForProtocol(ma.P_QUIC_V1); err == nil {
quicListenAddr = a
break
}
}
}
}
if !cfg.disableWebTransport {
if reuse == nil {
reuse, err = quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
if err != nil {
t.Fatal(err)
}
}
wtTransport, err := libp2pwebtransport.New(priv, nil, reuse, cfg.connectionGater, nil)
if err != nil {
t.Fatal(err)
}
if err := s.AddTransport(wtTransport); err != nil {
t.Fatal(err)
}
if !cfg.dialOnly {
listenAddr := ma.StringCast("/ip4/127.0.0.1/udp/0/quic-v1/webtransport")
if quicListenAddr != nil {
listenAddr = quicListenAddr.Encapsulate(ma.StringCast("/webtransport"))
}
if err := s.Listen(listenAddr); err != nil {
t.Fatal(err)
}
}
}

if !cfg.disableWebRTC {
listenUDPFn := func(network string, laddr *net.UDPAddr) (net.PacketConn, error) {
hasQuicAddrPortFor := func(network string, laddr *net.UDPAddr) bool {
quicAddrPorts := map[string]struct{}{}
for _, addr := range s.ListenAddresses() {
if _, err := addr.ValueForProtocol(ma.P_QUIC_V1); err == nil {
netw, addr, err := manet.DialArgs(addr)
if err != nil {
return false
}
quicAddrPorts[netw+"_"+addr] = struct{}{}
}
}
_, ok := quicAddrPorts[network+"_"+laddr.String()]
return ok
}
if hasQuicAddrPortFor(network, laddr) {
return reuse.SharedNonQUICPacketConn(network, laddr)
}
return net.ListenUDP(network, laddr)
}
wrtcTransport, err := libp2pwebrtc.New(priv, nil, cfg.connectionGater, nil, listenUDPFn)
if err != nil {
t.Fatal(err)
}
if err := s.AddTransport(wrtcTransport); err != nil {
t.Fatal(err)
}
if !cfg.dialOnly {
listenAddr := ma.StringCast("/ip4/127.0.0.1/udp/0/webrtc-direct")
if quicListenAddr != nil {
listenAddr = quicListenAddr.Decapsulate(ma.StringCast("/quic-v1")).Encapsulate(ma.StringCast("/webrtc-direct"))
}
if err := s.Listen(listenAddr); err != nil {
t.Fatal(err)
}
}
}
if !cfg.dialOnly {
Expand Down

0 comments on commit 53e4d7e

Please sign in to comment.