muxedstream_test.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package h2mux
  2. import (
  3. "bytes"
  4. "io"
  5. "testing"
  6. "github.com/stretchr/testify/assert"
  7. )
  8. const testWindowSize uint32 = 65535
  9. const testMaxWindowSize uint32 = testWindowSize << 2
  10. // Only sending WINDOW_UPDATE frame, so sendWindow should never change
  11. func TestFlowControlSingleStream(t *testing.T) {
  12. stream := &MuxedStream{
  13. responseHeadersReceived: make(chan struct{}),
  14. readBuffer: NewSharedBuffer(),
  15. writeBuffer: &bytes.Buffer{},
  16. receiveWindow: testWindowSize,
  17. receiveWindowCurrentMax: testWindowSize,
  18. receiveWindowMax: testMaxWindowSize,
  19. sendWindow: testWindowSize,
  20. readyList: NewReadyList(),
  21. }
  22. var tempWindowUpdate uint32
  23. var tempStreamChunk *streamChunk
  24. assert.True(t, stream.consumeReceiveWindow(testWindowSize/2))
  25. dataSent := testWindowSize / 2
  26. assert.Equal(t, testWindowSize-dataSent, stream.receiveWindow)
  27. assert.Equal(t, testWindowSize, stream.receiveWindowCurrentMax)
  28. assert.Equal(t, testWindowSize, stream.sendWindow)
  29. assert.Equal(t, uint32(0), stream.windowUpdate)
  30. tempStreamChunk = stream.getChunk()
  31. assert.Equal(t, uint32(0), tempStreamChunk.windowUpdate)
  32. assert.Equal(t, testWindowSize-dataSent, stream.receiveWindow)
  33. assert.Equal(t, testWindowSize, stream.receiveWindowCurrentMax)
  34. assert.Equal(t, testWindowSize, stream.sendWindow)
  35. assert.Equal(t, uint32(0), stream.windowUpdate)
  36. assert.True(t, stream.consumeReceiveWindow(2))
  37. dataSent += 2
  38. assert.Equal(t, testWindowSize-dataSent, stream.receiveWindow)
  39. assert.Equal(t, testWindowSize<<1, stream.receiveWindowCurrentMax)
  40. assert.Equal(t, testWindowSize, stream.sendWindow)
  41. assert.Equal(t, testWindowSize, stream.windowUpdate)
  42. tempWindowUpdate = stream.windowUpdate
  43. tempStreamChunk = stream.getChunk()
  44. assert.Equal(t, tempWindowUpdate, tempStreamChunk.windowUpdate)
  45. assert.Equal(t, (testWindowSize<<1)-dataSent, stream.receiveWindow)
  46. assert.Equal(t, testWindowSize<<1, stream.receiveWindowCurrentMax)
  47. assert.Equal(t, testWindowSize, stream.sendWindow)
  48. assert.Equal(t, uint32(0), stream.windowUpdate)
  49. assert.True(t, stream.consumeReceiveWindow(testWindowSize+10))
  50. dataSent += testWindowSize + 10
  51. assert.Equal(t, (testWindowSize<<1)-dataSent, stream.receiveWindow)
  52. assert.Equal(t, testWindowSize<<2, stream.receiveWindowCurrentMax)
  53. assert.Equal(t, testWindowSize, stream.sendWindow)
  54. assert.Equal(t, testWindowSize<<1, stream.windowUpdate)
  55. tempWindowUpdate = stream.windowUpdate
  56. tempStreamChunk = stream.getChunk()
  57. assert.Equal(t, tempWindowUpdate, tempStreamChunk.windowUpdate)
  58. assert.Equal(t, (testWindowSize<<2)-dataSent, stream.receiveWindow)
  59. assert.Equal(t, testWindowSize<<2, stream.receiveWindowCurrentMax)
  60. assert.Equal(t, testWindowSize, stream.sendWindow)
  61. assert.Equal(t, uint32(0), stream.windowUpdate)
  62. assert.False(t, stream.consumeReceiveWindow(testMaxWindowSize+1))
  63. assert.Equal(t, (testWindowSize<<2)-dataSent, stream.receiveWindow)
  64. assert.Equal(t, testMaxWindowSize, stream.receiveWindowCurrentMax)
  65. }
  66. func TestMuxedStreamEOF(t *testing.T) {
  67. for i := 0; i < 4096; i++ {
  68. readyList := NewReadyList()
  69. stream := &MuxedStream{
  70. streamID: 1,
  71. readBuffer: NewSharedBuffer(),
  72. receiveWindow: 65536,
  73. receiveWindowMax: 65536,
  74. sendWindow: 65536,
  75. readyList: readyList,
  76. }
  77. go func() { stream.Close() }()
  78. n, err := stream.Read([]byte{0})
  79. assert.Equal(t, io.EOF, err)
  80. assert.Equal(t, 0, n)
  81. // Write comes after read, because write buffers data before it is flushed. It wouldn't know about EOF
  82. // until some time later. Calling read first forces it to know about EOF now.
  83. n, err = stream.Write([]byte{1})
  84. assert.Equal(t, io.EOF, err)
  85. assert.Equal(t, 0, n)
  86. }
  87. }
  88. func TestIsRPCStream(t *testing.T) {
  89. tests := []struct {
  90. stream *MuxedStream
  91. isRPCStream bool
  92. }{
  93. {
  94. stream: &MuxedStream{},
  95. isRPCStream: false,
  96. },
  97. {
  98. stream: &MuxedStream{Headers: RPCHeaders()},
  99. isRPCStream: true,
  100. },
  101. {
  102. stream: &MuxedStream{Headers: []Header{
  103. {Name: ":method", Value: "rpc"},
  104. {Name: ":scheme", Value: "Capnp"},
  105. {Name: ":path", Value: "/"},
  106. }},
  107. isRPCStream: false,
  108. },
  109. }
  110. for _, test := range tests {
  111. assert.Equal(t, test.isRPCStream, test.stream.IsRPCStream())
  112. }
  113. }