mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 20:57:36 +03:00
use stream numbers, not stream ids, in the stream maps
This commit is contained in:
parent
a8633a952c
commit
857e4ae9a9
12 changed files with 524 additions and 467 deletions
|
@ -2,7 +2,6 @@ package quic
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
|
@ -13,7 +12,7 @@ import (
|
|||
)
|
||||
|
||||
type mockGenericStream struct {
|
||||
id protocol.StreamID
|
||||
num protocol.StreamNum
|
||||
|
||||
closed bool
|
||||
closeErr error
|
||||
|
@ -26,64 +25,65 @@ func (s *mockGenericStream) closeForShutdown(err error) {
|
|||
|
||||
var _ = Describe("Streams Map (incoming)", func() {
|
||||
const (
|
||||
firstNewStream protocol.StreamID = 2
|
||||
maxNumStreams uint64 = 5
|
||||
initialMaxStream protocol.StreamID = firstNewStream + 4*protocol.StreamID(maxNumStreams-1)
|
||||
maxNumStreams uint64 = 5
|
||||
)
|
||||
|
||||
var (
|
||||
m *incomingItemsMap
|
||||
newItem func(id protocol.StreamID) item
|
||||
newItemCounter int
|
||||
mockSender *MockStreamSender
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
newItemCounter = 0
|
||||
newItem = func(id protocol.StreamID) item {
|
||||
newItemCounter++
|
||||
return &mockGenericStream{id: id}
|
||||
}
|
||||
mockSender = NewMockStreamSender(mockCtrl)
|
||||
m = newIncomingItemsMap(firstNewStream, initialMaxStream, maxNumStreams, mockSender.queueControlFrame, newItem)
|
||||
m = newIncomingItemsMap(
|
||||
func(num protocol.StreamNum) item {
|
||||
newItemCounter++
|
||||
return &mockGenericStream{num: num}
|
||||
},
|
||||
maxNumStreams,
|
||||
mockSender.queueControlFrame,
|
||||
)
|
||||
})
|
||||
|
||||
It("opens all streams up to the id on GetOrOpenStream", func() {
|
||||
_, err := m.GetOrOpenStream(firstNewStream + 4*4)
|
||||
_, err := m.GetOrOpenStream(4)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(newItemCounter).To(Equal(5))
|
||||
Expect(newItemCounter).To(Equal(4))
|
||||
})
|
||||
|
||||
It("starts opening streams at the right position", func() {
|
||||
// like the test above, but with 2 calls to GetOrOpenStream
|
||||
_, err := m.GetOrOpenStream(firstNewStream + 4)
|
||||
_, err := m.GetOrOpenStream(2)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(newItemCounter).To(Equal(2))
|
||||
_, err = m.GetOrOpenStream(firstNewStream + 4*4)
|
||||
_, err = m.GetOrOpenStream(5)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(newItemCounter).To(Equal(5))
|
||||
})
|
||||
|
||||
It("accepts streams in the right order", func() {
|
||||
_, err := m.GetOrOpenStream(firstNewStream + 4) // open stream 20 and 24
|
||||
_, err := m.GetOrOpenStream(2) // open streams 1 and 2
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
str, err := m.AcceptStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.(*mockGenericStream).id).To(Equal(firstNewStream))
|
||||
Expect(str.(*mockGenericStream).num).To(Equal(protocol.StreamNum(1)))
|
||||
str, err = m.AcceptStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.(*mockGenericStream).id).To(Equal(firstNewStream + 4))
|
||||
Expect(str.(*mockGenericStream).num).To(Equal(protocol.StreamNum(2)))
|
||||
})
|
||||
|
||||
It("allows opening the maximum stream ID", func() {
|
||||
str, err := m.GetOrOpenStream(initialMaxStream)
|
||||
str, err := m.GetOrOpenStream(1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.(*mockGenericStream).id).To(Equal(initialMaxStream))
|
||||
Expect(str.(*mockGenericStream).num).To(Equal(protocol.StreamNum(1)))
|
||||
})
|
||||
|
||||
It("errors when trying to get a stream ID higher than the maximum", func() {
|
||||
_, err := m.GetOrOpenStream(initialMaxStream + 4)
|
||||
Expect(err).To(MatchError(fmt.Errorf("peer tried to open stream %d (current limit: %d)", initialMaxStream+4, initialMaxStream)))
|
||||
_, err := m.GetOrOpenStream(6)
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.(streamError).TestError()).To(MatchError("peer tried to open stream 6 (current limit: 5)"))
|
||||
})
|
||||
|
||||
It("blocks AcceptStream until a new stream is available", func() {
|
||||
|
@ -95,30 +95,12 @@ var _ = Describe("Streams Map (incoming)", func() {
|
|||
strChan <- str
|
||||
}()
|
||||
Consistently(strChan).ShouldNot(Receive())
|
||||
str, err := m.GetOrOpenStream(firstNewStream)
|
||||
str, err := m.GetOrOpenStream(1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.(*mockGenericStream).id).To(Equal(firstNewStream))
|
||||
Expect(str.(*mockGenericStream).num).To(Equal(protocol.StreamNum(1)))
|
||||
var acceptedStr item
|
||||
Eventually(strChan).Should(Receive(&acceptedStr))
|
||||
Expect(acceptedStr.(*mockGenericStream).id).To(Equal(firstNewStream))
|
||||
})
|
||||
|
||||
It("works with stream 0", func() {
|
||||
m = newIncomingItemsMap(0, 1000, 1000, mockSender.queueControlFrame, newItem)
|
||||
strChan := make(chan item)
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
str, err := m.AcceptStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
strChan <- str
|
||||
}()
|
||||
Consistently(strChan).ShouldNot(Receive())
|
||||
str, err := m.GetOrOpenStream(0)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.(*mockGenericStream).id).To(BeZero())
|
||||
var acceptedStr item
|
||||
Eventually(strChan).Should(Receive(&acceptedStr))
|
||||
Expect(acceptedStr.(*mockGenericStream).id).To(BeZero())
|
||||
Expect(acceptedStr.(*mockGenericStream).num).To(Equal(protocol.StreamNum(1)))
|
||||
})
|
||||
|
||||
It("unblocks AcceptStream when it is closed", func() {
|
||||
|
@ -143,9 +125,9 @@ var _ = Describe("Streams Map (incoming)", func() {
|
|||
})
|
||||
|
||||
It("closes all streams when CloseWithError is called", func() {
|
||||
str1, err := m.GetOrOpenStream(firstNewStream)
|
||||
str1, err := m.GetOrOpenStream(1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
str2, err := m.GetOrOpenStream(firstNewStream + 8)
|
||||
str2, err := m.GetOrOpenStream(3)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
testErr := errors.New("test err")
|
||||
m.CloseWithError(testErr)
|
||||
|
@ -157,37 +139,37 @@ var _ = Describe("Streams Map (incoming)", func() {
|
|||
|
||||
It("deletes streams", func() {
|
||||
mockSender.EXPECT().queueControlFrame(gomock.Any())
|
||||
_, err := m.GetOrOpenStream(firstNewStream)
|
||||
_, err := m.GetOrOpenStream(1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
str, err := m.AcceptStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.(*mockGenericStream).id).To(Equal(firstNewStream))
|
||||
Expect(m.DeleteStream(firstNewStream)).To(Succeed())
|
||||
str, err = m.GetOrOpenStream(firstNewStream)
|
||||
Expect(str.(*mockGenericStream).num).To(Equal(protocol.StreamNum(1)))
|
||||
Expect(m.DeleteStream(1)).To(Succeed())
|
||||
str, err = m.GetOrOpenStream(1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str).To(BeNil())
|
||||
})
|
||||
|
||||
It("waits until a stream is accepted before actually deleting it", func() {
|
||||
_, err := m.GetOrOpenStream(firstNewStream + 4)
|
||||
_, err := m.GetOrOpenStream(2)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(m.DeleteStream(firstNewStream + 4)).To(Succeed())
|
||||
Expect(m.DeleteStream(2)).To(Succeed())
|
||||
str, err := m.AcceptStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.(*mockGenericStream).id).To(Equal(firstNewStream))
|
||||
Expect(str.(*mockGenericStream).num).To(Equal(protocol.StreamNum(1)))
|
||||
// when accepting this stream, it will get deleted, and a MAX_STREAMS frame is queued
|
||||
mockSender.EXPECT().queueControlFrame(gomock.Any())
|
||||
str, err = m.AcceptStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.(*mockGenericStream).id).To(Equal(firstNewStream + 4))
|
||||
Expect(str.(*mockGenericStream).num).To(Equal(protocol.StreamNum(2)))
|
||||
})
|
||||
|
||||
It("doesn't return a stream queued for deleting from GetOrOpenStream", func() {
|
||||
str, err := m.GetOrOpenStream(firstNewStream)
|
||||
str, err := m.GetOrOpenStream(1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str).ToNot(BeNil())
|
||||
Expect(m.DeleteStream(firstNewStream)).To(Succeed())
|
||||
str, err = m.GetOrOpenStream(firstNewStream)
|
||||
Expect(m.DeleteStream(1)).To(Succeed())
|
||||
str, err = m.GetOrOpenStream(1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str).To(BeNil())
|
||||
// when accepting this stream, it will get deleted, and a MAX_STREAMS frame is queued
|
||||
|
@ -199,12 +181,13 @@ var _ = Describe("Streams Map (incoming)", func() {
|
|||
|
||||
It("errors when deleting a non-existing stream", func() {
|
||||
err := m.DeleteStream(1337)
|
||||
Expect(err).To(MatchError("Tried to delete unknown stream 1337"))
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.(streamError).TestError()).To(MatchError("Tried to delete unknown stream 1337"))
|
||||
})
|
||||
|
||||
It("sends MAX_STREAMS frames when streams are deleted", func() {
|
||||
// open a bunch of streams
|
||||
_, err := m.GetOrOpenStream(firstNewStream + 4*4)
|
||||
_, err := m.GetOrOpenStream(5)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
// accept all streams
|
||||
for i := 0; i < 5; i++ {
|
||||
|
@ -214,10 +197,10 @@ var _ = Describe("Streams Map (incoming)", func() {
|
|||
mockSender.EXPECT().queueControlFrame(gomock.Any()).Do(func(f wire.Frame) {
|
||||
Expect(f.(*wire.MaxStreamsFrame).MaxStreamNum).To(Equal(protocol.StreamNum(maxNumStreams + 1)))
|
||||
})
|
||||
Expect(m.DeleteStream(firstNewStream + 2*4)).To(Succeed())
|
||||
Expect(m.DeleteStream(3)).To(Succeed())
|
||||
mockSender.EXPECT().queueControlFrame(gomock.Any()).Do(func(f wire.Frame) {
|
||||
Expect(f.(*wire.MaxStreamsFrame).MaxStreamNum).To(Equal(protocol.StreamNum(maxNumStreams + 2)))
|
||||
})
|
||||
Expect(m.DeleteStream(firstNewStream + 3*4)).To(Succeed())
|
||||
Expect(m.DeleteStream(4)).To(Succeed())
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue