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