Skip to content

Commit

Permalink
tests: integrate connection gating tests into the transport tests
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Apr 5, 2023
1 parent f834b2c commit eccdae1
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 101 deletions.
Original file line number Diff line number Diff line change
@@ -1,37 +1,23 @@
package connectiongating
package transport_integration

import (
"context"
"fmt"
"testing"
"time"

"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/core/protocol"

"github.com/libp2p/go-libp2p/core/network"

"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/protocol"
"github.com/libp2p/go-libp2p/p2p/net/swarm"

"github.com/golang/mock/gomock"
ma "github.com/multiformats/go-multiaddr"
"github.com/stretchr/testify/require"
)

//go:generate go run github.com/golang/mock/mockgen -package connectiongating -destination mock_connection_gater_test.go github.com/libp2p/go-libp2p/core/connmgr ConnectionGater

// This list should contain (at least) one address for every transport we have.
var addrs = []ma.Multiaddr{
ma.StringCast("/ip4/127.0.0.1/tcp/0"),
ma.StringCast("/ip4/127.0.0.1/tcp/0/ws"),
ma.StringCast("/ip4/127.0.0.1/udp/0/quic"),
ma.StringCast("/ip4/127.0.0.1/udp/0/quic-v1"),
ma.StringCast("/ip4/127.0.0.1/udp/0/quic-v1/webtransport"),
}

func transportName(a ma.Multiaddr) string {
_, tr := ma.SplitLast(a)
return tr.Protocol().Name
}
//go:generate go run github.com/golang/mock/mockgen -package transport_integration -destination mock_connection_gater_test.go github.com/libp2p/go-libp2p/core/connmgr ConnectionGater

