comparison h2_server_push.t @ 1348:8cb66a4d3ca2

Tests: fixed HTTP/2 server push expectations, adjusted TODO.
author Sergey Kandaurov <pluknet@nginx.com>
date Thu, 14 Jun 2018 14:01:50 +0300
parents da711694bbd7
children 97c8280de681
comparison
equal deleted inserted replaced
1347:106d9f806288 1348:8cb66a4d3ca2
136 136
137 $t->try_run('no http2_push')->plan(42); 137 $t->try_run('no http2_push')->plan(42);
138 138
139 ############################################################################### 139 ###############################################################################
140 140
141 # 6.6. PUSH_PROMISE
142 # PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that
143 # is in either the "open" or "half-closed (remote)" state.
144
141 # preload & format 145 # preload & format
142 146
143 my $s = Test::Nginx::HTTP2->new(); 147 my $s = Test::Nginx::HTTP2->new();
144 my $sid = $s->new_stream({ path => '/preload' }); 148 my $sid = $s->new_stream({ path => '/preload' });
145 my $frames = $s->read(all => [{ sid => 1, fin => 1 }, { sid => 2, fin => 1 }]); 149 my $frames = $s->read(all => [{ sid => 1, fin => 1 }, { sid => 2, fin => 1 }]);
159 ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} eq $sid } @$frames; 163 ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} eq $sid } @$frames;
160 is($frame->{headers}->{'x-link'}, '</push>; rel=preload', 'sent_http_link'); 164 is($frame->{headers}->{'x-link'}, '</push>; rel=preload', 'sent_http_link');
161 165
162 $s = Test::Nginx::HTTP2->new(); 166 $s = Test::Nginx::HTTP2->new();
163 $sid = $s->new_stream({ path => '/preload2' }); 167 $sid = $s->new_stream({ path => '/preload2' });
164 $frames = $s->read(all => [{ sid => 8, fin => 1 }], wait => 0.5); 168 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
165 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 4, 'preload 2'); 169 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 4, 'preload 2');
166 170
167 $s = Test::Nginx::HTTP2->new(); 171 $s = Test::Nginx::HTTP2->new();
168 $sid = $s->new_stream({ path => '/preload/many' }); 172 $sid = $s->new_stream({ path => '/preload/many' });
169 $frames = $s->read(all => [{ sid => 8, fin => 1 }], wait => 0.5); 173 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
170 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 3, 'preload many'); 174 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 3, 'preload many');
171 175
172 # preload proxy 176 # preload proxy
173 177
174 $s = Test::Nginx::HTTP2->new(); 178 $s = Test::Nginx::HTTP2->new();
175 $sid = $s->new_stream({ path => '/preload/proxy' }); 179 $sid = $s->new_stream({ path => '/preload/proxy' });
176 $frames = $s->read(all => [{ sid => 8, fin => 1 }], wait => 0.5); 180 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
177 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 2, 'preload proxy'); 181 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 2, 'preload proxy');
178 182
179 # both h2_push & preload 183 # both h2_push & preload
180 184
181 $s = Test::Nginx::HTTP2->new(); 185 $s = Test::Nginx::HTTP2->new();
182 $sid = $s->new_stream({ path => '/both' }); 186 $sid = $s->new_stream({ path => '/both' });
183 $frames = $s->read(all => [{ sid => 8, fin => 1 }], wait => 0.5); 187 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
184 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 2, 'h2_push and preload'); 188 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 2, 'h2_push and preload');
185 189
186 # h2_push 190 # h2_push
187 191
188 $s = Test::Nginx::HTTP2->new(); 192 $s = Test::Nginx::HTTP2->new();
189 $sid = $s->new_stream({ path => '/expl' }); 193 $sid = $s->new_stream({ path => '/expl' });
190 $frames = $s->read(all => [{ sid => 1, fin => 1 }, { sid => 2, fin => 1 }]); 194 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
191 195
192 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames; 196 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames;
193 ok($frame, 'h2_push only'); 197 ok($frame, 'h2_push only');
194 198
195 # h2_push off 199 # h2_push off
196 200
197 $s = Test::Nginx::HTTP2->new(); 201 $s = Test::Nginx::HTTP2->new();
198 $sid = $s->new_stream({ path => '/expl/off' }); 202 $sid = $s->new_stream({ path => '/expl/off' });
199 $frames = $s->read(all => [{ type => 'PUSH_PROMISE' }], wait => 0.2); 203 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
200 204
201 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames; 205 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames;
202 ok(!$frame, 'h2_push off'); 206 ok(!$frame, 'h2_push off');
203 207
204 # h2_push $var 208 # h2_push $var
205 209
206 $s = Test::Nginx::HTTP2->new(); 210 $s = Test::Nginx::HTTP2->new();
207 $sid = $s->new_stream({ path => '/arg?push=/push' }); 211 $sid = $s->new_stream({ path => '/arg?push=/push' });
208 $frames = $s->read(all => [{ type => 'PUSH_PROMISE' }], wait => 0.2); 212 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
209 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames; 213 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames;
210 ok($frame, 'h2_push variable'); 214 ok($frame, 'h2_push variable');
211 215
212 $sid = $s->new_stream({ path => '/arg?push=' }); 216 $sid = $s->new_stream({ path => '/arg?push=' });
213 $frames = $s->read(all => [{ type => 'PUSH_PROMISE' }], wait => 0.2); 217 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
214 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames; 218 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames;
215 ok(!$frame, 'h2_push variable empty'); 219 ok(!$frame, 'h2_push variable empty');
216 220
217 $sid = $s->new_stream({ path => '/arg?push=off' }); 221 $sid = $s->new_stream({ path => '/arg?push=off' });
218 $frames = $s->read(all => [{ type => 'PUSH_PROMISE' }], wait => 0.2); 222 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
219 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames; 223 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames;
220 ok(!$frame, 'h2_push variable off'); 224 ok(!$frame, 'h2_push variable off');
221 225
222 $sid = $s->new_stream({ path => '/arg?push=foo' }); 226 $sid = $s->new_stream({ path => '/arg?push=foo' });
223 $frames = $s->read(all => [{ type => 'PUSH_PROMISE' }], wait => 0.2); 227 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
224 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames; 228 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames;
225 ok(!$frame, 'h2_push variable relative path'); 229 ok(!$frame, 'h2_push variable relative path');
226 230
227 # SETTINGS_ENABLE_PUSH 231 # SETTINGS_ENABLE_PUSH
228 232
229 $s = Test::Nginx::HTTP2->new(); 233 $s = Test::Nginx::HTTP2->new();
230 $s->h2_settings(0, 0x2 => 0); 234 $s->h2_settings(0, 0x2 => 0);
231 $sid = $s->new_stream({ path => '/expl' }); 235 $sid = $s->new_stream({ path => '/expl' });
232 $frames = $s->read(all => [{ type => 'PUSH_PROMISE' }], wait => 0.2); 236 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
233 237
234 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames; 238 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames;
235 ok(!$frame, 'push setting disabled'); 239 ok(!$frame, 'push setting disabled');
236 240
237 $s->h2_settings(0, 0x2 => 1); 241 $s->h2_settings(0, 0x2 => 1);
238 $sid = $s->new_stream({ path => '/expl' }); 242 $sid = $s->new_stream({ path => '/expl' });
239 $frames = $s->read(all => [{ sid => $sid, fin => 1 }, { sid => 2, fin => 1 }]); 243 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
240 244
241 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames; 245 ($frame) = grep { $_->{type} eq "PUSH_PROMISE" } @$frames;
242 ok($frame, 'push setting enabled'); 246 ok($frame, 'push setting enabled');
243 247
244 $s->h2_settings(0, 0x2 => 42); 248 $s->h2_settings(0, 0x2 => 42);
250 254
251 # SETTINGS_MAX_CONCURRENT_STREAMS 255 # SETTINGS_MAX_CONCURRENT_STREAMS
252 256
253 $s = Test::Nginx::HTTP2->new(); 257 $s = Test::Nginx::HTTP2->new();
254 $sid = $s->new_stream({ path => '/expl' }); 258 $sid = $s->new_stream({ path => '/expl' });
255 $frames = $s->read(all => [ 259 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
256 { sid => 1, fin => 1 },
257 { sid => 2, fin => 1 },
258 { sid => 4, fin => 1 }]);
259 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 2, 'max pushes default'); 260 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 2, 'max pushes default');
260 261
261 $s = Test::Nginx::HTTP2->new(); 262 $s = Test::Nginx::HTTP2->new();
262 $s->h2_settings(0, 0x3 => 1); 263 $s->h2_settings(0, 0x3 => 1);
263 $sid = $s->new_stream({ path => '/expl' }); 264 $sid = $s->new_stream({ path => '/expl' });
264 $frames = $s->read(all => [{ sid => 1, fin => 1 }, { sid => 2, fin => 1 }]); 265 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
265 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 1, 'max pushes limited'); 266 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 1, 'max pushes limited');
266 267
267 $s = Test::Nginx::HTTP2->new(); 268 $s = Test::Nginx::HTTP2->new();
268 $s->h2_settings(0, 0x3 => 0); 269 $s->h2_settings(0, 0x3 => 0);
269 $sid = $s->new_stream({ path => '/expl' }); 270 $sid = $s->new_stream({ path => '/expl' });
270 $frames = $s->read(all => [{ type => 'PUSH_PROMISE' }], wait => 0.2); 271 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
271 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 0, 'max pushes disabled'); 272 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 0, 'max pushes disabled');
272 273
273 TODO: { 274 TODO: {
274 local $TODO = 'not yet' if $t->read_file('nginx.conf') =~ /aio on/ 275 todo_skip 'long tests with aio', 6 unless $ENV{TEST_NGINX_UNSAFE}
275 or $t->read_file('nginx.conf') =~ /aio threads/; 276 or $t->read_file('nginx.conf') !~ /aio (on|threads)/;
277 local $TODO = 'not yet' if $t->read_file('nginx.conf') =~ /aio (on|threads)/;
276 278
277 # server push flow control & rst 279 # server push flow control & rst
278 280
279 $s = Test::Nginx::HTTP2->new(); 281 $s = Test::Nginx::HTTP2->new();
280 $sid = $s->new_stream({ path => '/explf' }); 282 $sid = $s->new_stream({ path => '/explf' });
302 304
303 $s->h2_rst(4, 7); 305 $s->h2_rst(4, 7);
304 $s->h2_window(2**16); 306 $s->h2_window(2**16);
305 307
306 $frames = $s->read(all => [{ sid => 2, length => 1 }]); 308 $frames = $s->read(all => [{ sid => 2, length => 1 }]);
307 push @$frames, @{ $s->read(all => [{ sid => 4, fin => 1 }], wait => 0.5) }; 309 push @$frames, @{ $s->read(all => [{ sid => 4, fin => 1 }], wait => 0.2) };
308 310
309 ($frame) = grep { $_->{type} eq "DATA" && $_->{sid} == 2 } @$frames; 311 ($frame) = grep { $_->{type} eq "DATA" && $_->{sid} == 2 } @$frames;
310 is($frame->{length}, 1, 'pushed response flow control'); 312 is($frame->{length}, 1, 'pushed response flow control');
311 is($frame->{flags}, 1, 'pushed response END_STREAM'); 313 is($frame->{flags}, 1, 'pushed response END_STREAM');
312 314
314 316
315 ($frame) = grep { $_->{type} eq "DATA" && $_->{sid} == 4 } @$frames; 317 ($frame) = grep { $_->{type} eq "DATA" && $_->{sid} == 4 } @$frames;
316 ok(!$frame, 'rst pushed stream'); 318 ok(!$frame, 'rst pushed stream');
317 319
318 TODO: { 320 TODO: {
319 local $TODO = 'not yet' if $t->read_file('nginx.conf') =~ /aio on/ 321 todo_skip 'long tests with aio', 2 unless $ENV{TEST_NGINX_UNSAFE}
320 or $t->read_file('nginx.conf') =~ /aio threads/; 322 or $t->read_file('nginx.conf') !~ /aio (on|threads)/;
323 local $TODO = 'not yet' if $t->read_file('nginx.conf') =~ /aio (on|threads)/;
321 324
322 # priority 325 # priority
323 326
324 $s = Test::Nginx::HTTP2->new(); 327 $s = Test::Nginx::HTTP2->new();
325 $sid = $s->new_stream({ path => '/prio' }); 328 $sid = $s->new_stream({ path => '/prio' });
357 $sid = $s->new_stream({ headers => [ 360 $sid = $s->new_stream({ headers => [
358 { name => ':method', value => 'GET', mode => 0 }, 361 { name => ':method', value => 'GET', mode => 0 },
359 { name => ':scheme', value => 'http', mode => 0 }, 362 { name => ':scheme', value => 'http', mode => 0 },
360 { name => ':path', value => '/', mode => 0 }, 363 { name => ':path', value => '/', mode => 0 },
361 { name => ':authority', value => 'max_pushes', mode => 1 }]}); 364 { name => ':authority', value => 'max_pushes', mode => 1 }]});
362 $frames = $s->read(all => [{ sid => $sid, fin => 1 }, 365 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
363 { sid => 2, fin => 1 }, { sid => 4, fin => 1 }]);
364 push @$frames, @{ $s->read(all => [{ sid => 6, fin => 1 }], wait => 0.2) };
365 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 2, 'http2 max pushes lim'); 366 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 2, 'http2 max pushes lim');
366 367
367 $s = Test::Nginx::HTTP2->new(port(8082)); 368 $s = Test::Nginx::HTTP2->new(port(8082));
368 $s->h2_settings(0, 0x3 => 1); 369 $s->h2_settings(0, 0x3 => 1);
369 $sid = $s->new_stream({ headers => [ 370 $sid = $s->new_stream({ headers => [
370 { name => ':method', value => 'GET', mode => 0 }, 371 { name => ':method', value => 'GET', mode => 0 },
371 { name => ':scheme', value => 'http', mode => 0 }, 372 { name => ':scheme', value => 'http', mode => 0 },
372 { name => ':path', value => '/', mode => 0 }, 373 { name => ':path', value => '/', mode => 0 },
373 { name => ':authority', value => 'max_pushes', mode => 1 }]}); 374 { name => ':authority', value => 'max_pushes', mode => 1 }]});
374 $frames = $s->read(all => [{ sid => $sid, fin => 1 }, { sid => 2, fin => 1 }]); 375 $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
375 push @$frames, @{ $s->read(all => [{ sid => 4, fin => 1 }], wait => 0.2) };
376 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 1, 'http2 max pushes 2'); 376 is(grep({ $_->{type} eq "PUSH_PROMISE" } @$frames), 1, 'http2 max pushes 2');
377 377
378 # missing request header ':authority' 378 # missing request header ':authority'
379 379
380 $s = Test::Nginx::HTTP2->new(port(8082)); 380 $s = Test::Nginx::HTTP2->new(port(8082));