forked from quic-go/quic-go
107 lines
2.5 KiB
Go
107 lines
2.5 KiB
Go
package http3
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestDatagramReceiving(t *testing.T) {
|
|
dg := newDatagrammer(nil)
|
|
|
|
type result struct {
|
|
data []byte
|
|
err error
|
|
}
|
|
|
|
// Receive blocks until a datagram is received
|
|
resultChan := make(chan result)
|
|
go func() {
|
|
defer close(resultChan)
|
|
data, err := dg.Receive(context.Background())
|
|
resultChan <- result{data: data, err: err}
|
|
}()
|
|
|
|
select {
|
|
case <-time.After(scaleDuration(10 * time.Millisecond)):
|
|
case <-resultChan:
|
|
t.Fatal("should not have received a datagram")
|
|
}
|
|
dg.enqueue([]byte("foobar"))
|
|
|
|
select {
|
|
case res := <-resultChan:
|
|
require.NoError(t, res.err)
|
|
require.Equal(t, []byte("foobar"), res.data)
|
|
case <-time.After(time.Second):
|
|
t.Fatal("should have received a datagram")
|
|
}
|
|
|
|
// up to 32 datagrams can be queued
|
|
for i := range streamDatagramQueueLen + 1 {
|
|
dg.enqueue([]byte{uint8(i)})
|
|
}
|
|
for i := range streamDatagramQueueLen {
|
|
data, err := dg.Receive(context.Background())
|
|
require.NoError(t, err)
|
|
require.Equal(t, []byte{uint8(i)}, data)
|
|
}
|
|
|
|
// Receive respects the context
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel()
|
|
_, err := dg.Receive(ctx)
|
|
require.ErrorIs(t, err, context.Canceled)
|
|
}
|
|
|
|
func TestDatagramReceiveError(t *testing.T) {
|
|
dg := newDatagrammer(nil)
|
|
|
|
errChan := make(chan error)
|
|
go func() {
|
|
_, err := dg.Receive(context.Background())
|
|
errChan <- err
|
|
}()
|
|
|
|
select {
|
|
case <-time.After(scaleDuration(10 * time.Millisecond)):
|
|
case err := <-errChan:
|
|
t.Fatalf("should not have received an error: %v", err)
|
|
}
|
|
|
|
dg.SetReceiveError(assert.AnError)
|
|
select {
|
|
case err := <-errChan:
|
|
require.ErrorIs(t, err, assert.AnError)
|
|
case <-time.After(time.Second):
|
|
t.Fatal("timeout")
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
defer cancel()
|
|
_, err := dg.Receive(ctx)
|
|
require.ErrorIs(t, err, assert.AnError)
|
|
}
|
|
|
|
func TestDatagramSending(t *testing.T) {
|
|
var sendQueue [][]byte
|
|
errors := []error{nil, nil, assert.AnError}
|
|
dg := newDatagrammer(func(b []byte) error {
|
|
sendQueue = append(sendQueue, b)
|
|
err := errors[0]
|
|
errors = errors[1:]
|
|
return err
|
|
})
|
|
require.NoError(t, dg.Send([]byte("foo")))
|
|
require.NoError(t, dg.Send([]byte("bar")))
|
|
require.ErrorIs(t, dg.Send([]byte("baz")), assert.AnError)
|
|
require.Equal(t, [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")}, sendQueue)
|
|
|
|
dg.SetSendError(net.ErrClosed)
|
|
require.ErrorIs(t, dg.Send([]byte("foobar")), net.ErrClosed)
|
|
}
|