1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
package quic
import (
"context"
"io"
"os"
"testing"
"time"
"github.com/quic-go/quic-go/internal/mocks"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/wire"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
)
func TestStreamDeadlines(t *testing.T) {
const streamID protocol.StreamID = 1337
mockCtrl := gomock.NewController(t)
mockSender := NewMockStreamSender(mockCtrl)
mockFC := mocks.NewMockStreamFlowController(mockCtrl)
str := newStream(context.Background(), streamID, mockSender, mockFC, false)
// SetDeadline sets both read and write deadlines
str.SetDeadline(time.Now().Add(-time.Second))
n, err := (&writerWithTimeout{Writer: str, Timeout: time.Second}).Write([]byte("foobar"))
require.ErrorIs(t, err, os.ErrDeadlineExceeded)
require.Zero(t, n)
mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(6), false, gomock.Any()).AnyTimes()
require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, time.Now()))
n, err = (&readerWithTimeout{Reader: str, Timeout: time.Second}).Read(make([]byte, 6))
require.ErrorIs(t, err, os.ErrDeadlineExceeded)
require.Zero(t, n)
}
func TestStreamCompletion(t *testing.T) {
completeReadSide := func(
t *testing.T,
str *Stream,
mockCtrl *gomock.Controller,
mockFC *mocks.MockStreamFlowController,
) {
t.Helper()
mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(6), true, gomock.Any())
mockFC.EXPECT().AddBytesRead(protocol.ByteCount(6))
require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{
StreamID: str.StreamID(),
Data: []byte("foobar"),
Fin: true,
}, time.Now()))
_, err := (&readerWithTimeout{Reader: str, Timeout: time.Second}).Read(make([]byte, 6))
require.ErrorIs(t, err, io.EOF)
require.True(t, mockCtrl.Satisfied())
}
completeWriteSide := func(
t *testing.T,
str *Stream,
mockCtrl *gomock.Controller,
mockFC *mocks.MockStreamFlowController,
mockSender *MockStreamSender,
) {
t.Helper()
mockSender.EXPECT().onHasStreamData(str.StreamID(), gomock.Any()).Times(2)
_, err := (&writerWithTimeout{Writer: str, Timeout: time.Second}).Write([]byte("foobar"))
require.NoError(t, err)
require.NoError(t, str.Close())
mockFC.EXPECT().SendWindowSize().Return(protocol.MaxByteCount)
mockFC.EXPECT().AddBytesSent(protocol.ByteCount(6))
f, _, _ := str.popStreamFrame(protocol.MaxByteCount, protocol.Version1)
require.NotNil(t, f.Frame)
require.True(t, f.Frame.Fin)
f.Handler.OnAcked(f.Frame)
require.True(t, mockCtrl.Satisfied())
}
const streamID protocol.StreamID = 1337
t.Run("first read, then write", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
mockSender := NewMockStreamSender(mockCtrl)
mockFC := mocks.NewMockStreamFlowController(mockCtrl)
str := newStream(context.Background(), streamID, mockSender, mockFC, false)
completeReadSide(t, str, mockCtrl, mockFC)
mockSender.EXPECT().onStreamCompleted(streamID)
completeWriteSide(t, str, mockCtrl, mockFC, mockSender)
})
t.Run("first write, then read", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
mockSender := NewMockStreamSender(mockCtrl)
mockFC := mocks.NewMockStreamFlowController(mockCtrl)
str := newStream(context.Background(), streamID, mockSender, mockFC, false)
completeWriteSide(t, str, mockCtrl, mockFC, mockSender)
mockSender.EXPECT().onStreamCompleted(streamID)
completeReadSide(t, str, mockCtrl, mockFC)
})
}
|