Skip to content

Commit

Permalink
check the options passed to transport constructor match
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Nov 10, 2022
1 parent d0704fd commit b90b74f
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
56 changes: 55 additions & 1 deletion libp2p_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func TestTransportConstructorTCP(t *testing.T) {

func TestTransportConstructorQUIC(t *testing.T) {
h, err := New(
Transport(quic.NewTransport),
Transport(quic.NewTransport, quic.DisableReuseport()),
DisableRelay(),
)
require.NoError(t, err)
Expand All @@ -197,6 +197,60 @@ func TestTransportConstructorQUIC(t *testing.T) {
require.Contains(t, err.Error(), swarm.ErrNoTransport.Error())
}

type mockTransport struct{}

func (m mockTransport) Dial(context.Context, ma.Multiaddr, peer.ID) (transport.CapableConn, error) {
panic("implement me")
}

func (m mockTransport) CanDial(ma.Multiaddr) bool { panic("implement me") }
func (m mockTransport) Listen(ma.Multiaddr) (transport.Listener, error) { panic("implement me") }
func (m mockTransport) Protocols() []int { return []int{1337} }
func (m mockTransport) Proxy() bool { panic("implement me") }

var _ transport.Transport = &mockTransport{}

func TestTransportConstructorWithoutOpts(t *testing.T) {
t.Run("successful", func(t *testing.T) {
var called bool
constructor := func() transport.Transport {
called = true
return &mockTransport{}
}

h, err := New(
Transport(constructor),
DisableRelay(),
)
require.NoError(t, err)
require.True(t, called, "expected constructor to be called")
defer h.Close()
})

t.Run("with options", func(t *testing.T) {
var called bool
constructor := func() transport.Transport {
called = true
return &mockTransport{}
}

_, err := New(
Transport(constructor, tcp.DisableReuseport()),
DisableRelay(),
)
require.EqualError(t, err, "transport constructor doesn't take any options")
require.False(t, called, "didn't expected constructor to be called")
})
}

func TestTransportConstructorWithWrongOpts(t *testing.T) {
_, err := New(
Transport(quic.NewTransport, tcp.DisableReuseport()),
DisableRelay(),
)
require.EqualError(t, err, "transport option of type tcp.Option not assignable to libp2pquic.Option")
}

func TestSecurityConstructor(t *testing.T) {
h, err := New(
Transport(tcp.NewTCPTransport),
Expand Down
13 changes: 13 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,19 @@ func Transport(constructor interface{}, opts ...interface{}) Option {
typ := reflect.ValueOf(constructor).Type()
numParams := typ.NumIn()
isVariadic := typ.IsVariadic()

if !isVariadic && len(opts) > 0 {
return errors.New("transport constructor doesn't take any options")
}
if isVariadic && numParams >= 1 {
paramType := typ.In(numParams - 1).Elem()
for _, opt := range opts {
if typ := reflect.TypeOf(opt); !typ.AssignableTo(paramType) {
return fmt.Errorf("transport option of type %s not assignable to %s", typ, paramType)
}
}
}

var params []string
if isVariadic && len(opts) > 0 {
// If there are transport options, apply the tag.
Expand Down

0 comments on commit b90b74f

Please sign in to comment.