forked from quic-go/quic-go
use synctest to make the send queue tests fully deterministic (#5302)
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/synctest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -20,6 +21,7 @@ func getPacketWithContents(b []byte) *packetBuffer {
|
||||
}
|
||||
|
||||
func TestSendQueueSendOnePacket(t *testing.T) {
|
||||
synctest.Test(t, func(t *testing.T) {
|
||||
mockCtrl := gomock.NewController(t)
|
||||
c := NewMockSendConn(mockCtrl)
|
||||
q := newSendQueue(c)
|
||||
@@ -36,22 +38,27 @@ func TestSendQueueSendOnePacket(t *testing.T) {
|
||||
}()
|
||||
|
||||
q.Send(getPacketWithContents([]byte("foobar")), 10, protocol.ECT1)
|
||||
synctest.Wait()
|
||||
|
||||
select {
|
||||
case <-written:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("timeout")
|
||||
default:
|
||||
t.Fatal("write should have returned")
|
||||
}
|
||||
|
||||
q.Close()
|
||||
synctest.Wait()
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("timeout")
|
||||
default:
|
||||
t.Fatal("Run should have returned")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSendQueueBlocking(t *testing.T) {
|
||||
synctest.Test(t, func(t *testing.T) {
|
||||
mockCtrl := gomock.NewController(t)
|
||||
c := NewMockSendConn(mockCtrl)
|
||||
q := newSendQueue(c)
|
||||
@@ -76,7 +83,7 @@ func TestSendQueueBlocking(t *testing.T) {
|
||||
}()
|
||||
|
||||
// +1, since one packet will be queued in the Write call
|
||||
for i := 0; i < sendQueueCapacity+1; i++ {
|
||||
for i := range sendQueueCapacity + 1 {
|
||||
require.False(t, q.WouldBlock())
|
||||
q.Send(getPacketWithContents([]byte("foobar")), 10, protocol.ECT1)
|
||||
// make sure that the first packet is actually enqueued in the Write call
|
||||
@@ -117,28 +124,34 @@ func TestSendQueueBlocking(t *testing.T) {
|
||||
close(closed)
|
||||
}()
|
||||
|
||||
synctest.Wait()
|
||||
|
||||
select {
|
||||
case <-closed:
|
||||
t.Fatal("Close should have blocked")
|
||||
case <-time.After(scaleDuration(10 * time.Millisecond)):
|
||||
default:
|
||||
}
|
||||
|
||||
for i := 0; i < sendQueueCapacity; i++ {
|
||||
for range sendQueueCapacity {
|
||||
blockWrite <- struct{}{}
|
||||
}
|
||||
synctest.Wait()
|
||||
|
||||
select {
|
||||
case <-closed:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("timeout")
|
||||
default:
|
||||
t.Fatal("Close should have returned")
|
||||
}
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("timeout")
|
||||
default:
|
||||
t.Fatal("Run should have returned")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSendQueueWriteError(t *testing.T) {
|
||||
synctest.Test(t, func(t *testing.T) {
|
||||
mockCtrl := gomock.NewController(t)
|
||||
c := NewMockSendConn(mockCtrl)
|
||||
q := newSendQueue(c)
|
||||
@@ -149,27 +162,32 @@ func TestSendQueueWriteError(t *testing.T) {
|
||||
errChan := make(chan error, 1)
|
||||
go func() { errChan <- q.Run() }()
|
||||
|
||||
synctest.Wait()
|
||||
|
||||
select {
|
||||
case err := <-errChan:
|
||||
require.ErrorIs(t, err, assert.AnError)
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("timeout")
|
||||
default:
|
||||
t.Fatal("Run should have returned")
|
||||
}
|
||||
|
||||
// further calls to Send should not block
|
||||
sent := make(chan struct{})
|
||||
go func() {
|
||||
defer close(sent)
|
||||
for i := 0; i < 2*sendQueueCapacity; i++ {
|
||||
for range 2 * sendQueueCapacity {
|
||||
q.Send(getPacketWithContents([]byte("raboof")), 6, protocol.ECNNon)
|
||||
}
|
||||
}()
|
||||
|
||||
synctest.Wait()
|
||||
|
||||
select {
|
||||
case <-sent:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("timeout")
|
||||
default:
|
||||
t.Fatal("Send should have returned")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSendQueueSendProbe(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user