ceremonyclient/go-libp2p/p2p/protocol/circuitv2/client/reservation_test.go
2023-08-20 23:07:43 -05:00

120 lines
3.3 KiB
Go

package client_test
import (
"context"
"errors"
"math"
"testing"
"time"
"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client"
pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb"
"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto"
"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util"
"github.com/stretchr/testify/require"
)
func TestReservationFailures(t *testing.T) {
type testcase struct {
name string
streamHandler network.StreamHandler
err string
status pbv2.Status
}
testcases := []testcase{
{
name: "unsupported protocol",
streamHandler: nil,
err: "protocols not supported",
},
{
name: "wrong message type",
streamHandler: func(s network.Stream) {
util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
Type: pbv2.HopMessage_RESERVE.Enum(),
})
},
err: "unexpected relay response: not a status message",
status: pbv2.Status_MALFORMED_MESSAGE,
},
{
name: "unknown status",
streamHandler: func(s network.Stream) {
status := pbv2.Status(1337)
util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
Type: pbv2.HopMessage_STATUS.Enum(),
Status: &status,
})
},
err: "reservation failed",
status: pbv2.Status(1337),
},
{
name: "invalid time",
streamHandler: func(s network.Stream) {
status := pbv2.Status_OK
expire := uint64(math.MaxUint64)
util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
Type: pbv2.HopMessage_STATUS.Enum(),
Status: &status,
Reservation: &pbv2.Reservation{Expire: &expire},
})
},
err: "received reservation with expiration date in the past",
status: pbv2.Status_MALFORMED_MESSAGE,
},
{
name: "invalid voucher",
streamHandler: func(s network.Stream) {
status := pbv2.Status_OK
expire := uint64(time.Now().Add(time.Hour).UnixNano())
util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
Type: pbv2.HopMessage_STATUS.Enum(),
Status: &status,
Reservation: &pbv2.Reservation{
Expire: &expire,
Voucher: []byte("foobar"),
},
})
},
err: "error consuming voucher envelope: failed when unmarshalling the envelope",
status: pbv2.Status_MALFORMED_MESSAGE,
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
host, err := libp2p.New(libp2p.ResourceManager(&network.NullResourceManager{}))
require.NoError(t, err)
defer host.Close()
if tc.streamHandler != nil {
host.SetStreamHandler(proto.ProtoIDv2Hop, tc.streamHandler)
}
cl, err := libp2p.New(libp2p.ResourceManager(&network.NullResourceManager{}))
require.NoError(t, err)
defer cl.Close()
_, err = client.Reserve(context.Background(), cl, peer.AddrInfo{ID: host.ID(), Addrs: host.Addrs()})
if tc.err == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.err)
if tc.status != 0 {
var re client.ReservationError
if !errors.As(err, &re) {
t.Errorf("expected error to be of type %T", re)
}
if re.Status != tc.status {
t.Errorf("expected status %d got %d", tc.status, re.Status)
}
}
}
})
}
}