func stripCertHash(addr ma.Multiaddr) ma.Multiaddr {
for {
Expand All @@ -44,18 +30,14 @@ func stripCertHash(addr ma.Multiaddr) ma.Multiaddr {
}

func TestInterceptPeerDial(t *testing.T) {
for _, a := range addrs {
t.Run(fmt.Sprintf("dialing %s", transportName(a)), func(t *testing.T) {
for _, tc := range transportsToTest {
t.Run(tc.Name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
connGater := NewMockConnectionGater(ctrl)

h1, err := libp2p.New(libp2p.ConnectionGater(connGater))
require.NoError(t, err)
defer h1.Close()
h2, err := libp2p.New(libp2p.ListenAddrs(a))
require.NoError(t, err)
defer h2.Close()
h1 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true, ConnGater: connGater})
h2 := tc.HostGenerator(t, TransportTestCaseOpts{})
require.Len(t, h2.Addrs(), 1)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
Expand All @@ -67,18 +49,14 @@ func TestInterceptPeerDial(t *testing.T) {
}

func TestInterceptAddrDial(t *testing.T) {
for _, a := range addrs {
t.Run(fmt.Sprintf("dialing %s", transportName(a)), func(t *testing.T) {
for _, tc := range transportsToTest {
t.Run(tc.Name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
connGater := NewMockConnectionGater(ctrl)

h1, err := libp2p.New(libp2p.ConnectionGater(connGater))
require.NoError(t, err)
defer h1.Close()
h2, err := libp2p.New(libp2p.ListenAddrs(a))
require.NoError(t, err)
defer h2.Close()
h1 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true, ConnGater: connGater})
h2 := tc.HostGenerator(t, TransportTestCaseOpts{})
require.Len(t, h2.Addrs(), 1)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
Expand All @@ -93,18 +71,15 @@ func TestInterceptAddrDial(t *testing.T) {
}

func TestInterceptSecuredOutgoing(t *testing.T) {
for _, a := range addrs {
t.Run(fmt.Sprintf("dialing %s", transportName(a)), func(t *testing.T) {
for _, tc := range transportsToTest {
t.Run(tc.Name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
connGater := NewMockConnectionGater(ctrl)

h1, err := libp2p.New(libp2p.ConnectionGater(connGater))
require.NoError(t, err)
defer h1.Close()
h2, err := libp2p.New(libp2p.ListenAddrs(a))
require.NoError(t, err)
defer h2.Close()
h1 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true, ConnGater: connGater})
h2 := tc.HostGenerator(t, TransportTestCaseOpts{})
require.Len(t, h2.Addrs(), 1)
require.Len(t, h2.Addrs(), 1)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
Expand All @@ -117,30 +92,26 @@ func TestInterceptSecuredOutgoing(t *testing.T) {
require.Equal(t, stripCertHash(h2.Addrs()[0]).String(), addrs.RemoteMultiaddr().String())
}),
)
err = h1.Connect(ctx, peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()})
require.Error(t, err)
require.Error(t, h1.Connect(ctx, peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()}))
// There's a bug in the WebSocket library, making Close block for up to 5s.
// See https://github.com/nhooyr/websocket/issues/355 for details.
if _, err := a.ValueForProtocol(ma.P_WS); err == nil {
if _, err := h2.Addrs()[0].ValueForProtocol(ma.P_WS); err == nil {
require.NotErrorIs(t, err, context.DeadlineExceeded)
}
})
}
}

func TestInterceptUpgradedOutgoing(t *testing.T) {
for _, a := range addrs {
t.Run(fmt.Sprintf("dialing %s", transportName(a)), func(t *testing.T) {
for _, tc := range transportsToTest {
t.Run(tc.Name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
connGater := NewMockConnectionGater(ctrl)

h1, err := libp2p.New(libp2p.ConnectionGater(connGater))
require.NoError(t, err)
defer h1.Close()
h2, err := libp2p.New(libp2p.ListenAddrs(a))
require.NoError(t, err)
defer h2.Close()
h1 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true, ConnGater: connGater})
h2 := tc.HostGenerator(t, TransportTestCaseOpts{})
require.Len(t, h2.Addrs(), 1)
require.Len(t, h2.Addrs(), 1)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
Expand All @@ -155,33 +126,25 @@ func TestInterceptUpgradedOutgoing(t *testing.T) {
require.Equal(t, h1.ID(), c.LocalPeer())
require.Equal(t, h2.ID(), c.RemotePeer())
}))
err = h1.Connect(ctx, peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()})
require.Error(t, err)
require.Error(t, h1.Connect(ctx, peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()}))
// There's a bug in the WebSocket library, making Close block for up to 5s.
// See https://github.com/nhooyr/websocket/issues/355 for details.
if _, err := a.ValueForProtocol(ma.P_WS); err == nil {
if _, err := h2.Addrs()[0].ValueForProtocol(ma.P_WS); err == nil {
require.NotErrorIs(t, err, context.DeadlineExceeded)
}
})
}
}

func TestInterceptAccept(t *testing.T) {
for _, a := range addrs {
t.Run(fmt.Sprintf("accepting %s", transportName(a)), func(t *testing.T) {
for _, tc := range transportsToTest {
t.Run(tc.Name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
connGater := NewMockConnectionGater(ctrl)

h1, err := libp2p.New()
require.NoError(t, err)
defer h1.Close()
h2, err := libp2p.New(
libp2p.ListenAddrs(a),
libp2p.ConnectionGater(connGater),
)
require.NoError(t, err)
defer h2.Close()
h1 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true})
h2 := tc.HostGenerator(t, TransportTestCaseOpts{ConnGater: connGater})
require.Len(t, h2.Addrs(), 1)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
Expand All @@ -192,33 +155,26 @@ func TestInterceptAccept(t *testing.T) {
require.Equal(t, stripCertHash(h2.Addrs()[0]), addrs.LocalMultiaddr())
})
h1.Peerstore().AddAddrs(h2.ID(), h2.Addrs(), time.Hour)
_, err = h1.NewStream(ctx, h2.ID(), protocol.TestingID)
_, err := h1.NewStream(ctx, h2.ID(), protocol.TestingID)
require.Error(t, err)
// There's a bug in the WebSocket library, making Close block for up to 5s.
// See https://github.com/nhooyr/websocket/issues/355 for details.
if _, err := a.ValueForProtocol(ma.P_WS); err == nil {
if _, err := h2.Addrs()[0].ValueForProtocol(ma.P_WS); err == nil {
require.NotErrorIs(t, err, context.DeadlineExceeded)
}
})
}
}

func TestInterceptSecuredIncoming(t *testing.T) {
for _, a := range addrs {
t.Run(fmt.Sprintf("accepting %s", transportName(a)), func(t *testing.T) {
for _, tc := range transportsToTest {
t.Run(tc.Name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
connGater := NewMockConnectionGater(ctrl)

h1, err := libp2p.New()
require.NoError(t, err)
defer h1.Close()
h2, err := libp2p.New(
libp2p.ListenAddrs(a),
libp2p.ConnectionGater(connGater),
)
require.NoError(t, err)
defer h2.Close()
h1 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true})
h2 := tc.HostGenerator(t, TransportTestCaseOpts{ConnGater: connGater})
require.Len(t, h2.Addrs(), 1)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
Expand All @@ -231,34 +187,26 @@ func TestInterceptSecuredIncoming(t *testing.T) {
}),
)
h1.Peerstore().AddAddrs(h2.ID(), h2.Addrs(), time.Hour)
_, err = h1.NewStream(ctx, h2.ID(), protocol.TestingID)
_, err := h1.NewStream(ctx, h2.ID(), protocol.TestingID)
require.Error(t, err)
// There's a bug in the WebSocket library, making Close block for up to 5s.
// See https://github.com/nhooyr/websocket/issues/355 for details.
if _, err := a.ValueForProtocol(ma.P_WS); err == nil {
if _, err := h2.Addrs()[0].ValueForProtocol(ma.P_WS); err == nil {
require.NotErrorIs(t, err, context.DeadlineExceeded)
}
})
}
}

func TestInterceptUpgradedIncoming(t *testing.T) {
for _, a := range addrs {
_, tr := ma.SplitLast(a)
t.Run(fmt.Sprintf("accepting %s", tr.Protocol().Name), func(t *testing.T) {
for _, tc := range transportsToTest {
t.Run(tc.Name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
connGater := NewMockConnectionGater(ctrl)

h1, err := libp2p.New()
require.NoError(t, err)
defer h1.Close()
h2, err := libp2p.New(
libp2p.ListenAddrs(a),
libp2p.ConnectionGater(connGater),
)
require.NoError(t, err)
defer h2.Close()
h1 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true})
h2 := tc.HostGenerator(t, TransportTestCaseOpts{ConnGater: connGater})
require.Len(t, h2.Addrs(), 1)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
Expand All @@ -274,11 +222,11 @@ func TestInterceptUpgradedIncoming(t *testing.T) {
}),
)
h1.Peerstore().AddAddrs(h2.ID(), h2.Addrs(), time.Hour)
_, err = h1.NewStream(ctx, h2.ID(), protocol.TestingID)
_, err := h1.NewStream(ctx, h2.ID(), protocol.TestingID)
require.Error(t, err)
// There's a bug in the WebSocket library, making Close block for up to 5s.
// See https://github.com/nhooyr/websocket/issues/355 for details.
if _, err := a.ValueForProtocol(ma.P_WS); err == nil {
if _, err := h2.Addrs()[0].ValueForProtocol(ma.P_WS); err == nil {
require.NotErrorIs(t, err, context.DeadlineExceeded)
}
})
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/config"
"github.com/libp2p/go-libp2p/core/connmgr"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
Expand All @@ -30,8 +31,9 @@ type TransportTestCase struct {
}

type TransportTestCaseOpts struct {
NoListen bool
NoRcmgr bool
NoListen bool
NoRcmgr bool
ConnGater connmgr.ConnectionGater
}

func transformOpts(opts TransportTestCaseOpts) []config.Option {
Expand All @@ -40,6 +42,9 @@ func transformOpts(opts TransportTestCaseOpts) []config.Option {
if opts.NoRcmgr {
libp2pOpts = append(libp2pOpts, libp2p.ResourceManager(&network.NullResourceManager{}))
}
if opts.ConnGater != nil {
libp2pOpts = append(libp2pOpts, libp2p.ConnectionGater(opts.ConnGater))
}
return libp2pOpts
}

Expand Down

0 comments on commit eccdae1

Please sign in to comment.