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.
 
 
 

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