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