Mercurial > hg > nginx-tests
annotate grpc.t @ 1427:eb1d883305ea
Tests: avoid edge cases in upstream random two test.
Unavailable servers contribute to the number of attempts, if selected,
before the balancer would fall back to the default round-robin method.
This means that it's quite possible to get server with more connections.
To facilitate with selecting two alive servers, down server was removed
from the upstream configuration at the cost of slightly worse coverage.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Thu, 10 Jan 2019 17:42:34 +0300 |
parents | 01d806268a12 |
children | 144c6ce732e4 |
rev | line source |
---|---|
1303 | 1 #!/usr/bin/perl |
2 | |
3 # (C) Sergey Kandaurov | |
4 # (C) Nginx, Inc. | |
5 | |
6 # Tests for grpc backend. | |
7 | |
8 ############################################################################### | |
9 | |
10 use warnings; | |
11 use strict; | |
12 | |
13 use Test::More; | |
14 | |
15 BEGIN { use FindBin; chdir($FindBin::Bin); } | |
16 | |
17 use lib 'lib'; | |
18 use Test::Nginx; | |
19 use Test::Nginx::HTTP2; | |
20 | |
21 ############################################################################### | |
22 | |
23 select STDERR; $| = 1; | |
24 select STDOUT; $| = 1; | |
25 | |
1312
6f95c0ed2335
Tests: removed proxy prerequisite from grpc tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1303
diff
changeset
|
26 my $t = Test::Nginx->new()->has(qw/http rewrite http_v2 grpc/) |
1381
97c8280de681
Tests: removed TODO and try_run() checks for legacy versions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1370
diff
changeset
|
27 ->has(qw/upstream_keepalive/)->plan(105); |
1303 | 28 |
29 $t->write_file_expand('nginx.conf', <<'EOF'); | |
30 | |
31 %%TEST_GLOBALS%% | |
32 | |
33 daemon off; | |
34 | |
35 events { | |
36 } | |
37 | |
38 http { | |
39 %%TEST_GLOBALS_HTTP%% | |
40 | |
41 upstream u { | |
42 server 127.0.0.1:8081; | |
43 keepalive 1; | |
44 } | |
45 | |
46 server { | |
47 listen 127.0.0.1:8080 http2; | |
48 server_name localhost; | |
49 | |
50 http2_max_field_size 128k; | |
51 http2_max_header_size 128k; | |
52 http2_body_preread_size 128k; | |
53 | |
54 location / { | |
55 grpc_pass grpc://127.0.0.1:8081; | |
56 | |
57 if ($arg_if) { | |
58 # nothing | |
59 } | |
60 | |
61 limit_except GET { | |
62 # nothing | |
63 } | |
64 } | |
65 | |
66 location /KeepAlive { | |
67 grpc_pass u; | |
68 } | |
69 | |
70 location /LongHeader { | |
71 grpc_pass 127.0.0.1:8081; | |
72 grpc_set_header X-LongHeader $arg_h; | |
73 } | |
74 | |
75 location /LongField { | |
76 grpc_pass 127.0.0.1:8081; | |
77 grpc_buffer_size 65k; | |
78 } | |
79 | |
80 location /SetHost { | |
81 grpc_pass 127.0.0.1:8081; | |
82 grpc_set_header Host custom; | |
83 } | |
84 | |
85 location /SetArgs { | |
86 grpc_pass 127.0.0.1:8081; | |
87 set $args $arg_c; | |
88 } | |
89 } | |
90 } | |
91 | |
92 EOF | |
93 | |
1381
97c8280de681
Tests: removed TODO and try_run() checks for legacy versions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1370
diff
changeset
|
94 $t->run(); |
1303 | 95 |
96 ############################################################################### | |
97 | |
98 my $p = port(8081); | |
99 my $f = grpc(); | |
100 | |
101 my $frames = $f->{http_start}('/SayHello'); | |
102 my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
103 is($frame->{flags}, 4, 'request - HEADERS flags'); | |
104 ok((my $sid = $frame->{sid}) % 2, 'request - HEADERS sid odd'); | |
105 is($frame->{headers}{':method'}, 'POST', 'request - method'); | |
106 is($frame->{headers}{':scheme'}, 'http', 'request - scheme'); | |
107 is($frame->{headers}{':path'}, '/SayHello', 'request - path'); | |
108 is($frame->{headers}{':authority'}, "127.0.0.1:$p", 'request - authority'); | |
109 is($frame->{headers}{'content-type'}, 'application/grpc', | |
110 'request - content type'); | |
111 is($frame->{headers}{te}, 'trailers', 'request - te'); | |
112 | |
113 $frames = $f->{data}('Hello'); | |
114 ($frame) = grep { $_->{type} eq "SETTINGS" } @$frames; | |
115 is($frame->{flags}, 1, 'request - SETTINGS ack'); | |
116 is($frame->{sid}, 0, 'request - SETTINGS sid'); | |
117 is($frame->{length}, 0, 'request - SETTINGS length'); | |
118 | |
119 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
120 is($frame->{data}, 'Hello', 'request - DATA'); | |
121 is($frame->{length}, 5, 'request - DATA length'); | |
122 is($frame->{flags}, 1, 'request - DATA flags'); | |
123 is($frame->{sid}, $sid, 'request - DATA sid match'); | |
124 | |
125 $frames = $f->{http_end}(); | |
126 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
127 is($frame->{flags}, 4, 'response - HEADERS flags'); | |
128 is($frame->{sid}, 1, 'response - HEADERS sid'); | |
129 is($frame->{headers}{':status'}, '200', 'response - status'); | |
130 is($frame->{headers}{'content-type'}, 'application/grpc', | |
131 'response - content type'); | |
132 ok($frame->{headers}{server}, 'response - server'); | |
133 ok($frame->{headers}{date}, 'response - date'); | |
134 ok(my $c = $frame->{headers}{'x-connection'}, 'response - connection'); | |
135 | |
136 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
137 is($frame->{data}, 'Hello world', 'response - DATA'); | |
138 is($frame->{length}, 11, 'response - DATA length'); | |
139 is($frame->{flags}, 0, 'response - DATA flags'); | |
140 is($frame->{sid}, 1, 'response - DATA sid'); | |
141 | |
142 (undef, $frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
143 is($frame->{flags}, 5, 'response - trailers flags'); | |
144 is($frame->{sid}, 1, 'response - trailers sid'); | |
145 is($frame->{headers}{'grpc-message'}, '', 'response - trailers message'); | |
146 is($frame->{headers}{'grpc-status'}, '0', 'response - trailers status'); | |
147 | |
148 # next request is on a new backend connection, no sid incremented | |
149 | |
150 $frames = $f->{http_start}('/SayHello'); | |
151 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
152 is($frame->{sid}, $sid, 'request 2 - HEADERS sid again'); | |
153 $f->{data}('Hello'); | |
154 $frames = $f->{http_end}(); | |
155 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
156 cmp_ok($frame->{headers}{'x-connection'}, '>', $c, 'response 2 - connection'); | |
157 | |
158 # upstream keepalive | |
159 | |
160 $frames = $f->{http_start}('/KeepAlive'); | |
161 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
162 is($frame->{sid}, $sid, 'keepalive - HEADERS sid'); | |
163 $f->{data}('Hello'); | |
164 $frames = $f->{http_end}(); | |
165 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
166 ok($c = $frame->{headers}{'x-connection'}, 'keepalive - connection'); | |
167 | |
168 $frames = $f->{http_start}('/KeepAlive', reuse => 1); | |
169 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
170 cmp_ok($frame->{sid}, '>', $sid, 'keepalive - HEADERS sid next'); | |
171 $f->{data}('Hello'); | |
172 $frames = $f->{http_end}(); | |
173 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
174 is($frame->{headers}{'x-connection'}, $c, 'keepalive - connection reuse'); | |
175 | |
1370
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
176 # upstream keepalive |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
177 # pending control frame ack after the response |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
178 |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
179 undef $f; |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
180 $f = grpc(); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
181 |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
182 $frames = $f->{http_start}('/KeepAlive'); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
183 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
184 is($frame->{sid}, $sid, 'keepalive 2 - HEADERS sid'); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
185 $f->{data}('Hello'); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
186 $f->{settings}(0, 1 => 4096); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
187 $frames = $f->{http_end}(); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
188 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
189 ok($c = $frame->{headers}{'x-connection'}, 'keepalive 2 - connection'); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
190 |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
191 $frames = $f->{http_start}('/KeepAlive', reuse => 1); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
192 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
193 ok($frame, 'upstream keepalive reused'); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
194 |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
195 cmp_ok($frame->{sid}, '>', $sid, 'keepalive 2 - HEADERS sid next'); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
196 $f->{data}('Hello'); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
197 $frames = $f->{http_end}(); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
198 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
199 is($frame->{headers}{'x-connection'}, $c, 'keepalive 2 - connection reuse'); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
200 |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
201 undef $f; |
1390
2c0955286894
Tests: unbreak grpc.t on stable versions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1381
diff
changeset
|
202 # don't bother with a new instance until the old one is over |
2c0955286894
Tests: unbreak grpc.t on stable versions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1381
diff
changeset
|
203 select undef, undef, undef, 0.2 unless $t->has_version('1.15.4'); |
1370
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
204 $f = grpc(); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
205 |
1303 | 206 # various header compression formats |
207 | |
208 $f->{http_start}('/SayHello'); | |
209 $f->{data}('Hello'); | |
210 $frames = $f->{http_end}(mode => 3); | |
211 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
212 is($frame->{headers}{':status'}, '200', 'without indexing'); | |
213 is($frame->{headers}{'content-type'}, 'application/grpc', | |
214 'without indexing 2'); | |
215 | |
216 $f->{http_start}('/SayHello'); | |
217 $f->{data}('Hello'); | |
218 $frames = $f->{http_end}(mode => 4); | |
219 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
220 is($frame->{headers}{':status'}, '200', 'without indexing new'); | |
221 is($frame->{headers}{'content-type'}, 'application/grpc', | |
222 'without indexing new 2'); | |
223 | |
224 $f->{http_start}('/SayHello'); | |
225 $f->{data}('Hello'); | |
226 $frames = $f->{http_end}(mode => 5); | |
227 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
228 is($frame->{headers}{':status'}, '200', 'never indexed'); | |
229 is($frame->{headers}{'content-type'}, 'application/grpc', | |
230 'never indexed 2'); | |
231 | |
232 $f->{http_start}('/SayHello'); | |
233 $f->{data}('Hello'); | |
234 $frames = $f->{http_end}(mode => 6); | |
235 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
236 is($frame->{headers}{':status'}, '200', 'never indexed new'); | |
237 is($frame->{headers}{'content-type'}, 'application/grpc', | |
238 'never indexed new 2'); | |
239 | |
240 # padding & priority | |
241 | |
242 $f->{http_start}('/SayHello'); | |
243 $f->{data}('Hello'); | |
244 $frames = $f->{http_end}(padding => 7); | |
245 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
246 is($frame->{headers}{':status'}, '200', 'padding'); | |
247 | |
248 $f->{http_start}('/SayHello'); | |
249 $f->{data}('Hello'); | |
250 $frames = $f->{http_end}(prio => 137, dep => 0x01020304); | |
251 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
252 is($frame->{headers}{':status'}, '200', 'priority'); | |
253 | |
254 $f->{http_start}('/SayHello'); | |
255 $f->{data}('Hello'); | |
256 $frames = $f->{http_end}(padding => 7, prio => 137, dep => 0x01020304); | |
257 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
258 is($frame->{headers}{':status'}, '200', 'padding priority'); | |
259 | |
260 SKIP: { | |
261 skip 'long test', 1 unless $ENV{TEST_NGINX_UNSAFE}; | |
262 | |
263 $f->{http_start}('/SaySplit'); | |
264 $f->{data}('Hello'); | |
265 $frames = $f->{http_end}(padding => 7, prio => 137, dep => 0x01020304, | |
266 split => [(map{1}(1..20)), 30], split_delay => 0.1); | |
267 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
268 is($frame->{headers}{':status'}, '200', 'padding priority split'); | |
269 | |
270 } | |
271 | |
272 # grpc error, no empty data frame expected | |
273 | |
274 $f->{http_start}('/SayHello'); | |
275 $f->{data}('Hello'); | |
276 $frames = $f->{http_err}(); | |
277 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
278 is($frame->{flags}, 5, 'grpc error - HEADERS flags'); | |
279 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
280 ok(!$frame, 'grpc error - no DATA frame'); | |
281 | |
282 # continuation from backend, expect parts assembled | |
283 | |
284 $f->{http_start}('/SayHello'); | |
285 $f->{data}('Hello'); | |
286 $frames = $f->{continuation}(); | |
287 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
288 is($frame->{flags}, 4, 'continuation - HEADERS flags'); | |
289 is($frame->{headers}{':status'}, '200', 'continuation - status'); | |
290 is($frame->{headers}{'content-type'}, 'application/grpc', | |
291 'continuation - content type'); | |
292 | |
293 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
294 is($frame->{data}, 'Hello world', 'continuation - DATA'); | |
295 is($frame->{length}, 11, 'continuation - DATA length'); | |
296 is($frame->{flags}, 0, 'continuation - DATA flags'); | |
297 | |
298 (undef, $frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
299 is($frame->{flags}, 5, 'continuation - trailers flags'); | |
300 is($frame->{headers}{'grpc-message'}, '', 'continuation - trailers message'); | |
301 is($frame->{headers}{'grpc-status'}, '0', 'continuation - trailers status'); | |
302 | |
303 # continuation from backend, header split | |
304 | |
305 $f->{http_start}('/SayHello'); | |
306 $f->{data}('Hello'); | |
307 $frames = $f->{http_end}(mode => 6, continuation => [map { 1 } (1 .. 42)]); | |
308 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
309 is($frame->{headers}{':status'}, '200', 'continuation - header split'); | |
310 | |
311 # continuation to backend | |
312 | |
313 $frames = $f->{http_start}('/LongHeader?h=' . ('Z' x 31337)); | |
314 @$frames = grep { $_->{type} =~ "HEADERS|CONTINUATION" } @$frames; | |
315 is(@$frames, 4, 'continuation - frames'); | |
316 | |
317 $frame = shift @$frames; | |
318 is($frame->{type}, 'HEADERS', 'continuation - HEADERS'); | |
319 is($frame->{length}, 16384, 'continuation - HEADERS length'); | |
320 is($frame->{flags}, 1, 'continuation - HEADERS flags'); | |
321 ok($frame->{sid}, 'continuation - HEADERS sid'); | |
322 | |
323 $frame = shift @$frames; | |
324 is($frame->{type}, 'CONTINUATION', 'continuation - CONTINUATION'); | |
325 is($frame->{length}, 16384, 'continuation - CONTINUATION length'); | |
326 is($frame->{flags}, 0, 'continuation - CONTINUATION flags'); | |
327 ok($frame->{sid}, 'continuation - CONTINUATION sid'); | |
328 | |
329 $frame = shift @$frames; | |
330 is($frame->{type}, 'CONTINUATION', 'continuation - CONTINUATION 2'); | |
331 is($frame->{length}, 16384, 'continuation - CONTINUATION 2 length'); | |
332 is($frame->{flags}, 0, 'continuation - CONTINUATION 2 flags'); | |
333 | |
334 $frame = shift @$frames; | |
335 is($frame->{type}, 'CONTINUATION', 'continuation - CONTINUATION n'); | |
336 cmp_ok($frame->{length}, '<', 16384, 'continuation - CONTINUATION n length'); | |
337 is($frame->{flags}, 4, 'continuation - CONTINUATION n flags'); | |
338 is($frame->{headers}{':path'}, '/LongHeader?h=' . 'Z' x 31337, | |
339 'continuation - path'); | |
340 is($frame->{headers}{'x-longheader'}, 'Z' x 31337, 'continuation - header'); | |
341 | |
342 $f->{http_end}(); | |
343 | |
344 # long header field | |
345 | |
346 $f->{http_start}('/LongField'); | |
347 $f->{data}('Hello'); | |
348 $frames = $f->{field_len}(2**7); | |
349 ($frame) = grep { $_->{flags} & 0x4 } @$frames; | |
350 is($frame->{headers}{'x' x 2**7}, 'y' x 2**7, 'long header field 1'); | |
351 | |
352 $f->{http_start}('/LongField'); | |
353 $f->{data}('Hello'); | |
354 $frames = $f->{field_len}(2**8); | |
355 ($frame) = grep { $_->{flags} & 0x4 } @$frames; | |
356 is($frame->{headers}{'x' x 2**8}, 'y' x 2**8, 'long header field 2'); | |
357 | |
358 $f->{http_start}('/LongField'); | |
359 $f->{data}('Hello'); | |
360 $frames = $f->{field_len}(2**15); | |
361 ($frame) = grep { $_->{flags} & 0x4 } @$frames; | |
362 is($frame->{headers}{'x' x 2**15}, 'y' x 2**15, 'long header field 3'); | |
363 | |
364 # flow control | |
365 | |
366 $f->{http_start}('/FlowControl'); | |
367 $frames = $f->{data_len}(('Hello' x 13000) . ('x' x 550), 65535); | |
368 my $sum = eval join '+', map { $_->{type} eq "DATA" && $_->{length} } @$frames; | |
369 is($sum, 65535, 'flow control - iws length'); | |
370 | |
371 $f->{update}(10); | |
372 $f->{update_sid}(10); | |
373 | |
374 $frames = $f->{data_len}(undef, 10); | |
375 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
376 is($frame->{length}, 10, 'flow control - update length'); | |
377 is($frame->{flags}, 0, 'flow control - update flags'); | |
378 | |
379 $f->{update_sid}(10); | |
380 $f->{update}(10); | |
381 | |
382 $frames = $f->{data_len}(undef, 5); | |
383 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
384 is($frame->{length}, 5, 'flow control - rest length'); | |
385 is($frame->{flags}, 1, 'flow control - rest flags'); | |
386 | |
387 $f->{http_end}(); | |
388 | |
1318
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
389 # preserve output |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
390 |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
391 $f->{http_start}('/Preserve'); |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
392 $f->{data}('Hello'); |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
393 $frames = $f->{http_pres}(); |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
394 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
395 is($frame->{flags}, 4, 'preserve - HEADERS'); |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
396 |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
397 my @data = grep { $_->{type} eq "DATA" } @$frames; |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
398 $sum = eval join '+', map { $_->{length} } @data; |
1319
3b30e97acdcb
Tests: made grpc preserve output test pass on win32 and Solaris.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1318
diff
changeset
|
399 is($sum, 20480, 'preserve - DATA'); |
1318
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
400 |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
401 (undef, $frame) = grep { $_->{type} eq "HEADERS" } @$frames; |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
402 is($frame->{flags}, 5, 'preserve - trailers'); |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
403 |
1303 | 404 # DATA padding |
405 | |
406 $f->{http_start}('/SayPadding'); | |
407 $f->{data}('Hello'); | |
408 $frames = $f->{http_end}(body_padding => 42); | |
409 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
1362
6874b32dc3d2
Tests: renamed some grpc.t tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1321
diff
changeset
|
410 is($frame->{data}, 'Hello world', 'DATA padding'); |
6874b32dc3d2
Tests: renamed some grpc.t tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1321
diff
changeset
|
411 is($frame->{length}, 11, 'DATA padding - length'); |
6874b32dc3d2
Tests: renamed some grpc.t tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1321
diff
changeset
|
412 is($frame->{flags}, 0, 'DATA padding - flags'); |
1303 | 413 |
414 # :authority inheritance | |
415 | |
416 $frames = $f->{http_start}('/SayHello?if=1'); | |
417 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
418 is($frame->{headers}{':authority'}, "127.0.0.1:$p", 'authority in if'); | |
419 $f->{data}('Hello'); | |
420 $f->{http_end}(); | |
421 | |
422 # misc tests | |
423 | |
424 $frames = $f->{http_start}('/SetHost'); | |
425 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
426 ok(!$frame->{headers}{':authority'}, 'set host - authority'); | |
427 is($frame->{headers}{'host'}, 'custom', 'set host - host'); | |
428 $f->{data}('Hello'); | |
429 $f->{http_end}(); | |
430 | |
431 $frames = $f->{http_start}('/SetArgs?f'); | |
432 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
433 is($frame->{headers}{':path'}, '/SetArgs', 'set args'); | |
434 $f->{data}('Hello'); | |
435 $f->{http_end}(); | |
436 | |
437 $frames = $f->{http_start}('/SetArgs?c=1'); | |
438 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
439 is($frame->{headers}{':path'}, '/SetArgs?1', 'set args len'); | |
440 $f->{data}('Hello'); | |
441 $f->{http_end}(); | |
442 | |
443 $frames = $f->{http_start}('/SetArgs esc'); | |
444 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
445 is($frame->{headers}{':path'}, '/SetArgs%20esc', 'uri escape'); | |
446 $f->{data}('Hello'); | |
447 $f->{http_end}(); | |
448 | |
449 $frames = $f->{http_start}('/'); | |
450 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
451 is($frame->{headers}{':path'}, '/', 'root index'); | |
452 $f->{data}('Hello'); | |
453 $f->{http_end}(); | |
454 | |
455 $frames = $f->{http_start}('/', method => 'GET'); | |
456 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
457 is($frame->{headers}{':method'}, 'GET', 'method get'); | |
458 $f->{data}('Hello'); | |
459 $f->{http_end}(); | |
460 | |
461 $frames = $f->{http_start}('/', method => 'HEAD'); | |
462 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
463 is($frame->{headers}{':method'}, 'HEAD', 'method head'); | |
464 $f->{data}('Hello'); | |
465 $f->{http_end}(); | |
466 | |
467 ############################################################################### | |
468 | |
469 sub grpc { | |
1318
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
470 my ($server, $client, $f, $s, $c, $sid, $csid, $uri); |
1303 | 471 my $n = 0; |
472 | |
473 $server = IO::Socket::INET->new( | |
474 Proto => 'tcp', | |
475 LocalHost => '127.0.0.1', | |
476 LocalPort => $p, | |
477 Listen => 5, | |
478 Reuse => 1 | |
479 ) | |
480 or die "Can't create listening socket: $!\n"; | |
481 | |
482 $f->{http_start} = sub { | |
483 ($uri, my %extra) = @_; | |
484 my $body_more = 1 if $uri !~ /LongHeader/; | |
485 my $meth = $extra{method} || 'POST'; | |
486 $s = Test::Nginx::HTTP2->new() if !defined $s; | |
1318
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
487 $csid = $s->new_stream({ body_more => $body_more, headers => [ |
1303 | 488 { name => ':method', value => $meth, mode => !!$meth }, |
489 { name => ':scheme', value => 'http', mode => 0 }, | |
490 { name => ':path', value => $uri, }, | |
491 { name => ':authority', value => 'localhost' }, | |
492 { name => 'content-type', value => 'application/grpc' }, | |
493 { name => 'te', value => 'trailers', mode => 2 }]}); | |
494 | |
495 if (!$extra{reuse}) { | |
1321
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
496 eval { |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
497 local $SIG{ALRM} = sub { die "timeout\n" }; |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
498 alarm(5); |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
499 |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
500 $client = $server->accept() or return; |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
501 |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
502 alarm(0); |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
503 }; |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
504 alarm(0); |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
505 if ($@) { |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
506 log_in("died: $@"); |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
507 return undef; |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
508 } |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1319
diff
changeset
|
509 |
1303 | 510 log2c("(new connection $client)"); |
511 $n++; | |
512 | |
513 $client->sysread(my $buf, 24) == 24 or return; # preface | |
514 | |
515 $c = Test::Nginx::HTTP2->new(1, socket => $client, | |
516 pure => 1, preface => "") or return; | |
517 } | |
518 | |
519 my $frames = $c->read(all => [{ fin => 4 }]); | |
520 | |
521 if (!$extra{reuse}) { | |
522 $c->h2_settings(0); | |
523 $c->h2_settings(1); | |
524 } | |
525 | |
526 my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
527 $sid = $frame->{sid}; | |
528 return $frames; | |
529 }; | |
530 $f->{data} = sub { | |
531 my ($body, %extra) = @_; | |
532 $s->h2_body($body, { %extra }); | |
533 return $c->read(all => [{ sid => $sid, | |
534 length => length($body) }]); | |
535 }; | |
536 $f->{data_len} = sub { | |
537 my ($body, $len) = @_; | |
538 $s->h2_body($body) if defined $body; | |
539 return $c->read(all => [{ sid => $sid, length => $len }]); | |
540 }; | |
541 $f->{update} = sub { | |
542 $c->h2_window(shift); | |
543 }; | |
544 $f->{update_sid} = sub { | |
545 $c->h2_window(shift, $sid); | |
546 }; | |
1370
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
547 $f->{settings} = sub { |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
548 $c->h2_settings(@_); |
23e407a72fe9
Tests: upstream keepalive with grpc pending frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1362
diff
changeset
|
549 }; |
1303 | 550 $f->{http_end} = sub { |
551 my (%extra) = @_; | |
552 $c->new_stream({ body_more => 1, %extra, headers => [ | |
553 { name => ':status', value => '200', | |
554 mode => $extra{mode} || 0 }, | |
555 { name => 'content-type', value => 'application/grpc', | |
556 mode => $extra{mode} || 1, huff => 1 }, | |
557 { name => 'x-connection', value => $n, | |
558 mode => 2, huff => 1 }, | |
559 ]}, $sid); | |
560 $c->h2_body('Hello world', { body_more => 1, | |
561 body_padding => $extra{body_padding} }); | |
562 $c->new_stream({ headers => [ | |
563 { name => 'grpc-status', value => '0', | |
564 mode => 2, huff => 1 }, | |
565 { name => 'grpc-message', value => '', | |
566 mode => 2, huff => 1 }, | |
567 ]}, $sid); | |
568 | |
569 return $s->read(all => [{ fin => 1 }]); | |
570 }; | |
1318
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
571 $f->{http_pres} = sub { |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
572 my (%extra) = @_; |
1319
3b30e97acdcb
Tests: made grpc preserve output test pass on win32 and Solaris.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1318
diff
changeset
|
573 $s->h2_settings(0, 0x4 => 8192); |
1318
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
574 $c->new_stream({ body_more => 1, %extra, headers => [ |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
575 { name => ':status', value => '200', |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
576 mode => $extra{mode} || 0 }, |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
577 { name => 'content-type', value => 'application/grpc', |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
578 mode => $extra{mode} || 1, huff => 1 }, |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
579 { name => 'x-connection', value => $n, |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
580 mode => 2, huff => 1 }, |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
581 ]}, $sid); |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
582 for (1 .. 20) { |
1319
3b30e97acdcb
Tests: made grpc preserve output test pass on win32 and Solaris.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1318
diff
changeset
|
583 $c->h2_body(sprintf('Hello %02d', $_) x 128, { |
1318
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
584 body_more => 1, |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
585 body_padding => $extra{body_padding} }); |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
586 $c->h2_ping("PING"); |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
587 } |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
588 # reopen window |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
589 $s->h2_window(2**24); |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
590 $s->h2_window(2**24, $csid); |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
591 $c->new_stream({ headers => [ |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
592 { name => 'grpc-status', value => '0', |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
593 mode => 2, huff => 1 }, |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
594 { name => 'grpc-message', value => '', |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
595 mode => 2, huff => 1 }, |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
596 ]}, $sid); |
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
597 |
1319
3b30e97acdcb
Tests: made grpc preserve output test pass on win32 and Solaris.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1318
diff
changeset
|
598 return $s->read(all => [{ sid => $csid, fin => 1 }]); |
1318
6de2a27af2d3
Tests: grpc preserve output tests added (ticket #1519).
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
599 }; |
1303 | 600 $f->{http_err} = sub { |
601 $c->new_stream({ headers => [ | |
602 { name => ':status', value => '200', mode => 0 }, | |
603 { name => 'content-type', value => 'application/grpc', | |
604 mode => 1, huff => 1 }, | |
605 { name => 'grpc-status', value => '12', | |
606 mode => 2, huff => 1 }, | |
607 { name => 'grpc-message', value => 'unknown service', | |
608 mode => 2, huff => 1 }, | |
609 ]}, $sid); | |
610 | |
611 return $s->read(all => [{ fin => 1 }]); | |
612 }; | |
613 $f->{continuation} = sub { | |
614 $c->new_stream({ continuation => 1, body_more => 1, headers => [ | |
615 { name => ':status', value => '200', mode => 0 }, | |
616 ]}, $sid); | |
617 $c->h2_continue($sid, { continuation => 1, headers => [ | |
618 { name => 'content-type', value => 'application/grpc', | |
619 mode => 1, huff => 1 }, | |
620 ]}); | |
621 $c->h2_continue($sid, { headers => [ | |
622 # an empty CONTINUATION frame is legitimate | |
623 ]}); | |
624 $c->h2_body('Hello world', { body_more => 1 }); | |
625 $c->new_stream({ continuation => 1, headers => [ | |
626 { name => 'grpc-status', value => '0', | |
627 mode => 2, huff => 1 }, | |
628 ]}, $sid); | |
629 $c->h2_continue($sid, { headers => [ | |
630 { name => 'grpc-message', value => '', | |
631 mode => 2, huff => 1 }, | |
632 ]}); | |
633 | |
634 return $s->read(all => [{ fin => 1 }]); | |
635 }; | |
636 $f->{field_len} = sub { | |
637 my ($len) = @_; | |
638 $c->new_stream({ continuation => [map {2**14} (0..$len/2**13)], | |
639 body_more => 1, headers => [ | |
640 { name => ':status', value => '200', mode => 0 }, | |
641 { name => 'content-type', value => 'application/grpc', | |
642 mode => 1, huff => 1 }, | |
643 { name => 'x' x $len, value => 'y' x $len, mode => 6 }, | |
644 ]}, $sid); | |
645 $c->h2_body('Hello world', { body_more => 1 }); | |
646 $c->new_stream({ headers => [ | |
647 { name => 'grpc-status', value => '0', | |
648 mode => 2, huff => 1 }, | |
649 { name => 'grpc-message', value => '', | |
650 mode => 2, huff => 1 }, | |
651 ]}, $sid); | |
652 | |
653 return $s->read(all => [{ fin => 1 }]); | |
654 }; | |
655 return $f; | |
656 } | |
657 | |
658 sub log2i { Test::Nginx::log_core('|| <<', @_); } | |
659 sub log2o { Test::Nginx::log_core('|| >>', @_); } | |
660 sub log2c { Test::Nginx::log_core('||', @_); } | |
661 | |
662 ############################################################################### |