123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package h2mux
- import (
- "bytes"
- "io"
- "testing"
- "github.com/stretchr/testify/assert"
- )
- const testWindowSize uint32 = 65535
- const testMaxWindowSize uint32 = testWindowSize << 2
- // Only sending WINDOW_UPDATE frame, so sendWindow should never change
- func TestFlowControlSingleStream(t *testing.T) {
- stream := &MuxedStream{
- responseHeadersReceived: make(chan struct{}),
- readBuffer: NewSharedBuffer(),
- writeBuffer: &bytes.Buffer{},
- receiveWindow: testWindowSize,
- receiveWindowCurrentMax: testWindowSize,
- receiveWindowMax: testMaxWindowSize,
- sendWindow: testWindowSize,
- readyList: NewReadyList(),
- }
- var tempWindowUpdate uint32
- var tempStreamChunk *streamChunk
- assert.True(t, stream.consumeReceiveWindow(testWindowSize/2))
- dataSent := testWindowSize / 2
- assert.Equal(t, testWindowSize-dataSent, stream.receiveWindow)
- assert.Equal(t, testWindowSize, stream.receiveWindowCurrentMax)
- assert.Equal(t, testWindowSize, stream.sendWindow)
- assert.Equal(t, uint32(0), stream.windowUpdate)
- tempStreamChunk = stream.getChunk()
- assert.Equal(t, uint32(0), tempStreamChunk.windowUpdate)
- assert.Equal(t, testWindowSize-dataSent, stream.receiveWindow)
- assert.Equal(t, testWindowSize, stream.receiveWindowCurrentMax)
- assert.Equal(t, testWindowSize, stream.sendWindow)
- assert.Equal(t, uint32(0), stream.windowUpdate)
- assert.True(t, stream.consumeReceiveWindow(2))
- dataSent += 2
- assert.Equal(t, testWindowSize-dataSent, stream.receiveWindow)
- assert.Equal(t, testWindowSize<<1, stream.receiveWindowCurrentMax)
- assert.Equal(t, testWindowSize, stream.sendWindow)
- assert.Equal(t, testWindowSize, stream.windowUpdate)
- tempWindowUpdate = stream.windowUpdate
- tempStreamChunk = stream.getChunk()
- assert.Equal(t, tempWindowUpdate, tempStreamChunk.windowUpdate)
- assert.Equal(t, (testWindowSize<<1)-dataSent, stream.receiveWindow)
- assert.Equal(t, testWindowSize<<1, stream.receiveWindowCurrentMax)
- assert.Equal(t, testWindowSize, stream.sendWindow)
- assert.Equal(t, uint32(0), stream.windowUpdate)
- assert.True(t, stream.consumeReceiveWindow(testWindowSize+10))
- dataSent += testWindowSize + 10
- assert.Equal(t, (testWindowSize<<1)-dataSent, stream.receiveWindow)
- assert.Equal(t, testWindowSize<<2, stream.receiveWindowCurrentMax)
- assert.Equal(t, testWindowSize, stream.sendWindow)
- assert.Equal(t, testWindowSize<<1, stream.windowUpdate)
- tempWindowUpdate = stream.windowUpdate
- tempStreamChunk = stream.getChunk()
- assert.Equal(t, tempWindowUpdate, tempStreamChunk.windowUpdate)
- assert.Equal(t, (testWindowSize<<2)-dataSent, stream.receiveWindow)
- assert.Equal(t, testWindowSize<<2, stream.receiveWindowCurrentMax)
- assert.Equal(t, testWindowSize, stream.sendWindow)
- assert.Equal(t, uint32(0), stream.windowUpdate)
- assert.False(t, stream.consumeReceiveWindow(testMaxWindowSize+1))
- assert.Equal(t, (testWindowSize<<2)-dataSent, stream.receiveWindow)
- assert.Equal(t, testMaxWindowSize, stream.receiveWindowCurrentMax)
- }
- func TestMuxedStreamEOF(t *testing.T) {
- for i := 0; i < 4096; i++ {
- readyList := NewReadyList()
- stream := &MuxedStream{
- streamID: 1,
- readBuffer: NewSharedBuffer(),
- receiveWindow: 65536,
- receiveWindowMax: 65536,
- sendWindow: 65536,
- readyList: readyList,
- }
- go func() { stream.Close() }()
- n, err := stream.Read([]byte{0})
- assert.Equal(t, io.EOF, err)
- assert.Equal(t, 0, n)
- // Write comes after read, because write buffers data before it is flushed. It wouldn't know about EOF
- // until some time later. Calling read first forces it to know about EOF now.
- n, err = stream.Write([]byte{1})
- assert.Equal(t, io.EOF, err)
- assert.Equal(t, 0, n)
- }
- }
- func TestIsRPCStream(t *testing.T) {
- tests := []struct {
- stream *MuxedStream
- isRPCStream bool
- }{
- {
- stream: &MuxedStream{},
- isRPCStream: false,
- },
- {
- stream: &MuxedStream{Headers: RPCHeaders()},
- isRPCStream: true,
- },
- {
- stream: &MuxedStream{Headers: []Header{
- {Name: ":method", Value: "rpc"},
- {Name: ":scheme", Value: "Capnp"},
- {Name: ":path", Value: "/"},
- }},
- isRPCStream: false,
- },
- }
- for _, test := range tests {
- assert.Equal(t, test.isRPCStream, test.stream.IsRPCStream())
- }
- }
|