File: stream_test.go

package info (click to toggle)
golang-github-lucas-clemente-quic-go 0.54.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,312 kB
  • sloc: sh: 54; makefile: 7
file content (102 lines) | stat: -rw-r--r-- 3,478 bytes parent folder | download
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)
	})
}