github.com/quic-go/quic-go@v0.44.0/stream_test.go (about)

     1  package quic
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"io"
     7  	"os"
     8  	"strconv"
     9  	"time"
    10  
    11  	"github.com/quic-go/quic-go/internal/mocks"
    12  	"github.com/quic-go/quic-go/internal/protocol"
    13  	"github.com/quic-go/quic-go/internal/wire"
    14  
    15  	. "github.com/onsi/ginkgo/v2"
    16  	. "github.com/onsi/gomega"
    17  	"github.com/onsi/gomega/gbytes"
    18  )
    19  
    20  // in the tests for the stream deadlines we set a deadline
    21  // and wait to make an assertion when Read / Write was unblocked
    22  // on the CIs, the timing is a lot less precise, so scale every duration by this factor
    23  func scaleDuration(t time.Duration) time.Duration {
    24  	scaleFactor := 1
    25  	if f, err := strconv.Atoi(os.Getenv("TIMESCALE_FACTOR")); err == nil { // parsing "" errors, so this works fine if the env is not set
    26  		scaleFactor = f
    27  	}
    28  	Expect(scaleFactor).ToNot(BeZero())
    29  	return time.Duration(scaleFactor) * t
    30  }
    31  
    32  var _ = Describe("Stream", func() {
    33  	const streamID protocol.StreamID = 1337
    34  
    35  	var (
    36  		str            *stream
    37  		strWithTimeout io.ReadWriter // str wrapped with gbytes.Timeout{Reader,Writer}
    38  		mockFC         *mocks.MockStreamFlowController
    39  		mockSender     *MockStreamSender
    40  	)
    41  
    42  	BeforeEach(func() {
    43  		mockSender = NewMockStreamSender(mockCtrl)
    44  		mockFC = mocks.NewMockStreamFlowController(mockCtrl)
    45  		str = newStream(context.Background(), streamID, mockSender, mockFC)
    46  
    47  		timeout := scaleDuration(250 * time.Millisecond)
    48  		strWithTimeout = struct {
    49  			io.Reader
    50  			io.Writer
    51  		}{
    52  			gbytes.TimeoutReader(str, timeout),
    53  			gbytes.TimeoutWriter(str, timeout),
    54  		}
    55  	})
    56  
    57  	It("gets stream id", func() {
    58  		Expect(str.StreamID()).To(Equal(protocol.StreamID(1337)))
    59  	})
    60  
    61  	Context("deadlines", func() {
    62  		It("sets a write deadline, when SetDeadline is called", func() {
    63  			str.SetDeadline(time.Now().Add(-time.Second))
    64  			n, err := strWithTimeout.Write([]byte("foobar"))
    65  			Expect(err).To(MatchError(errDeadline))
    66  			Expect(n).To(BeZero())
    67  		})
    68  
    69  		It("sets a read deadline, when SetDeadline is called", func() {
    70  			mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(6), false).AnyTimes()
    71  			f := &wire.StreamFrame{Data: []byte("foobar")}
    72  			err := str.handleStreamFrame(f)
    73  			Expect(err).ToNot(HaveOccurred())
    74  			str.SetDeadline(time.Now().Add(-time.Second))
    75  			b := make([]byte, 6)
    76  			n, err := strWithTimeout.Read(b)
    77  			Expect(err).To(MatchError(errDeadline))
    78  			Expect(n).To(BeZero())
    79  		})
    80  	})
    81  
    82  	Context("completing", func() {
    83  		It("is not completed when only the receive side is completed", func() {
    84  			// don't EXPECT a call to mockSender.onStreamCompleted()
    85  			str.receiveStream.sender.onStreamCompleted(streamID)
    86  		})
    87  
    88  		It("is not completed when only the send side is completed", func() {
    89  			// don't EXPECT a call to mockSender.onStreamCompleted()
    90  			str.sendStream.sender.onStreamCompleted(streamID)
    91  		})
    92  
    93  		It("is completed when both sides are completed", func() {
    94  			mockSender.EXPECT().onStreamCompleted(streamID)
    95  			str.sendStream.sender.onStreamCompleted(streamID)
    96  			str.receiveStream.sender.onStreamCompleted(streamID)
    97  		})
    98  	})
    99  })
   100  
   101  var _ = Describe("Deadline Error", func() {
   102  	It("is a net.Error that wraps os.ErrDeadlineError", func() {
   103  		err := deadlineError{}
   104  		Expect(err.Timeout()).To(BeTrue())
   105  		Expect(errors.Is(err, os.ErrDeadlineExceeded)).To(BeTrue())
   106  		Expect(errors.Unwrap(err)).To(Equal(os.ErrDeadlineExceeded))
   107  	})
   108  })