1
2
3
4
5 package http2
6
7 import (
8 "fmt"
9 "math"
10 "reflect"
11 "testing"
12 )
13
14 func makeWriteNonStreamRequest() FrameWriteRequest {
15 return FrameWriteRequest{writeSettingsAck{}, nil, nil}
16 }
17
18 func makeWriteHeadersRequest(streamID uint32) FrameWriteRequest {
19 st := &stream{id: streamID}
20 return FrameWriteRequest{&writeResHeaders{streamID: streamID, httpResCode: 200}, st, nil}
21 }
22
23 func makeHandlerPanicRST(streamID uint32) FrameWriteRequest {
24 st := &stream{id: streamID}
25 return FrameWriteRequest{&handlerPanicRST{StreamID: streamID}, st, nil}
26 }
27
28 func makeWriteRSTStream(streamID uint32) FrameWriteRequest {
29 return FrameWriteRequest{write: streamError(streamID, ErrCodeInternal)}
30 }
31
32 func checkConsume(wr FrameWriteRequest, nbytes int32, want []FrameWriteRequest) error {
33 consumed, rest, n := wr.Consume(nbytes)
34 var wantConsumed, wantRest FrameWriteRequest
35 switch len(want) {
36 case 0:
37 case 1:
38 wantConsumed = want[0]
39 case 2:
40 wantConsumed = want[0]
41 wantRest = want[1]
42 }
43 if !reflect.DeepEqual(consumed, wantConsumed) || !reflect.DeepEqual(rest, wantRest) || n != len(want) {
44 return fmt.Errorf("got %v, %v, %v\nwant %v, %v, %v", consumed, rest, n, wantConsumed, wantRest, len(want))
45 }
46 return nil
47 }
48
49 func TestFrameWriteRequestNonData(t *testing.T) {
50 wr := makeWriteNonStreamRequest()
51 if got, want := wr.DataSize(), 0; got != want {
52 t.Errorf("DataSize: got %v, want %v", got, want)
53 }
54
55
56 if err := checkConsume(wr, 0, []FrameWriteRequest{wr}); err != nil {
57 t.Errorf("Consume:\n%v", err)
58 }
59
60 wr = makeWriteRSTStream(123)
61 if got, want := wr.DataSize(), 0; got != want {
62 t.Errorf("DataSize: got %v, want %v", got, want)
63 }
64
65
66 if err := checkConsume(wr, 0, []FrameWriteRequest{wr}); err != nil {
67 t.Errorf("Consume:\n%v", err)
68 }
69 }
70
71
72
73
74 func TestFrameWriteRequestWithData(t *testing.T) {
75 st := &stream{
76 id: 1,
77 sc: &serverConn{maxFrameSize: 16},
78 }
79 st.flow.conn = &connOutflow{}
80 const size = 32
81 wr := FrameWriteRequest{&writeData{st.id, make([]byte, size), true}, st, make(chan error)}
82 if got, want := wr.DataSize(), size; got != want {
83 t.Errorf("DataSize: got %v, want %v", got, want)
84 }
85
86
87 if err := checkConsume(wr, math.MaxInt32, []FrameWriteRequest{}); err != nil {
88 t.Errorf("Consume(limited by flow control):\n%v", err)
89 }
90
91 wr = makeWriteNonStreamRequest()
92 if got, want := wr.DataSize(), 0; got != want {
93 t.Errorf("DataSize: got %v, want %v", got, want)
94 }
95
96
97 if err := checkConsume(wr, 0, []FrameWriteRequest{wr}); err != nil {
98 t.Errorf("Consume:\n%v", err)
99 }
100
101 wr = makeWriteRSTStream(1)
102 if got, want := wr.DataSize(), 0; got != want {
103 t.Errorf("DataSize: got %v, want %v", got, want)
104 }
105
106
107 if err := checkConsume(wr, 0, []FrameWriteRequest{wr}); err != nil {
108 t.Errorf("Consume:\n%v", err)
109 }
110 }
111
112 func TestFrameWriteRequestData(t *testing.T) {
113 st := &stream{
114 id: 1,
115 sc: &serverConn{maxFrameSize: 16},
116 }
117 st.flow.conn = &connOutflow{}
118 st.flow.conn.add(maxFlowWindow)
119 const size = 32
120 wr := FrameWriteRequest{&writeData{st.id, make([]byte, size), true}, st, make(chan error)}
121 if got, want := wr.DataSize(), size; got != want {
122 t.Errorf("DataSize: got %v, want %v", got, want)
123 }
124
125
126 if err := checkConsume(wr, math.MaxInt32, []FrameWriteRequest{}); err != nil {
127 t.Errorf("Consume(limited by flow control):\n%v", err)
128 }
129
130
131
132 st.flow.add(size)
133 want := []FrameWriteRequest{
134 {
135 write: &writeData{st.id, make([]byte, st.sc.maxFrameSize), false},
136 stream: st,
137 done: nil,
138 },
139 {
140 write: &writeData{st.id, make([]byte, size-st.sc.maxFrameSize), true},
141 stream: st,
142 done: wr.done,
143 },
144 }
145 if err := checkConsume(wr, math.MaxInt32, want); err != nil {
146 t.Errorf("Consume(limited by maxFrameSize):\n%v", err)
147 }
148 rest := want[1]
149
150
151 want = []FrameWriteRequest{
152 {
153 write: &writeData{st.id, make([]byte, 8), false},
154 stream: st,
155 done: nil,
156 },
157 {
158 write: &writeData{st.id, make([]byte, size-st.sc.maxFrameSize-8), true},
159 stream: st,
160 done: wr.done,
161 },
162 }
163 if err := checkConsume(rest, 8, want); err != nil {
164 t.Errorf("Consume(8):\n%v", err)
165 }
166 rest = want[1]
167
168
169 want = []FrameWriteRequest{
170 {
171 write: &writeData{st.id, make([]byte, size-st.sc.maxFrameSize-8), true},
172 stream: st,
173 done: wr.done,
174 },
175 }
176 if err := checkConsume(rest, math.MaxInt32, want); err != nil {
177 t.Errorf("Consume(remainder):\n%v", err)
178 }
179 }
180
181 func TestFrameWriteRequest_StreamID(t *testing.T) {
182 const streamID = 123
183 wr := FrameWriteRequest{write: streamError(streamID, ErrCodeNo)}
184 if got := wr.StreamID(); got != streamID {
185 t.Errorf("FrameWriteRequest(StreamError) = %v; want %v", got, streamID)
186 }
187 }
188
View as plain text