Skip to content

Commit fe7c25e

Browse files
committed
Test to sanity check cert registration during concurrent requests.
1 parent 7ed301b commit fe7c25e

File tree

1 file changed

+78
-40
lines changed

1 file changed

+78
-40
lines changed

t/multiple_workers.t

Lines changed: 78 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,24 @@ repeat_each(10);
2121

2222
master_on();
2323
workers(5);
24+
worker_connections(1024);
2425

25-
plan tests => repeat_each() * (blocks() * 7);
26+
plan tests => repeat_each() * (blocks() * 6);
2627

27-
check_accum_error_log();
2828
no_long_string();
2929
no_shuffle();
3030

3131
run_tests();
3232

3333
__DATA__
3434
35-
=== TEST 1: issues a new SSL certificate when multiple nginx workers are running
35+
=== TEST 1: issues a new SSL certificate when multiple nginx workers are running and concurrent requests are made
3636
--- main_config
3737
$TEST_NGINX_USER
3838
--- http_config
3939
resolver $TEST_NGINX_RESOLVER;
4040
lua_shared_dict auto_ssl 1m;
41+
lua_shared_dict test_counts 128k;
4142
4243
init_by_lua_block {
4344
auto_ssl = (require "lib.resty.auto-ssl").new({
@@ -63,9 +64,7 @@ $TEST_NGINX_USER
6364
}
6465
6566
location /foo {
66-
server_tokens off;
67-
more_clear_headers Date;
68-
echo "foo";
67+
echo -n "foo";
6968
}
7069
}
7170
@@ -91,57 +90,96 @@ $TEST_NGINX_USER
9190
lua_ssl_verify_depth 5;
9291
location /t {
9392
content_by_lua_block {
94-
local sock = ngx.socket.tcp()
95-
sock:settimeout(30000)
96-
local ok, err = sock:connect("127.0.0.1:9443")
97-
if not ok then
98-
ngx.say("failed to connect: ", err)
99-
return
100-
end
93+
local host = "$TEST_NGINX_NGROK_HOSTNAME"
94+
95+
-- Since repeat_each is being used, clear the cached information across
96+
-- test runs so we try to issue a new cert each time.
97+
ngx.log(ngx.DEBUG, "auto-ssl: delete: domain:fullchain_der:" .. host)
98+
ngx.shared.auto_ssl:delete("domain:fullchain_der:" .. host)
99+
ngx.shared.auto_ssl:delete("domain:privkey_der:" .. host)
100+
ngx.shared.auto_ssl:delete("domain:ocsp:" .. host)
101+
ngx.shared.test_counts:flush_all()
102+
os.execute("rm -rf $TEST_NGINX_RESTY_AUTO_SSL_DIR/storage/file/*")
103+
104+
local http = require "resty.http"
105+
106+
local function make_http_requests()
107+
local httpc = http.new()
108+
109+
local _, err = httpc:set_timeout(30000)
110+
if err then ngx.say("http set_timeout error", err); return end
111+
local _, err = httpc:connect("127.0.0.1", 9443)
112+
if err then ngx.say("http connect error: ", err); return end
113+
local _, err = httpc:ssl_handshake(nil, host, true)
114+
if err then ngx.say("http ssl_handshake error: ", err); return end
115+
116+
-- Make pipelined requests on this connection to test behavior across
117+
-- the same connection.
118+
local requests = {}
119+
for i = 1, 10 do
120+
table.insert(requests, {
121+
path = "/foo",
122+
headers = { ["Host"] = host },
123+
})
124+
end
101125
102-
local sess, err = sock:sslhandshake(nil, "$TEST_NGINX_NGROK_HOSTNAME", true)
103-
if not sess then
104-
ngx.say("failed to do SSL handshake: ", err)
105-
return
106-
end
126+
local responses, err = httpc:request_pipeline(requests)
127+
if err then ngx.say("http error: ", err); return end
128+
129+
for _, res in ipairs(responses) do
130+
local body, err = res:read_body()
131+
if err then ngx.say("http read_body error: ", err); return end
132+
133+
-- Keep track of the total number of successful requests across all
134+
-- the parallel requests.
135+
if res.status == 200 and body == "foo" then
136+
local _, err = ngx.shared.test_counts:incr("successes", 1)
137+
if err then ngx.say("incr error: ", err); return end
138+
else
139+
ngx.say("Unexpected Response: " .. res.status .. " Body: " .. body)
140+
end
141+
end
107142
108-
local req = "GET /foo HTTP/1.0\r\nHost: $TEST_NGINX_NGROK_HOSTNAME\r\nConnection: close\r\n\r\n"
109-
local bytes, err = sock:send(req)
110-
if not bytes then
111-
ngx.say("failed to send http request: ", err)
112-
return
143+
local _, err = httpc:close()
144+
if err then ngx.say("http close error: ", err); return end
113145
end
114146
115-
while true do
116-
local line, err = sock:receive()
117-
if not line then
118-
break
119-
end
147+
local _, err = ngx.shared.test_counts:set("successes", 0)
148+
if err then ngx.say("set error: ", err); return end
120149
121-
ngx.say("received: ", line)
150+
-- Make 50 concurrent requests to see how separate connections are
151+
-- handled during initial registration.
152+
local threads = {}
153+
for i = 1, 50 do
154+
table.insert(threads, ngx.thread.spawn(make_http_requests))
155+
end
156+
for _, thread in ipairs(threads) do
157+
ngx.thread.wait(thread)
122158
end
123159
124-
local ok, err = sock:close()
125-
if not ok then
126-
ngx.say("failed to close: ", err)
127-
return
160+
-- Make some more concurrent requests after waiting for the first batch
161+
-- to succeed. All of these should then be dealing with the cached certs.
162+
local threads = {}
163+
for i = 1, 50 do
164+
table.insert(threads, ngx.thread.spawn(make_http_requests))
128165
end
166+
for _, thread in ipairs(threads) do
167+
ngx.thread.wait(thread)
168+
end
169+
170+
-- Report the total number of successful requests across all the parallel
171+
-- requests to make sure it matches what's expected.
172+
ngx.say("Successes: ", ngx.shared.test_counts:get("successes"))
129173
}
130174
}
131175
--- timeout: 30s
132176
--- request
133177
GET /t
134178
--- response_body
135-
received: HTTP/1.1 200 OK
136-
received: Server: openresty
137-
received: Content-Type: text/plain
138-
received: Connection: close
139-
received:
140-
received: foo
179+
Successes: 1000
141180
--- error_log
142181
auto-ssl: issuing new certificate for
143182
--- no_error_log
144-
[warn]
145183
[error]
146184
[alert]
147185
[emerg]

0 commit comments

Comments
 (0)