# vim:set ft= ts=4 sw=4 et fdm=marker: use Test::Nginx::Socket::Lua; use Cwd qw(cwd); #worker_connections(1014); #master_on(); #workers(2); #log_level('warn'); repeat_each(2); plan tests => repeat_each() * (blocks() * 4 + 5); $ENV{TEST_NGINX_CWD} = cwd(); #worker_connections(1024); #no_diff(); no_long_string(); run_tests(); __DATA__ === TEST 1: set current peer (separate addr and port) --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; upstream backend { server 0.0.0.1; balancer_by_lua_block { print("hello from balancer by lua!") local b = require "ngx.balancer" assert(b.set_current_peer("127.0.0.3", 12345)) } } --- config location = /t { proxy_pass http://backend; } --- request GET /t --- response_body_like: 502 Bad Gateway --- error_code: 502 --- error_log eval [ '[lua] balancer_by_lua:2: hello from balancer by lua! while connecting to upstream,', qr{connect\(\) failed .*?, upstream: "http://127\.0\.0\.3:12345/t"}, ] --- no_error_log [warn] === TEST 2: set current peer & next upstream (3 tries) --- skip_nginx: 4: < 1.7.5 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_403 http_404; proxy_next_upstream_tries 10; upstream backend { server 0.0.0.1; balancer_by_lua_block { print("hello from balancer by lua!") local b = require "ngx.balancer" if not ngx.ctx.tries then ngx.ctx.tries = 0 end if ngx.ctx.tries < 2 then local ok, err = b.set_more_tries(1) if not ok then return error("failed to set more tries: ", err) elseif err then ngx.log(ngx.WARN, "set more tries: ", err) end end ngx.ctx.tries = ngx.ctx.tries + 1 assert(b.set_current_peer("127.0.0.3", 12345)) } } --- config location = /t { proxy_pass http://backend; } --- request GET /t --- response_body_like: 502 Bad Gateway --- error_code: 502 --- grep_error_log eval: qr{connect\(\) failed .*, upstream: "http://.*?"} --- grep_error_log_out eval qr#^(?:connect\(\) failed .*?, upstream: "http://127.0.0.3:12345/t"\n){3}$# --- no_error_log [warn] === TEST 3: set current peer & next upstream (no retries) --- skip_nginx: 4: < 1.7.5 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_403 http_404; upstream backend { server 0.0.0.1; balancer_by_lua_block { print("hello from balancer by lua!") local b = require "ngx.balancer" if not ngx.ctx.tries then ngx.ctx.tries = 0 end ngx.ctx.tries = ngx.ctx.tries + 1 assert(b.set_current_peer("127.0.0.3", 12345)) } } --- config location = /t { proxy_pass http://backend; } --- request GET /t --- response_body_like: 502 Bad Gateway --- error_code: 502 --- grep_error_log eval: qr{connect\(\) failed .*, upstream: "http://.*?"} --- grep_error_log_out eval qr#^(?:connect\(\) failed .*?, upstream: "http://127.0.0.3:12345/t"\n){1}$# --- no_error_log [warn] === TEST 4: set current peer & next upstream (3 tries exceeding the limit) --- skip_nginx: 4: < 1.7.5 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_403 http_404; proxy_next_upstream_tries 2; upstream backend { server 0.0.0.1; balancer_by_lua_block { local b = require "ngx.balancer" if not ngx.ctx.tries then ngx.ctx.tries = 0 end if ngx.ctx.tries < 2 then local ok, err = b.set_more_tries(1) if not ok then return error("failed to set more tries: ", err) elseif err then ngx.log(ngx.WARN, "set more tries: ", err) end end ngx.ctx.tries = ngx.ctx.tries + 1 assert(b.set_current_peer("127.0.0.3", 12345)) } } --- config location = /t { proxy_pass http://backend; } --- request GET /t --- response_body_like: 502 Bad Gateway --- error_code: 502 --- grep_error_log eval: qr{connect\(\) failed .*, upstream: "http://.*?"} --- grep_error_log_out eval qr#^(?:connect\(\) failed .*?, upstream: "http://127.0.0.3:12345/t"\n){2}$# --- error_log set more tries: reduced tries due to limit === TEST 5: get last peer failure status (404) --- skip_nginx: 4: < 1.7.5 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_403 http_404; proxy_next_upstream_tries 10; upstream backend { server 0.0.0.1; balancer_by_lua_block { local b = require "ngx.balancer" local state, status = b.get_last_failure() print("last peer failure: ", state, " ", status) if not ngx.ctx.tries then ngx.ctx.tries = 0 end if ngx.ctx.tries < 2 then local ok, err = b.set_more_tries(1) if not ok then return error("failed to set more tries: ", err) elseif err then ngx.log(ngx.WARN, "set more tries: ", err) end end ngx.ctx.tries = ngx.ctx.tries + 1 assert(b.set_current_peer("127.0.0.1", tonumber(ngx.var.server_port))) } } --- config location = /t { proxy_pass http://backend/back; } location = /back { return 404; } --- request GET /t --- response_body_like: 404 Not Found --- error_code: 404 --- grep_error_log eval: qr{last peer failure: \S+ \S+} --- grep_error_log_out last peer failure: nil nil last peer failure: next 404 last peer failure: next 404 --- no_error_log [warn] === TEST 6: get last peer failure status (500) --- skip_nginx: 4: < 1.7.5 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_403 http_404; proxy_next_upstream_tries 10; upstream backend { server 0.0.0.1; balancer_by_lua_block { local b = require "ngx.balancer" local state, status = b.get_last_failure() print("last peer failure: ", state, " ", status) if not ngx.ctx.tries then ngx.ctx.tries = 0 end if ngx.ctx.tries < 2 then local ok, err = b.set_more_tries(1) if not ok then return error("failed to set more tries: ", err) elseif err then ngx.log(ngx.WARN, "set more tries: ", err) end end ngx.ctx.tries = ngx.ctx.tries + 1 assert(b.set_current_peer("127.0.0.1", tonumber(ngx.var.server_port))) } } --- config location = /t { proxy_pass http://backend/back; } location = /back { return 500; } --- request GET /t --- response_body_like: 500 Internal Server Error --- error_code: 500 --- grep_error_log eval: qr{last peer failure: \S+ \S+} --- grep_error_log_out last peer failure: nil nil last peer failure: failed 500 last peer failure: failed 500 --- no_error_log [warn] === TEST 7: get last peer failure status (503) --- skip_nginx: 4: < 1.7.5 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_403 http_404; proxy_next_upstream_tries 10; upstream backend { server 0.0.0.1; balancer_by_lua_block { local b = require "ngx.balancer" local state, status = b.get_last_failure() print("last peer failure: ", state, " ", status) if not ngx.ctx.tries then ngx.ctx.tries = 0 end if ngx.ctx.tries < 2 then local ok, err = b.set_more_tries(1) if not ok then return error("failed to set more tries: ", err) elseif err then ngx.log(ngx.WARN, "set more tries: ", err) end end ngx.ctx.tries = ngx.ctx.tries + 1 assert(b.set_current_peer("127.0.0.1", tonumber(ngx.var.server_port))) } } --- config location = /t { proxy_pass http://backend/back; } location = /back { return 503; } --- request GET /t --- response_body_like: 503 Service Temporarily Unavailable --- error_code: 503 --- grep_error_log eval: qr{last peer failure: \S+ \S+} --- grep_error_log_out last peer failure: nil nil last peer failure: failed 502 last peer failure: failed 502 --- no_error_log [warn] === TEST 8: get last peer failure status (connect failed) --- skip_nginx: 4: < 1.7.5 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_403 http_404; proxy_next_upstream_tries 10; upstream backend { server 0.0.0.1; balancer_by_lua_block { local b = require "ngx.balancer" local state, status = b.get_last_failure() print("last peer failure: ", state, " ", status) if not ngx.ctx.tries then ngx.ctx.tries = 0 end if ngx.ctx.tries < 2 then local ok, err = b.set_more_tries(1) if not ok then return error("failed to set more tries: ", err) elseif err then ngx.log(ngx.WARN, "set more tries: ", err) end end ngx.ctx.tries = ngx.ctx.tries + 1 assert(b.set_current_peer("127.0.0.3", 12345)) } } --- config location = /t { proxy_pass http://backend/back; } location = /back { return 404; } --- request GET /t --- response_body_like: 502 Bad Gateway --- error_code: 502 --- grep_error_log eval: qr{last peer failure: \S+ \S+} --- grep_error_log_out last peer failure: nil nil last peer failure: failed 502 last peer failure: failed 502 --- no_error_log [warn] === TEST 9: set current peer (port embedded in addr) --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; upstream backend { server 0.0.0.1; balancer_by_lua_block { print("hello from balancer by lua!") local b = require "ngx.balancer" assert(b.set_current_peer("127.0.0.3:12345")) } } --- config location = /t { proxy_pass http://backend; } --- request GET /t --- response_body_like: 502 Bad Gateway --- error_code: 502 --- error_log eval [ '[lua] balancer_by_lua:2: hello from balancer by lua! while connecting to upstream,', qr{connect\(\) failed .*?, upstream: "http://127\.0\.0\.3:12345/t"}, ] --- no_error_log [warn] === TEST 10: keepalive before balancer --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; upstream backend { server 0.0.0.1; keepalive 10; balancer_by_lua_block { print("hello from balancer by lua!") local b = require "ngx.balancer" assert(b.set_current_peer("127.0.0.3:12345")) } } --- config location = /t { proxy_pass http://backend; } --- request GET /t --- response_body_like: 502 Bad Gateway --- grep_error_log eval: qr/load balancing method redefined in/ --- grep_error_log_out eval [ "load balancing method redefined in ", "", ] --- error_code: 502 --- error_log eval [ '[lua] balancer_by_lua:2: hello from balancer by lua! while connecting to upstream,', qr{connect\(\) failed .*?, upstream: "http://127\.0\.0\.3:12345/t"}, ] --- no_error_log [crit] === TEST 11: keepalive after balancer --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; upstream backend { server 0.0.0.1; balancer_by_lua_block { local b = require "ngx.balancer" assert(b.set_current_peer("127.0.0.1", tonumber(ngx.var.server_port))) } keepalive 1; } --- config location = /t { content_by_lua_block { local res0 = ngx.location.capture("/tt") local res1 = ngx.location.capture("/tt") local res2 = ngx.location.capture("/tt") if res2.status == ngx.HTTP_OK then ngx.print(res2.body) end } } location = /tt { proxy_pass http://backend/back; proxy_http_version 1.1; proxy_set_header Connection ""; } location = /back { echo "hello keepalive!"; } --- request GET /t --- response_body hello keepalive! --- error_code: 200 --- grep_error_log eval: qr{\S+ keepalive peer:.*?connection} --- grep_error_log_out eval ["free keepalive peer: saving connection get keepalive peer: using connection free keepalive peer: saving connection get keepalive peer: using connection free keepalive peer: saving connection ", "get keepalive peer: using connection free keepalive peer: saving connection get keepalive peer: using connection free keepalive peer: saving connection get keepalive peer: using connection free keepalive peer: saving connection ", ] --- no_error_log [warn] === TEST 12: set_current_peer called in a wrong context --- wait: 0.2 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; upstream backend { server 127.0.0.1:$TEST_NGINX_SERVER_PORT; balancer_by_lua_block { print("hello from balancer by lua!") } } --- config location = /fake { echo ok; } location = /t { proxy_pass http://backend/fake; log_by_lua_block { local balancer = require "ngx.balancer" local ok, err = balancer.set_current_peer("127.0.0.1", 1234) if not ok then ngx.log(ngx.ERR, "failed to call: ", err) return end ngx.log(ngx.ALERT, "unexpected success") } } --- request GET /t --- response_body ok --- error_log eval qr/\[error\] .*? log_by_lua.*? failed to call: API disabled in the current context/ --- no_error_log [alert] === TEST 13: get_last_failure called in a wrong context --- wait: 0.2 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; upstream backend { server 127.0.0.1:$TEST_NGINX_SERVER_PORT; balancer_by_lua_block { print("hello from balancer by lua!") } } --- config location = /fake { echo ok; } location = /t { proxy_pass http://backend/fake; log_by_lua_block { local balancer = require "ngx.balancer" local state, status, err = balancer.get_last_failure() if not state and err then ngx.log(ngx.ERR, "failed to call: ", err) return end ngx.log(ngx.ALERT, "unexpected success") } } --- request GET /t --- response_body ok --- error_log eval qr/\[error\] .*? log_by_lua.*? failed to call: API disabled in the current context/ --- no_error_log [alert] === TEST 14: set_more_tries called in a wrong context --- wait: 0.2 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; upstream backend { server 127.0.0.1:$TEST_NGINX_SERVER_PORT; balancer_by_lua_block { print("hello from balancer by lua!") } } --- config location = /fake { echo ok; } location = /t { proxy_pass http://backend/fake; log_by_lua_block { local balancer = require "ngx.balancer" local ok, err = balancer.set_more_tries(1) if not ok then ngx.log(ngx.ERR, "failed to call: ", err) return end ngx.log(ngx.ALERT, "unexpected success") } } --- request GET /t --- response_body ok --- error_log eval qr/\[error\] .*? log_by_lua.*? failed to call: API disabled in the current context/ --- no_error_log [alert] === TEST 15: hot loop when proxy_upstream_next error is hit and keepalive is used. github issue openresty/lua-nginx-module#693 --- skip_nginx: 4: < 1.7.5 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; upstream backend { server 0.0.0.1; balancer_by_lua_block { local b = require "ngx.balancer" print("hello from balancer by lua!") assert(b.set_current_peer("127.0.0.1", $TEST_NGINX_SERVER_PORT)) } keepalive 1; } --- config location /t { rewrite ^/t(.*) $1 break; proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Connection ""; } location = /back { return 200; } location = /main { echo_location /t/back; echo_location /t/bad; } location = /bad { content_by_lua_block { ngx.exit(444) } } --- request GET /main --- no_error_log [alert] --- ignore_response --- grep_error_log eval: qr{hello from balancer by lua!} --- grep_error_log_out hello from balancer by lua! hello from balancer by lua! hello from balancer by lua! --- error_log eval qr/\[error] .*? upstream prematurely closed connection while reading response header from upstream/ === TEST 16: https (keepalive) --- skip_nginx: 4: < 1.7.5 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; upstream backend { server 0.0.0.1; balancer_by_lua_block { local b = require "ngx.balancer" print("hello from balancer by lua!") assert(b.set_current_peer("127.0.0.1", 1234)) } keepalive 1; } server { listen 1234 ssl; ssl_certificate ../../cert/test.crt; ssl_certificate_key ../../cert/test.key; server_tokens off; location = /back { return 200 "ok"; } } --- config location /t { proxy_pass https://backend/back; proxy_http_version 1.1; proxy_set_header Connection ""; } --- request GET /t --- no_error_log [alert] [error] --- response_body chomp ok --- grep_error_log eval: qr{hello from balancer by lua!} --- grep_error_log_out hello from balancer by lua! === TEST 17: https (no keepalive) --- skip_nginx: 5: < 1.7.5 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; upstream backend { server 0.0.0.1; balancer_by_lua_block { local b = require "ngx.balancer" print("hello from balancer by lua!") assert(b.set_current_peer("127.0.0.1", 12347)) } } server { listen 12347 ssl; ssl_certificate ../../cert/test.crt; ssl_certificate_key ../../cert/test.key; server_tokens off; location = /back { return 200 "ok"; } } --- config location /t { proxy_pass https://backend/back; proxy_http_version 1.1; proxy_set_header Connection ""; } --- request GET /t --- no_error_log [alert] [error] --- response_body chomp ok --- grep_error_log eval: qr{hello from balancer by lua!} --- grep_error_log_out hello from balancer by lua! --- no_check_leak === TEST 18: test ngx.var.upstream_addr after using more than one set_current_peer --- wait: 0.2 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; proxy_next_upstream_tries 3; upstream backend { server 127.0.0.1:$TEST_NGINX_SERVER_PORT; balancer_by_lua_block { local balancer = require "ngx.balancer" if ngx.ctx.tries == nil then balancer.set_more_tries(1) ngx.ctx.tries = 1 balancer.set_current_peer("127.0.0.3", 12345) else balancer.set_current_peer("127.0.0.3", 12346) end } } --- config location = /t { proxy_pass http://backend; log_by_lua_block { ngx.log(ngx.INFO, "ngx.var.upstream_addr is " .. ngx.var.upstream_addr) } } --- request GET /t --- response_body_like: 502 Bad Gateway --- error_code: 502 --- error_log [lua] log_by_lua(nginx.conf:59):2: ngx.var.upstream_addr is 127.0.0.3:12345, 127.0.0.3:12346 --- no_error_log [alert]