You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
4.3 KiB

  1. // Copyright 2017 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build go1.7
  5. package http2
  6. import (
  7. "bytes"
  8. "fmt"
  9. "reflect"
  10. "testing"
  11. )
  12. func fmtDataChunk(chunk []byte) string {
  13. out := ""
  14. var last byte
  15. var count int
  16. for _, c := range chunk {
  17. if c != last {
  18. if count > 0 {
  19. out += fmt.Sprintf(" x %d ", count)
  20. count = 0
  21. }
  22. out += string([]byte{c})
  23. last = c
  24. }
  25. count++
  26. }
  27. if count > 0 {
  28. out += fmt.Sprintf(" x %d", count)
  29. }
  30. return out
  31. }
  32. func fmtDataChunks(chunks [][]byte) string {
  33. var out string
  34. for _, chunk := range chunks {
  35. out += fmt.Sprintf("{%q}", fmtDataChunk(chunk))
  36. }
  37. return out
  38. }
  39. func testDataBuffer(t *testing.T, wantBytes []byte, setup func(t *testing.T) *dataBuffer) {
  40. // Run setup, then read the remaining bytes from the dataBuffer and check
  41. // that they match wantBytes. We use different read sizes to check corner
  42. // cases in Read.
  43. for _, readSize := range []int{1, 2, 1 * 1024, 32 * 1024} {
  44. t.Run(fmt.Sprintf("ReadSize=%d", readSize), func(t *testing.T) {
  45. b := setup(t)
  46. buf := make([]byte, readSize)
  47. var gotRead bytes.Buffer
  48. for {
  49. n, err := b.Read(buf)
  50. gotRead.Write(buf[:n])
  51. if err == errReadEmpty {
  52. break
  53. }
  54. if err != nil {
  55. t.Fatalf("error after %v bytes: %v", gotRead.Len(), err)
  56. }
  57. }
  58. if got, want := gotRead.Bytes(), wantBytes; !bytes.Equal(got, want) {
  59. t.Errorf("FinalRead=%q, want %q", fmtDataChunk(got), fmtDataChunk(want))
  60. }
  61. })
  62. }
  63. }
  64. func TestDataBufferAllocation(t *testing.T) {
  65. writes := [][]byte{
  66. bytes.Repeat([]byte("a"), 1*1024-1),
  67. []byte("a"),
  68. bytes.Repeat([]byte("b"), 4*1024-1),
  69. []byte("b"),
  70. bytes.Repeat([]byte("c"), 8*1024-1),
  71. []byte("c"),
  72. bytes.Repeat([]byte("d"), 16*1024-1),
  73. []byte("d"),
  74. bytes.Repeat([]byte("e"), 32*1024),
  75. }
  76. var wantRead bytes.Buffer
  77. for _, p := range writes {
  78. wantRead.Write(p)
  79. }
  80. testDataBuffer(t, wantRead.Bytes(), func(t *testing.T) *dataBuffer {
  81. b := &dataBuffer{}
  82. for _, p := range writes {
  83. if n, err := b.Write(p); n != len(p) || err != nil {
  84. t.Fatalf("Write(%q x %d)=%v,%v want %v,nil", p[:1], len(p), n, err, len(p))
  85. }
  86. }
  87. want := [][]byte{
  88. bytes.Repeat([]byte("a"), 1*1024),
  89. bytes.Repeat([]byte("b"), 4*1024),
  90. bytes.Repeat([]byte("c"), 8*1024),
  91. bytes.Repeat([]byte("d"), 16*1024),
  92. bytes.Repeat([]byte("e"), 16*1024),
  93. bytes.Repeat([]byte("e"), 16*1024),
  94. }
  95. if !reflect.DeepEqual(b.chunks, want) {
  96. t.Errorf("dataBuffer.chunks\ngot: %s\nwant: %s", fmtDataChunks(b.chunks), fmtDataChunks(want))
  97. }
  98. return b
  99. })
  100. }
  101. func TestDataBufferAllocationWithExpected(t *testing.T) {
  102. writes := [][]byte{
  103. bytes.Repeat([]byte("a"), 1*1024), // allocates 16KB
  104. bytes.Repeat([]byte("b"), 14*1024),
  105. bytes.Repeat([]byte("c"), 15*1024), // allocates 16KB more
  106. bytes.Repeat([]byte("d"), 2*1024),
  107. bytes.Repeat([]byte("e"), 1*1024), // overflows 32KB expectation, allocates just 1KB
  108. }
  109. var wantRead bytes.Buffer
  110. for _, p := range writes {
  111. wantRead.Write(p)
  112. }
  113. testDataBuffer(t, wantRead.Bytes(), func(t *testing.T) *dataBuffer {
  114. b := &dataBuffer{expected: 32 * 1024}
  115. for _, p := range writes {
  116. if n, err := b.Write(p); n != len(p) || err != nil {
  117. t.Fatalf("Write(%q x %d)=%v,%v want %v,nil", p[:1], len(p), n, err, len(p))
  118. }
  119. }
  120. want := [][]byte{
  121. append(bytes.Repeat([]byte("a"), 1*1024), append(bytes.Repeat([]byte("b"), 14*1024), bytes.Repeat([]byte("c"), 1*1024)...)...),
  122. append(bytes.Repeat([]byte("c"), 14*1024), bytes.Repeat([]byte("d"), 2*1024)...),
  123. bytes.Repeat([]byte("e"), 1*1024),
  124. }
  125. if !reflect.DeepEqual(b.chunks, want) {
  126. t.Errorf("dataBuffer.chunks\ngot: %s\nwant: %s", fmtDataChunks(b.chunks), fmtDataChunks(want))
  127. }
  128. return b
  129. })
  130. }
  131. func TestDataBufferWriteAfterPartialRead(t *testing.T) {
  132. testDataBuffer(t, []byte("cdxyz"), func(t *testing.T) *dataBuffer {
  133. b := &dataBuffer{}
  134. if n, err := b.Write([]byte("abcd")); n != 4 || err != nil {
  135. t.Fatalf("Write(\"abcd\")=%v,%v want 4,nil", n, err)
  136. }
  137. p := make([]byte, 2)
  138. if n, err := b.Read(p); n != 2 || err != nil || !bytes.Equal(p, []byte("ab")) {
  139. t.Fatalf("Read()=%q,%v,%v want \"ab\",2,nil", p, n, err)
  140. }
  141. if n, err := b.Write([]byte("xyz")); n != 3 || err != nil {
  142. t.Fatalf("Write(\"xyz\")=%v,%v want 3,nil", n, err)
  143. }
  144. return b
  145. })
  146. }