Skip to content

Commit 7cee3cf

Browse files
committed
tests: add test cases for http2_subreq_error_wakeup.patch
Signed-off-by: tzssangglass <[email protected]>
1 parent 54e8135 commit 7cee3cf

File tree

1 file changed

+220
-0
lines changed

1 file changed

+220
-0
lines changed

t/189-http2-subreq-error-wakeup.t

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# vim:set ft= ts=4 sw=4 et fdm=marker:
2+
#
3+
# Test for HTTP/2 subrequest wakeup issue when parent request times out
4+
# Bug: When an HTTP/2 parent request times out while waiting for a subrequest,
5+
# the parent's error_wakeup() could incorrectly try to wake up the still-running
6+
# subrequest, causing undefined behavior.
7+
#
8+
# Reproduction: timeout 2 curl -i --http2 -k https://localhost:8443/delay/5
9+
# The parent times out after 2s but the subrequest is still sleeping for 5s.
10+
11+
use Test::Nginx::Socket::Lua;
12+
use Cwd qw(abs_path realpath);
13+
use File::Basename;
14+
15+
log_level('info');
16+
17+
repeat_each(2);
18+
19+
plan tests => repeat_each() * (blocks() * 9 + 2);
20+
21+
#no_diff();
22+
no_long_string();
23+
run_tests();
24+
25+
__DATA__
26+
27+
=== TEST 1: HTTP/2 parent request timeout during subrequest sleep
28+
--- config
29+
location /delay {
30+
content_by_lua_block {
31+
ngx.log(ngx.INFO, "Parent request started, issuing subrequest with 3s delay")
32+
local res = ngx.location.capture("/sub_delay")
33+
ngx.log(ngx.INFO, "Parent request finished, got response from subrequest")
34+
ngx.say("parent: ", res.body)
35+
}
36+
}
37+
38+
location /sub_delay {
39+
content_by_lua_block {
40+
ngx.log(ngx.INFO, "Subrequest started, sleeping for 3 seconds")
41+
ngx.sleep(3)
42+
ngx.log(ngx.INFO, "Subrequest woke up after 3 seconds")
43+
ngx.say("subreq completed after 3s delay")
44+
}
45+
}
46+
--- http2
47+
--- request
48+
GET /delay
49+
--- timeout: 1
50+
--- abort
51+
--- ignore_response
52+
--- curl_error: (28) Operation timed out
53+
--- error_log
54+
Parent request started, issuing subrequest with 3s delay
55+
Subrequest started, sleeping for 3 seconds
56+
--- shutdown_error_log
57+
Subrequest woke up after 3 seconds
58+
Parent request finished, got response from subrequest
59+
--- no_error_log
60+
[alert]
61+
[crit]
62+
[emerg]
63+
[error]
64+
--- no_shutdown_error_log
65+
[alert]
66+
[crit]
67+
[emerg]
68+
[error]
69+
70+
71+
72+
=== TEST 2: HTTP/2 nested subrequests with parent timeout
73+
--- config
74+
location /outer {
75+
content_by_lua_block {
76+
ngx.log(ngx.INFO, "Outer request started")
77+
local res = ngx.location.capture("/middle")
78+
ngx.log(ngx.INFO, "Outer request completed")
79+
ngx.say("outer: ", res.body)
80+
}
81+
}
82+
83+
location /middle {
84+
content_by_lua_block {
85+
ngx.log(ngx.INFO, "Middle subrequest started")
86+
local res = ngx.location.capture("/inner")
87+
ngx.log(ngx.INFO, "Middle subrequest completed")
88+
ngx.say("middle: ", res.body)
89+
}
90+
}
91+
92+
location /inner {
93+
content_by_lua_block {
94+
ngx.log(ngx.INFO, "Inner subrequest started, sleeping 3s")
95+
ngx.sleep(3)
96+
ngx.log(ngx.INFO, "Inner subrequest woke up")
97+
ngx.say("inner done")
98+
}
99+
}
100+
--- http2
101+
--- request
102+
GET /outer
103+
--- timeout: 1
104+
--- abort
105+
--- ignore_response
106+
--- curl_error: (28) Operation timed out
107+
--- error_log
108+
Outer request started
109+
Middle subrequest started
110+
Inner subrequest started, sleeping 3s
111+
--- shutdown_error_log
112+
Inner subrequest woke up
113+
Middle subrequest completed
114+
Outer request completed
115+
--- no_error_log
116+
[alert]
117+
[crit]
118+
[emerg]
119+
[error]
120+
--- no_shutdown_error_log
121+
[alert]
122+
[crit]
123+
[emerg]
124+
[error]
125+
126+
127+
128+
=== TEST 3: HTTP/2 parallel subrequests with parent timeout
129+
--- config
130+
location /parallel {
131+
content_by_lua_block {
132+
ngx.log(ngx.INFO, "Starting parallel subrequests")
133+
local res1, res2 = ngx.location.capture_multi({
134+
{"/slow1"},
135+
{"/slow2"}
136+
})
137+
ngx.log(ngx.INFO, "Parallel subrequests completed")
138+
ngx.say("parallel done: ", res1.body, ", ", res2.body)
139+
}
140+
}
141+
142+
location /slow1 {
143+
content_by_lua_block {
144+
ngx.log(ngx.INFO, "Subrequest slow1 sleeping 3s")
145+
ngx.sleep(3)
146+
ngx.log(ngx.INFO, "Subrequest slow1 finished")
147+
ngx.say("slow1 done")
148+
}
149+
}
150+
151+
location /slow2 {
152+
content_by_lua_block {
153+
ngx.log(ngx.INFO, "Subrequest slow2 sleeping 3s")
154+
ngx.sleep(3)
155+
ngx.log(ngx.INFO, "Subrequest slow2 finished")
156+
ngx.say("slow2 done")
157+
}
158+
}
159+
160+
--- http2
161+
--- request
162+
GET /parallel
163+
--- timeout: 1
164+
--- abort
165+
--- ignore_response
166+
--- curl_error: (28) Operation timed out
167+
--- error_log
168+
Starting parallel subrequests
169+
Subrequest slow1 sleeping 3s
170+
Subrequest slow2 sleeping 3s
171+
--- shutdown_error_log
172+
Subrequest slow1 finished
173+
Subrequest slow2 finished
174+
Parallel subrequests completed
175+
--- no_error_log
176+
[alert]
177+
[crit]
178+
[emerg]
179+
[error]
180+
--- no_shutdown_error_log
181+
[alert]
182+
[crit]
183+
[emerg]
184+
[error]
185+
186+
187+
188+
=== TEST 4: HTTP/2 short subrequest completes before timeout
189+
--- config
190+
location /fast {
191+
content_by_lua_block {
192+
ngx.log(ngx.INFO, "Fast parent started")
193+
local res = ngx.location.capture("/fast_sub")
194+
ngx.log(ngx.INFO, "Fast parent completed")
195+
ngx.print("result: ", res.body)
196+
}
197+
}
198+
199+
location /fast_sub {
200+
content_by_lua_block {
201+
ngx.log(ngx.INFO, "Fast subrequest, sleeping 0.1s")
202+
ngx.sleep(0.1)
203+
ngx.log(ngx.INFO, "Fast subrequest finished")
204+
ngx.print("fast done")
205+
}
206+
}
207+
208+
--- http2
209+
--- request
210+
GET /fast
211+
--- response_body chomp
212+
result: fast done
213+
--- error_log
214+
Fast parent started
215+
Fast subrequest, sleeping 0.1s
216+
Fast subrequest finished
217+
Fast parent completed
218+
--- no_error_log
219+
[alert]
220+
[crit]

0 commit comments

Comments
 (0)