Remove unused test files and certificates from stream-lua-nginx-module

This commit is contained in:
Théophile Diot 2025-01-16 10:35:12 +01:00
parent 9e07798513
commit 9aef1a879a
No known key found for this signature in database
GPG key ID: FA995104A0BA376A
147 changed files with 0 additions and 57201 deletions

View file

@ -1,248 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3 + 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: basic print
--- stream_server_config
content_by_lua_block {
local ok, err = ngx.print("Hello, Lua!\n")
if not ok then
ngx.log(ngx.ERR, "print failed: ", err)
end
}
--- stream_response
Hello, Lua!
--- no_error_log
[error]
=== TEST 2: basic say
--- stream_server_config
content_by_lua_block {
local ok, err = ngx.say("Hello, Lua!")
if not ok then
ngx.log(ngx.ERR, "say failed: ", err)
return
end
local ok, err = ngx.say("Yay! ", 123)
if not ok then
ngx.log(ngx.ERR, "say failed: ", err)
return
end
}
--- stream_response
Hello, Lua!
Yay! 123
--- no_error_log
[error]
=== TEST 3: no ngx.echo
--- stream_server_config
content_by_lua_block { ngx.echo("Hello, Lua!\n") }
--- stream_response
--- error_log eval
qr/content_by_lua\(nginx\.conf:\d+\):1: attempt to call field 'echo' \(a nil value\)/
=== TEST 4: calc expression
--- stream_server_config
content_by_lua_file html/calc.lua;
--- user_files
>>> calc.lua
local function uri_unescape(uri)
local function convert(hex)
return string.char(tonumber("0x"..hex))
end
local s = string.gsub(uri, "%%([0-9a-fA-F][0-9a-fA-F])", convert)
return s
end
local function eval_exp(str)
return loadstring("return "..str)()
end
local exp_str = 1+2*math.sin(3)/math.exp(4)-math.sqrt(2)
-- print("exp: '", exp_str, "'\n")
local status, res
status, res = pcall(uri_unescape, exp_str)
if not status then
ngx.print("error: ", res, "\n")
return
end
status, res = pcall(eval_exp, res)
if status then
ngx.print("result: ", res, "\n")
else
ngx.print("error: ", res, "\n")
end
--- stream_response
result: -0.4090441561579
--- no_error_log
[error]
=== TEST 5: nil is "nil"
--- stream_server_config
content_by_lua_block { ngx.say(nil) }
--- stream_response
nil
--- no_error_log
[error]
=== TEST 6: write boolean
--- stream_server_config
content_by_lua_block { ngx.say(true, " ", false) }
--- stream_response
true false
--- no_error_log
[error]
=== TEST 7: nginx quote sql string 1
--- stream_server_config
content_by_lua_block { ngx.say(ngx.quote_sql_str('hello\n\r\'"\\')) }
--- stream_response
'hello\n\r\'\"\\'
--- no_error_log
[error]
=== TEST 8: nginx quote sql string 2
--- stream_server_config
content_by_lua_block { ngx.say(ngx.quote_sql_str("hello\n\r'\"\\")) }
--- stream_response
'hello\n\r\'\"\\'
--- no_error_log
[error]
=== TEST 9: multiple eof
--- stream_server_config
content_by_lua_block {
ngx.say("Hi")
local ok, err = ngx.eof()
if not ok then
ngx.log(ngx.WARN, "eof failed: ", err)
return
end
ok, err = ngx.eof()
if not ok then
ngx.log(ngx.WARN, "eof failed: ", err)
return
end
}
--- stream_response
Hi
--- no_error_log
[error]
--- error_log
lua send eof
eof failed: seen eof
=== TEST 10: ngx.eof before ngx.say
--- stream_server_config
content_by_lua_block {
local ok, err = ngx.eof()
if not ok then
ngx.log(ngx.ERR, "eof failed: ", err)
return
end
ok, err = ngx.say(ngx.headers_sent)
if not ok then
ngx.log(ngx.WARN, "failed to say: ", err)
return
end
}
--- stream_response
--- no_error_log
[error]
--- error_log
failed to say: seen eof
=== TEST 11: ngx.print table arguments (github issue #54)
--- stream_server_config
content_by_lua_block { ngx.print({10, {0, 5}, 15}, 32) }
--- stream_response chop
10051532
--- no_error_log
[error]
=== TEST 12: ngx.say table arguments (github issue #54)
--- stream_server_config
content_by_lua_block { ngx.say({10, {0, "5"}, 15}, 32) }
--- stream_response
10051532
--- no_error_log
[error]
=== TEST 13: Lua file does not exist
--- stream_server_config
content_by_lua_file html/test2.lua;
--- user_files
>>> test.lua
v = ngx.var["request_uri"]
ngx.print("request_uri: ", v, "\n")
--- stream_response
--- error_log eval
qr/failed to load external Lua file ".*?test2\.lua": cannot open .*? No such file or directory/
=== TEST 14: .lua file with shebang
--- stream_server_config
content_by_lua_file html/test.lua;
--- user_files
>>> test.lua
#!/bin/lua
ngx.say("line ", debug.getinfo(1).currentline)
--- stream_response
line 3
--- no_error_log
[error]
=== TEST 15: syntax error in inlined Lua code
--- stream_server_config
content_by_lua_block {for end}
--- stream_response
--- error_log eval
qr/failed to load inlined Lua code: /

View file

@ -1,38 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => blocks() * (repeat_each() * 3);
#$ENV{LUA_PATH} = $ENV{HOME} . '/work/JSON4Lua-0.9.30/json/?.lua';
no_long_string();
run_tests();
__DATA__
=== TEST 1: syntax error in lua code chunk
--- stream_server_config
content_by_lua_block {local a
a = a+;
return a}
--- stream_response
--- error_log eval
qr/failed to load inlined Lua code: content_by_lua\(nginx\.conf:\d+\):2: unexpected symbol near ';'/
=== TEST 2: syntax error in lua file
--- stream_server_config
content_by_lua_file 'html/test.lua';
--- user_files
>>> test.lua
local a
a = 3 +;
return a
--- stream_response
--- error_log eval
qr{failed to load external Lua file ".*?html/test\.lua": .*?test\.lua:2: unexpected symbol near ';'}

View file

@ -1,157 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#log_level('warn');
#master_on();
#repeat_each(120);
repeat_each(2);
plan tests => blocks() * (repeat_each() * 3);
our $HtmlDir = html_dir;
#warn $html_dir;
#$ENV{LUA_PATH} = "$html_dir/?.lua";
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
# load
content_by_lua_block {
package.loaded.foo = nil;
collectgarbage()
local foo = require "foo";
foo.hi()
}
--- stream_server_config2
# check
content_by_lua_block {
local foo = package.loaded.foo
if foo then
ngx.say("found")
foo.hi()
else
ngx.say("not found")
end
}
--- stream_server_config3
# check
content_by_lua_block {
local foo = package.loaded.foo
if foo then
ngx.say("found")
foo.hi()
else
ngx.say("not found")
end
}
--- user_files
>>> foo.lua
local _M = {}
ngx.say("loading");
function _M.hi ()
ngx.say("hello, foo")
end
return _M
--- stream_response
loading
hello, foo
found
hello, foo
found
hello, foo
--- no_error_log
[error]
=== TEST 2: sanity
--- stream_config eval
"lua_package_cpath '$::HtmlDir/?.so';"
--- stream_server_config
content_by_lua_block {
ngx.print(package.cpath);
}
--- stream_response_like: ^[^;]+/servroot(_\d+)?/html/\?\.so$
--- no_error_log
[error]
=== TEST 3: expand default path (after)
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;;';"
--- stream_server_config
content_by_lua_block {
ngx.print(package.path)
}
--- stream_response_like: ^[^;]+/servroot(_\d+)?/html/\?\.lua;(.+\.lua)?;*$
--- no_error_log
[error]
=== TEST 4: expand default cpath (after)
--- stream_config eval
"lua_package_cpath '$::HtmlDir/?.so;;';"
--- stream_server_config
content_by_lua_block {
ngx.print(package.cpath)
}
--- stream_response_like: ^[^;]+/servroot(_\d+)?/html/\?\.so;(.+\.so)?;*$
--- no_error_log
[error]
=== TEST 5: expand default path (before)
--- stream_config eval
"lua_package_path ';;$::HtmlDir/?.lua';"
--- stream_server_config
content_by_lua_block {
ngx.print(package.path);
}
--- stream_response_like: ^(.+\.lua)?;*?[^;]+/servroot(_\d+)?/html/\?\.lua$
--- no_error_log
[error]
=== TEST 6: expand default cpath (before)
--- stream_config eval
"lua_package_cpath ';;$::HtmlDir/?.so';"
--- stream_server_config
content_by_lua_block {
ngx.print(package.cpath);
}
--- stream_response_like: ^(.+\.so)?;*?[^;]+/servroot(_\d+)?/html/\?\.so$
--- no_error_log
[error]
=== TEST 7: require "ngx" (content_by_lua_block)
--- stream_server_config
content_by_lua_block {
local ngx = require "ngx"
ngx.say("hello, world")
}
--- stream_response
hello, world
--- no_error_log
[error]

View file

@ -1,114 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#repeat_each(20000);
repeat_each(2);
#master_on();
#workers(1);
#log_level('debug');
#log_level('warn');
#worker_connections(1024);
plan tests => repeat_each() * (blocks() * 3);
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_MYSQL_PORT} ||= 3306;
our $LuaCpath = $ENV{LUA_CPATH} ||
'/usr/local/openresty-debug/lualib/?.so;/usr/local/openresty/lualib/?.so;;';
#$ENV{LUA_PATH} = $ENV{HOME} . '/work/JSON4Lua-0.9.30/json/?.lua';
no_long_string();
run_tests();
__DATA__
=== TEST 1: throw error
--- stream_server_config
content_by_lua_block { ngx.exit(ngx.ERROR);ngx.say('hi') }
--- stream_response
--- no_error_log
[error]
=== TEST 2: throw error after sending the header and partial body
--- stream_server_config
content_by_lua_block { ngx.say('hi');ngx.exit(ngx.ERROR);ngx.say(', you') }
--- no_error_log
[error]
--- stream_response
hi
=== TEST 3: throw 0
--- stream_server_config
content_by_lua_block { ngx.say('Hi'); ngx.eof(); ngx.exit(0);ngx.say('world') }
--- stream_response
Hi
--- no_error_log
[error]
=== TEST 4: pcall safe
--- stream_server_config
content_by_lua_block {
function f ()
ngx.say("hello")
ngx.exit(200)
end
pcall(f)
ngx.say("world")
}
--- stream_response
hello
--- no_error_log
[error]
=== TEST 5: throw 444 after sending out responses
--- stream_server_config
content_by_lua_block {
ngx.say('ok');
return ngx.exit(444)
}
--- stream_response
ok
--- log_level: debug
--- no_error_log
[error]
=== TEST 6: throw 499 after sending out responses
--- stream_server_config
content_by_lua_block {
ngx.say('ok');
return ngx.exit(499)
}
--- stream_response
ok
--- log_level: debug
--- no_error_log
[error]
=== TEST 7: throw 408 after sending out responses
--- stream_server_config
content_by_lua_block {
ngx.say('ok');
return ngx.exit(408)
}
--- stream_response
ok
--- log_level: debug
--- no_error_log
[error]

View file

@ -1,173 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3 + 3);
no_long_string();
run_tests();
__DATA__
=== TEST 1: escape uri in content_by_lua
--- stream_server_config
content_by_lua_block {ngx.say(ngx.escape_uri('a 你'))}
--- stream_response
a%20%E4%BD%A0
--- no_error_log
[error]
=== TEST 2: unescape uri in content_by_lua
--- stream_server_config
content_by_lua_block { ngx.say(ngx.unescape_uri('a%20%e4%bd%a0')) }
--- stream_response
a 你
--- no_error_log
[error]
=== TEST 3: escape uri in content_by_lua
--- stream_server_config
content_by_lua_block { ngx.say(ngx.escape_uri('a+b')) }
--- stream_response
a%2Bb
--- no_error_log
[error]
=== TEST 4: escape uri in content_by_lua
--- stream_server_config
content_by_lua_block { ngx.say(ngx.escape_uri('"a/b={}:<>;&[]\\^')) }
--- stream_response
%22a%2Fb%3D%7B%7D%3A%3C%3E%3B%26%5B%5D%5C%5E
--- no_error_log
[error]
=== TEST 5: escape a string that cannot be escaped
--- stream_server_config
content_by_lua_block { ngx.say(ngx.escape_uri('abc')) }
--- stream_response
abc
--- no_error_log
[error]
=== TEST 6: escape an empty string that cannot be escaped
--- stream_server_config
content_by_lua_block { ngx.say(ngx.escape_uri('')) }
--- stream_response eval: "\n"
--- no_error_log
[error]
=== TEST 7: escape nil
--- stream_server_config
content_by_lua_block { ngx.say("[", ngx.escape_uri(nil), "]") }
--- stream_response
[]
--- no_error_log
[error]
=== TEST 8: escape numbers
--- stream_server_config
content_by_lua_block { ngx.say(ngx.escape_uri(32)) }
--- stream_response
32
--- no_error_log
[error]
=== TEST 9: unescape nil
--- stream_server_config
content_by_lua_block { ngx.say("[", ngx.unescape_uri(nil), "]") }
--- stream_response
[]
--- no_error_log
[error]
=== TEST 10: unescape numbers
--- stream_server_config
content_by_lua_block { ngx.say(ngx.unescape_uri(32)) }
--- stream_response
32
--- no_error_log
[error]
=== TEST 11: escape type
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.escape_uri("https://www.google.com/?t=abc@ :", 0))
ngx.say(ngx.escape_uri("https://www.google.com/?t=abc@ :", 1))
ngx.say(ngx.escape_uri("https://www.google.com/?t=abc@ :", 2))
ngx.say(ngx.escape_uri("https://www.google.com/?t=abc@ :", 3))
ngx.say(ngx.escape_uri("https://www.google.com/?t=abc@ :", 4))
ngx.say(ngx.escape_uri("https://www.google.com/?t=abc@ :", 5))
ngx.say(ngx.escape_uri("https://www.google.com/?t=abc@ :", 6))
}
--- stream_response
https://www.google.com/%3Ft=abc@%20:
https://www.google.com/%3Ft=abc@%20:
https%3A%2F%2Fwww.google.com%2F%3Ft%3Dabc%40%20%3A
https://www.google.com/?t=abc@%20:
https://www.google.com/?t=abc@%20:
https://www.google.com/?t=abc@%20:
https://www.google.com/?t=abc@%20:
--- no_error_log
[error]
=== TEST 12: escape type error
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.escape_uri("https://www.google.com/?t=abc@ :", true))
}
--- stream_response
--- error_log eval
qr/\[error\] \d+#\d+: \*\d+ lua entry thread aborted: runtime error: "type" is not a number/
--- no_error_log
[alert]
=== TEST 13: escape type out of range
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.escape_uri("https://www.google.com/?t=abc@ :", -1))
}
--- stream_response
--- error_log eval
qr/\[error\] \d+#\d+: \*\d+ lua entry thread aborted: runtime error: "type" -1 out of range/
--- no_error_log
[alert]
=== TEST 14: escape type error
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.escape_uri("https://www.google.com/?t=abc@ :", 100))
}
--- stream_response
--- error_log eval
qr/\[error\] \d+#\d+: \*\d+ lua entry thread aborted: runtime error: "type" 100 out of range/
--- no_error_log
[alert]

View file

@ -1,55 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_process_enabled(1);
log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: set md5 hello
--- stream_server_config
content_by_lua_block { ngx.say(ngx.md5("hello")) }
--- stream_response
5d41402abc4b2a76b9719d911017c592
--- no_error_log
[error]
=== TEST 2: nil string to ngx.md5
--- stream_server_config
content_by_lua_block { ngx.say(ngx.md5(nil)) }
--- stream_response
d41d8cd98f00b204e9800998ecf8427e
--- no_error_log
[error]
=== TEST 3: empty string to ngx.md5
--- stream_server_config
content_by_lua_block { ngx.say(ngx.md5("")) }
--- stream_response
d41d8cd98f00b204e9800998ecf8427e
--- no_error_log
[error]
=== TEST 4: md5(number)
--- stream_server_config
content_by_lua_block { ngx.say(ngx.md5(45)) }
--- stream_response
6c8349cc7260ae62e3b1396831a8398f
--- no_error_log
[error]

View file

@ -1,24 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_process_enabled(1);
log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: use ngx.today in content_by_lua*
--- stream_server_config
content_by_lua_block { ngx.say(ngx.today()) }
--- stream_response_like: ^\d{4}-\d{2}-\d{2}$
--- no_error_log
[error]

View file

@ -1,318 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_process_enabled(1);
log_level('debug'); # to ensure any log-level can be outputed
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3 + 2);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: test log-level STDERR
--- stream_server_config
content_by_lua_block {
ngx.say("before log")
ngx.log(ngx.STDERR, "hello, log", 1234, 3.14159)
ngx.say("after log")
}
--- stream_response
before log
after log
--- error_log eval
qr/\[\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):3: hello, log12343.14159/
=== TEST 2: test log-level EMERG
--- stream_server_config
content_by_lua_block {
ngx.say("before log")
ngx.log(ngx.EMERG, "hello, log", 1234, 3.14159)
ngx.say("after log")
}
--- stream_response
before log
after log
--- error_log eval
qr/\[emerg\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):3: hello, log12343.14159/
=== TEST 3: test log-level ALERT
--- stream_server_config
content_by_lua_block {
ngx.say("before log")
ngx.log(ngx.ALERT, "hello, log", 1234, 3.14159)
ngx.say("after log")
}
--- stream_response
before log
after log
--- error_log eval
qr/\[alert\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):3: hello, log12343.14159/
=== TEST 4: test log-level CRIT
--- stream_server_config
content_by_lua_block {
ngx.say("before log")
ngx.log(ngx.CRIT, "hello, log", 1234, 3.14159)
ngx.say("after log")
}
--- stream_response
before log
after log
--- error_log eval
qr/\[crit\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):3: hello, log12343.14159/
=== TEST 5: test log-level ERR
--- stream_server_config
content_by_lua_block {
ngx.say("before log")
ngx.log(ngx.ERR, "hello, log", 1234, 3.14159)
ngx.say("after log")
}
--- stream_response
before log
after log
--- error_log eval
qr/\[error\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):3: hello, log12343.14159/
=== TEST 6: test log-level WARN
--- stream_server_config
content_by_lua_block {
ngx.say("before log")
ngx.log(ngx.WARN, "hello, log", 1234, 3.14159)
ngx.say("after log")
}
--- stream_response
before log
after log
--- error_log eval
qr/\[warn\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):3: hello, log12343.14159/
=== TEST 7: test log-level NOTICE
--- stream_server_config
content_by_lua_block {
ngx.say("before log")
ngx.log(ngx.NOTICE, "hello, log", 1234, 3.14159)
ngx.say("after log")
}
--- stream_response
before log
after log
--- error_log eval
qr/\[notice\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):3: hello, log12343.14159/
=== TEST 8: test log-level INFO
--- stream_server_config
content_by_lua_block {
ngx.say("before log")
ngx.log(ngx.INFO, "hello, log", 1234, 3.14159)
ngx.say("after log")
}
--- stream_response
before log
after log
--- error_log eval
qr/\[info\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):3: hello, log12343.14159/
=== TEST 9: test log-level DEBUG
--- stream_server_config
content_by_lua_block {
ngx.say("before log")
ngx.log(ngx.DEBUG, "hello, log", 1234, 3.14159)
ngx.say("after log")
}
--- stream_response
before log
after log
--- error_log eval
qr/\[debug\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):3: hello, log12343.14159/
=== TEST 10: regression test print()
--- stream_server_config
content_by_lua_block {
ngx.say("before log")
print("hello, log", 1234, 3.14159)
ngx.say("after log")
}
--- stream_response
before log
after log
--- error_log eval
qr/\[notice\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):3: hello, log12343.14159/
=== TEST 11: print(nil)
--- stream_server_config
content_by_lua_block {
print()
print(nil)
print("nil: ", nil)
ngx.say("hi");
}
--- stream_response
hi
--- error_log eval
[
qr/\[lua\] content_by_lua\(nginx\.conf:\d+\):2: ,/,
qr/\[lua\] content_by_lua\(nginx\.conf:\d+\):3: nil,/,
qr/\[lua\] content_by_lua\(nginx\.conf:\d+\):4: nil: nil,/,
]
=== TEST 12: test booleans and nil
--- stream_server_config
content_by_lua_block {
ngx.log(ngx.ERR, true, false, nil)
ngx.say(32)
}
--- stream_response
32
--- error_log eval
qr/\[error\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):2: truefalsenil/
=== TEST 13: ngx.log() big data
--- stream_server_config
content_by_lua_block {
ngx.log(ngx.ERR, "a" .. string.rep("h", 1970) .. "b")
ngx.say("hi")
}
--- response_headers
--- error_log eval
[qr/ah{1970}b/]
=== TEST 14: ngx.log in Lua function calls & inlined lua
--- stream_server_config
content_by_lua_block {
function foo()
bar()
end
function bar()
ngx.log(ngx.ERR, "hello, log", 1234, 3.14159)
end
foo()
ngx.say("done")
}
--- stream_response
done
--- error_log eval
qr/\[error\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):7: bar\(\): hello, log12343.14159/
=== TEST 15: ngx.log in Lua function tail-calls & inlined lua
--- stream_server_config
content_by_lua_block {
function foo()
return bar(5)
end
function bar(n)
if n < 1 then
ngx.log(ngx.ERR, "hello, log", 1234, 3.14159)
return n
end
return bar(n - 1)
end
foo()
ngx.say("done")
}
--- stream_response
done
--- error_log eval
qr/\[error\] \S+: \S+ stream \[lua\] content_by_lua\(nginx\.conf:\d+\):8:(?: foo\(\):)? hello, log12343.14159/
=== TEST 16: ngx.log in Lua files
--- stream_server_config
content_by_lua_file 'html/test.lua';
--- user_files
>>> test.lua
function foo()
bar()
end
function bar()
ngx.log(ngx.ERR, "hello, log", 1234, 3.14159)
end
foo()
ngx.say("done")
--- stream_response
done
--- error_log eval
qr/\[error\] \S+: \S+ stream \[lua\] test.lua:6: bar\(\): hello, log12343.14159/
=== TEST 17: ngx.log with bad levels (ngx.ERROR, -1)
--- stream_server_config
content_by_lua_block {
ngx.log(ngx.ERROR, "hello lua")
ngx.say("done")
}
--- stream_response
--- error_log
bad log level: -1
=== TEST 18: ngx.log with bad levels (9)
--- stream_server_config
content_by_lua_block {
ngx.log(9, "hello lua")
ngx.say("done")
}
--- stream_response
--- error_log
bad log level: 9
=== TEST 19: \0 in the log message
--- stream_server_config
content_by_lua_block {
ngx.log(ngx.WARN, "hello\0world")
ngx.say("ok")
}
--- stream_response
ok
--- no_error_log
[error]
--- error_log eval
"2: hello\0world"

View file

@ -1,107 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_process_enabled(1);
log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
#no_long_string();
run_tests();
#md5_bin_bin is hard to test, so convert it to hex mode
__DATA__
=== TEST 1: set md5_bin hello ????xxoo
--- stream_server_config
content_by_lua_block {
local a = string.gsub(ngx.md5_bin("hello"), ".", function (c)
return string.format("%02x", string.byte(c))
end)
ngx.say(a)
}
--- stream_response
5d41402abc4b2a76b9719d911017c592
--- no_error_log
[error]
=== TEST 2: set md5_bin hello ????xxoo
--- stream_server_config
content_by_lua_block { ngx.say(string.len(ngx.md5_bin("hello"))) }
--- stream_response
16
--- no_error_log
[error]
=== TEST 3: set md5_bin hello
--- stream_server_config
content_by_lua_block {
local s = ngx.md5_bin("hello")
s = string.gsub(s, ".", function (c)
return string.format("%02x", string.byte(c))
end)
ngx.say(s)
}
--- stream_response
5d41402abc4b2a76b9719d911017c592
--- no_error_log
[error]
=== TEST 4: nil string to ngx.md5_bin
--- stream_server_config
content_by_lua_block {
local s = ngx.md5_bin(nil)
s = string.gsub(s, ".", function (c)
return string.format("%02x", string.byte(c))
end)
ngx.say(s)
}
--- stream_response
d41d8cd98f00b204e9800998ecf8427e
--- no_error_log
[error]
=== TEST 5: null string to ngx.md5_bin
--- stream_server_config
content_by_lua_block {
local s = ngx.md5_bin("")
s = string.gsub(s, ".", function (c)
return string.format("%02x", string.byte(c))
end)
ngx.say(s)
}
--- stream_response
d41d8cd98f00b204e9800998ecf8427e
--- no_error_log
[error]
=== TEST 6: md5_bin(number)
--- stream_server_config
content_by_lua_block {
s = ngx.md5_bin(45)
s = string.gsub(s, ".", function (c)
return string.format("%02x", string.byte(c))
end)
ngx.say(s)
}
--- stream_response
6c8349cc7260ae62e3b1396831a8398f
--- no_error_log
[error]

View file

@ -1,70 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_process_enabled(1);
log_level('warn');
repeat_each(1);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: use ngx.localtime in content_by_lua
--- stream_server_config
content_by_lua_block { ngx.say(ngx.localtime()) }
--- stream_response_like: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
--- no_error_log
[error]
=== TEST 2: use ngx.time in content_by_lua
--- stream_server_config
content_by_lua_block { ngx.say(ngx.time()) }
--- stream_response_like: ^\d{10,}$
--- no_error_log
[error]
=== TEST 3: use ngx.time in content_by_lua
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.time())
ngx.say(ngx.localtime())
ngx.say(ngx.utctime())
}
--- stream_response_like chomp
^\d{10,}
\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}
\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}
--- no_error_log
[error]
=== TEST 4: use ngx.now in content_by_lua
--- stream_server_config
content_by_lua_block { ngx.say(ngx.now()) }
--- stream_response_like: ^\d{10,}(\.\d{1,3})?$
--- no_error_log
[error]
=== TEST 5: use ngx.update_time & ngx.now in content_by_lua
--- stream_server_config
content_by_lua_block {
ngx.update_time()
ngx.say(ngx.now())
}
--- stream_response_like: ^\d{10,}(\.\d{1,3})?$
--- no_error_log
[error]

View file

@ -1,142 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_process_enabled(1);
log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: base64 encode hello
--- stream_server_config
content_by_lua_block { ngx.say(ngx.encode_base64("hello")) }
--- stream_response
aGVsbG8=
--- no_error_log
[error]
=== TEST 2: nil string to ngx.encode_base64
--- stream_server_config
content_by_lua_block { ngx.say("left" .. ngx.encode_base64(nil) .. "right") }
--- stream_response
leftright
--- no_error_log
[error]
=== TEST 3: empty string to ngx.encode_base64
--- stream_server_config
content_by_lua_block { ngx.say("left" .. ngx.encode_base64("") .. "right") }
--- stream_response
leftright
--- no_error_log
[error]
=== TEST 4: base64 encode hello
--- stream_server_config
content_by_lua_block { ngx.say(ngx.decode_base64("aGVsbG8=")) }
--- stream_response
hello
--- no_error_log
[error]
=== TEST 5: null string to ngx.decode_base64
--- stream_server_config
content_by_lua_block { ngx.say("left" .. ngx.decode_base64("") .. "right") }
--- stream_response
leftright
--- no_error_log
[error]
=== TEST 6: use ngx.decode_base64 in content_by_lua (nil)
--- stream_server_config
content_by_lua_block { ngx.say("left" .. ngx.decode_base64(nil) .. "right") }
--- stream_response
--- error_log
string argument only
=== TEST 7: base64 encode number
--- stream_server_config
content_by_lua_block { ngx.say(ngx.encode_base64(32)) }
--- stream_response
MzI=
--- no_error_log
[error]
=== TEST 8: base64 decode number
--- stream_server_config
content_by_lua_block { ngx.say(ngx.decode_base64(32)) }
--- stream_response
--- error_log
string argument only
=== TEST 9: base64 decode error
--- stream_server_config
content_by_lua_block { ngx.say(ngx.decode_base64("^*~")) }
--- stream_response
nil
--- no_error_log
[error]
=== TEST 10: base64 encode without padding (explicit true to no_padding)
--- stream_server_config
content_by_lua_block { ngx.say(ngx.encode_base64("hello", true)) }
--- stream_response
aGVsbG8
--- no_error_log
[error]
=== TEST 11: base64 encode short string
--- stream_server_config
content_by_lua_block { ngx.say(ngx.encode_base64("w")) }
--- stream_response
dw==
--- no_error_log
[error]
=== TEST 12: base64 encode short string with padding (explicit false to no_padding)
--- stream_server_config
content_by_lua_block { ngx.say(ngx.encode_base64("w", false)) }
--- stream_response
dw==
--- no_error_log
[error]
=== TEST 13: base64 encode with wrong 2nd parameter
--- stream_server_config
content_by_lua_block { ngx.say(ngx.encode_base64("w", 0)) }
--- stream_response
--- error_log eval
qr/runtime error: content_by_lua\(nginx\.conf:\d+\):\d+: bad no_padding: boolean expected, got number/

View file

@ -1,358 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
log_level('debug');
repeat_each(3);
plan tests => repeat_each() * (blocks() * 3);
our $HtmlDir = html_dir;
#warn $html_dir;
$ENV{TEST_NGINX_HTML_DIR} = $HtmlDir;
$ENV{TEST_NGINX_REDIS_PORT} ||= 6379;
#no_diff();
#no_long_string();
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
#no_shuffle();
no_long_string();
sub read_file {
my $infile = shift;
open my $in, $infile
or die "cannot open $infile for reading: $!";
my $cert = do { local $/; <$in> };
close $in;
$cert;
}
our $TestCertificate = read_file("t/cert/test.crt");
our $TestCertificateKey = read_file("t/cert/test.key");
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
content_by_lua_block {
package.loaded.foo = nil;
local foo = require "foo";
foo.hi()
}
--- user_files
>>> foo.lua
module(..., package.seeall);
function foo ()
return 1
return 2
end
--- stream_response
--- error_log
error loading module 'foo' from file
=== TEST 2: print lua empty strings
--- stream_server_config
content_by_lua_block { ngx.print("") ngx.flush() ngx.print("Hi") }
--- stream_response chop
Hi
--- no_error_log
[error]
=== TEST 3: say lua empty strings
--- stream_server_config
content_by_lua_block { ngx.say("") ngx.flush() ngx.print("Hi") }
--- stream_response eval
"
Hi"
--- no_error_log
[error]
=== TEST 4: lua_code_cache off + setkeepalive
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
lua_code_cache off;
content_by_lua_block {
local test = require "test"
local port = $TEST_NGINX_REDIS_PORT
test.go(port)
}
--- user_files
>>> test.lua
module("test", package.seeall)
function go(port)
local sock = ngx.socket.tcp()
local sock2 = ngx.socket.tcp()
sock:settimeout(1000)
sock2:settimeout(6000000)
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local ok, err = sock2:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local ok, err = sock:setkeepalive(100, 100)
if not ok then
ngx.say("failed to set reusable: ", err)
end
local ok, err = sock2:setkeepalive(200, 100)
if not ok then
ngx.say("failed to set reusable: ", err)
end
ngx.say("done")
end
--- stap2
F(ngx_close_connection) {
println("=== close connection")
print_ubacktrace()
}
--- stap_out2
--- stream_response
done
--- wait: 0.5
--- no_error_log
[error]
=== TEST 5: .lua file of exactly N*1024 bytes (github issue #385)
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files eval
my $s = "ngx.say('ok')\n";
">>> a.lua\n" . (" " x (8192 - length($s))) . $s;
--- stream_response
ok
--- no_error_log
[error]
=== TEST 6: tcp: nginx crash when resolve an not exist domain in ngx.thread.spawn
https://github.com/openresty/lua-nginx-module/issues/1915
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
content_by_lua_block {
local function tcp(host, port)
local sock = ngx.socket.tcp()
local ok,err = sock:connect(host, port)
if not ok then
ngx.log(ngx.WARN, "failed: ", err)
sock:close()
return false
end
sock:close()
return true
end
local host = "notexistdomain.openresty.org"
local port = 80
local threads = {}
for i = 1, 3 do
threads[i] = ngx.thread.spawn(tcp, host, port)
end
local ok, res = ngx.thread.wait(threads[1],threads[2],threads[3])
if not ok then
ngx.say("failed to wait thread")
return
end
ngx.say("res: ", res)
for i = 1, 3 do
ngx.thread.kill(threads[i])
end
}
--- request
GET /t
--- response_body
res: false
--- error_log
notexistdomain.openresty.org could not be resolved
=== TEST 7: domain exists with tcp socket
https://github.com/openresty/lua-nginx-module/issues/1915
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
content_by_lua_block {
local function tcp(host, port)
local sock = ngx.socket.tcp()
local ok,err = sock:connect(host, port)
if not ok then
ngx.log(ngx.WARN, "failed: ", err)
sock:close()
return false
end
sock:close()
return true
end
local host = "www.openresty.org"
local port = 80
local threads = {}
for i = 1, 3 do
threads[i] = ngx.thread.spawn(tcp, host, port)
end
local ok, res = ngx.thread.wait(threads[1],threads[2],threads[3])
if not ok then
ngx.say("failed to wait thread")
return
end
ngx.say("res: ", res)
for i = 1, 3 do
ngx.thread.kill(threads[i])
end
}
--- request
GET /t
--- response_body
res: true
--- no_error_log
[error]
=== TEST 8: domain exists with udp socket
https://github.com/openresty/lua-nginx-module/issues/1915
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
content_by_lua_block {
local function udp(host, port)
local sock = ngx.socket.udp()
local ok,err = sock:setpeername(host, port)
if not ok then
ngx.log(ngx.WARN, "failed: ", err)
sock:close()
return false
end
sock:close()
return true
end
local host = "notexistdomain.openresty.org"
local port = 80
local threads = {}
for i = 1, 3 do
threads[i] = ngx.thread.spawn(udp, host, port)
end
local ok, res = ngx.thread.wait(threads[1],threads[2],threads[3])
if not ok then
ngx.say("failed to wait thread")
return
end
ngx.say("res: ", res)
for i = 1, 3 do
ngx.thread.kill(threads[i])
end
}
--- request
GET /t
--- response_body
res: false
--- error_log
notexistdomain.openresty.org could not be resolved
=== TEST 9: udp: nginx crash when resolve an not exist domain in ngx.thread.spawn
https://github.com/openresty/lua-nginx-module/issues/1915
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
content_by_lua_block {
local function udp(host, port)
local sock = ngx.socket.udp()
local ok,err = sock:setpeername(host, port)
if not ok then
ngx.log(ngx.WARN, "failed: ", err)
sock:close()
return false
end
sock:close()
return true
end
local host = "www.openresty.org"
local port = 80
local threads = {}
for i = 1, 3 do
threads[i] = ngx.thread.spawn(udp, host, port)
end
local ok, res = ngx.thread.wait(threads[1],threads[2],threads[3])
if not ok then
ngx.say("failed to wait thread")
return
end
ngx.say("res: ", res)
for i = 1, 3 do
ngx.thread.kill(threads[i])
end
}
--- request
GET /t
--- response_body
res: true
--- no_error_log
[error]

View file

@ -1,32 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => blocks() * repeat_each() * 3;
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.OK)
ngx.say(ngx.AGAIN)
ngx.say(ngx.DONE)
ngx.say(ngx.ERROR)
ngx.say(ngx.DECLINED)
}
--- stream_response
0
-2
-4
-1
-5
--- no_error_log
[error]

View file

@ -1,451 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
use t::StapThread;
our $GCScript = <<_EOC_;
$t::StapThread::GCScript
F(ngx_http_lua_check_broken_connection) {
println("lua check broken conn")
}
F(ngx_http_lua_request_cleanup) {
println("lua req cleanup")
}
_EOC_
our $StapScript = $t::StapThread::StapScript;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4 - 2);
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= '11211';
$ENV{TEST_NGINX_REDIS_PORT} ||= '6379';
#no_shuffle();
no_long_string();
run_tests();
__DATA__
=== TEST 1: sleep + stop
--- stream_server_config
lua_check_client_abort on;
preread_by_lua_block {
ngx.sleep(1)
}
return here;
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua req cleanup
delete thread 1
--- wait: 0.1
--- timeout: 0.2
--- abort
--- no_error_log
[error]
--- error_log
client prematurely closed connection
=== TEST 2: sleep + stop (log handler still gets called)
--- stream_server_config
lua_check_client_abort on;
preread_by_lua_block {
ngx.sleep(1)
}
log_by_lua_block {
ngx.log(ngx.NOTICE, "here in log by lua")
}
return here;
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua req cleanup
delete thread 1
--- timeout: 0.2
--- abort
--- no_error_log
[error]
--- error_log
client prematurely closed connection
here in log by lua
=== TEST 3: sleep + ignore
--- stream_server_config
lua_check_client_abort off;
preread_by_lua_block {
ngx.sleep(1)
}
content_by_lua return;
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
lua req cleanup
--- wait: 1
--- timeout: 0.2
--- abort
--- no_error_log
[error]
=== TEST 4: ngx.req.socket + receive() + sleep + stop
--- stream_server_config
lua_check_client_abort on;
preread_by_lua_block {
local sock = ngx.req.socket()
sock:receive()
ngx.sleep(1)
}
return here;
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua req cleanup
delete thread 1
--- timeout: 0.2
--- abort
--- no_error_log
[error]
--- error_log
client prematurely closed connection
=== TEST 5: ngx.req.socket + receive(N) + sleep + stop
--- stream_server_config
lua_check_client_abort on;
preread_by_lua_block {
local sock = ngx.req.socket()
sock:receive(5)
ngx.sleep(1)
}
return here;
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua check broken conn
lua req cleanup
delete thread 1
--- wait: 0.1
--- timeout: 0.2
--- abort
--- no_error_log
[error]
--- error_log
client prematurely closed connection
=== TEST 6: ngx.req.socket + receive(n) + sleep + stop
--- stream_server_config
lua_check_client_abort on;
preread_by_lua_block {
local sock = ngx.req.socket()
sock:receive(2)
ngx.sleep(1)
}
content_by_lua return;
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out_like
^(?:lua check broken conn
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
lua req cleanup|lua check broken conn
lua req cleanup
delete thread 1)$
--- wait: 1
--- timeout: 0.2
--- abort
--- no_error_log
[error]
=== TEST 7: ngx.req.socket + m * receive(n) + sleep + stop
--- stream_server_config
lua_check_client_abort on;
lua_socket_log_errors off;
preread_by_lua_block {
local sock = ngx.req.socket()
sock:receive(2)
sock:receive(2)
sock:receive(1)
ngx.sleep(1)
}
content_by_lua return;
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua check broken conn
lua req cleanup
delete thread 1
--- wait: 1
--- timeout: 0.2
--- abort
--- no_error_log
[error]
--- error_log
client prematurely closed connection
=== TEST 8: ngx.req.socket + receiveuntil + sleep + stop
--- stream_server_config
lua_check_client_abort on;
preread_by_lua_block {
local sock = ngx.req.socket()
local it = sock:receiveuntil("\\n")
it()
ngx.sleep(1)
}
content_by_lua return;
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua req cleanup
delete thread 1
--- wait: 1
--- timeout: 0.2
--- abort
--- no_error_log
[error]
--- error_log
client prematurely closed connection
=== TEST 9: ngx.req.socket + receiveuntil + it(n) + sleep + stop
--- stream_server_config
lua_check_client_abort on;
preread_by_lua_block {
local sock = ngx.req.socket()
local it = sock:receiveuntil("\\n")
it(2)
it(3)
ngx.sleep(1)
}
content_by_lua return;
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua check broken conn
lua req cleanup
delete thread 1
--- timeout: 0.2
--- abort
--- no_error_log
[error]
--- error_log
client prematurely closed connection
=== TEST 10: cosocket + stop
--- stream_server_config
lua_check_client_abort on;
preread_by_lua_block {
local sock, err = ngx.socket.tcp()
if not sock then
ngx.log(ngx.ERR, "failed to get socket: ", err)
return
end
ok, err = sock:connect("127.0.0.1", $TEST_NGINX_REDIS_PORT)
if not ok then
ngx.log(ngx.ERR, "failed to connect: ", err)
return
end
local bytes, err = sock:send("blpop nonexist 2\\r\\n")
if not bytes then
ngx.log(ngx.ERR, "failed to send query: ", err)
return
end
-- ngx.log(ngx.ERR, "about to receive")
local res, err = sock:receive()
if not res then
ngx.log(ngx.ERR, "failed to receive query: ", err)
return
end
ngx.log(ngx.ERR, "res: ", res)
}
content_by_lua return;
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua req cleanup
delete thread 1
--- wait: 1
--- timeout: 0.2
--- abort
--- no_error_log
[error]
--- error_log
client prematurely closed connection
--- skip_nginx: 4: >= 1.25.5
=== TEST 11: ngx.req.socket + receive n < content-length + stop
--- stream_server_config
lua_check_client_abort on;
preread_by_lua_block {
local sock = ngx.req.socket()
local res, err = sock:receive("*a")
if not res then
ngx.log(ngx.NOTICE, "failed to receive: ", err)
return
end
error("bad")
}
content_by_lua return;
--- stream_request eval
"POST /t HTTP/1.0\r
Host: localhost\r
Connection: close\r
Content-Length: 100\r
\r
hello"
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
lua req cleanup
--- timeout: 0.2
--- abort
--- no_error_log
[error]
--- error_log
failed to receive: client aborted
=== TEST 12: ngx.req.socket + receive n == content-length + stop
--- stream_server_config
lua_check_client_abort on;
preread_by_lua_block {
local sock = ngx.req.socket()
local res, err = sock:receive("*a")
if not res then
ngx.log(ngx.NOTICE, "failed to receive: ", err)
return
end
ngx.sleep(1)
error("bad")
}
content_by_lua return;
--- stream_request eval
"POST /t HTTP/1.0\r
Host: localhost\r
Connection: close\r
Content-Length: 5\r
\r
hello"
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua check broken conn
lua req cleanup
delete thread 1
--- timeout: 0.2
--- abort
--- no_error_log
[error]
=== TEST 13: ngx.req.socket + receive n == content-length + ignore
--- stream_server_config
preread_by_lua_block {
local sock = ngx.req.socket()
local res, err = sock:receive("*a")
if not res then
ngx.log(ngx.NOTICE, "failed to receive: ", err)
return
end
ngx.say("done")
}
content_by_lua return;
--- stream_request eval
"POST /t HTTP/1.0\r
Host: localhost\r
Connection: close\r
Content-Length: 5\r
\r
hello"
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
lua req cleanup
--- timeout: 0.2
--- abort
--- no_error_log
[error]
[alert]

View file

@ -1,45 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#repeat_each(20000);
repeat_each(2);
#master_on();
#workers(1);
#log_level('debug');
#log_level('warn');
#worker_connections(1024);
plan tests => repeat_each() * (blocks() * 2);
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_MYSQL_PORT} ||= 3306;
our $LuaCpath = $ENV{LUA_CPATH} ||
'/usr/local/openresty-debug/lualib/?.so;/usr/local/openresty/lualib/?.so;;';
#$ENV{LUA_PATH} = $ENV{HOME} . '/work/JSON4Lua-0.9.30/json/?.lua';
no_long_string();
#no_shuffle();
run_tests();
__DATA__
=== TEST 1: throw 500
--- stream_server_config
preread_by_lua_block { ngx.exit(500);ngx.say('hi') }
content_by_lua_block { ngx.exit(ngx.OK) }
--- error_log
finalize stream request: 500
=== TEST 2: throw 0
--- stream_server_config
preread_by_lua_block { ngx.say('Hi'); ngx.eof(); ngx.exit(0);ngx.say('world') }
content_by_lua_block { ngx.exit(ngx.OK) }
--- stream_response
Hi

File diff suppressed because one or more lines are too long

View file

@ -1,215 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#no_nginx_manager();
#log_level('warn');
#master_on();
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: basic print
--- stream_server_config
preread_by_lua_block { ngx.print("Hello, Lua!\n") }
content_by_lua return;
#content_by_lua 'ngx.say("Hi")';
--- stream_response
Hello, Lua!
=== TEST 2: basic say
--- stream_server_config
preread_by_lua_block {
ngx.say("Hello, Lua!")
ngx.say("Yay! ", 123);
}
content_by_lua_block { ngx.exit(ngx.OK) }
--- stream_response
Hello, Lua!
Yay! 123
=== TEST 3: no ngx.echo
--- stream_server_config
preread_by_lua_block { ngx.echo("Hello, Lua!\\n") }
content_by_lua_block { ngx.exit(ngx.OK) }
--- error_log
attempt to call field 'echo' (a nil value)
=== TEST 4: variable
--- stream_server_config
# NOTE: the newline escape sequence must be double-escaped, as nginx config
# parser will unescape first!
preread_by_lua_block { v = ngx.var["remote_addr"] ngx.print("remote_addr: ", v, "\n") }
content_by_lua_block { ngx.exit(ngx.OK) }
--- stream_response
remote_addr: 127.0.0.1
=== TEST 5: variable (file)
--- stream_server_config
preread_by_lua_file html/test.lua;
content_by_lua_block { ngx.exit(ngx.OK) }
--- user_files
>>> test.lua
v = ngx.var["remote_addr"]
ngx.print("remote_addr: ", v, "\n")
--- stream_response
remote_addr: 127.0.0.1
=== TEST 6: nil is "nil"
--- stream_server_config
preread_by_lua_block { ngx.say(nil) }
content_by_lua return;
--- stream_response
nil
=== TEST 7: write boolean
--- stream_server_config
preread_by_lua_block { ngx.say(true, " ", false) }
content_by_lua return;
--- stream_response
true false
=== TEST 8: nginx quote sql string 1
--- stream_server_config
preread_by_lua_block { ngx.say(ngx.quote_sql_str('hello\n\r\'"\\')) }
content_by_lua_block { ngx.exit(ngx.OK) }
--- stream_response
'hello\n\r\'\"\\'
=== TEST 9: nginx quote sql string 2
--- stream_server_config
preread_by_lua_block { ngx.say(ngx.quote_sql_str("hello\n\r'\"\\")) }
content_by_lua_block { ngx.exit(ngx.OK) }
--- stream_response
'hello\n\r\'\"\\'
=== TEST 10: use dollar
--- stream_server_config
preread_by_lua_block {
local s = "hello 112";
ngx.say(string.find(s, "%d+$"));
}
content_by_lua_block { ngx.exit(ngx.OK) }
--- stream_response
79
=== TEST 11: short circuit
--- stream_server_config
preread_by_lua_block {
ngx.say("Hi")
ngx.eof()
ngx.exit(ngx.OK)
}
content_by_lua_block {
print("HERE")
ngx.print("BAD")
}
--- stream_response
Hi
=== TEST 12: nginx vars in script path
--- stream_server_config
preread_by_lua_file html/$remote_addr.lua;
content_by_lua_block {
print("HERE")
ngx.print("BAD")
}
--- user_files
>>> 127.0.0.1.lua
ngx.say("Hi")
ngx.eof()
ngx.exit(ngx.OK)
--- stream_response
Hi
=== TEST 13: phase postponing works
--- stream_server_config
ssl_preread on;
preread_by_lua_block {
local n = ngx.var.ssl_preread_server_name
if n then
ngx.log(ngx.INFO, "$ssl_preread_server_name = " .. n)
end
if n == "my.sni.server.name" then
ngx.exit(200)
end
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", tonumber(ngx.var.server_port))
if not ok then
ngx.say(err)
return ngx.exit(500)
end
local _, err = sock:sslhandshake(nil, "my.sni.server.name")
if not err then
ngx.say("did not error as expected")
return ngx.exit(500)
end
sock:close()
}
return done;
--- stream_request
hello
--- stream_response chop
done
--- error_log
$ssl_preread_server_name = my.sni.server.name while prereading client data
--- no_error_log
[crit]
[warn]
--- skip_nginx: 5: >= 1.25.5
=== TEST 14: Lua file does not exist
--- stream_server_config
preread_by_lua_file html/test2.lua;
return here;
--- user_files
>>> test.lua
v = ngx.var["remote_addr"]
ngx.print("remote_addr: ", v, "\n")
--- error_log eval
qr/failed to load external Lua file ".*?\btest2\.lua": cannot open .*? No such file or directory/

View file

@ -1,117 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
log_level('debug');
repeat_each(2);
plan tests => repeat_each() * 21;
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: sleep 0.5
--- stream_server_config
preread_by_lua_block {
ngx.update_time()
local before = ngx.now()
ngx.sleep(0.5)
local now = ngx.now()
ngx.say(now - before)
ngx.exit(200)
}
return here;
--- stream_response_like chop
^0\.(?:4[5-9]\d*|5[0-9]\d*|5)$
--- error_log
lua ready to sleep for
stream lua sleep timer expired
=== TEST 2: sleep ag
--- stream_server_config
preread_by_lua_block {
ngx.update_time()
local before = ngx.now()
ngx.sleep("a")
local now = ngx.now()
ngx.say(now - before)
ngx.exit(200)
}
return here;
--- error_log
bad argument #1 to 'sleep'
=== TEST 3: sleep 0.5 - multi-times
--- stream_server_config
preread_by_lua_block {
ngx.update_time()
local start = ngx.now()
ngx.sleep(0.3)
ngx.sleep(0.3)
ngx.sleep(0.3)
ngx.say(ngx.now() - start)
ngx.exit(200)
}
return here;
--- stream_response_like chop
^0\.(?:8[5-9]\d*|9[0-9]\d*|9)$
--- error_log
lua ready to sleep for
stream lua sleep timer expired
--- no_error_log
[error]
=== TEST 4: sleep 0.5 - interleaved by ngx.say() - ended by ngx.sleep
--- stream_server_config
preread_by_lua_block {
ngx.sleep(1)
ngx.say("blah")
ngx.sleep(1)
ngx.exit(200)
}
return here;
--- stream_response
blah
--- error_log
lua ready to sleep
stream lua sleep timer expired
--- no_error_log
[error]
=== TEST 5: sleep 0.5 - interleaved by ngx.say() - not ended by ngx.sleep
--- stream_server_config
preread_by_lua_block {
ngx.sleep(0.3)
ngx.say("blah")
ngx.sleep(0.5)
ngx.say("hiya")
ngx.exit(200)
}
return here;
--- stream_response
blah
hiya
--- error_log
lua ready to sleep for
stream lua sleep timer expired
--- no_error_log
[error]

View file

@ -1,175 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
our $SkipReason;
BEGIN {
use Test::Nginx::Util;
my $nginx_version = Test::Nginx::Util::get_nginx_version();
if (eval "$nginx_version >= 1.25.5") {
$SkipReason = "Nginx version greater than 1.25.5 have changed behavior, current version $nginx_version";
}
}
use Test::Nginx::Socket::Lua::Stream $SkipReason ? (skip_all => $SkipReason) : ();
repeat_each(2);
plan tests => repeat_each() * (blocks() * 5);
our $HtmlDir = html_dir;
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_HTML_DIR} = $HtmlDir;
#$ENV{TEST_NGINX_REDIS_PORT} ||= 6379;
$ENV{LUA_PATH} ||=
'/usr/local/openresty-debug/lualib/?.lua;/usr/local/openresty/lualib/?.lua;;';
no_long_string();
#no_diff();
#log_level 'warn';
no_shuffle();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
preread_by_lua_block {
local test = require "test"
local port = $TEST_NGINX_MEMCACHED_PORT
test.go(port)
test.go(port)
}
content_by_lua return;
--- user_files
>>> test.lua
module("test", package.seeall)
function go(port)
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes())
local req = "flush_all\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local line, err, part = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive a line: ", err, " [", part, "]")
end
local ok, err = sock:setkeepalive()
if not ok then
ngx.say("failed to set reusable: ", err)
end
end
--- stream_response_like
^connected: 1, reused: \d+
request sent: 11
received: OK
connected: 1, reused: [1-9]\d*
request sent: 11
received: OK
--- no_error_log eval
["[error]",
"lua tcp socket keepalive: free connection pool for "]
--- grep_error_log eval
qr/lua tcp socket get keepalive peer: using connection|lua tcp socket keepalive create connection pool for key "[^"]+"/
--- grep_error_log_out eval
[
qq{lua tcp socket keepalive create connection pool for key "127.0.0.1:$ENV{TEST_NGINX_MEMCACHED_PORT}"
lua tcp socket get keepalive peer: using connection
},
"lua tcp socket get keepalive peer: using connection
lua tcp socket get keepalive peer: using connection
"]
=== TEST 2: free up the whole connection pool if no active connections
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
preread_by_lua_block {
local test = require "test"
local port = $TEST_NGINX_MEMCACHED_PORT
test.go(port, true)
test.go(port, false)
}
content_by_lua return;
--- user_files
>>> test.lua
module("test", package.seeall)
function go(port, keepalive)
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes())
local req = "flush_all\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local line, err, part = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive a line: ", err, " [", part, "]")
end
if keepalive then
local ok, err = sock:setkeepalive()
if not ok then
ngx.say("failed to set reusable: ", err)
end
else
sock:close()
end
end
--- stream_response_like
^connected: 1, reused: \d+
request sent: 11
received: OK
connected: 1, reused: [1-9]\d*
request sent: 11
received: OK
--- no_error_log
[error]
--- error_log eval
["lua tcp socket get keepalive peer: using connection",
"lua tcp socket keepalive: free connection pool for "]

View file

@ -1,537 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
our $SkipReason;
BEGIN {
use Test::Nginx::Util;
my $nginx_version = Test::Nginx::Util::get_nginx_version();
if (eval "$nginx_version >= 1.25.5") {
$SkipReason = "Nginx version greater than 1.25.5 have changed behavior, current version $nginx_version";
}
}
BEGIN {
if (!defined $ENV{LD_PRELOAD}) {
$ENV{LD_PRELOAD} = '';
}
if ($ENV{LD_PRELOAD} !~ /\bmockeagain\.so\b/) {
$ENV{LD_PRELOAD} = "mockeagain.so $ENV{LD_PRELOAD}";
}
if ($ENV{MOCKEAGAIN} eq 'r') {
$ENV{MOCKEAGAIN} = 'rw';
} else {
$ENV{MOCKEAGAIN} = 'w';
}
$ENV{TEST_NGINX_EVENT_TYPE} = 'poll';
$ENV{MOCKEAGAIN_WRITE_TIMEOUT_PATTERN} = 'get helloworld';
}
use Test::Nginx::Socket::Lua::Stream $SkipReason ? (skip_all => $SkipReason) : ();
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4 + 8);
our $HtmlDir = html_dir;
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
no_long_string();
no_diff();
run_tests();
__DATA__
=== TEST 1: lua_socket_connect_timeout only
--- stream_server_config
lua_socket_connect_timeout 100ms;
resolver $TEST_NGINX_RESOLVER ipv6=off;
resolver_timeout 3s;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.2", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
}
content_by_lua return;
--- stream_response
failed to connect: timeout
--- error_log
lua tcp socket connect timeout: 100
stream lua tcp socket connect timed out, when connecting to 127.0.0.2:12345
--- timeout: 10
=== TEST 2: sock:settimeout() overrides lua_socket_connect_timeout
--- stream_server_config
lua_socket_connect_timeout 60s;
lua_socket_log_errors off;
resolver $TEST_NGINX_RESOLVER ipv6=off;
resolver_timeout 3s;
preread_by_lua_block {
local sock = ngx.socket.tcp()
sock:settimeout(150)
local ok, err = sock:connect("127.0.0.2", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
}
content_by_lua return;
--- stream_response
failed to connect: timeout
--- error_log
lua tcp socket connect timeout: 150
--- no_error_log
[error]
[alert]
--- timeout: 10
=== TEST 3: sock:settimeout(nil) does not override lua_socket_connect_timeout
--- stream_server_config
lua_socket_log_errors off;
lua_socket_connect_timeout 102ms;
resolver $TEST_NGINX_RESOLVER ipv6=off;
#resolver_timeout 3s;
preread_by_lua_block {
local sock = ngx.socket.tcp()
sock:settimeout(nil)
local ok, err = sock:connect("127.0.0.2", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
}
content_by_lua return;
--- stream_response
failed to connect: timeout
--- error_log
lua tcp socket connect timeout: 102
--- no_error_log
[error]
[alert]
--- timeout: 5
=== TEST 4: sock:settimeout(0) does not override lua_socket_connect_timeout
--- stream_server_config
lua_socket_connect_timeout 102ms;
lua_socket_log_errors off;
resolver $TEST_NGINX_RESOLVER ipv6=off;
resolver_timeout 3s;
preread_by_lua_block {
local sock = ngx.socket.tcp()
sock:settimeout(0)
local ok, err = sock:connect("127.0.0.2", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
}
content_by_lua return;
--- stream_response
failed to connect: timeout
--- error_log
lua tcp socket connect timeout: 102
--- timeout: 5
--- no_error_log
[error]
[alert]
--- timeout: 10
=== TEST 5: -1 is bad timeout value
--- stream_server_config
lua_socket_connect_timeout 102ms;
lua_socket_log_errors off;
resolver $TEST_NGINX_RESOLVER ipv6=off;
resolver_timeout 3s;
preread_by_lua_block {
local sock = ngx.socket.tcp()
sock:settimeout(-1)
local ok, err = sock:connect("127.0.0.2", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
}
content_by_lua return;
--- error_log
bad timeout value
finalize stream request: 500
--- timeout: 10
=== TEST 6: lua_socket_read_timeout only
--- stream_server_config
lua_socket_read_timeout 100ms;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local line
line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
}
content_by_lua return;
--- stream_response
connected: 1
failed to receive: timeout
--- error_log
lua tcp socket read timeout: 100
lua tcp socket connect timeout: 60000
lua tcp socket read timed out
=== TEST 7: sock:settimeout() overrides lua_socket_read_timeout
--- stream_server_config
lua_socket_read_timeout 60s;
#resolver $TEST_NGINX_RESOLVER ipv6=off;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(150)
local line
line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
}
content_by_lua return;
--- stream_response
connected: 1
failed to receive: timeout
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket read timeout: 150
lua tcp socket read timed out
=== TEST 8: sock:settimeout(nil) does not override lua_socket_read_timeout
--- stream_server_config
lua_socket_read_timeout 102ms;
#resolver $TEST_NGINX_RESOLVER ipv6=off;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(nil)
local line
line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
}
content_by_lua return;
--- stream_response
connected: 1
failed to receive: timeout
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket read timeout: 102
lua tcp socket read timed out
=== TEST 9: sock:settimeout(0) does not override lua_socket_read_timeout
--- stream_server_config
lua_socket_read_timeout 102ms;
#resolver $TEST_NGINX_RESOLVER ipv6=off;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(0)
local line
line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
}
content_by_lua return;
--- stream_response
connected: 1
failed to receive: timeout
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket read timeout: 102
lua tcp socket read timed out
=== TEST 10: -1 is bad timeout value
--- stream_server_config
lua_socket_read_timeout 102ms;
#resolver $TEST_NGINX_RESOLVER ipv6=off;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(-1)
local line
line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
}
content_by_lua return;
--- error_log
bad timeout value
finalize stream request: 500
=== TEST 11: lua_socket_send_timeout only
--- stream_server_config
lua_socket_send_timeout 100ms;
resolver $TEST_NGINX_RESOLVER ipv6=off;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local bytes
bytes, err = sock:send("get helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
end
}
content_by_lua return;
--- stream_response
connected: 1
failed to send: timeout
--- error_log
lua tcp socket send timeout: 100
lua tcp socket connect timeout: 60000
lua tcp socket write timed out
=== TEST 12: sock:settimeout() overrides lua_socket_send_timeout
--- stream_server_config
lua_socket_send_timeout 60s;
#resolver $TEST_NGINX_RESOLVER ipv6=off;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(150)
local bytes
bytes, err = sock:send("get helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
end
}
content_by_lua return;
--- stream_response
connected: 1
failed to send: timeout
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket send timeout: 150
lua tcp socket write timed out
=== TEST 13: sock:settimeout(nil) does not override lua_socket_send_timeout
--- stream_server_config
lua_socket_send_timeout 102ms;
#resolver $TEST_NGINX_RESOLVER ipv6=off;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(nil)
local bytes
bytes, err = sock:send("get helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
end
}
content_by_lua return;
--- stream_response
connected: 1
failed to send: timeout
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket send timeout: 102
lua tcp socket write timed out
=== TEST 14: sock:settimeout(0) does not override lua_socket_send_timeout
--- stream_server_config
lua_socket_send_timeout 102ms;
#resolver $TEST_NGINX_RESOLVER ipv6=off;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(0)
local bytes
bytes, err = sock:send("get helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
end
}
content_by_lua return;
--- stream_response
connected: 1
failed to send: timeout
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket send timeout: 102
lua tcp socket write timed out
=== TEST 15: -1 is bad timeout value
--- stream_server_config
lua_socket_send_timeout 102ms;
#resolver $TEST_NGINX_RESOLVER ipv6=off;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(-1)
local bytes
bytes, err = sock:send("get helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
end
}
content_by_lua return;
--- error_log
bad timeout value
finalize stream request: 500

View file

@ -1,340 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
our $SkipReason;
BEGIN {
use Test::Nginx::Util;
my $nginx_version = Test::Nginx::Util::get_nginx_version();
if (eval "$nginx_version >= 1.25.5") {
$SkipReason = "Nginx version greater than 1.25.5 have changed behavior, current version $nginx_version";
}
}
use Test::Nginx::Socket::Lua::Stream $SkipReason ? (skip_all => $SkipReason) : ();
repeat_each(2);
plan tests => repeat_each() * 24;
our $HtmlDir = html_dir;
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
$ENV{TEST_NGINX_HTML_DIR} ||= html_dir();
#log_level 'warn';
no_long_string();
#no_diff();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_config
server {
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock;
return testing\npreread\n;
}
--- stream_server_config
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock")
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
-- req = "OK"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
while true do
local line, err, part = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive a line: ", err, " [", part, "]")
break
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
content_by_lua return;
--- stream_response
connected: 1
request sent: 57
received: testing
received: preread
failed to receive a line: connection reset by peer []
close: 1 nil
--- error_log
recv() failed (104: Connection reset by peer
=== TEST 2: no resolver defined
--- stream_server_config
preread_by_lua_block {
local sock = ngx.socket.tcp()
local port = ngx.var.port
local ok, err = sock:connect("agentzh.org", 1234)
if not ok then
ngx.say("failed to connect: ", err)
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
-- req = "OK"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
}
content_by_lua return;
--- stream_response
failed to connect: no resolver defined to resolve "agentzh.org"
connected: nil
failed to send request: closed
--- error_log
attempt to send data on a closed socket:
=== TEST 3: with resolver
--- timeout: 10
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
resolver_timeout 3s;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local port = 80
local ok, err = sock:connect("agentzh.org", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET / HTTP/1.0\r\nHost: agentzh.org\r\nConnection: close\r\n\r\n"
-- req = "OK"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local line, err = sock:receive()
if line then
ngx.say("first line received: ", line)
else
ngx.say("failed to receive the first line: ", err)
end
line, err = sock:receive()
if line then
ngx.say("second line received: ", line)
else
ngx.say("failed to receive the second line: ", err)
end
}
content_by_lua return;
--- stream_response_like
connected: 1
request sent: 56
first line received: HTTP\/1\.1 200 OK
second line received: (?:Date|Server): .*?
--- no_error_log
[error]
=== TEST 4: connection refused (tcp)
--- stream_server_config
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", 16787)
ngx.say("connect: ", ok, " ", err)
local bytes
bytes, err = sock:send("hello")
ngx.say("send: ", bytes, " ", err)
local line
line, err = sock:receive()
ngx.say("receive: ", line, " ", err)
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
content_by_lua return;
--- stream_response
connect: nil connection refused
send: nil closed
receive: nil closed
close: nil closed
--- error_log eval
qr/connect\(\) failed \(\d+: Connection refused\)/
=== TEST 5: connection timeout (tcp)
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
lua_socket_connect_timeout 100ms;
lua_socket_send_timeout 100ms;
lua_socket_read_timeout 100ms;
resolver_timeout 3s;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.2", 12345)
ngx.say("connect: ", ok, " ", err)
local bytes
bytes, err = sock:send("hello")
ngx.say("send: ", bytes, " ", err)
local line
line, err = sock:receive()
ngx.say("receive: ", line, " ", err)
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
content_by_lua return;
--- stream_response
connect: nil timeout
send: nil closed
receive: nil closed
close: nil closed
--- error_log
stream lua tcp socket connect timed out, when connecting to 127.0.0.2:12345
--- timeout: 10
=== TEST 6: not closed manually
--- stream_server_config
preread_by_lua_block {
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
}
content_by_lua return;
--- stream_response
connected: 1
--- no_error_log
[error]
=== TEST 7: resolver error (host not found)
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
resolver_timeout 3s;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local port = 80
local ok, err = sock:connect("blah-blah-not-found.agentzh.org", 1234)
print("connected: ", ok, " ", err, " ", not ok)
if not ok then
ngx.say("failed to connect: ", err)
end
ngx.say("connected: ", ok)
local req = "GET / HTTP/1.0\\r\\nHost: agentzh.org\\r\\nConnection: close\\r\\n\\r\\n"
-- req = "OK"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
}
content_by_lua return;
--- stream_response_like
^failed to connect: blah-blah-not-found\.agentzh\.org could not be resolved(?: \(3: Host not found\))?
connected: nil
failed to send request: closed$
--- error_log
attempt to send data on a closed socket
--- timeout: 10
=== TEST 8: resolver error (timeout)
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
resolver_timeout 1ms;
preread_by_lua_block {
local sock = ngx.socket.tcp()
local port = 80
local ok, err = sock:connect("blah-blah-not-found.agentzh.org", port)
print("connected: ", ok, " ", err, " ", not ok)
if not ok then
ngx.say("failed to connect: ", err)
end
ngx.say("connected: ", ok)
local req = "GET / HTTP/1.0\\r\\nHost: agentzh.org\\r\\nConnection: close\\r\\n\\r\\n"
-- req = "OK"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
}
content_by_lua return;
--- stream_response_like
^failed to connect: blah-blah-not-found\.agentzh\.org could not be resolved(?: \(\d+: (?:Operation timed out|Host not found)\))?
connected: nil
failed to send request: closed$
--- error_log
attempt to send data on a closed socket

File diff suppressed because it is too large Load diff

View file

@ -1,283 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
no_root_location();
#no_shuffle();
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: ngx.encode_args (sanity)
--- stream_server_config
content_by_lua_block {
local t = {a = "bar", b = "foo"}
ngx.say(ngx.encode_args(t))
}
--- stream_response eval
qr/a=bar&b=foo|b=foo&a=bar/
--- no_error_log
[error]
=== TEST 2: ngx.encode_args (empty table)
--- stream_server_config
content_by_lua_block {
local t = {a = nil}
ngx.say("args:" .. ngx.encode_args(t))
}
--- stream_response
args:
--- no_error_log
[error]
=== TEST 3: ngx.encode_args (value is table)
--- stream_server_config
content_by_lua_block {
local t = {a = {9, 2}, b = 3}
ngx.say("args:" .. ngx.encode_args(t))
}
--- stream_response_like
(?x) ^args:
(?= .*? \b a=9 \b ) # 3 chars
(?= .*? \b a=2 \b ) # 3 chars
(?= .*? \b b=3 \b ) # 3 chars
(?= (?: [^&]+ & ){2} [^&]+ $ ) # requires exactly 2 &'s
(?= .{11} $ ) # requires for total 11 chars (exactly) in the string
--- no_error_log
[error]
=== TEST 4: ngx.encode_args (boolean values)
--- stream_server_config
content_by_lua_block {
local t = {a = true, foo = 3}
ngx.say("args: " .. ngx.encode_args(t))
}
--- stream_response_like
^args: (?:a&foo=3|foo=3&a)$
--- no_error_log
[error]
=== TEST 5: ngx.encode_args (boolean values, false)
--- stream_server_config
content_by_lua_block {
local t = {a = false, foo = 3}
ngx.say("args: " .. ngx.encode_args(t))
}
--- stream_response
args: foo=3
--- no_error_log
[error]
=== TEST 6: boolean values in ngx.encode_args
--- stream_server_config
content_by_lua_block {
local t = {bar = {32, true}, foo = 3}
ngx.say(ngx.encode_args(t))
}
--- stream_response_like
(?x) ^
(?= .*? \b bar=32 \b ) # 6 chars
(?= .*? \b bar (?!=) \b ) # 3 chars
(?= .*? \b foo=3 \b ) # 5 chars
(?= (?: [^&]+ & ){2} [^&]+ $ ) # requires exactly 2 &'s
(?= .{16} $ ) # requires for total 16 chars (exactly) in the string
--- no_error_log
[error]
=== TEST 7: ngx.encode_args (bad user data value)
--- stream_config
lua_shared_dict dogs 1m;
--- stream_server_config
content_by_lua_block {
local t = {bar = ngx.shared.dogs, foo = 3}
rc, err = pcall(ngx.encode_args, t)
ngx.say("rc: ", rc, ", err: ", err)
}
--- stream_response
rc: false, err: attempt to use userdata as query arg value
--- no_error_log
[error]
=== TEST 8: ngx.encode_args (empty table)
--- stream_server_config
content_by_lua_block {
local t = {}
ngx.say("args: ", ngx.encode_args(t))
}
--- stream_response
args:
--- no_error_log
[error]
=== TEST 9: ngx.encode_args (bad arg)
--- stream_server_config
content_by_lua_block {
local rc, err = pcall(ngx.encode_args, true)
ngx.say("rc: ", rc, ", err: ", err)
}
--- stream_response
rc: false, err: bad argument #1 to '?' (table expected, got boolean)
--- no_error_log
[error]
=== TEST 10: ngx.decode_args (sanity)
--- stream_server_config
content_by_lua_block {
local args = "a=bar&b=foo"
args = ngx.decode_args(args)
ngx.say("a = ", args.a)
ngx.say("b = ", args.b)
}
--- stream_response
a = bar
b = foo
--- no_error_log
[error]
=== TEST 11: ngx.decode_args (multi-value)
--- stream_server_config
content_by_lua_block {
local args = "a=bar&b=foo&a=baz"
args = ngx.decode_args(args)
ngx.say("a = ", table.concat(args.a, ", "))
ngx.say("b = ", args.b)
}
--- stream_response
a = bar, baz
b = foo
--- no_error_log
[error]
=== TEST 12: ngx.decode_args (empty string)
--- stream_server_config
content_by_lua_block {
local args = ""
args = ngx.decode_args(args)
ngx.say("n = ", #args)
}
--- stream_response
n = 0
--- no_error_log
[error]
=== TEST 13: ngx.decode_args (boolean args)
--- stream_server_config
content_by_lua_block {
local args = "a&b"
args = ngx.decode_args(args)
ngx.say("a = ", args.a)
ngx.say("b = ", args.b)
}
--- stream_response
a = true
b = true
--- no_error_log
[error]
=== TEST 14: ngx.decode_args (empty value args)
--- stream_server_config
content_by_lua_block {
local args = "a=&b="
args = ngx.decode_args(args)
ngx.say("a = ", args.a)
ngx.say("b = ", args.b)
}
--- stream_response
a =
b =
--- no_error_log
[error]
=== TEST 15: ngx.decode_args (max_args = 1)
--- stream_server_config
content_by_lua_block {
local args = "a=bar&b=foo"
args = ngx.decode_args(args, 1)
ngx.say("a = ", args.a)
ngx.say("b = ", args.b)
}
--- stream_response
a = bar
b = nil
--- no_error_log
[error]
=== TEST 16: ngx.decode_args (max_args = -1)
--- stream_server_config
content_by_lua_block {
local args = "a=bar&b=foo"
args = ngx.decode_args(args, -1)
ngx.say("a = ", args.a)
ngx.say("b = ", args.b)
}
--- stream_response
a = bar
b = foo
--- no_error_log
[error]
=== TEST 17: ngx.decode_args should not modify lua strings in place
--- stream_server_config
content_by_lua_block {
local s = "f+f=bar&B=foo"
args = ngx.decode_args(s)
local arr = {}
for k, v in pairs(args) do
table.insert(arr, k)
end
table.sort(arr)
for i, k in ipairs(arr) do
ngx.say("key: ", k)
end
ngx.say("s = ", s)
}
--- stream_response
key: B
key: f f
s = f+f=bar&B=foo
--- no_error_log
[error]

View file

@ -1,69 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_server_config
content_by_lua_block {
local table = {"hello", nil, true, false, 32.5, 56}
ngx.say(table)
}
--- stream_response
helloniltruefalse32.556
--- no_error_log
[error]
=== TEST 2: nested table
--- stream_server_config
content_by_lua_block {
local table = {"hello", nil, true, false, 32.5, 56}
local table2 = {table, "--", table}
ngx.say(table2)
}
--- stream_response
helloniltruefalse32.556--helloniltruefalse32.556
--- no_error_log
[error]
=== TEST 3: non-array table
--- stream_server_config
content_by_lua_block {
local table = {foo = 3}
ngx.say(table)
}
--- stream_response
--- error_log
bad argument #1 to 'say' (non-array table found)
=== TEST 4: bad data type in table
--- stream_server_config
content_by_lua_block {
local f = function () return end
local table = {1, 3, f}
ngx.say(table)
}
--- stream_response
--- error_log
bad argument #1 to 'say' (bad data type function found)

View file

@ -1,131 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_server_config
content_by_lua_block {
ngx.ctx.foo = 32;
ngx.say(ngx.ctx.foo)
}
--- stream_response
32
--- no_error_log
[error]
=== TEST 2: rewrite, access, and content
TODO
--- stream_server_config
rewrite_by_lua_block {
print("foo = ", ngx.ctx.foo)
ngx.ctx.foo = 76
}
access_by_lua_block {
ngx.ctx.foo = ngx.ctx.foo + 3
}
content_by_lua_block {
ngx.say(ngx.ctx.foo)
}
--- stream_response
79
--- no_error_log
[error]
--- grep_error_log eval: qr/foo = [^,]+/
--- log_level: info
--- grep_error_log_out
foo = nil
--- SKIP
=== TEST 3: different requests have different ngx.ctx
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.ctx.foo)
ngx.ctx.foo = 32
ngx.say(ngx.ctx.foo)
}
--- stream_server_config2
content_by_lua_block {
ngx.say(ngx.ctx.foo)
}
--- stream_response
nil
32
nil
--- no_error_log
[error]
=== TEST 4: overriding ctx
--- stream_server_config
content_by_lua_block {
ngx.ctx = { foo = 32, bar = 54 };
ngx.say(ngx.ctx.foo)
ngx.say(ngx.ctx.bar)
ngx.ctx = { baz = 56 };
ngx.say(ngx.ctx.foo)
ngx.say(ngx.ctx.baz)
}
--- stream_response
32
54
nil
56
--- no_error_log
[error]
=== TEST 5: ngx.ctx + ngx.exit(ngx.ERROR) + log_by_lua
TODO
--- stream_server_config
rewrite_by_lua_block {
ngx.ctx.foo = 32;
ngx.exit(ngx.ERROR)
}
log_by_lua_block { ngx.log(ngx.WARN, "ngx.ctx = ", ngx.ctx.foo) }
--- stream_response
--- no_error_log
[error]
--- error_log
ngx.ctx = 32
--- SKIP
=== TEST 6: ngx.ctx + ngx.exit(200) + log_by_lua
TODO
--- stream_server_config
rewrite_by_lua_block {
ngx.ctx.foo = 32;
ngx.say(ngx.ctx.foo)
ngx.exit(200)
}
log_by_lua 'ngx.log(ngx.WARN, "ctx.foo = ", ngx.ctx.foo)';
--- stream_response
32
--- no_error_log
[error]
--- error_log
ctx.foo = 32
--- SKIP

View file

@ -1,951 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([0-9]+)")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
--- no_error_log
[error]
=== TEST 2: escaping sequences
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", [[(\d+)]])
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
--- no_error_log
[error]
=== TEST 3: single capture
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([0-9]{2})[0-9]+")
if m then
ngx.say(m[0])
ngx.say(m[1])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
12
--- no_error_log
[error]
=== TEST 4: multiple captures
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([a-z]+).*?([0-9]{2})[0-9]+", "")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
else
ngx.say("not matched!")
end
}
--- stream_response
hello, 1234
hello
12
--- no_error_log
[error]
=== TEST 5: multiple captures (with o)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([a-z]+).*?([0-9]{2})[0-9]+", "o")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
else
ngx.say("not matched!")
end
}
--- stream_response
hello, 1234
hello
12
--- no_error_log
[error]
=== TEST 6: not matched
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "foo")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
not matched: nil
--- no_error_log
[error]
=== TEST 7: case sensitive by default
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "HELLO")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
not matched: nil
--- no_error_log
[error]
=== TEST 8: case insensitive
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "HELLO", "i")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
hello
--- no_error_log
[error]
=== TEST 9: UTF-8 mode
--- stream_server_config
content_by_lua_block {
rc, err = pcall(ngx.re.match, "hello章亦春", "HELLO.{2}", "iu")
if not rc then
ngx.say("FAIL: ", err)
return
end
local m = err
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response_like chop
^(?:FAIL: bad argument \#2 to '\?' \(pcre_compile\(\) failed: this version of PCRE is not compiled with PCRE_UTF8 support in "HELLO\.\{2\}" at "HELLO\.\{2\}"\)|hello章亦)$
--- no_error_log
[error]
=== TEST 10: multi-line mode (^ at line head)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello\nworld", "^world", "m")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
world
--- no_error_log
[error]
=== TEST 11: multi-line mode (. does not match \n)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello\nworld", ".*", "m")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
hello
--- no_error_log
[error]
=== TEST 12: single-line mode (^ as normal)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello\nworld", "^world", "s")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
not matched: nil
--- no_error_log
[error]
=== TEST 13: single-line mode (dot all)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello\nworld", ".*", "s")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
hello
world
--- no_error_log
[error]
=== TEST 14: extended mode (ignore whitespaces)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello\nworld", [[\w \w]], "x")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
he
--- no_error_log
[error]
=== TEST 15: bad pattern
--- stream_server_config
content_by_lua_block {
local m, err = ngx.re.match("hello\nworld", "(abc")
if m then
ngx.say(m[0])
else
if err then
ngx.say("error: ", err)
else
ngx.say("not matched: ", m)
end
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
=== TEST 16: bad option
--- stream_server_config
content_by_lua_block {
rc, m = pcall(ngx.re.match, "hello\nworld", ".*", "Hm")
if rc then
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
else
ngx.say("error: ", m)
end
}
--- stream_response_like chop
error: .*?unknown flag "H" \(flags "Hm"\)
=== TEST 17: extended mode (ignore whitespaces)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, world", "(world)|(hello)", "x")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
hello
false
hello
--- no_error_log
[error]
=== TEST 18: optional trailing captures
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([0-9]+)(h?)")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
else
ngx.say("not matched!")
end
}
--- stream_response eval
"1234
1234
"
--- no_error_log
[error]
=== TEST 19: anchored match (failed)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([0-9]+)", "a")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
not matched!
--- no_error_log
[error]
=== TEST 20: anchored match (succeeded)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("1234, hello", "([0-9]+)", "a")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
--- no_error_log
[error]
=== TEST 21: match with ctx but no pos
--- stream_server_config
content_by_lua_block {
local ctx = {}
m = ngx.re.match("1234, hello", "([0-9]+)", "", ctx)
if m then
ngx.say(m[0])
ngx.say(ctx.pos)
else
ngx.say("not matched!")
ngx.say(ctx.pos)
end
}
--- stream_response
1234
5
--- no_error_log
[error]
=== TEST 22: match with ctx and a pos
--- stream_server_config
content_by_lua_block {
local ctx = { pos = 3 }
m = ngx.re.match("1234, hello", "([0-9]+)", "", ctx)
if m then
ngx.say(m[0])
ngx.say(ctx.pos)
else
ngx.say("not matched!")
ngx.say(ctx.pos)
end
}
--- stream_response
34
5
--- no_error_log
[error]
=== TEST 23: match (look-behind assertion)
--- stream_server_config
content_by_lua_block {
local ctx = {}
local m = ngx.re.match("{foobarbaz}", "(?<=foo)bar|(?<=bar)baz", "", ctx)
ngx.say(m and m[0])
m = ngx.re.match("{foobarbaz}", "(?<=foo)bar|(?<=bar)baz", "", ctx)
ngx.say(m and m[0])
}
--- stream_response
bar
baz
--- no_error_log
[error]
=== TEST 24: escaping sequences
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local uri = "<impact>2</impact>"
local regex = '(?:>[\\w\\s]*</?\\w{2,}>)';
ngx.say("regex: ", regex)
m = ngx.re.match(uri, regex, "oi")
if m then
ngx.say("[", m[0], "]")
else
ngx.say("not matched!")
end
--- stream_response
regex: (?:>[\w\s]*</?\w{2,}>)
[>2</impact>]
--- no_error_log
[error]
=== TEST 25: long brackets
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", [[\d+]])
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
--- no_error_log
[error]
=== TEST 26: bad pattern
--- stream_server_config
content_by_lua_block {
local m, err = ngx.re.match("hello, 1234", "([0-9]+")
if m then
ngx.say(m[0])
else
if err then
ngx.say("error: ", err)
else
ngx.say("not matched!")
end
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile\(\) failed: missing closing parenthesis in \"\([0-9]+\"\n"
:
"error: pcre_compile\(\) failed: missing \) in \"\([0-9]+\"\n"
--- no_error_log
[error]
=== TEST 27: long brackets containing [...]
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", [[([0-9]+)]])
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
--- no_error_log
[error]
=== TEST 28: bug report (github issue #72)
--- stream_server_config
content_by_lua_block {
local m, err = ngx.re.match("hello", "hello", "j")
ngx.say("done: ", m and "yes" or "no")
}
--- stream_server_config2
content_by_lua_block {
ngx.re.match("hello", "world", "j")
ngx.say("done: ", m and "yes" or "no")
}
--- stream_response
done: yes
done: no
--- no_error_log
[error]
=== TEST 29: non-empty subject, empty pattern
--- stream_server_config
content_by_lua_block {
local ctx = {}
local m = ngx.re.match("hello, 1234", "", "", ctx)
if m then
ngx.say("pos: ", ctx.pos)
ngx.say("m: ", m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
pos: 1
m:
--- no_error_log
[error]
=== TEST 30: named subpatterns w/ extraction
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello, 1234", "(?<first>[a-z]+), [0-9]+")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m.first)
ngx.say(m.second)
else
ngx.say("not matched!")
end
}
--- stream_response
hello, 1234
hello
hello
nil
--- no_error_log
[error]
=== TEST 31: duplicate named subpatterns w/ extraction
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello, 1234", "(?<first>[a-z]+), (?<first>[0-9]+)", "D")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
ngx.say(table.concat(m.first,"-"))
else
ngx.say("not matched!")
end
}
--- stream_response
hello, 1234
hello
1234
hello-1234
--- no_error_log
[error]
=== TEST 32: named captures are empty strings
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("1234", "(?<first>[a-z]*)([0-9]+)")
if m then
ngx.say(m[0])
ngx.say(m.first)
ngx.say(m[1])
ngx.say(m[2])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
1234
--- no_error_log
[error]
=== TEST 33: named captures are nil
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello, world", "(world)|(hello)|(?<named>howdy)")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
ngx.say(m[3])
ngx.say(m["named"])
else
ngx.say("not matched!")
end
}
--- stream_response
hello
false
hello
false
false
--- no_error_log
[error]
=== TEST 34: duplicate named subpatterns
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello, world",
[[(?<named>\w+), (?<named>\w+)]],
"D")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
ngx.say(table.concat(m.named,"-"))
else
ngx.say("not matched!")
end
}
--- stream_response
hello, world
hello
world
hello-world
--- no_error_log
[error]
=== TEST 35: Javascript compatible mode
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("章", [[\u7AE0]], "uJ")
if m then
ngx.say("matched: ", m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
matched: 章
--- no_error_log
[error]
=== TEST 36: empty duplicate captures
--- stream_server_config
content_by_lua_block {
local target = 'test'
local regex = '^(?:(?<group1>(?:foo))|(?<group2>(?:bar))|(?<group3>(?:test)))$'
-- Note the D here
local m = ngx.re.match(target, regex, 'D')
ngx.say(type(m.group1))
ngx.say(type(m.group2))
}
--- stream_response
nil
nil
--- no_error_log
[error]
=== TEST 37: bad UTF-8
--- stream_server_config
content_by_lua_block {
local target = "你好"
local regex = "你好"
-- Note the D here
local m, err = ngx.re.match(string.sub(target, 1, 4), regex, "u")
if err then
ngx.say("error: ", err)
return
end
if m then
ngx.say("matched: ", m[0])
else
ngx.say("not matched")
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre_exec\(\) failed: -4\n"
:
"error: pcre_exec\(\) failed: -10\n"
--- no_error_log
[error]
=== TEST 38: UTF-8 mode without UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("你好", ".", "U")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 2000
--- stream_response
--- no_error_log
[error]
=== TEST 39: UTF-8 mode with UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("你好", ".", "u")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 0
--- stream_response
--- no_error_log
[error]
=== TEST 40: just hit match limit
--- stream_config
lua_regex_match_limit 5000;
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local re = [==[(?i:([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´\(\)]*)?\2|([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´\(\)]*)?(?!\6)([\d\w]+))]==]
s = string.rep([[ABCDEFG]], 10)
local start = ngx.now()
local res, err = ngx.re.match(s, re, "o")
--[[
ngx.update_time()
local elapsed = ngx.now() - start
ngx.say(elapsed, " sec elapsed.")
]]
if not res then
if err then
ngx.say("error: ", err)
return
end
ngx.say("failed to match")
return
end
--- stream_response eval
# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
# but PCRE2 replaces this with pcre2_set_match_limit interface,
# which has different effects.
$Test::Nginx::Util::PcreVersion == 2 ?
"failed to match\n"
:
"error: pcre_exec() failed: -8\n"
=== TEST 41: just not hit match limit
--- stream_config
lua_regex_match_limit 5700;
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local re = [==[(?i:([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´\(\)]*)?\2|([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´\(\)]*)?(?!\6)([\d\w]+))]==]
s = string.rep([[ABCDEFG]], 10)
local start = ngx.now()
local res, err = ngx.re.match(s, re, "o")
--[[
ngx.update_time()
local elapsed = ngx.now() - start
ngx.say(elapsed, " sec elapsed.")
]]
if not res then
if err then
ngx.say("error: ", err)
return
end
ngx.say("failed to match")
return
end
--- stream_response
failed to match
--- no_error_log
[error]
=== TEST 42: extra table argument
--- stream_server_config
content_by_lua_block {
local res = {}
local s = "hello, 1234"
m = ngx.re.match(s, [[(\d)(\d)]], "o", nil, res)
if m then
ngx.say("1: m size: ", #m)
ngx.say("1: res size: ", #res)
else
ngx.say("1: not matched!")
end
m = ngx.re.match(s, [[(\d)]], "o", nil, res)
if m then
ngx.say("2: m size: ", #m)
ngx.say("2: res size: ", #res)
else
ngx.say("2: not matched!")
end
}
--- stream_response
1: m size: 2
1: res size: 2
2: m size: 2
2: res size: 2
--- no_error_log
[error]
=== TEST 43: init_by_lua
--- stream_config
init_by_lua_block {
m = ngx.re.match("hello, 1234", [[(\d+)]])
--- stream_server_config
content_by_lua_block {
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
--- no_error_log
[error]
--- SKIP

View file

@ -1,766 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(5);
plan tests => repeat_each() * (blocks() * 2 + 7);
our $HtmlDir = html_dir;
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: gmatch
--- stream_server_config
content_by_lua_block {
for m in ngx.re.gmatch("hello, world", "[a-z]+") do
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
end
}
--- stream_response
hello
world
=== TEST 2: fail to match
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[0-9]")
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
}
--- stream_response
nil
nil
nil
=== TEST 3: match but iterate more times (not just match at the end)
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world!", "[a-z]+")
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
}
--- stream_response
hello
world
nil
nil
=== TEST 4: match but iterate more times (just matched at the end)
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[a-z]+")
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
}
--- stream_response
hello
world
nil
nil
=== TEST 5: anchored match (failed)
--- stream_server_config
content_by_lua_block {
it = ngx.re.gmatch("hello, 1234", "([0-9]+)", "a")
ngx.say(it())
}
--- stream_response
nil
=== TEST 6: anchored match (succeeded)
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("12 hello 34", "[0-9]", "a")
local m = it()
ngx.say(m[0])
m = it()
ngx.say(m[0])
ngx.say(it())
}
--- stream_response
1
2
nil
=== TEST 7: non-anchored gmatch (without regex cache)
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("12 hello 34", "[0-9]")
local m = it()
ngx.say(m and m[0])
m = it()
ngx.say(m and m[0])
m = it()
ngx.say(m and m[0])
m = it()
ngx.say(m and m[0])
m = it()
ngx.say(m and m[0])
}
--- stream_response
1
2
3
4
nil
=== TEST 8: non-anchored gmatch (with regex cache)
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("12 hello 34", "[0-9]", "o")
local m = it()
ngx.say(m and m[0])
m = it()
ngx.say(m and m[0])
m = it()
ngx.say(m and m[0])
m = it()
ngx.say(m and m[0])
m = it()
ngx.say(m and m[0])
}
--- stream_response
1
2
3
4
nil
=== TEST 9: anchored match (succeeded)
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("12 hello 34", "[0-9]", "a")
local m = it()
ngx.say(m[0])
m = it()
ngx.say(m[0])
ngx.say(it())
}
--- stream_response
1
2
nil
=== TEST 10: gmatch (look-behind assertion)
--- stream_server_config
content_by_lua_block {
for m in ngx.re.gmatch("{foobar}, {foobaz}", "(?<=foo)ba[rz]") do
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
end
}
--- stream_response
bar
baz
=== TEST 11: gmatch (look-behind assertion 2)
--- stream_server_config
content_by_lua_block {
for m in ngx.re.gmatch("{foobarbaz}", "(?<=foo)bar|(?<=bar)baz") do
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
end
}
--- stream_response
bar
baz
=== TEST 12: with regex cache
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, 1234", "([A-Z]+)", "io")
local m = it()
ngx.say(m and m[0])
it = ngx.re.gmatch("1234, okay", "([A-Z]+)", "io")
m = it()
ngx.say(m and m[0])
it = ngx.re.gmatch("hi, 1234", "([A-Z]+)", "o")
m = it()
ngx.say(m and m[0])
}
--- stap2
F(ngx_http_lua_ngx_re_gmatch_iterator) { println("iterator") }
F(ngx_http_lua_ngx_re_gmatch_gc) { println("gc") }
F(ngx_http_lua_ngx_re_gmatch_cleanup) { println("cleanup") }
--- stream_response
hello
okay
nil
=== TEST 13: exceeding regex cache max entries
--- stream_config
lua_regex_cache_max_entries 2;
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, 1234", "([0-9]+)", "o")
local m = it()
ngx.say(m and m[0])
it = ngx.re.gmatch("howdy, 567", "([0-9]+)", "oi")
m = it()
ngx.say(m and m[0])
it = ngx.re.gmatch("hiya, 98", "([0-9]+)", "ox")
m = it()
ngx.say(m and m[0])
}
--- stream_response
1234
567
98
=== TEST 14: disable regex cache completely
--- stream_config
lua_regex_cache_max_entries 0;
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, 1234", "([0-9]+)", "o")
local m = it()
ngx.say(m and m[0])
it = ngx.re.gmatch("howdy, 567", "([0-9]+)", "oi")
local m = it()
ngx.say(m and m[0])
it = ngx.re.gmatch("hiya, 98", "([0-9]+)", "ox")
local m = it()
ngx.say(m and m[0])
}
--- stream_response
1234
567
98
=== TEST 15: gmatch matched but no iterate
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[a-z]+")
ngx.say("done")
}
--- stream_response
done
=== TEST 16: gmatch matched but only iterate once and still matches remain
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[a-z]+")
local m = it()
if m then
ngx.say(m[0])
else
ngx.say("not matched")
end
}
--- stream_response
hello
=== TEST 17: gmatch matched but no iterate and early forced GC
--- stream_server_config
content_by_lua_block {
local a = {}
for i = 1, 3 do
it = ngx.re.gmatch("hello, world", "[a-z]+")
it()
collectgarbage()
table.insert(a, {"hello", "world"})
end
ngx.say("done")
}
--- stream_response
done
=== TEST 18: gmatch iterator used by another request
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;;';"
--- stream_server_config
content_by_lua_block {
package.loaded.foo = nil
collectgarbage()
local foo = require "foo"
local m = foo.go()
ngx.say(m and "matched" or "no")
}
--- stream_server_config2
content_by_lua_block {
local foo = require "foo"
local m = foo.go()
ngx.say(m and "matched" or "no")
}
--- user_files
>>> foo.lua
module("foo", package.seeall)
local it
function go()
if not it then
it = ngx.re.gmatch("hello, world", "[a-z]+")
end
return it()
end
--- stream_response
matched
matched
--- no_error_log
[error]
=== TEST 19: gmatch (empty matched string)
--- stream_server_config
content_by_lua_block {
for m in ngx.re.gmatch("hello", "a|") do
if m then
ngx.say("matched: [", m[0], "]")
else
ngx.say("not matched: ", m)
end
end
}
--- stream_response
matched: []
matched: []
matched: []
matched: []
matched: []
matched: []
=== TEST 20: gmatch with named pattern
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("1234, 1234", "(?<first>[0-9]+)")
m = it()
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m["first"])
else
ngx.say("not matched!")
end
m = it()
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m["first"])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
1234
1234
1234
1234
1234
=== TEST 21: gmatch with multiple named pattern
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("1234, abcd, 1234", "(?<first>[0-9]+)|(?<second>[a-z]+)")
m = it()
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
ngx.say(m["first"])
ngx.say(m["second"])
else
ngx.say("not matched!")
end
m = it()
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
ngx.say(m["first"])
ngx.say(m["second"])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
1234
false
1234
false
abcd
false
abcd
false
abcd
=== TEST 22: gmatch with duplicate named pattern w/ extraction
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, 1234", "(?<first>[a-z]+), (?<first>[0-9]+)", "D")
m = it()
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
ngx.say(table.concat(m.first,"-"))
else
ngx.say("not matched!")
end
m = it()
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
ngx.say(table.concat(m.first,"-"))
else
ngx.say("not matched!")
end
}
--- stream_response
hello, 1234
hello
1234
hello-1234
not matched!
=== TEST 23: named captures are empty
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("1234", "(?<first>[a-z]*)([0-9]+)", "")
local m = it()
if m then
ngx.say(m[0])
ngx.say(m.first)
ngx.say(m[1])
ngx.say(m[2])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
1234
=== TEST 24: named captures are empty (with regex cache)
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("1234", "(?<first>[a-z]*)([0-9]+)", "o")
local m = it()
if m then
ngx.say(m[0])
ngx.say(m.first)
ngx.say(m[1])
ngx.say(m[2])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
1234
=== TEST 25: bad pattern
--- stream_server_config
content_by_lua_block {
local it, err = ngx.re.gmatch("hello\nworld", "(abc")
if not err then
ngx.say("good")
else
ngx.say("error: ", err)
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
=== TEST 26: bad UTF-8
--- stream_server_config
content_by_lua_block {
local target = "你好"
local regex = "你好"
-- Note the D here
local it, err = ngx.re.gmatch(string.sub(target, 1, 4), regex, "u")
if err then
ngx.say("error: ", err)
return
end
local m, err = it()
if err then
ngx.say("error: ", err)
return
end
if m then
ngx.say("matched: ", m[0])
else
ngx.say("not matched")
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre_exec\(\) failed: -4\n"
:
"error: pcre_exec\(\) failed: -10\n"
--- no_error_log
[error]
=== TEST 27: UTF-8 mode without UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("你好", ".", "U")
local m = it()
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 2000
--- stream_response
--- no_error_log
[error]
=== TEST 28: UTF-8 mode with UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("你好", ".", "u")
local m = it()
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 0
--- stream_response
--- no_error_log
[error]
=== TEST 29: just hit match limit
--- stream_config
lua_regex_match_limit 5000;
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local re = [==[(?i:([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´\(\)]*)?\2|([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´\(\)]*)?(?!\6)([\d\w]+))]==]
s = string.rep([[ABCDEFG]], 10)
local start = ngx.now()
local it, err = ngx.re.gmatch(s, re, "o")
if not it then
ngx.say("failed to gen iterator: ", err)
return
end
local res, err = it()
--[[
ngx.update_time()
local elapsed = ngx.now() - start
ngx.say(elapsed, " sec elapsed.")
]]
if not res then
if err then
ngx.say("error: ", err)
return
end
ngx.say("failed to match")
return
end
--- stream_response eval
# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
# but PCRE2 replaces this with pcre2_set_match_limit interface,
# which has different effects.
$Test::Nginx::Util::PcreVersion == 2 ?
"failed to match\n"
:
"error: pcre_exec() failed: -8\n"
=== TEST 30: just not hit match limit
--- stream_config
lua_regex_match_limit 5700;
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local re = [==[(?i:([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´\(\)]*)?\2|([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´\(\)]*)?(?!\6)([\d\w]+))]==]
s = string.rep([[ABCDEFG]], 10)
local start = ngx.now()
local it, err = ngx.re.gmatch(s, re, "o")
if not it then
ngx.say("failed to gen iterator: ", err)
return
end
res, err = it()
--[[
ngx.update_time()
local elapsed = ngx.now() - start
ngx.say(elapsed, " sec elapsed.")
]]
if not res then
if err then
ngx.say("error: ", err)
return
end
ngx.say("failed to match")
return
end
--- stream_response
failed to match

View file

@ -1,605 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 18);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: matched but w/o variables
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, world", "[a-z]+", "howdy")
ngx.say(s)
ngx.say(n)
}
--- stream_response
howdy, world
1
=== TEST 2: not matched
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, world", "[A-Z]+", "howdy")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, world
0
=== TEST 3: matched and with variables
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("a b c d", "(b) (c)", "[$0] [$1] [$2] [$3] [$134]")
ngx.say(s)
ngx.say(n)
}
--- stream_response
a [b c] [b] [c] [] [] d
1
=== TEST 4: matched and with named variables
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("a b c d",
"(b) (c)", "[$0] [$1] [$2] [$3] [$hello]")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response
error: failed to compile the replacement template
--- error_log
attempt to use named capturing variable "hello" (named captures not supported yet)
=== TEST 5: matched and with named variables (bracketed)
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("a b c d",
"(b) (c)", "[$0] [$1] [$2] [$3] [${hello}]")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response
error: failed to compile the replacement template
--- error_log
attempt to use named capturing variable "hello" (named captures not supported yet)
=== TEST 6: matched and with bracketed variables
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("b c d", "(b) (c)", "[$0] [$1] [${2}] [$3] [${134}]")
ngx.say(s)
ngx.say(n)
}
--- stream_response
[b c] [b] [c] [] [] d
1
=== TEST 7: matched and with bracketed variables (unmatched brackets)
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("b c d", "(b) (c)", "[$0] [$1] [${2}] [$3] [${134]")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response
error: failed to compile the replacement template
--- error_log
the closing bracket in "134" variable is missing
=== TEST 8: matched and with bracketed variables (unmatched brackets)
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("b c d", "(b) (c)", "[$0] [$1] [${2}] [$3] [${134")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response
error: failed to compile the replacement template
--- error_log
the closing bracket in "134" variable is missing
=== TEST 9: matched and with bracketed variables (unmatched brackets)
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("b c d", "(b) (c)", "[$0] [$1] [${2}] [$3] [${")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response
error: failed to compile the replacement template
--- error_log
lua script: invalid capturing variable name found in "[$0] [$1] [${2}] [$3] [${"
=== TEST 10: trailing $
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("b c d", "(b) (c)", "[$0] [$1] [${2}] [$3] [$")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response
error: failed to compile the replacement template
--- error_log
lua script: invalid capturing variable name found in "[$0] [$1] [${2}] [$3] [$"
=== TEST 11: matched but w/o variables and with literal $
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, world", "[a-z]+", "ho$$wdy")
ngx.say(s)
ngx.say(n)
}
--- stream_response
ho$wdy, world
1
=== TEST 12: non-anchored match
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234", "[0-9]", "x")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, x234
1
=== TEST 13: anchored match
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234", "[0-9]", "x", "a")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, 1234
0
=== TEST 14: function replace
--- stream_server_config
content_by_lua_block {
local repl = function (m)
return "[" .. m[0] .. "] [" .. m[1] .. "]"
end
local s, n = ngx.re.sub("hello, 34", "([0-9])", repl)
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, [3] [3]4
1
=== TEST 15: function replace (failed)
--- stream_server_config
content_by_lua_block {
local repl = function (m)
return "[" .. m[0] .. "] [" .. m[1] .. "]"
end
local s, n = ngx.re.sub("hello, 34", "([A-Z])", repl)
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, 34
0
=== TEST 16: bad repl arg type
--- stream_server_config
content_by_lua_block {
local rc, s, n = pcall(ngx.re.sub, "hello, 34", "([A-Z])", true)
ngx.say(rc)
ngx.say(s)
ngx.say(n)
}
--- stream_response
false
bad argument #3 to '?' (string, number, or function expected, got boolean)
nil
--- SKIP
=== TEST 17: use number to replace
--- stream_server_config
content_by_lua_block {
local rc, s, n = pcall(ngx.re.sub, "hello, 34", "([0-9])", 72)
ngx.say(rc)
ngx.say(s)
ngx.say(n)
}
--- stream_response
true
hello, 724
1
=== TEST 18: bad function return value type
--- SKIP
--- stream_server_config
content_by_lua_block {
local f = function (m) end
local rc, s, n = pcall(ngx.re.sub, "hello, 34", "([0-9])", f)
ngx.say(rc)
ngx.say(s)
ngx.say(n)
}
--- stream_response
false
bad argument #3 to '?' (string or number expected to be returned by the replace function, got nil)
nil
=== TEST 19: matched and with variables w/o using named patterns in sub
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("a b c d", "(?<first>b) (?<second>c)", "[$0] [$1] [$2] [$3] [$134]")
ngx.say(s)
ngx.say(n)
}
--- stream_response
a [b c] [b] [c] [] [] d
1
=== TEST 20: matched and with variables using named patterns in func
--- stream_server_config
error_log /tmp/nginx_error debug;
content_by_lua_block {
local repl = function (m)
return "[" .. m[0] .. "] [" .. m["first"] .. "] [" .. m[2] .. "]"
end
local s, n = ngx.re.sub("a b c d", "(?<first>b) (?<second>c)", repl)
ngx.say(s)
ngx.say(n)
}
--- stream_response
a [b c] [b] [c] d
1
--- no_error_log
[error]
[alert]
--- timeout: 5
=== TEST 21: matched and with variables w/ using named patterns in sub
This is still a TODO
--- SKIP
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("a b c d", "(?<first>b) (?<second>c)", "[$0] [${first}] [${second}] [$3] [$134]")
ngx.say(s)
ngx.say(n)
}
--- stream_response
a [b c] [b] [c] [] [] d
1
--- no_error_log
[error]
=== TEST 22: $0 without parens
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("a b c d", [[\w]], "[$0]")
ngx.say(s)
ngx.say(n)
}
--- stream_response
[a] b c d
1
--- no_error_log
[error]
=== TEST 23: bad pattern
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("hello\\nworld", "(abc", "")
if s then
ngx.say("subs: ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
=== TEST 24: bad UTF-8
--- stream_server_config
content_by_lua_block {
local target = "你好"
local regex = "你好"
-- Note the D here
local s, n, err = ngx.re.sub(string.sub(target, 1, 4), regex, "", "u")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre_exec\(\) failed: -4\n"
:
"error: pcre_exec\(\) failed: -10\n"
--- no_error_log
[error]
=== TEST 25: UTF-8 mode without UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("你好", ".", "a", "U")
if s then
ngx.say("s: ", s)
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 2000
--- stream_response
s: a好
--- no_error_log
[error]
=== TEST 26: UTF-8 mode with UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("你好", ".", "a", "u")
if s then
ngx.say("s: ", s)
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 0
--- stream_response
s: a好
--- no_error_log
[error]
=== TEST 27: just hit match limit
--- stream_config
lua_regex_match_limit 5000;
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local re = [==[(?i:([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´\(\)]*)?\2|([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´\(\)]*)?(?!\6)([\d\w]+))]==]
s = string.rep([[ABCDEFG]], 10)
local start = ngx.now()
local res, cnt, err = ngx.re.sub(s, re, "", "o")
--[[
ngx.update_time()
local elapsed = ngx.now() - start
ngx.say(elapsed, " sec elapsed.")
]]
if err then
ngx.say("error: ", err)
return
end
ngx.say("sub: ", cnt)
--- stream_response eval
# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
# but PCRE2 replaces this with pcre2_set_match_limit interface,
# which has different effects.
$Test::Nginx::Util::PcreVersion == 2 ?
"sub: 0\n"
:
"error: pcre_exec() failed: -8\n"
=== TEST 28: just not hit match limit
--- stream_config
lua_regex_match_limit 5700;
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local re = [==[(?i:([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´\(\)]*)?\2|([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´\(\)]*)?(?!\6)([\d\w]+))]==]
local s = string.rep([[ABCDEFG]], 10)
local start = ngx.now()
local res, cnt, err = ngx.re.sub(s, re, "", "o")
--[[
ngx.update_time()
local elapsed = ngx.now() - start
ngx.say(elapsed, " sec elapsed.")
]]
if err then
ngx.say("error: ", err)
return
end
ngx.say("sub: ", cnt)
--- stream_response
sub: 0
=== TEST 29: bug: sub incorrectly swallowed a character is the first character
Original bad result: estCase
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("TestCase", "^ *", "", "o")
if s then
ngx.say(s)
end
}
--- stream_response
TestCase
=== TEST 30: bug: sub incorrectly swallowed a character is not the first character
Original bad result: .b.d
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("abcd", "(?=c)", ".")
if s then
ngx.say(s)
end
}
--- stream_response
ab.cd
=== TEST 31: ngx.re.gsub: recursive calling (github #445)
--- stream_server_config
content_by_lua_block {
function test()
local data = [[
OUTER {FIRST}
]]
local p1 = "(OUTER)(.+)"
local p2 = "{([A-Z]+)}"
ngx.print(data)
local res = ngx.re.gsub(data, p1, function(m)
-- ngx.say("pre: m[1]: [", m[1], "]")
-- ngx.say("pre: m[2]: [", m[2], "]")
local res = ngx.re.gsub(m[2], p2, function(_)
return "REPLACED"
end, "")
-- ngx.say("post: m[1]: [", m[1], "]")
-- ngx.say("post m[2]: [", m[2], "]")
return m[1] .. res
end, "")
ngx.print(res)
end
test()
}
--- stream_response
OUTER {FIRST}
OUTER REPLACED
--- no_error_log
[error]
bad argument type
NYI

View file

@ -1,498 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 14);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("[hello, world]", "[a-z]+", "howdy")
ngx.say(s)
ngx.say(n)
}
--- stream_response
[howdy, howdy]
2
=== TEST 2: trimmed
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, world", "[a-z]+", "howdy")
ngx.say(s)
ngx.say(n)
}
--- stream_response
howdy, howdy
2
=== TEST 3: not matched
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, world", "[A-Z]+", "howdy")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, world
0
=== TEST 4: replace by function (trimmed)
--- stream_server_config
content_by_lua_block {
local f = function (m)
return "[" .. m[0] .. "," .. m[1] .. "]"
end
local s, n = ngx.re.gsub("hello, world", "([a-z])[a-z]+", f)
ngx.say(s)
ngx.say(n)
}
--- stream_response
[hello,h], [world,w]
2
=== TEST 5: replace by function (not trimmed)
--- stream_server_config
content_by_lua_block {
local f = function (m)
return "[" .. m[0] .. "," .. m[1] .. "]"
end
local s, n = ngx.re.gsub("{hello, world}", "([a-z])[a-z]+", f)
ngx.say(s)
ngx.say(n)
}
--- stream_response
{[hello,h], [world,w]}
2
=== TEST 6: replace by script (trimmed)
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, world", "([a-z])[a-z]+", "[$0,$1]")
ngx.say(s)
ngx.say(n)
}
--- stream_response
[hello,h], [world,w]
2
=== TEST 7: replace by script (not trimmed)
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("{hello, world}", "([a-z])[a-z]+", "[$0,$1]")
ngx.say(s)
ngx.say(n)
}
--- stream_response
{[hello,h], [world,w]}
2
=== TEST 8: look-behind assertion
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("{foobarbaz}", "(?<=foo)bar|(?<=bar)baz", "h$0")
ngx.say(s)
ngx.say(n)
}
--- stream_response
{foohbarhbaz}
2
=== TEST 9: gsub with a patch matching an empty substring (string template)
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello", "a|", "b")
ngx.say("s: ", s)
ngx.say("n: ", n)
}
--- stream_response
s: bhbeblblbob
n: 6
--- no_error_log
[error]
=== TEST 10: gsub with a patch matching an empty substring (string template, empty subj)
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("", "a|", "b")
ngx.say("s: ", s)
ngx.say("n: ", n)
}
--- stream_response
s: b
n: 1
--- no_error_log
[error]
=== TEST 11: gsub with a patch matching an empty substring (func)
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello", "a|", function () return "b" end)
ngx.say("s: ", s)
ngx.say("n: ", n)
}
--- stream_response
s: bhbeblblbob
n: 6
--- no_error_log
[error]
=== TEST 12: gsub with a patch matching an empty substring (func, empty subj)
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("", "a|", function () return "b" end)
ngx.say("s: ", s)
ngx.say("n: ", n)
}
--- stream_response
s: b
n: 1
--- no_error_log
[error]
=== TEST 13: big subject string exceeding the luabuf chunk size (with trailing unmatched data, func repl)
--- stream_server_config
content_by_lua_block {
local subj = string.rep("a", 8000)
.. string.rep("b", 1000)
.. string.rep("a", 8000)
.. string.rep("b", 1000)
.. "aaa"
local function repl(m)
return string.rep("c", string.len(m[0]))
end
local s, n = ngx.re.gsub(subj, "b+", repl)
ngx.say(s)
ngx.say(n)
}
--- stream_response eval
("a" x 8000) . ("c" x 1000) . ("a" x 8000) . ("c" x 1000)
. "aaa
2
"
--- no_error_log
[error]
=== TEST 14: big subject string exceeding the luabuf chunk size (without trailing unmatched data, func repl)
--- stream_server_config
content_by_lua_block {
local subj = string.rep("a", 8000)
.. string.rep("b", 1000)
.. string.rep("a", 8000)
.. string.rep("b", 1000)
local function repl(m)
return string.rep("c", string.len(m[0]))
end
local s, n = ngx.re.gsub(subj, "b+", repl)
ngx.say(s)
ngx.say(n)
}
--- stream_response eval
("a" x 8000) . ("c" x 1000) . ("a" x 8000) . ("c" x 1000)
. "\n2\n"
--- no_error_log
[error]
=== TEST 15: big subject string exceeding the luabuf chunk size (with trailing unmatched data, str repl)
--- stream_server_config
content_by_lua_block {
local subj = string.rep("a", 8000)
.. string.rep("b", 1000)
.. string.rep("a", 8000)
.. string.rep("b", 1000)
.. "aaa"
local s, n = ngx.re.gsub(subj, "b(b+)(b)", "$1 $2")
ngx.say(s)
ngx.say(n)
}
--- stream_response eval
("a" x 8000) . ("b" x 998) . " b" . ("a" x 8000) . ("b" x 998) . " baaa
2
"
--- no_error_log
[error]
=== TEST 16: big subject string exceeding the luabuf chunk size (without trailing unmatched data, str repl)
--- stream_server_config
content_by_lua_block {
local subj = string.rep("a", 8000)
.. string.rep("b", 1000)
.. string.rep("a", 8000)
.. string.rep("b", 1000)
local s, n = ngx.re.gsub(subj, "b(b+)(b)", "$1 $2")
ngx.say(s)
ngx.say(n)
}
--- stream_response eval
("a" x 8000) . ("b" x 998) . " b" . ("a" x 8000) . ("b" x 998) . " b\n2\n"
--- no_error_log
[error]
=== TEST 17: named pattern repl w/ callback
--- stream_server_config
content_by_lua_block {
local repl = function (m)
return "[" .. m[0] .. "," .. m["first"] .. "]"
end
local s, n = ngx.re.gsub("hello, world", "(?<first>[a-z])[a-z]+", repl)
ngx.say(s)
ngx.say(n)
}
--- stream_response
[hello,h], [world,w]
2
=== TEST 18: $0 without parens
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("a b c d", [[\w]], "[$0]")
ngx.say(s)
ngx.say(n)
}
--- stream_response
[a] [b] [c] [d]
4
--- no_error_log
[error]
=== TEST 19: bad UTF-8
--- stream_server_config
content_by_lua_block {
local target = "你好"
local regex = "你好"
-- Note the D here
local s, n, err = ngx.re.gsub(string.sub(target, 1, 4), regex, "", "u")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre_exec\(\) failed: -4\n"
:
"error: pcre_exec\(\) failed: -10\n"
--- no_error_log
[error]
=== TEST 20: UTF-8 mode without UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.gsub("你好", ".", "a", "U")
if s then
ngx.say("s: ", s)
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 2000
exec opts: 2000
exec opts: 2000
--- stream_response
s: aa
--- no_error_log
[error]
=== TEST 21: UTF-8 mode with UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.gsub("你好", ".", "a", "u")
if s then
ngx.say("s: ", s)
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 0
exec opts: 0
exec opts: 0
--- stream_response
s: aa
--- no_error_log
[error]
=== TEST 22: just hit match limit
--- stream_config
lua_regex_match_limit 5000;
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local re = [==[(?i:([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´\(\)]*)?\2|([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´\(\)]*)?(?!\6)([\d\w]+))]==]
s = string.rep([[ABCDEFG]], 10)
local start = ngx.now()
local res, cnt, err = ngx.re.gsub(s, re, "", "o")
--[[
ngx.update_time()
local elapsed = ngx.now() - start
ngx.say(elapsed, " sec elapsed.")
]]
if err then
ngx.say("error: ", err)
return
end
ngx.say("gsub: ", cnt)
--- stream_response eval
# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
# but PCRE2 replaces this with pcre2_set_match_limit interface,
# which has different effects.
$Test::Nginx::Util::PcreVersion == 2 ?
"gsub: 0\n"
:
"error: pcre_exec() failed: -8\n"
=== TEST 23: just not hit match limit
--- stream_config
lua_regex_match_limit 5700;
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local re = [==[(?i:([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´\(\)]*)?\2|([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´\(\)]*)?(?!\6)([\d\w]+))]==]
local s = string.rep([[ABCDEFG]], 10)
local start = ngx.now()
local res, cnt, err = ngx.re.gsub(s, re, "", "o")
--[[
ngx.update_time()
local elapsed = ngx.now() - start
ngx.say(elapsed, " sec elapsed.")
]]
if err then
ngx.say("error: ", err)
return
end
ngx.say("gsub: ", cnt)
--- stream_response
gsub: 0
--- timeout: 10
=== TEST 24: bug: gsub incorrectly swallowed a character is the first character
Original bad result: estCase
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("TestCase", "^ *", "", "o")
if s then
ngx.say(s)
end
}
--- stream_response
TestCase
=== TEST 25: bug: gsub incorrectly swallowed a character is not the first character
Original bad result: .b.d
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("abcd", "a|(?=c)", ".")
if s then
ngx.say(s)
end
}
--- stream_response
.b.cd

View file

@ -1,563 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 1);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([0-9]+)", "o")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
=== TEST 2: escaping sequences
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "(\\d+)", "o")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
=== TEST 3: single capture
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([0-9]{2})[0-9]+", "o")
if m then
ngx.say(m[0])
ngx.say(m[1])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
12
=== TEST 4: multiple captures
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([a-z]+).*?([0-9]{2})[0-9]+", "o")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
else
ngx.say("not matched!")
end
}
--- stream_response
hello, 1234
hello
12
=== TEST 5: not matched
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "foo", "o")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
not matched: nil
=== TEST 6: case sensitive by default
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "HELLO", "o")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
not matched: nil
=== TEST 7: case sensitive by default
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "HELLO", "oi")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
hello
=== TEST 8: UTF-8 mode
--- stream_server_config
content_by_lua_block {
local rc, m = pcall(ngx.re.match, "hello章亦春", "HELLO.{2}", "iou")
if not rc then
ngx.say("error: ", m)
return
end
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response_like chop
this version of PCRE is not compiled with PCRE_UTF8 support|^hello章亦$
=== TEST 9: multi-line mode (^ at line head)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello\nworld", "^world", "mo")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
world
=== TEST 10: multi-line mode (. does not match \n)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello\nworld", ".*", "om")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
hello
=== TEST 11: single-line mode (^ as normal)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello\nworld", "^world", "so")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
not matched: nil
=== TEST 12: single-line mode (dot all)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello\nworld", ".*", "os")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
hello
world
=== TEST 13: extended mode (ignore whitespaces)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello\nworld", [[\w \w]], "xo")
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
he
=== TEST 14: bad pattern
--- stream_server_config
content_by_lua_block {
local m, err = ngx.re.match("hello\\nworld", "(abc", "o")
if m then
ngx.say(m[0])
else
if err then
ngx.say("error: ", err)
else
ngx.say("not matched: ", m)
end
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
=== TEST 15: bad option
--- stream_server_config
content_by_lua_block {
rc, m = pcall(ngx.re.match, "hello\\nworld", ".*", "Ho")
if rc then
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
else
ngx.say("error: ", m)
end
}
--- stream_response_like chop
^error: .*?unknown flag "H"
=== TEST 16: extended mode (ignore whitespaces)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, world", "(world)|(hello)", "xo")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
else
ngx.say("not matched: ", m)
end
}
--- stream_response
hello
false
hello
=== TEST 17: optional trailing captures
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([0-9]+)(h?)", "o")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
else
ngx.say("not matched!")
end
}
--- stream_response eval
"1234
1234
"
=== TEST 18: anchored match (failed)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([0-9]+)", "oa")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
not matched!
=== TEST 19: anchored match (succeeded)
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("1234, hello", "([0-9]+)", "ao")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
=== TEST 20: match with ctx but no pos
--- stream_server_config
content_by_lua_block {
local ctx = {}
m = ngx.re.match("1234, hello", "([0-9]+)", "o", ctx)
if m then
ngx.say(m[0])
ngx.say(ctx.pos)
else
ngx.say("not matched!")
ngx.say(ctx.pos)
end
}
--- stream_response
1234
5
=== TEST 21: match with ctx and a pos
--- stream_server_config
content_by_lua_block {
local ctx = { pos = 3 }
m = ngx.re.match("1234, hello", "([0-9]+)", "o", ctx)
if m then
ngx.say(m[0])
ngx.say(ctx.pos)
else
ngx.say("not matched!")
ngx.say(ctx.pos)
end
}
--- stream_response
34
5
=== TEST 22: match (look-behind assertion)
--- stream_server_config
content_by_lua_block {
local ctx = {}
local m = ngx.re.match("{foobarbaz}", "(?<=foo)bar|(?<=bar)baz", "o", ctx)
ngx.say(m and m[0])
m = ngx.re.match("{foobarbaz}", "(?<=foo)bar|(?<=bar)baz", "o", ctx)
ngx.say(m and m[0])
}
--- stream_response
bar
baz
=== TEST 23: match (with regex cache)
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello, 1234", "([A-Z]+)", "io")
ngx.say(m and m[0])
m = ngx.re.match("1234, okay", "([A-Z]+)", "io")
ngx.say(m and m[0])
m = ngx.re.match("hello, 1234", "([A-Z]+)", "o")
ngx.say(m and m[0])
}
--- stream_response
hello
okay
nil
=== TEST 24: match (with regex cache and ctx)
--- stream_server_config
content_by_lua_block {
local ctx = {}
local m = ngx.re.match("hello, 1234", "([A-Z]+)", "io", ctx)
ngx.say(m and m[0])
ngx.say(ctx.pos)
m = ngx.re.match("1234, okay", "([A-Z]+)", "io", ctx)
ngx.say(m and m[0])
ngx.say(ctx.pos)
ctx.pos = 1
m = ngx.re.match("hi, 1234", "([A-Z]+)", "o", ctx)
ngx.say(m and m[0])
ngx.say(ctx.pos)
}
--- stream_response
hello
6
okay
11
nil
1
=== TEST 25: exceeding regex cache max entries
--- stream_config
lua_regex_cache_max_entries 2;
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello, 1234", "([0-9]+)", "o")
ngx.say(m and m[0])
m = ngx.re.match("howdy, 567", "([0-9]+)", "oi")
ngx.say(m and m[0])
m = ngx.re.match("hiya, 98", "([0-9]+)", "ox")
ngx.say(m and m[0])
}
--- stream_response
1234
567
98
=== TEST 26: disable regex cache completely
--- stream_config
lua_regex_cache_max_entries 0;
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello, 1234", "([0-9]+)", "o")
ngx.say(m and m[0])
m = ngx.re.match("howdy, 567", "([0-9]+)", "oi")
ngx.say(m and m[0])
m = ngx.re.match("hiya, 98", "([0-9]+)", "ox")
ngx.say(m and m[0])
}
--- stream_response
1234
567
98
=== TEST 27: named subpatterns w/ extraction
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello, 1234", "(?<first>[a-z]+), [0-9]+", "o")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m.first)
ngx.say(m.second)
else
ngx.say("not matched!")
end
}
--- stream_response
hello, 1234
hello
hello
nil
=== TEST 28: duplicate named subpatterns w/ extraction
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello, 1234", "(?<first>[a-z]+), (?<first>[0-9]+)", "Do")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
ngx.say(table.concat(m.first,"-"))
else
ngx.say("not matched!")
end
}
--- stream_response
hello, 1234
hello
1234
hello-1234
=== TEST 29: named captures are empty strings
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("1234", "(?<first>[a-z]*)([0-9]+)", "o")
if m then
ngx.say(m[0])
ngx.say(m.first)
ngx.say(m[1])
ngx.say(m[2])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
1234
=== TEST 30: named captures are nil
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello, world", "(world)|(hello)|(?<named>howdy)", "o")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
ngx.say(m[3])
ngx.say(m["named"])
else
ngx.say("not matched!")
end
}
--- stream_response
hello
false
hello
false
false

View file

@ -1,464 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 6);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: matched but w/o variables
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, world", "[a-z]+", "howdy", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
howdy, world
1
=== TEST 2: not matched
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, world", "[A-Z]+", "howdy", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, world
0
=== TEST 3: matched and with variables
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("a b c d", "(b) (c)", "[$0] [$1] [$2] [$3] [$134]", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
a [b c] [b] [c] [] [] d
1
=== TEST 4: matched and with named variables (bad template)
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("a b c d",
"(b) (c)",
"[$0] [$1] [$2] [$3] [$hello]",
"o")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response
error: failed to compile the replacement template
--- error_log
attempt to use named capturing variable "hello" (named captures not supported yet)
=== TEST 5: matched and with named variables (bracketed)
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("a b c d",
"(b) (c)",
"[$0] [$1] [$2] [$3] [${hello}]",
"o")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response
error: failed to compile the replacement template
--- error_log
attempt to use named capturing variable "hello" (named captures not supported yet)
=== TEST 6: matched and with bracketed variables
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("b c d", "(b) (c)", "[$0] [$1] [${2}] [$3] [${134}]", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
[b c] [b] [c] [] [] d
1
=== TEST 7: matched and with bracketed variables (unmatched brackets)
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("b c d", "(b) (c)", "[$0] [$1] [${2}] [$3] [${134]", "o")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response
error: failed to compile the replacement template
--- error_log
the closing bracket in "134" variable is missing
=== TEST 8: matched and with bracketed variables (unmatched brackets)
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("b c d", "(b) (c)", "[$0] [$1] [${2}] [$3] [${134", "o")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response
error: failed to compile the replacement template
--- error_log
the closing bracket in "134" variable is missing
=== TEST 9: matched and with bracketed variables (unmatched brackets)
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("b c d", "(b) (c)", "[$0] [$1] [${2}] [$3] [${", "o")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response
error: failed to compile the replacement template
--- error_log
lua script: invalid capturing variable name found in "[$0] [$1] [${2}] [$3] [${"
=== TEST 10: trailing $
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("b c d", "(b) (c)", "[$0] [$1] [${2}] [$3] [$", "o")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response
error: failed to compile the replacement template
--- error_log
lua script: invalid capturing variable name found in "[$0] [$1] [${2}] [$3] [$"
=== TEST 11: matched but w/o variables and with literal $
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, world", "[a-z]+", "ho$$wdy", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
ho$wdy, world
1
=== TEST 12: non-anchored match
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234", " [0-9] ", "x", "xo")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, x234
1
=== TEST 13: anchored match
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234", "[0-9]", "x", "ao")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, 1234
0
=== TEST 14: function replace
--- stream_server_config
content_by_lua_block {
local repl = function (m)
return "[" .. m[0] .. "] [" .. m[1] .. "]"
end
local s, n = ngx.re.sub("hello, 34", "([0-9])", repl, "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, [3] [3]4
1
=== TEST 15: function replace (failed)
--- stream_server_config
content_by_lua_block {
local repl = function (m)
return "[" .. m[0] .. "] [" .. m[1] .. "]"
end
local s, n = ngx.re.sub("hello, 34", "([A-Z])", repl, "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, 34
0
=== TEST 16: bad repl arg type
--- SKIP
--- stream_server_config
content_by_lua_block {
local rc, s, n = pcall(ngx.re.sub, "hello, 34", "([A-Z])", true, "o")
ngx.say(rc)
ngx.say(s)
ngx.say(n)
}
--- stream_response
false
bad argument #3 to '?' (string, number, or function expected, got boolean)
nil
=== TEST 17: use number to replace
--- stream_server_config
content_by_lua_block {
local rc, s, n = pcall(ngx.re.sub, "hello, 34", "([0-9])", 72, "o")
ngx.say(rc)
ngx.say(s)
ngx.say(n)
}
--- stream_response
true
hello, 724
1
=== TEST 18: bad function return value type
--- SKIP
--- stream_server_config
content_by_lua_block {
local f = function (m) end
local rc, s, n = pcall(ngx.re.sub, "hello, 34", "([0-9])", f, "o")
ngx.say(rc)
ngx.say(s)
ngx.say(n)
}
--- stream_response
false
bad argument #3 to '?' (string or number expected to be returned by the replace function, got nil)
nil
=== TEST 19: with regex cache (with text replace)
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234", "([A-Z]+)", "baz", "io")
ngx.say(s)
ngx.say(n)
local s, n = ngx.re.sub("howdy, 1234", "([A-Z]+)", "baz", "io")
ngx.say(s)
ngx.say(n)
s, n = ngx.re.sub("1234, okay", "([A-Z]+)", "blah", "io")
ngx.say(s)
ngx.say(n)
s, n = ngx.re.sub("hi, 1234", "([A-Z]+)", "hello", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
baz, 1234
1
baz, 1234
1
1234, blah
1
hi, 1234
0
=== TEST 20: with regex cache (with func replace)
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234", "([A-Z]+)", "baz", "io")
ngx.say(s)
ngx.say(n)
local s, n = ngx.re.sub("howdy, 1234", "([A-Z]+)", function () return "bah" end, "io")
ngx.say(s)
ngx.say(n)
s, n = ngx.re.sub("1234, okay", "([A-Z]+)", function () return "blah" end, "io")
ngx.say(s)
ngx.say(n)
s, n = ngx.re.sub("hi, 1234", "([A-Z]+)", "hello", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
baz, 1234
1
bah, 1234
1
1234, blah
1
hi, 1234
0
=== TEST 21: exceeding regex cache max entries
--- stream_config
lua_regex_cache_max_entries 2;
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234", "([0-9]+)", "hello", "o")
ngx.say(s)
ngx.say(n)
s, n = ngx.re.sub("howdy, 567", "([0-9]+)", "hello", "oi")
ngx.say(s)
ngx.say(n)
s, n = ngx.re.sub("hiya, 98", "([0-9]+)", "hello", "ox")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, hello
1
howdy, hello
1
hiya, hello
1
=== TEST 22: disable regex cache completely
--- stream_config
lua_regex_cache_max_entries 0;
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234", "([0-9]+)", "hello", "o")
ngx.say(s)
ngx.say(n)
s, n = ngx.re.sub("howdy, 567", "([0-9]+)", "hello", "oi")
ngx.say(s)
ngx.say(n)
s, n = ngx.re.sub("hiya, 98", "([0-9]+)", "hello", "ox")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, hello
1
howdy, hello
1
hiya, hello
1
=== TEST 23: empty replace
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234", "([0-9]+)", "", "o")
ngx.say(s)
ngx.say(n)
local s, n = ngx.re.sub("hi, 5432", "([0-9]+)", "", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello,
1
hi,
1
=== TEST 24: matched and with variables w/o using named patterns in sub
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("a b c d", "(?<first>b) (?<second>c)", "[$0] [$1] [$2] [$3] [$134]", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
a [b c] [b] [c] [] [] d
1
=== TEST 25: matched and with variables using named patterns in func
--- stream_server_config
error_log /tmp/nginx_error debug;
content_by_lua_block {
local repl = function (m)
return "[" .. m[0] .. "] [" .. m["first"] .. "] [" .. m[2] .. "]"
end
local s, n = ngx.re.sub("a b c d", "(?<first>b) (?<second>c)", repl, "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
a [b c] [b] [c] d
1

View file

@ -1,144 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("[hello, world]", "[a-z]+", "howdy", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
[howdy, howdy]
2
=== TEST 2: trimmed
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, world", "[a-z]+", "howdy", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
howdy, howdy
2
=== TEST 3: not matched
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, world", "[A-Z]+", "howdy", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
hello, world
0
=== TEST 4: replace by function (trimmed)
--- stream_server_config
content_by_lua_block {
local f = function (m)
return "[" .. m[0] .. "," .. m[1] .. "]"
end
local s, n = ngx.re.gsub("hello, world", "([a-z])[a-z]+", f, "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
[hello,h], [world,w]
2
=== TEST 5: replace by function (not trimmed)
--- stream_server_config
content_by_lua_block {
local f = function (m)
return "[" .. m[0] .. "," .. m[1] .. "]"
end
local s, n = ngx.re.gsub("{hello, world}", "([a-z])[a-z]+", f, "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
{[hello,h], [world,w]}
2
=== TEST 6: replace by script (trimmed)
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, world", "([a-z])[a-z]+", "[$0,$1]", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
[hello,h], [world,w]
2
=== TEST 7: replace by script (not trimmed)
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("{hello, world}", "([a-z])[a-z]+", "[$0,$1]", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
{[hello,h], [world,w]}
2
=== TEST 8: look-behind assertion
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("{foobarbaz}", "(?<=foo)bar|(?<=bar)baz", "h$0", "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
{foohbarhbaz}
2
=== TEST 9: named pattern repl w/ callback
--- stream_server_config
content_by_lua_block {
local repl = function (m)
return "[" .. m[0] .. "," .. m["first"] .. "]"
end
local s, n = ngx.re.gsub("hello, world", "(?<first>[a-z])[a-z]+", repl, "o")
ngx.say(s)
ngx.say(n)
}
--- stream_response
[hello,h], [world,w]
2

View file

@ -1,44 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_process_enabled(1);
log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: short sanity
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.crc32_short("hello, world"))
}
--- stream_response
4289425978
=== TEST 2: long sanity
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.crc32_long("hello, world"))
}
--- stream_response
4289425978
=== TEST 3: long sanity (empty)
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.crc32_long(""))
}
--- stream_response
0

File diff suppressed because it is too large Load diff

View file

@ -1,133 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_process_enabled(1);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 3);
#no_diff();
#no_long_string();
#master_on();
#workers(2);
run_tests();
__DATA__
=== TEST 1: pid
--- stream_server_config
content_by_lua_block {
local pid = ngx.var.pid
ngx.say("variable pid: ", pid)
if pid ~= tostring(ngx.worker.pid()) then
ngx.say("variable pid is wrong.")
else
ngx.say("variable pid is correct.")
end
}
--- stream_response_like
variable pid: \d+
variable pid is correct\.
--- no_error_log
[error]
=== TEST 2: remote_addr
--- stream_server_config
content_by_lua_block {
ngx.say("remote_addr: ", ngx.var.remote_addr)
ngx.say("type: ", type(ngx.var.remote_addr))
}
--- stream_response
remote_addr: 127.0.0.1
type: string
=== TEST 3: binary_remote_addr
--- stream_server_config
content_by_lua_block {
ngx.say("binary_remote_addr len: ", #ngx.var.binary_remote_addr)
ngx.say("type: ", type(ngx.var.binary_remote_addr))
}
--- stream_response
binary_remote_addr len: 4
type: string
=== TEST 4: server_addr & server_port
--- stream_server_config
content_by_lua_block {
ngx.say("server_addr: ", ngx.var.server_addr)
ngx.say("server_port: ", ngx.var.server_port)
ngx.say(type(ngx.var.server_addr))
ngx.say(type(ngx.var.server_port))
}
--- stream_response_like eval
qr/^server_addr: 127\.0\.0\.1
server_port: \d{4,}
string
string
$/
=== TEST 5: connection & nginx_version
--- stream_server_config
content_by_lua_block {
ngx.say("connection: ", ngx.var.connection)
ngx.say("nginx_version: ", ngx.var.nginx_version)
ngx.say(type(ngx.var.connection))
ngx.say(type(ngx.var.nginx_version))
}
--- stream_response_like eval
qr/^connection: \d+
nginx_version: \d+\.\d+\.\d+.*
string
string$/
=== TEST 6: reference nonexistent variable
--- stream_server_config
content_by_lua_block {
ngx.say("value: ", ngx.var.notfound)
}
--- stream_response
value: nil
=== TEST 7: variable name is caseless
--- stream_server_config
content_by_lua_block {
ngx.say("value: ", ngx.var.REMOTE_ADDR)
}
--- stream_response
value: 127.0.0.1
=== TEST 8: get a bad variable name
--- stream_server_config
content_by_lua_block {
ngx.say("value: ", ngx.var[true])
}
--- stream_response
--- error_log
bad variable name
=== TEST 9: can not set variable
--- stream_server_config
content_by_lua_block {
ngx.var.foo = 56
}
--- stream_response
--- error_log
variable "foo" not found for writing

View file

@ -1,27 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
#repeat_each(1);
plan tests => repeat_each() * (blocks() * 2);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_server_config
content_by_lua_block {
local digest = ngx.hmac_sha1("thisisverysecretstuff", "some string we want to sign")
ngx.say(ngx.encode_base64(digest))
}
--- stream_response
R/pvxzHC4NLtj7S+kXFg/NePTmk=

View file

@ -1,214 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 5);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: matched with j
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([0-9]+)", "j")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
=== TEST 2: not matched with j
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, world", "([0-9]+)", "j")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
not matched!
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
=== TEST 3: matched with jo
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, 1234", "([0-9]+)", "jo")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
1234
--- grep_error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
=== TEST 4: not matched with jo
--- stream_server_config
content_by_lua_block {
m = ngx.re.match("hello, world", "([0-9]+)", "jo")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
not matched!
--- grep_error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
=== TEST 5: bad pattern
--- stream_server_config
content_by_lua_block {
local m, err = ngx.re.match("hello\\nworld", "(abc", "j")
if m then
ngx.say(m[0])
else
if err then
ngx.say("error: ", err)
else
ngx.say("not matched: ", m)
end
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
=== TEST 6: just hit match limit
--- stream_config
lua_regex_match_limit 2940;
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local re = [==[(?i:([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´\(\)]*)?\2|([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´\(\)]*)?(?!\6)([\d\w]+))]==]
s = string.rep([[ABCDEFG]], 21)
local start = ngx.now()
local res, err = ngx.re.match(s, re, "jo")
--[[
ngx.update_time()
local elapsed = ngx.now() - start
ngx.say(elapsed, " sec elapsed.")
]]
if not res then
if err then
ngx.say("error: ", err)
return
end
ngx.say("failed to match")
return
end
--- stream_response eval
# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
# but PCRE2 replaces this with pcre2_set_match_limit interface,
# which has different effects.
$Test::Nginx::Util::PcreVersion == 2 ?
# PCRE2_ERROR_MATCHLIMIT (-47)
"error: pcre_exec() failed: -47\n"
:
"error: pcre_exec() failed: -8\n"
=== TEST 7: just not hit match limit
--- stream_config
lua_regex_match_limit 2950;
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local re = [==[(?i:([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´\(\)]*)?\2|([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´\(\)]*)?(?!\6)([\d\w]+))]==]
s = string.rep([[ABCDEFG]], 21)
local start = ngx.now()
local res, err = ngx.re.match(s, re, "jo")
--[[
ngx.update_time()
local elapsed = ngx.now() - start
ngx.say(elapsed, " sec elapsed.")
]]
if not res then
if err then
ngx.say("error: ", err)
return
end
ngx.say("failed to match")
return
end
--- stream_response
failed to match

View file

@ -1,177 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 4);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: matched with d
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello", "(he|hell)", "d")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
hell
=== TEST 2: matched with d + j
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello", "(he|hell)", "jd")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
hell
=== TEST 3: not matched with j
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("world", "(he|hell)", "d")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
not matched!
=== TEST 4: matched with do
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("hello", "he|hell", "do")
if m then
ngx.say(m[0])
ngx.say(m[1])
ngx.say(m[2])
else
ngx.say("not matched!")
end
}
--- stream_response
hell
nil
nil
=== TEST 5: not matched with do
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("world", "([0-9]+)", "do")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stream_response
not matched!
=== TEST 6: UTF-8 mode without UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("你好", ".", "Ud")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_dfa_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 2000
--- stream_response
--- no_error_log
[error]
=== TEST 7: UTF-8 mode with UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local m = ngx.re.match("你好", ".", "ud")
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_dfa_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 0
--- stream_response
--- no_error_log
[error]
=== TEST 8: matched dfa after nfa
--- stream_server_config
content_by_lua_block {
local m1 = ngx.re.match("hello", "(a)(a)(a)")
if m1 then
ngx.say(m1[0])
else
ngx.say("not matched!")
end
local m2 = ngx.re.match("world", "w", "d")
if m2 then
ngx.say(m2[0])
else
ngx.say("not matched!")
end
}
--- stream_response
not matched!
w

View file

@ -1,231 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 9);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: gmatch matched
--- stream_server_config
content_by_lua_block {
for m in ngx.re.gmatch("hello, world", "[a-z]+", "j") do
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
end
}
--- stream_response
hello
world
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
=== TEST 2: fail to match
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[0-9]", "j")
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
}
--- stream_response
nil
nil
nil
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
=== TEST 3: gmatch matched but no iterate
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[a-z]+", "j")
ngx.say("done")
}
--- stream_response
done
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
=== TEST 4: gmatch matched but only iterate once and still matches remain
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[a-z]+", "j")
local m = it()
if m then
ngx.say(m[0])
else
ngx.say("not matched")
end
}
--- stream_response
hello
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
=== TEST 5: gmatch matched + o
--- stream_server_config
content_by_lua_block {
for m in ngx.re.gmatch("hello, world", "[a-z]+", "jo") do
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
end
}
--- stream_response
hello
world
--- grep_error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
=== TEST 6: fail to match + o
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[0-9]", "jo")
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
}
--- stream_response
nil
nil
nil
--- grep_error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
=== TEST 7: gmatch matched but no iterate + o
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[a-z]+", "jo")
ngx.say("done")
}
--- stream_response
done
--- grep_error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
=== TEST 8: gmatch matched but only iterate once and still matches remain + o
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[a-z]+", "jo")
local m = it()
if m then
ngx.say(m[0])
else
ngx.say("not matched")
end
}
--- stream_response
hello
--- grep_error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
=== TEST 9: bad pattern
--- stream_server_config
content_by_lua_block {
local m, err = ngx.re.gmatch("hello\\nworld", "(abc", "j")
if not m then
ngx.say("error: ", err)
return
end
ngx.say("success")
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]

View file

@ -1,242 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 5);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: gmatch matched
--- stream_server_config
content_by_lua_block {
for m in ngx.re.gmatch("hello, halo", "h[a-z]|h[a-z][a-z]", "d") do
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
end
}
--- stream_response
hel
hal
=== TEST 2: d + j
--- stream_server_config
content_by_lua_block {
for m in ngx.re.gmatch("hello, halo", "h[a-z]|h[a-z][a-z]", "dj") do
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
end
}
--- stream_response
hel
hal
=== TEST 3: fail to match
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[0-9]", "d")
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
}
--- stream_response
nil
nil
nil
=== TEST 4: gmatch matched but no iterate
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[a-z]+", "d")
ngx.say("done")
}
--- stream_response
done
=== TEST 5: gmatch matched but only iterate once and still matches remain
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[a-z]+", "d")
local m = it()
if m then
ngx.say(m[0])
else
ngx.say("not matched")
end
}
--- stream_response
hello
=== TEST 6: gmatch matched + o
--- stream_server_config
content_by_lua_block {
for m in ngx.re.gmatch("hello, world", "[a-z]+", "do") do
if m then
ngx.say(m[0])
else
ngx.say("not matched: ", m)
end
end
}
--- stream_response
hello
world
=== TEST 7: fail to match + o
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[0-9]", "do")
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
local m = it()
if m then ngx.say(m[0]) else ngx.say(m) end
}
--- stream_response
nil
nil
nil
=== TEST 8: gmatch matched but no iterate + o
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[a-z]+", "do")
ngx.say("done")
}
--- stream_response
done
=== TEST 9: gmatch matched but only iterate once and still matches remain + o
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("hello, world", "[a-z]+", "do")
local m = it()
if m then
ngx.say(m[0])
else
ngx.say("not matched")
end
}
--- stream_response
hello
=== TEST 10: bad pattern
--- stream_server_config
content_by_lua_block {
local it, err = ngx.re.gmatch("hello\\nworld", "(abc", "d")
if not it then
ngx.say("error: ", err)
return
end
ngx.say("success")
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
=== TEST 11: UTF-8 mode without UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("你好", ".", "Ud")
local m = it()
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_dfa_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 2000
--- stream_response
--- no_error_log
[error]
=== TEST 12: UTF-8 mode with UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local it = ngx.re.gmatch("你好", ".", "ud")
local m = it()
if m then
ngx.say(m[0])
else
ngx.say("not matched!")
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_dfa_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 0
--- stream_response
--- no_error_log
[error]

View file

@ -1,149 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 6);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: matched with j
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234 5678", "([0-9]+)", "world", "j")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world 5678: 1
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
=== TEST 2: not matched with j
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, world", "[0-9]+", "hiya", "j")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world: 0
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
=== TEST 3: matched with jo
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234 5678", "([0-9]+)", "world", "jo")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world 5678: 1
--- grep_error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
=== TEST 4: not matched with jo
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, world", "[0-9]+", "hiya", "jo")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world: 0
--- grep_error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
=== TEST 5: bad pattern
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("hello\\nworld", "(abc", "world", "j")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
=== TEST 6: bad pattern + o
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub( "hello\\nworld", "(abc", "world", "jo")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]

View file

@ -1,173 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 6);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: matched with d
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234 5678", "[0-9]|[0-9][0-9]", "world", "d")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world34 5678: 1
=== TEST 2: not matched with d
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, world", "[0-9]+", "hiya", "d")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world: 0
=== TEST 3: matched with do
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, 1234 5678", "[0-9]|[0-9][0-9]", "world", "do")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world34 5678: 1
=== TEST 4: not matched with do
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.sub("hello, world", "[0-9]+", "hiya", "do")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world: 0
=== TEST 5: bad pattern
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("hello\\nworld", "(abc", "world", "j")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
=== TEST 6: bad pattern + o
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("hello\\nworld", "(abc", "world", "jo")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
=== TEST 7: UTF-8 mode without UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("你好", ".", "a", "Ud")
if s then
ngx.say("s: ", s)
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_dfa_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 2000
--- stream_response
s: a好
--- no_error_log
[error]
=== TEST 8: UTF-8 mode with UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.sub("你好", ".", "a", "ud")
if s then
ngx.say("s: ", s)
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_dfa_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 0
--- stream_response
s: a好
--- no_error_log
[error]

View file

@ -1,149 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 6);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: matched with j
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, 1234 5678", "([0-9]+)", "world", "j")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world world: 2
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
=== TEST 2: not matched with j
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, world", "[0-9]+", "hiya", "j")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world: 0
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
=== TEST 3: matched with jo
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, 1234 5678", "([0-9]+)", "world", "jo")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world world: 2
--- grep_error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
=== TEST 4: not matched with jo
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, world", "[0-9]+", "hiya", "jo")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world: 0
--- grep_error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
=== TEST 5: bad pattern
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.gsub("hello\\nworld", "(abc", "world", "j")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
=== TEST 6: bad pattern + o
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.gsub("hello\\nworld", "(abc", "world", "jo")
if s then
ngx.say(s, ": ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]

View file

@ -1,174 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 5);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: matched with d
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, 1234 5678", "[0-9]|[0-9][0-9]", "world", "d")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, worldworld worldworld: 4
=== TEST 2: not matched with d
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, world", "[0-9]+", "hiya", "d")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world: 0
=== TEST 3: matched with do
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, 1234 5678", "[0-9]|[0-9][0-9]", "world", "do")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, worldworld worldworld: 4
=== TEST 4: not matched with do
--- stream_server_config
content_by_lua_block {
local s, n = ngx.re.gsub("hello, world", "[0-9]+", "hiya", "do")
if n then
ngx.say(s, ": ", n)
else
ngx.say(s)
end
}
--- stream_response
hello, world: 0
=== TEST 5: bad pattern
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.gsub("hello\\nworld", "(abc", "world", "j")
if s then
ngx.say("gsub: ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
=== TEST 6: bad pattern + o
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.gsub("hello\\nworld", "(abc", "world", "jo")
if s then
ngx.say("gsub: ", n)
else
ngx.say("error: ", err)
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
=== TEST 7: UTF-8 mode without UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.gsub("你好", ".", "a", "Ud")
if s then
ngx.say("s: ", s)
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_dfa_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 2000
exec opts: 2000
exec opts: 2000
--- stream_response
s: aa
--- no_error_log
[error]
=== TEST 8: UTF-8 mode with UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local s, n, err = ngx.re.gsub("你好", ".", "a", "ud")
if s then
ngx.say("s: ", s)
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_dfa_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 0
exec opts: 0
exec opts: 0
--- stream_response
s: aa
--- no_error_log
[error]

View file

@ -1,210 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
BEGIN {
$ENV{TEST_NGINX_POSTPONE_OUTPUT} = 1;
}
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * 12;
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: flush wait - content
--- stream_server_config
content_by_lua_block {
ngx.say("hello, world")
local ok, err = ngx.flush(true)
if not ok then
ngx.log(ngx.ERR, "flush failed: ", err)
return
end
ngx.say("hiya")
}
--- stream_response
hello, world
hiya
--- no_error_log
[error]
--- error_log
lua reuse free buf memory 13 >= 5
=== TEST 2: flush no wait - content
--- stream_server_config
lua_socket_send_timeout 500ms;
content_by_lua_block {
ngx.say("hello, world")
local ok, err = ngx.flush(false)
if not ok then
ngx.log(ngx.ERR, "flush failed: ", err)
return
end
ngx.say("hiya")
}
--- stream_response
hello, world
hiya
=== TEST 3: flush wait - big data
--- stream_server_config
content_by_lua_block {
ngx.say(string.rep("a", 1024 * 64))
ngx.flush(true)
ngx.say("hiya")
}
--- stream_response
hello, world
hiya
--- SKIP
=== TEST 4: flush wait in a user coroutine
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello, world")
ngx.flush(true)
coroutine.yield()
ngx.say("hiya")
end
local c = coroutine.create(f)
ngx.say(coroutine.resume(c))
ngx.say(coroutine.resume(c))
}
--- stap2
F(ngx_http_lua_wev_handler) {
printf("wev handler: wev:%d\n", $r->connection->write->ready)
}
global ids, cur
function gen_id(k) {
if (ids[k]) return ids[k]
ids[k] = ++cur
return cur
}
F(ngx_http_handler) {
delete ids
cur = 0
}
/*
F(ngx_http_lua_run_thread) {
id = gen_id($ctx->cur_co)
printf("run thread %d\n", id)
}
probe process("/usr/local/openresty-debug/luajit/lib/libluajit-5.1.so.2").function("lua_resume") {
id = gen_id($L)
printf("lua resume %d\n", id)
}
*/
M(http-lua-user-coroutine-resume) {
p = gen_id($arg2)
c = gen_id($arg3)
printf("resume %x in %x\n", c, p)
}
M(http-lua-entry-coroutine-yield) {
println("entry coroutine yield")
}
/*
F(ngx_http_lua_coroutine_yield) {
printf("yield %x\n", gen_id($L))
}
*/
M(http-lua-user-coroutine-yield) {
p = gen_id($arg2)
c = gen_id($arg3)
printf("yield %x in %x\n", c, p)
}
F(ngx_http_lua_atpanic) {
printf("lua atpanic(%d):", gen_id($L))
print_ubacktrace();
}
M(http-lua-user-coroutine-create) {
p = gen_id($arg2)
c = gen_id($arg3)
printf("create %x in %x\n", c, p)
}
F(ngx_http_lua_ngx_exec) { println("exec") }
F(ngx_http_lua_ngx_exit) { println("exit") }
F(ngx_http_writer) { println("http writer") }
--- stream_response
hello, world
true
hiya
true
--- error_log
lua reuse free buf memory 13 >= 5
=== TEST 5: flush before sending out the header
--- stream_server_config
content_by_lua_block {
ngx.flush()
ngx.status = 404
ngx.say("not found")
}
--- stream_response
not found
--- no_error_log
[error]
=== TEST 6: limit_rate
TODO
--- SKIP
--- stream_server_config
limit_rate 150;
content_by_lua_block {
local begin = ngx.now()
for i = 1, 2 do
ngx.print(string.rep("a", 100))
local ok, err = ngx.flush(true)
if not ok then
ngx.log(ngx.ERR, "failed to flush: ", err)
end
end
local elapsed = ngx.now() - begin
ngx.log(ngx.WARN, "lua writes elapsed ", elapsed, " sec")
}
--- stream_response eval
"a" x 200
--- error_log eval
[
qr/lua writes elapsed [12](?:\.\d+)? sec/,
qr/lua flush requires waiting: buffered 0x[0-9a-f]+, delayed:1/,
]
--- no_error_log
[error]
--- timeout: 4

View file

@ -1,313 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
BEGIN {
if (!defined $ENV{LD_PRELOAD}) {
$ENV{LD_PRELOAD} = '';
}
if ($ENV{LD_PRELOAD} !~ /\bmockeagain\.so\b/) {
$ENV{LD_PRELOAD} = "mockeagain.so $ENV{LD_PRELOAD}";
}
if ($ENV{MOCKEAGAIN} eq 'r') {
$ENV{MOCKEAGAIN} = 'rw';
} else {
$ENV{MOCKEAGAIN} = 'w';
}
$ENV{TEST_NGINX_EVENT_TYPE} = 'poll';
$ENV{MOCKEAGAIN_WRITE_TIMEOUT_PATTERN} = 'hello, world';
$ENV{TEST_NGINX_POSTPONE_OUTPUT} = 1;
}
use Test::Nginx::Socket::Lua::Stream;
use t::StapThread;
our $GCScript = $t::StapThread::GCScript;
our $StapScript = $t::StapThread::StapScript;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * 25;
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: flush wait - timeout
--- stream_server_config
lua_socket_send_timeout 100ms;
content_by_lua_block {
ngx.say("hello, world")
ngx.flush(true)
ngx.say("hiya")
}
--- stream_response
received 12 bytes of response data.
--- log_stream_response
--- error_log eval
[
qr/client timed out \(\d+: .*?timed out\)/,
qr/stream response: hello, world, client/,
]
--- no_error_log
[error]
=== TEST 2: send timeout timer got removed in time
--- stream_server_config
lua_socket_send_timeout 1234ms;
content_by_lua_block {
ngx.say(string.rep("blah blah blah", 10))
-- ngx.flush(true)
ngx.eof()
for i = 1, 20 do
ngx.sleep(0.1)
end
}
--- stap
global evtime
F(ngx_http_handler) {
delete evtime
}
M(timer-add) {
if ($arg2 == 1234) {
printf("add timer %d\n", $arg2)
evtime[$arg1] = $arg2
}
}
M(timer-del) {
time = evtime[$arg1]
if (time == 1234) {
printf("del timer %d\n", time)
}
}
M(timer-expire) {
time = evtime[$arg1]
if (time == 1234) {
printf("expire timer %d\n", time)
#print_ubacktrace()
}
}
/*
probe syscall.writev.return {
if (pid() == target()) {
printf("writev: %s\n", retstr)
}
}
*/
--- stap_out
add timer 1234
del timer 1234
--- log_stream_response
--- stream_response
received 141 bytes of response data.
--- no_error_log
[error]
--- timeout: 3
=== TEST 3: exit in user thread (entry thread is still pending on ngx.flush)
--- stream_server_config
lua_socket_send_timeout 1s;
content_by_lua_block {
function f()
ngx.say("hello in thread")
ngx.sleep(0.2)
ngx.exit(0)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
ngx.say("hello, world!")
ngx.flush(true)
ngx.say("end")
}
--- stap2 eval: $::StapScript
--- stap eval
<<'_EOC_' . $::GCScript;
global timers
F(ngx_http_free_request) {
println("free request")
}
M(timer-add) {
if ($arg2 == 200 || $arg2 == 100) {
timers[$arg1] = $arg2
printf("add timer %d\n", $arg2)
}
}
M(timer-del) {
tm = timers[$arg1]
if (tm == 200 || tm == 100) {
printf("delete timer %d\n", tm)
delete timers[$arg1]
}
}
M(timer-expire) {
tm = timers[$arg1]
if (tm == 200 || tm == 100) {
printf("expire timer %d\n", timers[$arg1])
delete timers[$arg1]
}
}
F(ngx_http_lua_coctx_cleanup) {
println("lua tcp socket cleanup")
}
/*
F(ngx_http_finalize_request) {
printf("finalize request: c:%d, a:%d, cb:%d, rb:%d\n", $r->main->count,
$r == $r->connection->data, $r->connection->buffered, $r->buffered)
}
F(ngx_http_set_write_handler) {
println("set write handler")
}
*/
F(ngx_http_lua_flush_cleanup) {
println("lua flush cleanup")
}
_EOC_
--- stap_out
create 2 in 1
spawn user thread 2 in 1
add timer 100
add timer 200
expire timer 100
terminate 2: ok
delete thread 2
lua flush cleanup
delete timer 200
delete thread 1
add timer 200
expire timer 200
free request
--- log_stream_response
--- stream_response
received 41 bytes of response data.
--- no_error_log
[error]
--- timeout: 7
=== TEST 4: flush wait - return "timeout" error
--- stream_server_config
lua_socket_send_timeout 100ms;
content_by_lua_block {
ngx.say("hello, world")
local ok, err = ngx.flush(true)
if not ok then
ngx.log(ngx.ERR, "failed to flush: ", err)
return
end
ngx.say("hiya")
}
--- log_stream_response
--- stream_response
received 12 bytes of response data.
--- error_log eval
[
qr/client timed out \(\d+: .*?timed out\)/,
'failed to flush: timeout',
]
--- no_error_log
[alert]
=== TEST 5: flush wait in multiple user threads - return "timeout" error
--- stream_server_config
lua_socket_send_timeout 100ms;
content_by_lua_block {
ngx.say("hello, world")
local function run(tag)
local ok, err = ngx.flush(true)
if not ok then
ngx.log(ngx.ERR, "thread ", tag, ": failed to flush: ", err)
return
end
ngx.say("hiya")
end
local function new_thread(tag)
local ok, err = ngx.thread.spawn(run, tag)
if not ok then
return error("failed to spawn thread: ", err)
end
end
new_thread("A")
new_thread("B")
run("main")
}
--- log_stream_response
--- stream_response
received 12 bytes of response data.
--- error_log eval
[
qr/client timed out \(\d+: .*?timed out\)/,
'thread main: failed to flush: timeout',
'thread A: failed to flush: timeout',
'thread B: failed to flush: timeout',
]
--- no_error_log
[alert]
=== TEST 6: flush wait - client abort connection prematurely
TODO
--- SKIP
--- stream_server_config
#lua_socket_send_timeout 100ms;
limit_rate 2;
content_by_lua_block {
ngx.say("hello, world")
if not ok then
ngx.log(ngx.ERR, "failed to flush: ", err)
return
end
ngx.say("hiya")
}
--- stream_response
--- error_log eval
[
qr/writev\(\) failed .*? Broken pipe/i,
qr/failed to flush: client aborted/,
]
--- no_error_log
[alert]
--- timeout: 0.2
--- abort
--- wait: 1

File diff suppressed because it is too large Load diff

View file

@ -1,123 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 1);
$ENV{TEST_NGINX_HTML_DIR} ||= html_dir();
no_long_string();
#no_shuffle();
run_tests();
__DATA__
=== TEST 1: connection refused (unix domain socket)
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("unix:/tmp/nosuchfile.sock")
ngx.say("connect: ", ok, " ", err)
local bytes
bytes, err = sock:send("hello")
ngx.say("send: ", bytes, " ", err)
local line
line, err = sock:receive()
ngx.say("receive: ", line, " ", err)
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- stream_response
connect: nil no such file or directory
send: nil closed
receive: nil closed
close: nil closed
--- error_log eval
qr{\[crit\] .*? connect\(\) to unix:/tmp/nosuchfile\.sock failed}
=== TEST 2: invalid host argument
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("/tmp/test-nginx.sock")
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
}
--- stream_response
failed to connect: failed to parse host name "/tmp/test-nginx.sock": invalid host
=== TEST 3: sanity
--- http_config
server {
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock;
default_type 'text/plain';
server_tokens off;
location /foo {
content_by_lua 'ngx.say("foo")';
more_clear_headers Date;
}
}
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock")
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
-- req = "OK"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
while true do
print("calling receive")
local line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive a line: ", err)
break
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- stream_response
connected: 1
request sent: 57
received: HTTP/1.1 200 OK
received: Server: nginx
received: Content-Type: text/plain
received: Content-Length: 4
received: Connection: close
received:
received: foo
failed to receive a line: closed
close: 1 nil

View file

@ -1,160 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3 + 1);
our $HtmlDir = html_dir;
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
my $pwd = `pwd`;
chomp $pwd;
$ENV{TEST_NGINX_PWD} ||= $pwd;
#master_on();
workers(1);
#log_level('warn');
#worker_connections(1014);
no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_config
lua_package_path '$TEST_NGINX_PWD/t/lib/?.lua;;';
--- stream_server_config
content_by_lua_block {
package.loaded["socket"] = ngx.socket
local Memcached = require "Memcached"
Memcached.socket = ngx.socket
local memc = Memcached.Connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
memc:set("some_key", "hello 1234")
local data = memc:get("some_key")
ngx.say("some_key: ", data)
}
--- stream_response
some_key: hello 1234
--- no_error_log
[error]
=== TEST 2: raw memcached
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;;';"
--- stream_server_config
content_by_lua_block {
local memcached = require "resty.memcached"
local memc, err = memcached.connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
local ok, err = memc:set("some_key", "hello 1234")
if not ok then
ngx.log(ngx.ERR, "failed to set some_key: ", err)
ngx.exit(500)
end
local data, err = memc:get("some_key")
if not data and err then
ngx.log(ngx.ERR, "failed to get some_key: ", err)
ngx.exit(500)
end
ngx.say("some_key: ", data)
local res, err = memc:set_keepalive()
if not res then
ngx.say("failed to set keepalive: ", err)
return
end
}
--- user_files
>>> resty/memcached.lua
module("resty.memcached", package.seeall)
local mt = { __index = resty.memcached }
local sub = string.sub
local escape_uri = ngx.escape_uri
local socket_connect = ngx.socket.connect
local match = string.match
function connect(...)
local sock, err = socket_connect(...)
return setmetatable({ sock = sock }, mt)
end
function get(self, key)
local cmd = "get " .. escape_uri(key) .. "\r\n"
local bytes, err = self.sock:send(cmd)
if not bytes then
return nil, err
end
local line, err = self.sock:receive()
if line == 'END' then
return nil, nil
end
local flags, len = match(line, [[^VALUE %S+ (%d+) (%d+)]])
if not flags then
return nil, "bad response: " .. line
end
print("size: ", size, ", flags: ", len)
local data, err = self.sock:receive(len)
if not data then
return nil, err
end
line, err = self.sock:receive(2) -- discard the trailing CRLF
if not line then
return nil, nil, "failed to receive CRLF: " .. (err or "")
end
line, err = self.sock:receive() -- discard "END\r\n"
if not line then
return nil, nil, "failed to receive END CRLF: " .. (err or "")
end
return data
end
function set(self, key, value, exptime, flags)
if not exptime then
exptime = 0
end
if not flags then
flags = 0
end
local cmd = table.concat({"set ", escape_uri(key), " ", flags, " ", exptime, " ", #value, "\r\n", value, "\r\n"}, "")
local bytes, err = self.sock:send(cmd)
if not bytes then
return nil, err
end
local data, err = self.sock:receive()
if sub(data, 1, 6) == "STORED" then
return true
end
return false, err
end
function set_keepalive(self)
return self.sock:setkeepalive(0, 100)
end
--- stream_response
some_key: hello 1234
--- no_error_log
[error]
--- error_log
lua reuse free buf memory

View file

@ -1,176 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
$ENV{TEST_NGINX_REDIS_PORT} ||= 6379;
#log_level "warn";
#worker_connections(1024);
#master_on();
my $pwd = `pwd`;
chomp $pwd;
$ENV{TEST_NGINX_PWD} ||= $pwd;
our $LuaCpath = $ENV{LUA_CPATH} ||
'/usr/local/openresty-debug/lualib/?.so;/usr/local/openresty/lualib/?.so;;';
no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_config
lua_package_path '$TEST_NGINX_PWD/t/lib/?.lua;;';
--- stream_server_config
content_by_lua_block {
package.loaded["socket"] = ngx.socket
local Redis = require "Redis"
local redis = Redis.connect("127.0.0.1", $TEST_NGINX_REDIS_PORT)
redis:set("some_key", "hello 1234")
local data = redis:get("some_key")
ngx.say("some_key: ", data)
}
--- stream_response
some_key: hello 1234
--- no_error_log
[error]
=== TEST 2: coroutine-based pub/sub
--- stream_config eval
qq{
lua_package_path '\$TEST_NGINX_PWD/t/lib/?.lua;;';
lua_package_cpath '$::LuaCpath';
}
--- stream_server_config
content_by_lua_block {
package.loaded["socket"] = ngx.socket
local Redis = require "Redis"
local ljson = require "ljson"
local r1 = Redis.connect("127.0.0.1", $TEST_NGINX_REDIS_PORT)
local r2 = Redis.connect("127.0.0.1", $TEST_NGINX_REDIS_PORT)
local loop = r2:pubsub({ subscribe = "foo" })
local msg, abort = loop()
ngx.say("msg type: ", type(msg))
ngx.say("abort: ", type(abort))
if msg then
ngx.say("msg: ", ljson.encode(msg))
end
for i = 1, 3 do
r1:publish("foo", "test " .. i)
msg, abort = loop()
if msg then
ngx.say("msg: ", ljson.encode(msg))
end
ngx.say("abort: ", type(abort))
end
abort()
msg, abort = loop()
ngx.say("msg type: ", type(msg))
}
--- stap2
global ids, cur
function gen_id(k) {
if (ids[k]) return ids[k]
ids[k] = ++cur
return cur
}
F(ngx_http_handler) {
delete ids
cur = 0
}
/*
probe process("/usr/local/openresty-debug/luajit/lib/libluajit-5.1.so.2").function("lua_yield") {
id = gen_id($L)
printf("raw lua yield %d\n", id)
#print_ubacktrace()
}
probe process("/usr/local/openresty-debug/luajit/lib/libluajit-5.1.so.2").function("lua_resume") {
id = gen_id($L)
printf("raw lua resume %d\n", id)
}
*/
/*
F(ngx_http_lua_run_thread) {
id = gen_id($ctx->cur_co)
printf("run thread %d\n", id)
}
*/
M(http-lua-user-coroutine-resume) {
p = gen_id($arg2)
c = gen_id($arg3)
printf("resume %x in %x\n", c, p)
}
M(http-lua-entry-coroutine-yield) {
println("entry coroutine yield")
}
F(ngx_http_lua_coroutine_yield) {
printf("yield %x\n", gen_id($L))
}
/*
F(ngx_http_lua_coroutine_resume) {
printf("resume %x\n", gen_id($L))
}
*/
M(http-lua-user-coroutine-yield) {
p = gen_id($arg2)
c = gen_id($arg3)
printf("yield %x in %x\n", c, p)
}
F(ngx_http_lua_atpanic) {
printf("lua atpanic(%d):", gen_id($L))
print_ubacktrace();
}
M(http-lua-user-coroutine-create) {
p = gen_id($arg2)
c = gen_id($arg3)
printf("create %x in %x\n", c, p)
}
F(ngx_http_lua_ngx_exec) { println("exec") }
F(ngx_http_lua_ngx_exit) { println("exit") }
--- stream_response
msg type: table
abort: function
msg: {"channel":"foo","kind":"subscribe","payload":1}
msg: {"channel":"foo","kind":"message","payload":"test 1"}
abort: function
msg: {"channel":"foo","kind":"message","payload":"test 2"}
abort: function
msg: {"channel":"foo","kind":"message","payload":"test 3"}
abort: function
msg type: nil
--- no_error_log
[error]

View file

@ -1,300 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(4);
#log_level('warn');
no_root_location();
#repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
our $HtmlDir = html_dir;
#$ENV{LUA_CPATH} = "/usr/local/openresty/lualib/?.so;" . $ENV{LUA_CPATH};
no_long_string();
run_tests();
__DATA__
=== TEST 1: entries under ngx. (content by lua)
--- stream_server_config
content_by_lua_block {
local n = 0
for k, v in pairs(ngx) do
n = n + 1
end
ngx.say("ngx: ", n)
}
--- stream_response
ngx: 53
--- no_error_log
[error]
=== TEST 2: entries under ngx.req (content by lua)
--- stream_server_config
content_by_lua_block {
local n = 0
for k, v in pairs(ngx.req) do
n = n + 1
end
-- ngx.req.socket
-- ngx.req.start_time
ngx.say("n = ", n)
}
--- stream_response
n = 2
--- no_error_log
[error]
=== TEST 3: entries under ngx.socket
--- stream_server_config
content_by_lua_block {
local n = 0
for k, v in pairs(ngx.socket) do
n = n + 1
end
ngx.say("n = ", n)
}
--- stream_response
n = 4
--- no_error_log
[error]
=== TEST 4: entries under ngx._tcp_meta
--- SKIP
--- stream_server_config
content_by_lua_block {
local n = 0
for k, v in pairs(ngx._tcp_meta) do
n = n + 1
end
ngx.say("n = ", n)
}
--- stream_response
n = 10
--- no_error_log
[error]
=== TEST 5: entries under the metatable of req sockets
--- stream_server_config
content_by_lua_block {
local n = 0
local sock, err = ngx.req.socket()
if not sock then
ngx.say("failed to get the request socket: ", err)
end
for k, v in pairs(getmetatable(sock)) do
print("key: ", k)
n = n + 1
end
assert(ngx.say("n = ", n))
}
--- stream_response
n = 9
--- no_error_log
[error]
=== TEST 6: shdict metatable
--- stream_config
lua_shared_dict dogs 1m;
--- stream_server_config
content_by_lua_block {
local dogs = ngx.shared.dogs
local mt = dogs.__index
local n = 0
for k, v in pairs(mt) do
n = n + 1
end
ngx.say("n = ", n)
}
--- stream_response
n = 22
--- no_error_log
[error]
=== TEST 7: entries under ngx.timer
--- stream_server_config
content_by_lua_block {
local n = 0
for k, v in pairs(ngx.timer) do
n = n + 1
end
ngx.say("n = ", n)
}
--- stream_response
n = 4
--- no_error_log
[error]
=== TEST 8: entries under ngx.config
--- stream_server_config
content_by_lua_block {
local n = 0
for k, v in pairs(ngx.config) do
n = n + 1
end
ngx.say("n = ", n)
}
--- stream_response
n = 6
--- no_error_log
[error]
=== TEST 9: entries under ngx.re
--- stream_server_config
content_by_lua_block {
local n = 0
for k, v in pairs(ngx.re) do
n = n + 1
end
ngx.say("n = ", n)
}
--- stream_response
n = 5
--- no_error_log
[error]
=== TEST 10: entries under coroutine. (content by lua)
--- stream_server_config
content_by_lua_block {
local n = 0
for k, v in pairs(coroutine) do
n = n + 1
end
ngx.say("coroutine: ", n)
}
--- stap2
global c
probe process("$LIBLUA_PATH").function("rehashtab") {
c++
printf("rehash: %d\n", c)
}
--- stap_out2
3
--- stream_response
coroutine: 16
--- no_error_log
[error]
=== TEST 11: entries under ngx.thread. (content by lua)
--- stream_server_config
content_by_lua_block {
local n = 0
for k, v in pairs(ngx.thread) do
n = n + 1
end
ngx.say("thread: ", n)
}
--- stap2
global c
probe process("$LIBLUA_PATH").function("rehashtab") {
c++
printf("rehash: %d\n", c)
}
--- stap_out2
--- stream_response
thread: 3
--- no_error_log
[error]
=== TEST 12: entries under ngx.worker
--- stream_server_config
content_by_lua_block {
local n = 0
for k, v in pairs(ngx.worker) do
n = n + 1
end
ngx.say("worker: ", n)
}
--- stream_response
worker: 5
--- no_error_log
[error]
=== TEST 13: entries under the metatable of tcp sockets
--- stream_server_config
content_by_lua_block {
local n = 0
local sock = ngx.socket.tcp()
for k, v in pairs(getmetatable(sock)) do
n = n + 1
end
ngx.say("n = ", n)
}
--- stream_response
n = 14
--- no_error_log
[error]
=== TEST 14: entries under the metatable of udp sockets
--- stream_server_config
content_by_lua_block {
local n = 0
local sock = ngx.socket.udp()
for k, v in pairs(getmetatable(sock)) do
n = n + 1
end
ngx.say("n = ", n)
}
--- stream_response
n = 6
--- no_error_log
[error]
=== TEST 15: entries under the metatable of req raw sockets
--- stream_server_config
content_by_lua_block {
local n = 0
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
for k, v in pairs(getmetatable(sock)) do
n = n + 1
end
local ok, err = sock:send("n = " .. n .. "\n")
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
return
end
}
--- stream_response
n = 9
--- no_error_log
[error]

View file

@ -1,98 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
worker_connections(1014);
#master_on();
#workers(4);
#log_level('warn');
no_root_location();
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
our $HtmlDir = html_dir;
#$ENV{LUA_CPATH} = "/usr/local/openresty/lualib/?.so;" . $ENV{LUA_CPATH};
no_long_string();
run_tests();
__DATA__
=== TEST 1: pcall works
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
content_by_lua_block {
function f(a, b)
if a == 0 and b == 0 then
error("zero error")
end
return 23, "hello", true
end
local res = {pcall(f, 0, 0)}
ngx.say("res len: ", #res)
ngx.say("res: ", unpack(res))
res = {pcall(f, 0)}
ngx.say("res len: ", #res)
ngx.say("res: ", unpack(res))
}
--- stream_response eval
qr/^res len: 2
res: falsecontent_by_lua\(nginx\.conf:\d+\):4: zero error
res len: 4
res: true23hellotrue
$/s
--- no_error_log
[error]
=== TEST 2: xpcall works
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
content_by_lua_block {
function f(a, b)
if a == 0 and b == 0 then
error("zero error")
end
return 23, "hello", true
end
function g()
return f(0, 0)
end
function h()
return f(0)
end
function err(...)
ngx.say("error handler called: ", ...)
return "this is the new err"
end
local res = {xpcall(g, err)}
ngx.say("res len: ", #res)
ngx.say("res: ", unpack(res))
res = {xpcall(h, err)}
ngx.say("res len: ", #res)
ngx.say("res: ", unpack(res))
}
--- stream_response eval
qr/^error handler called: content_by_lua\(nginx\.conf:\d+\):4: zero error
res len: 2
res: falsethis is the new err
res len: 4
res: true23hellotrue
$/
--- no_error_log
[error]

View file

@ -1,872 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
BEGIN {
if (!defined $ENV{LD_PRELOAD}) {
$ENV{LD_PRELOAD} = '';
}
if ($ENV{LD_PRELOAD} !~ /\bmockeagain\.so\b/) {
$ENV{LD_PRELOAD} = "mockeagain.so $ENV{LD_PRELOAD}";
}
if ($ENV{MOCKEAGAIN} eq 'r') {
$ENV{MOCKEAGAIN} = 'rw';
} else {
$ENV{MOCKEAGAIN} = 'w';
}
$ENV{TEST_NGINX_EVENT_TYPE} = 'poll';
$ENV{MOCKEAGAIN_WRITE_TIMEOUT_PATTERN} = 'get helloworld';
}
use Test::Nginx::Socket::Lua::Stream;
use t::StapThread;
our $GCScript = $t::StapThread::GCScript;
our $StapScript = $t::StapThread::StapScript;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4 + 9);
our $HtmlDir = html_dir;
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
log_level("debug");
no_long_string();
#no_diff();
run_tests();
__DATA__
=== TEST 1: lua_socket_connect_timeout only
--- stream_server_config
lua_socket_connect_timeout 100ms;
resolver $TEST_NGINX_RESOLVER ipv6=off;
resolver_timeout 3s;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.2", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
}
--- stream_response
failed to connect: timeout
--- error_log
lua tcp socket connect timeout: 100
stream lua tcp socket connect timed out, when connecting to 127.0.0.2:12345
--- timeout: 10
=== TEST 2: sock:settimeout() overrides lua_socket_connect_timeout
--- stream_server_config
lua_socket_connect_timeout 60s;
resolver $TEST_NGINX_RESOLVER ipv6=off;
resolver_timeout 3s;
content_by_lua_block {
local sock = ngx.socket.tcp()
sock:settimeout(150)
local ok, err = sock:connect("127.0.0.2", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
}
--- stream_response
failed to connect: timeout
--- error_log
lua tcp socket connect timeout: 150
stream lua tcp socket connect timed out, when connecting to 127.0.0.2:12345
--- timeout: 10
=== TEST 3: sock:settimeout(nil) does not override lua_socket_connect_timeout
--- stream_server_config
lua_socket_connect_timeout 102ms;
resolver $TEST_NGINX_RESOLVER ipv6=off;
content_by_lua_block {
local sock = ngx.socket.tcp()
sock:settimeout(nil)
local ok, err = sock:connect("127.0.0.2", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
}
--- stream_response
failed to connect: timeout
--- error_log
lua tcp socket connect timeout: 102
stream lua tcp socket connect timed out, when connecting to 127.0.0.2:12345
=== TEST 4: sock:settimeout(0) does not override lua_socket_connect_timeout
--- stream_server_config
lua_socket_connect_timeout 102ms;
resolver $TEST_NGINX_RESOLVER ipv6=off;
resolver_timeout 3s;
content_by_lua_block {
local sock = ngx.socket.tcp()
sock:settimeout(0)
local ok, err = sock:connect("127.0.0.2", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
}
--- stream_response
failed to connect: timeout
--- error_log
lua tcp socket connect timeout: 102
stream lua tcp socket connect timed out, when connecting to 127.0.0.2:12345
--- timeout: 10
=== TEST 5: -1 is bad timeout value
--- stream_server_config
lua_socket_connect_timeout 102ms;
resolver $TEST_NGINX_RESOLVER ipv6=off;
content_by_lua_block {
local sock = ngx.socket.tcp()
sock:settimeout(-1)
local ok, err = sock:connect("127.0.0.2", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
}
--- error_log
bad timeout value
finalize stream request: 500
=== TEST 6: lua_socket_read_timeout only
--- stream_server_config
lua_socket_read_timeout 100ms;
resolver $TEST_NGINX_RESOLVER ipv6=off;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local line
line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
}
--- stream_response
connected: 1
failed to receive: timeout
--- error_log
lua tcp socket read timeout: 100
lua tcp socket connect timeout: 60000
lua tcp socket read timed out
=== TEST 7: sock:settimeout() overrides lua_socket_read_timeout
--- stream_server_config
lua_socket_read_timeout 60s;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(150)
local line
line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
}
--- stream_response
connected: 1
failed to receive: timeout
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket read timeout: 150
lua tcp socket read timed out
=== TEST 8: sock:settimeout(nil) does not override lua_socket_read_timeout
--- stream_server_config
lua_socket_read_timeout 102ms;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(nil)
local line
line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
}
--- stream_response
connected: 1
failed to receive: timeout
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket read timeout: 102
lua tcp socket read timed out
=== TEST 9: sock:settimeout(0) does not override lua_socket_read_timeout
--- stream_server_config
lua_socket_read_timeout 102ms;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(0)
local line
line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
}
--- stream_response
connected: 1
failed to receive: timeout
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket read timeout: 102
lua tcp socket read timed out
=== TEST 10: -1 is bad timeout value
--- stream_server_config
lua_socket_read_timeout 102ms;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(-1)
local line
line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
}
--- error_log
bad timeout value
finalize stream request: 500
=== TEST 11: lua_socket_send_timeout only
--- stream_server_config
lua_socket_send_timeout 100ms;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local bytes
bytes, err = sock:send("get helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
end
}
--- stap2
global active = 0
F(ngx_http_lua_socket_send) {
active = 1
println(probefunc())
}
probe syscall.send,
syscall.sendto,
syscall.writev
{
if (active && pid() == target()) {
println(probefunc())
}
}
--- stream_response
connected: 1
failed to send: timeout
--- error_log
lua tcp socket send timeout: 100
lua tcp socket connect timeout: 60000
lua tcp socket write timed out
=== TEST 12: sock:settimeout() overrides lua_socket_send_timeout
--- stream_server_config
lua_socket_send_timeout 60s;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(150)
local bytes
bytes, err = sock:send("get helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
end
}
--- stream_response
connected: 1
failed to send: timeout
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket send timeout: 150
lua tcp socket write timed out
=== TEST 13: sock:settimeout(nil) does not override lua_socket_send_timeout
--- stream_server_config
lua_socket_send_timeout 102ms;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(nil)
local bytes
bytes, err = sock:send("get helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
end
}
--- stream_response
connected: 1
failed to send: timeout
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket send timeout: 102
lua tcp socket write timed out
=== TEST 14: sock:settimeout(0) does not override lua_socket_send_timeout
--- stream_server_config
lua_socket_send_timeout 102ms;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(0)
local bytes
bytes, err = sock:send("get helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
end
}
--- stream_response
connected: 1
failed to send: timeout
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket send timeout: 102
lua tcp socket write timed out
=== TEST 15: sock:settimeout(-1) does not override lua_socket_send_timeout
--- stream_server_config
lua_socket_send_timeout 102ms;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(-1)
local bytes
bytes, err = sock:send("get helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
end
}
--- error_log
bad timeout value
finalize stream request: 500
=== TEST 16: exit in user thread (entry thread is still pending on tcpsock:send)
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello in thread")
ngx.sleep(0.1)
ngx.exit(0)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
sock:settimeout(12000)
local bytes, ok = sock:send("get helloworld!")
if not bytes then
ngx.say("failed to send: ", err)
return
end
ngx.say("end")
}
--- stap2 eval: $::StapScript
--- stap eval
<<'_EOC_' . $::GCScript;
global timers
F(ngx_http_free_request) {
println("free request")
}
M(timer-add) {
if ($arg2 == 12000 || $arg2 == 100) {
timers[$arg1] = $arg2
printf("add timer %d\n", $arg2)
}
}
M(timer-del) {
tm = timers[$arg1]
if (tm == 12000 || tm == 100) {
printf("delete timer %d\n", tm)
delete timers[$arg1]
}
}
M(timer-expire) {
tm = timers[$arg1]
if (tm == 12000 || tm == 100) {
printf("expire timer %d\n", timers[$arg1])
delete timers[$arg1]
}
}
F(ngx_http_lua_coctx_cleanup) {
println("lua tcp socket cleanup")
}
_EOC_
--- stap_out
create 2 in 1
spawn user thread 2 in 1
add timer 100
add timer 12000
expire timer 100
terminate 2: ok
delete thread 2
lua tcp socket cleanup
delete timer 12000
delete thread 1
free request
--- stream_response
before
hello in thread
after
--- no_error_log
[error]
=== TEST 17: re-connect after timed out
--- stream_server_config
lua_socket_connect_timeout 100ms;
resolver $TEST_NGINX_RESOLVER ipv6=off;
resolver_timeout 3s;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.2", 12345)
if not ok then
ngx.say("1: failed to connect: ", err)
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_SERVER_PORT)
if not ok then
ngx.say("2: failed to connect: ", err)
return
end
ngx.say("2: connected: ", ok)
return
end
ngx.say("1: connected: ", ok)
}
--- stream_response
1: failed to connect: timeout
2: connected: 1
--- error_log
lua tcp socket connect timeout: 100
stream lua tcp socket connect timed out, when connecting to 127.0.0.2:12345
--- timeout: 10
=== TEST 18: re-send on the same object after a send timeout happens
--- stream_server_config
#lua_socket_send_timeout 100ms;
resolver $TEST_NGINX_RESOLVER ipv6=off;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(100)
local bytes
bytes, err = sock:send("get helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
bytes, err = sock:send("blah")
if not bytes then
ngx.say("failed to send again: ", err)
end
end
}
--- stap2
global active = 0
F(ngx_http_lua_socket_send) {
active = 1
println(probefunc())
}
probe syscall.send,
syscall.sendto,
syscall.writev
{
if (active && pid() == target()) {
println(probefunc())
}
}
--- stream_response
connected: 1
failed to send: timeout
failed to send again: closed
--- error_log
lua tcp socket send timeout: 100
lua tcp socket connect timeout: 60000
lua tcp socket write timed out
=== TEST 19: abort when upstream sockets pending on writes
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(100)
ngx.thread.spawn(function () ngx.sleep(0.001) ngx.say("done") ngx.exit(200) end)
local bytes
bytes, err = sock:send("get helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
end
}
--- stap2
global active = 0
F(ngx_http_lua_socket_send) {
active = 1
println(probefunc())
}
probe syscall.send,
syscall.sendto,
syscall.writev
{
if (active && pid() == target()) {
println(probefunc())
}
}
--- stream_response
connected: 1
done
--- error_log
lua tcp socket send timeout: 100
lua tcp socket connect timeout: 60000
--- no_error_log
lua tcp socket write timed out
=== TEST 20: abort when downstream socket pending on writes
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
#lua_lingering_timeout 10ms;
content_by_lua_block {
ngx.flush(true)
local sock, err = ngx.req.socket(true)
if not sock then
ngx.say("failed to acquire the req socket: ", err)
return
end
sock:settimeout(100)
ngx.thread.spawn(function ()
ngx.sleep(0.001)
ngx.log(ngx.WARN, "quitting request now")
ngx.exit(200)
end)
local bytes
bytes, err = sock:send("e\r\nget helloworld!")
if bytes then
ngx.say("sent: ", bytes)
else
ngx.say("failed to send: ", err)
end
}
--- stap2
global active = 0
F(ngx_http_lua_socket_send) {
active = 1
println(probefunc())
}
probe syscall.send,
syscall.sendto,
syscall.writev
{
if (active && pid() == target()) {
println(probefunc())
}
}
--- stream_response_like chomp
^received [1-9]\d* bytes of response data\.$
--- log_stream_response
--- error_log
stream lua tcp socket send timeout: 100
quitting request now
--- no_error_log
lua tcp socket write timed out
[alert]
=== TEST 21: read timeout on receive(N)
--- stream_server_config
lua_socket_read_timeout 100ms;
resolver $TEST_NGINX_RESOLVER ipv6=off;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
sock:settimeout(10)
local line
line, err = sock:receive(3)
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
}
--- stream_response
connected: 1
failed to receive: timeout
--- error_log
lua tcp socket read timeout: 10
lua tcp socket connect timeout: 60000
lua tcp socket read timed out
=== TEST 22: concurrent operations while writing
--- stream_server_config
lua_socket_log_errors off;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ready = false
local function f()
while not ready do
ngx.sleep(0.001)
end
local bytes, err = sock:send("flush_all")
ngx.say("send: ", bytes, " ", err)
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
local ok, err = sock:getreusedtimes()
ngx.say("getreusedtimes: ", ok, " ", err)
local ok, err = sock:setkeepalive()
ngx.say("setkeepalive: ", ok, " ", err)
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
ngx.say("connect: ", ok, " ", err)
sock:settimeout(1)
local res, err = sock:receive(1)
ngx.say("receive: ", res, " ", err)
end
local ok, err = ngx.thread.spawn(f)
if not ok then
ngx.say("failed to spawn writer thread: ", err)
return
end
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
ngx.say("connect: ", ok, " ", err)
ready = true
sock:settimeout(300)
local bytes, err = sock:send("get helloworld!")
if not bytes then
ngx.say("send failed: ", err)
end
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- stream_response
connect: 1 nil
send: nil socket busy writing
close: nil socket busy writing
getreusedtimes: 0 nil
setkeepalive: nil socket busy writing
connect: nil socket busy writing
receive: nil timeout
send failed: timeout
close: 1 nil
--- no_error_log
[error]

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -1,79 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
#master_on();
#workers(1);
#log_level('debug');
#log_level('warn');
#worker_connections(1024);
plan tests => repeat_each() * (blocks() * 3 + 1);
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_MYSQL_PORT} ||= 3306;
our $LuaCpath = $ENV{LUA_CPATH} ||
'/usr/local/openresty-debug/lualib/?.so;/usr/local/openresty/lualib/?.so;;';
no_long_string();
run_tests();
__DATA__
=== TEST 1: compare ngx.null with cjson.null
--- stream_config eval
"lua_package_cpath '$::LuaCpath';";
--- stream_server_config
content_by_lua_block {
local cjson = require "cjson"
ngx.say(cjson.null == ngx.null)
ngx.say(cjson.encode(ngx.null))
}
--- stream_response
true
null
--- no_error_log
[error]
=== TEST 2: output ngx.null
--- stream_server_config
content_by_lua_block {
ngx.say("ngx.null: ", ngx.null)
}
--- stream_response
ngx.null: null
--- no_error_log
[error]
=== TEST 3: output ngx.null in a table
--- stream_server_config
content_by_lua_block {
ngx.say({"ngx.null: ", ngx.null})
}
--- stream_response
ngx.null: null
--- no_error_log
[error]
=== TEST 4: log ngx.null
--- stream_server_config
content_by_lua_block {
print("ngx.null: ", ngx.null)
ngx.say("done")
}
--- stream_response
done
--- error_log
ngx.null: null
--- no_error_log
[error]

View file

@ -1,48 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_process_enabled(1);
log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 1);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: set sha1 hello
--- stream_server_config
content_by_lua_block { ngx.say(ngx.encode_base64(ngx.sha1_bin("hello"))) }
--- stream_response
qvTGHdzF6KLavt4PO0gs2a6pQ00=
=== TEST 2: set sha1 ""
--- stream_server_config
content_by_lua_block { ngx.say(ngx.encode_base64(ngx.sha1_bin(""))) }
--- stream_response
2jmj7l5rSw0yVb/vlWAYkK/YBwk=
=== TEST 3: set sha1 nil
--- stream_server_config
content_by_lua_block { ngx.say(ngx.encode_base64(ngx.sha1_bin(nil))) }
--- stream_response
2jmj7l5rSw0yVb/vlWAYkK/YBwk=
=== TEST 4: set sha1 number
--- stream_server_config
content_by_lua_block { ngx.say(ngx.encode_base64(ngx.sha1_bin(512))) }
--- stream_response
zgmxJ9SPg4aKRWReJG07UvS97L4=
--- no_error_log
[error]

View file

@ -1,354 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
our $HtmlDir = html_dir;
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
no_long_string();
#no_diff();
#log_level 'warn';
run_tests();
__DATA__
=== TEST 1: read events come when socket is idle
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local reader = sock:receiveuntil("foofoo\r\n")
local line, err, part = reader()
if line then
ngx.print("read: ", line)
else
ngx.say("failed to read a line: ", err, " [", part, "]")
end
ngx.sleep(0.5)
local data, err, part = sock:receive("*a")
if not data then
ngx.say("failed to read the 2nd part: ", err)
else
ngx.say("2nd part: [", data, "]")
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
location = /foo {
echo -n foofoo;
echo_flush;
echo_sleep 0.3;
echo -n barbar;
more_clear_headers Date;
}
--- stream_response eval
qq{connected: 1
request sent: 57
read: HTTP/1.1 200 OK\r
Server: nginx\r
Content-Type: text/plain\r
Transfer-Encoding: chunked\r
Connection: close\r
\r
6\r
2nd part: [6\r
barbar\r
0\r
\r
]
close: 1 nil
}
--- no_error_log
[error]
=== TEST 2: read timer cleared in time
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_MEMCACHED_PORT
sock:settimeout(400)
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "flush_all\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local line, err, part = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive a line: ", err, " [", part, "]")
end
ngx.sleep(0.5)
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent again: ", bytes)
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- stream_response
connected: 1
request sent: 11
received: OK
request sent again: 11
close: 1 nil
--- no_error_log
[error]
=== TEST 3: connect timer cleared in time
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_MEMCACHED_PORT
sock:settimeout(300)
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
ngx.sleep(0.5)
local req = "flush_all\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- stream_response
connected: 1
request sent: 11
close: 1 nil
--- no_error_log
[error]
=== TEST 4: send timer cleared in time
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_MEMCACHED_PORT
sock:settimeout(300)
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "flush_all\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
ngx.sleep(0.5)
local line, err, part = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive a line: ", err, " [", part, "]")
return
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- stream_response
connected: 1
request sent: 11
received: OK
close: 1 nil
--- no_error_log
[error]
=== TEST 5: set keepalive when system socket recv buffer has unread data
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local reader = sock:receiveuntil("foofoo\r\n")
local line, err, part = reader()
if line then
ngx.print("read: ", line)
else
ngx.say("failed to read a line: ", err, " [", part, "]")
end
ngx.sleep(0.5)
local ok, err = sock:setkeepalive()
if not ok then
ngx.say("failed to set keepalive: ", err)
end
}
--- config
server_tokens off;
location = /foo {
echo -n foofoo;
echo_flush;
echo_sleep 0.3;
echo -n barbar;
more_clear_headers Date;
}
--- stream_response_like eval
qr{connected: 1
request sent: 57
read: HTTP/1\.1 200 OK\r
Server: nginx\r
Content-Type: text/plain\r
Transfer-Encoding: chunked\r
Connection: close\r
\r
6\r
failed to set keepalive: (?:unread data in buffer|connection in dubious state)
}
--- no_error_log
[error]
=== TEST 6: set keepalive when cosocket recv buffer has unread data
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_MEMCACHED_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "flush_all\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local data, err = sock:receive(1)
if not data then
ngx.say("failed to read the 1st byte: ", err)
return
end
ngx.say("read: ", data)
local ok, err = sock:setkeepalive()
if not ok then
ngx.say("failed to set keepalive: ", err)
end
}
--- stream_response eval
qq{connected: 1
request sent: 11
read: O
failed to set keepalive: unread data in buffer
}
--- no_error_log
[error]

View file

@ -1,173 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
#repeat_each(1);
plan tests => repeat_each() * 59;
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_server_config
content_by_lua_block
{ function bar()
return lua_concat(3)
end
function foo()
bar()
end
foo()
}
--- stream_response
--- error_log
attempt to call global 'lua_concat'
: in function 'bar'
:5: in function 'foo'
:7: in main chunk
=== TEST 2: error(nil)
--- stream_server_config
content_by_lua_block
{ function bar()
error(nil)
end
function foo()
bar()
end
foo()
}
--- stream_response
--- error_log eval
[
'lua entry thread aborted: runtime error: unknown reason',
'stack traceback:',
" in function 'error'",
": in function 'bar'",
":5: in function 'foo'",
qr/:7: in main chunk/,
]
=== TEST 3: deep backtrace in a single coroutine (more than 15)
--- stream_server_config eval
my $s = "
content_by_lua_block {
";
my $prev;
for my $i (1..18) {
if (!defined $prev) {
$s .= "
local function func$i()
return error([[blah]])
end";
} else {
$s .= "
local function func$i()
local v = func$prev()
return v
end";
}
$prev = $i;
}
$s .= "
func$prev()
}
";
--- stap2
probe process("$LIBLUA_PATH").function("lua_concat") {
println("lua concat")
//print_ubacktrace()
}
--- stap_out2
--- stream_response
--- error_log
: blah
: in function 'func1'
:7: in function 'func2'
:11: in function 'func3'
:15: in function 'func4'
:19: in function 'func5'
:23: in function 'func6'
:27: in function 'func7'
:31: in function 'func8'
:35: in function 'func9'
:39: in function 'func10'
:43: in function 'func11'
:47: in function 'func12'
:51: in function 'func13'
:55: in function 'func14'
:59: in function 'func15'
:63: in function 'func16'
:67: in function 'func17'
:71: in function 'func18'
:74: in main chunk
=== TEST 4: deep backtrace in a single coroutine (more than 22)
--- stream_server_config eval
my $s = "
content_by_lua_block {
";
my $prev;
for my $i (1..23) {
if (!defined $prev) {
$s .= "
local function func$i()
return error([[blah]])
end";
} else {
$s .= "
local function func$i()
local v = func$prev()
return v
end";
}
$prev = $i;
}
$s .= "
func$prev()
}
";
--- stap2
probe process("$LIBLUA_PATH").function("lua_concat") {
println("lua concat")
//print_ubacktrace()
}
--- stap_out2
--- stream_response
--- error_log
: blah
: in function 'func1'
:7: in function 'func2'
:11: in function 'func3'
:15: in function 'func4'
:19: in function 'func5'
:23: in function 'func6'
:27: in function 'func7'
:31: in function 'func8'
:35: in function 'func9'
:39: in function 'func10'
:43: in function 'func11'
:47: in function 'func12'
:59: in function 'func15'
:63: in function 'func16'
:67: in function 'func17'
:71: in function 'func18'
:75: in function 'func19'
:79: in function 'func20'
:83: in function 'func21'
...

View file

@ -1,58 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
#repeat_each(1);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: $prefix
--- stream_config: lua_package_path "$prefix/html/?.lua;;";
--- stream_server_config
content_by_lua_block {
local foo = require "foo"
foo.go()
}
--- user_files
>>> foo.lua
module("foo", package.seeall)
function go()
ngx.say("Greetings from module foo.")
end
--- stream_response
Greetings from module foo.
--- no_error_log
[error]
=== TEST 2: ${prefix}
--- stream_config: lua_package_path "${prefix}html/?.lua;;";
--- stream_server_config
content_by_lua_block {
local foo = require "foo"
foo.go()
}
--- user_files
>>> foo.lua
module("foo", package.seeall)
function go()
ngx.say("Greetings from module foo.")
end
--- stream_response
Greetings from module foo.
--- no_error_log
[error]

View file

@ -1,379 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
log_level('debug');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3 + 8);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: log_by_lua
--- stream_server_config
content_by_lua_block {
ngx.say('hello')
}
log_by_lua_block { ngx.log(ngx.ERR, "Hello from log_by_lua: ", ngx.var.protocol) }
--- stream_response
hello
--- error_log
Hello from log_by_lua: TCP
=== TEST 2: log_by_lua_file
--- stream_server_config
content_by_lua_block {
ngx.say('hello')
}
log_by_lua_file html/a.lua;
--- user_files
>>> a.lua
ngx.log(ngx.ERR, "Hello from log_by_lua: ", ngx.var.protocol)
--- stream_response
hello
--- error_log
Hello from log_by_lua: TCP
=== TEST 3: log_by_lua_file & content_by_lua
--- stream_server_config
content_by_lua_block { ngx.say(ngx.var.remote_addr) }
log_by_lua_file html/a.lua;
--- user_files
>>> a.lua
ngx.log(ngx.ERR, "Hello from log_by_lua: ", ngx.var.status)
--- stream_response
127.0.0.1
--- error_log
Hello from log_by_lua: 200
=== TEST 4: ngx.ctx available in log_by_lua (already defined)
--- stream_server_config
content_by_lua_block { ngx.ctx.counter = 3 ngx.say(ngx.ctx.counter) }
log_by_lua_block { ngx.log(ngx.ERR, "ngx.ctx.counter: ", ngx.ctx.counter) }
--- stream_response
3
--- error_log
ngx.ctx.counter: 3
lua release ngx.ctx
=== TEST 5: ngx.ctx available in log_by_lua (not defined yet)
--- stream_server_config
content_by_lua_block {
ngx.say('hello')
}
log_by_lua_block {
ngx.log(ngx.ERR, "ngx.ctx.counter: ", ngx.ctx.counter)
ngx.ctx.counter = "hello world"
}
--- stream_response
hello
--- error_log
ngx.ctx.counter: nil
lua release ngx.ctx
=== TEST 6: log_by_lua + shared dict
--- stream_config
lua_shared_dict foo 100k;
--- stream_server_config
content_by_lua_block {
ngx.say('hello')
}
log_by_lua_block {
local foo = ngx.shared.foo
local key = ngx.var.remote_addr .. ngx.status
local newval, err = foo:incr(key, 1)
if not newval then
if err == "not found" then
foo:add(key, 0)
newval, err = foo:incr(key, 1)
if not newval then
ngx.log(ngx.ERR, "failed to incr ", key, ": ", err)
return
end
else
ngx.log(ngx.ERR, "failed to incr ", key, ": ", err)
return
end
end
print(key, ": ", foo:get(key))
}
--- stream_response
hello
--- error_log eval
qr{127.0.0.1200: [12]}
--- no_error_log
[error]
=== TEST 7: lua error (string)
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_block { error("Bad") }
--- stream_response
ok
--- error_log eval
qr/failed to run log_by_lua\*: log_by_lua\(nginx\.conf:\d+\):1: Bad/
=== TEST 8: lua error (nil)
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_block { error(nil) }
--- stream_response
ok
--- error_log
failed to run log_by_lua*: unknown reason
=== TEST 9: globals shared
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_block {
if not foo then
foo = 1
else
ngx.log(ngx.INFO, "old foo: ", foo)
foo = foo + 1
end
}
--- stream_response
ok
--- grep_error_log eval: qr/old foo: \d+/
--- grep_error_log_out eval
["", "old foo: 1\n"]
=== TEST 10: no ngx.print
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_block { ngx.print(32) return 1 }
--- stream_response
ok
--- error_log
API disabled in the context of log_by_lua*
=== TEST 11: no ngx.say
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_block { ngx.say(32) return 1 }
--- stream_response
ok
--- error_log
API disabled in the context of log_by_lua*
=== TEST 12: no ngx.flush
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_block { ngx.flush() }
--- stream_response
ok
--- error_log
API disabled in the context of log_by_lua*
=== TEST 13: no ngx.eof
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_block { ngx.eof() }
--- stream_response
ok
--- error_log
API disabled in the context of log_by_lua*
=== TEST 14: no ngx.exit
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_block { ngx.exit(0) }
--- stream_response
ok
--- error_log
API disabled in the context of log_by_lua*
=== TEST 15: no ngx.req.socket()
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_block { return ngx.req.socket() }
--- stream_response
ok
--- error_log
API disabled in the context of log_by_lua*
=== TEST 16: no ngx.socket.tcp()
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_block { return ngx.socket.tcp() }
--- stream_response
ok
--- error_log
API disabled in the context of log_by_lua*
=== TEST 17: no ngx.socket.connect()
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_block { return ngx.socket.connect("127.0.0.1", 80) }
--- stream_response
ok
--- error_log
API disabled in the context of log_by_lua*
=== TEST 18: backtrace
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_block {
function foo()
bar()
end
function bar()
error("something bad happened")
end
foo()
}
--- stream_response
ok
--- error_log
something bad happened
stack traceback:
in function 'error'
in function 'bar'
in function 'foo'
=== TEST 19: Lua file does not exist
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
log_by_lua_file html/test2.lua;
--- user_files
>>> test.lua
v = ngx.var["request_uri"]
ngx.print("request_uri: ", v, "\n")
--- stream_response
ok
--- error_log eval
qr/failed to load external Lua file ".*?test2\.lua": cannot open .*? No such file or directory/
=== TEST 20: log_by_lua runs before access logging (github issue #254)
--- stream_config
log_format basic '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
access_log logs/foo.log basic;
log_by_lua_block { print("hello") }
--- stap
F(ngx_http_log_handler) {
println("log handler")
}
F(ngx_http_lua_log_handler) {
println("lua log handler")
}
--- stap_out
lua log handler
log handler
--- stream_response
ok
--- no_error_log
[error]
=== TEST 21: log_by_lua in stream level
--- stream_config
log_by_lua_block { ngx.log(ngx.ERR, "Hello from log_by_lua stream level: ", ngx.var.protocol) }
--- stream_server_config
content_by_lua_block {
ngx.say('hello')
}
--- stream_response
hello
--- error_log
Hello from log_by_lua stream level: TCP

View file

@ -1,207 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
log_level('debug');
repeat_each(2);
plan tests => repeat_each() * 39;
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: sleep 0.5 - content
--- stream_server_config
content_by_lua_block {
ngx.update_time()
local before = ngx.now()
ngx.sleep(0.5)
local now = ngx.now()
ngx.say(now - before)
}
--- stream_response_like chop
^0\.(?:4[5-9]\d*|5[0-5]\d*|5)$
--- error_log
lua ready to sleep for
stream lua sleep timer expired
=== TEST 2: sleep a - content
--- stream_server_config
content_by_lua_block {
ngx.update_time()
local before = ngx.now()
ngx.sleep("a")
local now = ngx.now()
ngx.say(now - before)
}
--- stream_response
--- error_log
bad argument #1 to 'sleep'
=== TEST 3: sleep 0.33 - multi-times in content
--- stream_server_config
content_by_lua_block {
ngx.update_time()
local start = ngx.now()
ngx.sleep(0.33)
ngx.sleep(0.33)
ngx.sleep(0.33)
ngx.say(ngx.now() - start)
}
--- stream_response_like chop
^(?:0\.9\d*|1\.[0-2]\d*|1)$
--- error_log
lua ready to sleep for
stream lua sleep timer expired
--- no_error_log
[error]
=== TEST 4: sleep 0.5 - interleaved by ngx.say() - ended by ngx.sleep
--- stream_server_config
content_by_lua_block {
ngx.sleep(1)
ngx.say("blah")
ngx.sleep(1)
}
--- stream_response
blah
--- error_log
lua ready to sleep
stream lua sleep timer expired
--- no_error_log
[error]
=== TEST 5: sleep 0.5 - interleaved by ngx.say() - not ended by ngx.sleep
--- stream_server_config
content_by_lua_block {
ngx.sleep(0.3)
ngx.say("blah")
ngx.sleep(0.5)
ngx.say("hiya")
}
--- stream_response
blah
hiya
--- error_log
lua ready to sleep for
stream lua sleep timer expired
--- no_error_log
[error]
=== TEST 6: sleep 0
--- stream_server_config
content_by_lua_block {
ngx.update_time()
local before = ngx.now()
ngx.sleep(0)
local now = ngx.now()
ngx.say("elapsed: ", now - before)
}
--- stream_response_like chop
elapsed: 0
--- error_log
lua ready to sleep for
stream lua sleep timer expired
--- no_error_log
[error]
=== TEST 7: ngx.sleep unavailable in log_by_lua
TODO
--- SKIP
--- stream_server_config
echo hello;
log_by_lua_block {
ngx.sleep(0.1)
}
--- stream_response
hello
--- wait: 0.1
--- error_log
API disabled in the context of log_by_lua*
=== TEST 8: ngx.sleep() fails to yield (xpcall err handler)
--- stream_server_config
content_by_lua_block {
local function f()
return error(1)
end
local function err()
ngx.sleep(0.001)
end
xpcall(f, err)
ngx.say("ok")
}
--- stream_response
ok
--- error_log
lua clean up the timer for pending ngx.sleep
--- no_error_log
[error]
=== TEST 9: ngx.sleep() fails to yield (require)
--- stream_config
lua_package_path "$prefix/html/?.lua;;";
--- stream_server_config
content_by_lua_block {
package.loaded["foosleep"] = nil
require "foosleep";
}
--- user_files
>>> foosleep.lua
ngx.sleep(0.001)
--- stream_response
--- wait: 0.2
--- error_log eval
[
"lua clean up the timer for pending ngx.sleep",
qr{runtime error: attempt to yield across (?:metamethod/)?C-call boundary},
]
=== TEST 10: sleep coctx handler did not get called in ngx.exit().
--- stream_server_config
content_by_lua_block {
local function sleep(t)
--- nginx return reply to client without waiting
ngx.sleep(t)
end
local function wait()
--- worker would crash afterwards
xpcall(function () error(1) end, function() return sleep(0.001) end)
--- ngx.exit was required to crash worker
ngx.exit(200)
end
wait()
}
--- wait: 0.1
--- stream_response
--- no_error_log
[error]
[alert]

View file

@ -1,75 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
our $SkipReason;
BEGIN {
if ($ENV{TEST_NGINX_CHECK_LEAK}) {
$SkipReason = "unavailable for the hup tests";
} else {
$ENV{TEST_NGINX_USE_HUP} = 1;
undef $ENV{TEST_NGINX_USE_STAP};
}
}
use Test::Nginx::Socket::Lua::Stream $SkipReason ? (skip_all => $SkipReason) : ();
#worker_connections(1014);
#master_process_enabled(1);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
no_long_string();
#master_on();
#workers(2);
no_shuffle();
run_tests();
__DATA__
=== TEST 1: initialize the fields in shdict
--- stream_config
lua_shared_dict dogs 1m;
--- stream_server_config
content_by_lua_block {
local dogs = ngx.shared.dogs
dogs:set("foo", 32)
dogs:set("bah", 10502)
local val = dogs:get("foo")
ngx.say(val, " ", type(val))
val = dogs:get("bah")
ngx.say(val, " ", type(val))
}
--- stream_response
32 number
10502 number
--- no_error_log
[error]
=== TEST 2: retrieve the fields in shdict after HUP reload
--- stream_config
lua_shared_dict dogs 1m;
--- stream_server_config
content_by_lua_block {
local dogs = ngx.shared.dogs
-- dogs:set("foo", 32)
-- dogs:set("bah", 10502)
local val = dogs:get("foo")
ngx.say(val, " ", type(val))
val = dogs:get("bah")
ngx.say(val, " ", type(val))
}
--- stream_response
32 number
10502 number
--- no_error_log
[error]

View file

@ -1,51 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
#repeat_each(1);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: bytecode (not stripped)
--- stream_server_config
content_by_lua_block {
local f = assert(loadstring("local a = a and a + 1 or 1 ngx.say('a = ', a)", "=code"))
local bc = string.dump(f)
local f = assert(io.open("$TEST_NGINX_SERVER_ROOT/html/a.luac", "w"))
f:write(bc)
f:close()
}
--- stream_server_config2
content_by_lua_file html/a.luac;
--- stream_response
a = 1
--- no_error_log
[error]
=== TEST 2: bytecode (stripped)
--- stream_server_config
content_by_lua_block {
local f = assert(loadstring("local a = a and a + 1 or 1 ngx.say('a = ', a)", "=code"))
local bc = string.dump(f, true)
local f = assert(io.open("$TEST_NGINX_SERVER_ROOT/html/a.luac", "w"))
f:write(bc)
f:close()
}
--- stream_server_config2
content_by_lua_file html/a.luac;
--- stream_response
a = 1
--- no_error_log
[error]

View file

@ -1,100 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
our $HtmlDir = html_dir;
#$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
no_long_string();
#no_diff();
#log_level 'warn';
run_tests();
__DATA__
=== TEST 1: receive
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket()
sock.receive("l")
}
--- stream_response
--- error_log
bad argument #1 to 'receive' (table expected, got string)
=== TEST 2: receiveuntil
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket()
sock.receiveuntil(32, "ab")
}
--- stream_response
--- error_log
bad argument #1 to 'receiveuntil' (table expected, got number)
=== TEST 3: send (bad arg number)
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.socket.tcp()
sock.send("hello")
}
--- stream_response
--- error_log
expecting 2 arguments (including the object), but got 1
=== TEST 4: send (bad self)
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.socket.tcp()
sock.send("hello", 32)
}
--- stream_response
--- error_log
bad argument #1 to 'send' (table expected, got string)
=== TEST 5: getreusedtimes (bad self)
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.socket.tcp()
sock.getreusedtimes(2)
}
--- stream_response
--- error_log
bad argument #1 to 'getreusedtimes' (table expected, got number)
=== TEST 6: close (bad self)
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.socket.tcp()
sock.close(2)
}
--- stream_response
--- error_log
bad argument #1 to 'close' (table expected, got number)
=== TEST 7: setkeepalive (bad self)
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.socket.tcp()
sock.setkeepalive(2)
}
--- stream_response
--- error_log
bad argument #1 to 'setkeepalive' (table expected, got number)

View file

@ -1,712 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3 + 4);
our $HtmlDir = html_dir;
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
no_long_string();
#no_diff();
#log_level 'warn';
run_tests();
__DATA__
=== TEST 1: ambiguous boundary patterns (abcabd) - inclusive mode
--- stream_server_config
content_by_lua_block {
-- collectgarbage("collect")
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local read_headers = sock:receiveuntil("\r\n\r\n")
local headers, err, part = read_headers()
if not headers then
ngx.say("failed to read headers: ", err, " [", part, "]")
end
local reader = sock:receiveuntil("abcabd", { inclusive = true })
for i = 1, 3 do
line, err, part = reader()
if line then
ngx.say("read: ", line)
else
ngx.say("failed to read a line: ", err, " [", part, "]")
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
location = /foo {
echo abcabcabdabcabd;
more_clear_headers Date;
}
--- stream_response eval
qq{connected: 1
request sent: 57
read: abcabcabd
read: abcabd
failed to read a line: closed [
]
close: 1 nil
}
--- no_error_log
[error]
=== TEST 2: ambiguous boundary patterns (abcabdabcabe 4) - inclusive mode
--- stream_server_config
content_by_lua_block {
-- collectgarbage("collect")
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local read_headers = sock:receiveuntil("\r\n\r\n")
local headers, err, part = read_headers()
if not headers then
ngx.say("failed to read headers: ", err, " [", part, "]")
end
local reader = sock:receiveuntil("abcabdabcabe", { inclusive = true })
for i = 1, 2 do
line, err, part = reader()
if line then
ngx.say("read: ", line)
else
ngx.say("failed to read a line: ", err, " [", part, "]")
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
location = /foo {
echo ababcabdabcabe;
more_clear_headers Date;
}
--- stream_response eval
qq{connected: 1
request sent: 57
read: ababcabdabcabe
failed to read a line: closed [
]
close: 1 nil
}
--- no_error_log
[error]
=== TEST 3: ambiguous boundary patterns (abcabd) - inclusive mode - small buffers
--- stream_server_config
lua_socket_buffer_size 1;
content_by_lua_block {
-- collectgarbage("collect")
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local read_headers = sock:receiveuntil("\r\n\r\n")
local headers, err, part = read_headers()
if not headers then
ngx.say("failed to read headers: ", err, " [", part, "]")
end
local reader = sock:receiveuntil("abcabd", { inclusive = true })
for i = 1, 3 do
line, err, part = reader()
if line then
ngx.say("read: ", line)
else
ngx.say("failed to read a line: ", err, " [", part, "]")
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
location = /foo {
echo abcabcabdabcabd;
more_clear_headers Date;
}
--- stream_response eval
qq{connected: 1
request sent: 57
read: abcabcabd
read: abcabd
failed to read a line: closed [
]
close: 1 nil
}
--- no_error_log
[error]
=== TEST 4: inclusive option value nil
--- stream_server_config
content_by_lua_block {
-- collectgarbage("collect")
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local read_headers = sock:receiveuntil("\r\n\r\n")
local headers, err, part = read_headers()
if not headers then
ngx.say("failed to read headers: ", err, " [", part, "]")
end
local reader = sock:receiveuntil("aa", { inclusive = nil })
for i = 1, 2 do
line, err, part = reader()
if line then
ngx.say("read: ", line)
else
ngx.say("failed to read a line: ", err, " [", part, "]")
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
location = /foo {
echo abcabcaad;
more_clear_headers Date;
}
--- stream_response eval
qq{connected: 1
request sent: 57
read: abcabc
failed to read a line: closed [d
]
close: 1 nil
}
--- no_error_log
[error]
=== TEST 5: inclusive option value false
--- stream_server_config
content_by_lua_block {
-- collectgarbage("collect")
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local read_headers = sock:receiveuntil("\r\n\r\n")
local headers, err, part = read_headers()
if not headers then
ngx.say("failed to read headers: ", err, " [", part, "]")
end
local reader = sock:receiveuntil("aa", { inclusive = false })
for i = 1, 2 do
line, err, part = reader()
if line then
ngx.say("read: ", line)
else
ngx.say("failed to read a line: ", err, " [", part, "]")
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
location = /foo {
echo abcabcaad;
more_clear_headers Date;
}
--- stream_response eval
qq{connected: 1
request sent: 57
read: abcabc
failed to read a line: closed [d
]
close: 1 nil
}
--- no_error_log
[error]
=== TEST 6: inclusive option value true (aa)
--- stream_server_config
content_by_lua_block {
-- collectgarbage("collect")
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local read_headers = sock:receiveuntil("\r\n\r\n")
local headers, err, part = read_headers()
if not headers then
ngx.say("failed to read headers: ", err, " [", part, "]")
end
local reader = sock:receiveuntil("aa", { inclusive = true })
for i = 1, 2 do
line, err, part = reader()
if line then
ngx.say("read: ", line)
else
ngx.say("failed to read a line: ", err, " [", part, "]")
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
location = /foo {
echo abcabcaad;
more_clear_headers Date;
}
--- stream_response eval
qq{connected: 1
request sent: 57
read: abcabcaa
failed to read a line: closed [d
]
close: 1 nil
}
--- no_error_log
[error]
=== TEST 7: bad inclusive option value type
--- stream_server_config
content_by_lua_block {
-- collectgarbage("collect")
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
ngx.flush(true)
local read_headers = sock:receiveuntil("\r\n\r\n")
local headers, err, part = read_headers()
if not headers then
ngx.say("failed to read headers: ", err, " [", part, "]")
end
local reader = sock:receiveuntil("aa", { inclusive = "true" })
for i = 1, 2 do
line, err, part = reader()
if line then
ngx.say("read: ", line)
else
ngx.say("failed to read a line: ", err, " [", part, "]")
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
location = /foo {
echo abcabcaad;
more_clear_headers Date;
}
--- stream_response
connected: 1
request sent: 57
--- error_log
bad "inclusive" option value type: string
--- no_error_log
[alert]
[warn]
=== TEST 8: bad option table
--- stream_server_config
content_by_lua_block {
-- collectgarbage("collect")
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
ngx.flush(true)
local read_headers = sock:receiveuntil("\r\n\r\n")
local headers, err, part = read_headers()
if not headers then
ngx.say("failed to read headers: ", err, " [", part, "]")
end
local reader = sock:receiveuntil("aa", { inclusive = "true" })
for i = 1, 2 do
line, err, part = reader()
if line then
ngx.say("read: ", line)
else
ngx.say("failed to read a line: ", err, " [", part, "]")
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
location = /foo {
echo abcabcaad;
more_clear_headers Date;
}
--- stream_response
connected: 1
request sent: 57
--- error_log
bad "inclusive" option value type: string
--- no_error_log
[alert]
[warn]
=== TEST 9: ambiguous boundary patterns (--abc), small buffer
--- stream_server_config
lua_socket_buffer_size 1;
content_by_lua_block {
-- collectgarbage("collect")
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local read_headers = sock:receiveuntil("\r\n\r\n")
local headers, err, part = read_headers()
if not headers then
ngx.say("failed to read headers: ", err, " [", part, "]")
end
local reader = sock:receiveuntil("--abc", { inclusive = true })
for i = 1, 7 do
line, err, part = reader(4)
if line then
ngx.say("read: ", line)
else
ngx.say("failed to read a line: ", err, " [", part, "]")
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
location = /foo {
echo "hello, world ----abc";
more_clear_headers Date;
}
--- stream_response eval
qq{connected: 1
request sent: 57
read: hell
read: o, w
read: orld
read: --
read: --abc
failed to read a line: nil [nil]
failed to read a line: closed [
]
close: 1 nil
}
--- no_error_log
[error]
=== TEST 10: ambiguous boundary patterns (--abc), small buffer, mixed by other reading calls
--- stream_server_config
lua_socket_buffer_size 1;
content_by_lua_block {
-- collectgarbage("collect")
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local read_headers = sock:receiveuntil("\r\n\r\n")
local headers, err, part = read_headers()
if not headers then
ngx.say("failed to read headers: ", err, " [", part, "]")
end
local reader = sock:receiveuntil("--abc", { inclusive = true })
for i = 1, 7 do
line, err, part = reader(4)
if line then
ngx.say("read: ", line)
else
ngx.say("failed to read a chunk: ", err, " [", part, "]")
end
local data, err, part = sock:receive(1)
if not data then
ngx.say("failed to read a byte: ", err, " [", part, "]")
break
else
ngx.say("read one byte: ", data)
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
location = /foo {
echo "hello, world ----abc";
more_clear_headers Date;
}
--- stream_response eval
qq{connected: 1
request sent: 57
read: hell
read one byte: o
read: , wo
read one byte: r
read: ld -
read one byte: -
read: --abc
read one byte:
failed to read a chunk: nil [nil]
failed to read a byte: closed []
close: 1 nil
}
--- no_error_log
[error]

View file

@ -1,261 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3 + 3);
#no_diff();
#no_long_string();
no_shuffle();
run_tests();
__DATA__
=== TEST 1: sanity (inline)
--- stream_config
init_by_lua_block { foo = "hello, FOO" }
--- stream_server_config
content_by_lua_block { ngx.say(foo) }
--- stream_response
hello, FOO
--- no_error_log
[error]
=== TEST 2: sanity (file)
--- stream_config
init_by_lua_file html/init.lua;
--- stream_server_config
content_by_lua_block { ngx.say(foo) }
--- user_files
>>> init.lua
foo = "hello, FOO"
--- stream_response
hello, FOO
--- no_error_log
[error]
=== TEST 3: require
--- stream_config
lua_package_path "$prefix/html/?.lua;;";
init_by_lua_block { require "blah" }
--- stream_server_config
content_by_lua_block {
blah.go()
}
--- user_files
>>> blah.lua
module(..., package.seeall)
function go()
ngx.say("hello, blah")
end
--- stream_response
hello, blah
--- no_error_log
[error]
=== TEST 4: shdict (single)
--- stream_config
lua_shared_dict dogs 1m;
init_by_lua_block {
local dogs = ngx.shared.dogs
dogs:set("Jim", 6)
dogs:get("Jim")
}
--- stream_server_config
content_by_lua_block {
local dogs = ngx.shared.dogs
ngx.say("Jim: ", dogs:get("Jim"))
}
--- stream_response
Jim: 6
--- no_error_log
[error]
=== TEST 5: shdict (multi)
--- stream_config
lua_shared_dict dogs 1m;
lua_shared_dict cats 1m;
init_by_lua_block {
local dogs = ngx.shared.dogs
dogs:set("Jim", 6)
dogs:get("Jim")
local cats = ngx.shared.cats
cats:set("Tom", 2)
dogs:get("Tom")
}
--- stream_server_config
content_by_lua_block {
local dogs = ngx.shared.dogs
ngx.say("Jim: ", dogs:get("Jim"))
}
--- stream_response
Jim: 6
--- no_error_log
[error]
=== TEST 6: print
--- stream_config
lua_shared_dict dogs 1m;
lua_shared_dict cats 1m;
init_by_lua_block {
print("log from init_by_lua")
}
--- stream_server_config
content_by_lua_block { ngx.say('ok') }
--- stream_response
ok
--- grep_error_log chop
log from init_by_lua
--- grep_error_log_out eval
["log from init_by_lua\n", ""]
=== TEST 7: ngx.log
--- stream_config
lua_shared_dict dogs 1m;
lua_shared_dict cats 1m;
init_by_lua_block {
ngx.log(ngx.NOTICE, "log from init_by_lua")
}
--- stream_server_config
content_by_lua_block { ngx.say('ok') }
--- stream_response
ok
--- grep_error_log chop
log from init_by_lua
--- grep_error_log_out eval
["log from init_by_lua\n", ""]
=== TEST 8: require (with shm defined)
--- stream_config
lua_package_path "$prefix/html/?.lua;;";
lua_shared_dict dogs 1m;
init_by_lua_block { require "blah" }
--- stream_server_config
content_by_lua_block {
blah.go()
}
--- user_files
>>> blah.lua
module(..., package.seeall)
function go()
ngx.say("hello, blah")
end
--- stream_response
hello, blah
--- no_error_log
[error]
=== TEST 9: coroutine API (inlined init_by_lua)
--- stream_config
init_by_lua_block {
local function f()
foo = 32
coroutine.yield(78)
bar = coroutine.status(coroutine.running())
end
local co = coroutine.create(f)
local ok, err = coroutine.resume(co)
if not ok then
print("Failed to resume our co: ", err)
return
end
baz = err
coroutine.resume(co)
}
--- stream_server_config
content_by_lua_block {
ngx.say("foo = ", foo)
ngx.say("bar = ", bar)
ngx.say("baz = ", baz)
}
--- stream_response
foo = 32
bar = running
baz = 78
--- no_error_log
[error]
Failed to resume our co:
=== TEST 10: coroutine API (init_by_lua_file)
--- stream_config
init_by_lua_file html/init.lua;
--- stream_server_config
content_by_lua_block {
ngx.say("foo = ", foo)
ngx.say("bar = ", bar)
ngx.say("baz = ", baz)
}
--- user_files
>>> init.lua
local function f()
foo = 32
coroutine.yield(78)
bar = coroutine.status(coroutine.running())
end
local co = coroutine.create(f)
local ok, err = coroutine.resume(co)
if not ok then
print("Failed to resume our co: ", err)
return
end
baz = err
coroutine.resume(co)
--- stream_response
foo = 32
bar = running
baz = 78
--- no_error_log
[error]
Failed to resume our co:
=== TEST 11: access a field in the ngx. table
--- stream_config
init_by_lua_block {
print("INIT 1: foo = ", ngx.foo)
ngx.foo = 3
print("INIT 2: foo = ", ngx.foo)
}
--- stream_server_config
content_by_lua_block { ngx.say('ok') }
--- stream_response
ok
--- no_error_log
[error]
--- grep_error_log eval: qr/INIT \d+: foo = \S+/
--- grep_error_log_out eval
[
"INIT 1: foo = nil
INIT 2: foo = 3
",
"",
]

View file

@ -1,914 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => repeat_each() * (3 * blocks() + 14);
our $HtmlDir = html_dir;
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
#log_level 'warn';
no_long_string();
#no_diff();
#no_shuffle();
check_accum_error_log();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_server_config
content_by_lua_block {
local socket = ngx.socket
-- local socket = require "socket"
local udp = socket.udp()
local port = $TEST_NGINX_MEMCACHED_PORT
udp:settimeout(1000) -- 1 sec
local ok, err = udp:setpeername("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected")
local req = "\0\1\0\0\0\1\0\0flush_all\r\n"
local ok, err = udp:send(req)
if not ok then
ngx.say("failed to send: ", err)
return
end
local data, err = udp:receive()
if not data then
ngx.say("failed to receive data: ", err)
return
end
ngx.print("received ", #data, " bytes: ", data)
}
--- config
server_tokens off;
--- stream_response eval
"connected\nreceived 12 bytes: \x{00}\x{01}\x{00}\x{00}\x{00}\x{01}\x{00}\x{00}OK\x{0d}\x{0a}"
--- no_error_log
[error]
--- log_level: debug
--- error_log
lua udp socket receive buffer size: 8192
=== TEST 2: multiple parallel queries
--- stream_server_config
content_by_lua_block {
local socket = ngx.socket
-- local socket = require "socket"
local udp = socket.udp()
local port = $TEST_NGINX_MEMCACHED_PORT
udp:settimeout(1000) -- 1 sec
local ok, err = udp:setpeername("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected")
local req = "\0\1\0\0\0\1\0\0flush_all\r\n"
local ok, err = udp:send(req)
if not ok then
ngx.say("failed to send: ", err)
return
end
req = "\0\2\0\0\0\1\0\0flush_all\r\n"
ok, err = udp:send(req)
if not ok then
ngx.say("failed to send: ", err)
return
end
ngx.sleep(0.05)
local data, err = udp:receive()
if not data then
ngx.say("failed to receive data: ", err)
return
end
ngx.print("1: received ", #data, " bytes: ", data)
data, err = udp:receive()
if not data then
ngx.say("failed to receive data: ", err)
return
end
ngx.print("2: received ", #data, " bytes: ", data)
}
--- config
server_tokens off;
--- stream_response_like eval
"^connected\n"
."1: received 12 bytes: "
."\x{00}[\1\2]\x{00}\x{00}\x{00}\x{01}\x{00}\x{00}OK\x{0d}\x{0a}"
."2: received 12 bytes: "
."\x{00}[\1\2]\x{00}\x{00}\x{00}\x{01}\x{00}\x{00}OK\x{0d}\x{0a}\$"
--- no_error_log
[error]
=== TEST 3: access a TCP interface
--- stream_server_config
content_by_lua_block {
local socket = ngx.socket
-- local socket = require "socket"
local udp = socket.udp()
local port = $TEST_NGINX_SERVER_PORT
udp:settimeout(1000) -- 1 sec
local ok, err = udp:setpeername("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected")
local req = "\0\1\0\0\0\1\0\0flush_all\r\n"
local ok, err = udp:send(req)
if not ok then
ngx.say("failed to send: ", err)
return
end
local data, err = udp:receive()
if not data then
ngx.say("failed to receive data: ", err)
return
end
ngx.print("received ", #data, " bytes: ", data)
}
--- config
server_tokens off;
--- stream_response
connected
failed to receive data: connection refused
--- error_log eval
qr/recv\(\) failed \(\d+: Connection refused\)/
=== TEST 4: access conflicts of connect() on shared udp objects
--- stream_config
lua_package_path '$prefix/html/?.lua;;';
--- stream_server_config
content_by_lua_block {
local function f()
local port = $TEST_NGINX_MEMCACHED_PORT
local foo = require "foo"
local udp = foo.get_udp()
udp:settimeout(100) -- 100 ms
local ok, err = udp:setpeername("127.0.0.1", port)
if not ok then
ngx.log(ngx.ERR, "failed to connect: ", err)
return
end
print("test: connected")
local data, err = udp:receive()
if not data then
ngx.say("failed to receive data: ", err)
return
end
print("test: received ", #data, " bytes: ", data)
end
for i = 1, 170 do
assert(ngx.timer.at(0, f))
end
}
--- user_files
>>> foo.lua
module("foo", package.seeall)
local udp
function get_udp()
if not udp then
udp = ngx.socket.udp()
end
return udp
end
--- stap2
M(http-lua-info) {
printf("udp resume: %p\n", $coctx)
print_ubacktrace()
}
--- stream_response
--- error_log eval
qr/content_by_lua\(nginx\.conf:\d+\):9: bad request/
=== TEST 5: access conflicts of receive() on shared udp objects
--- stream_config
lua_package_path '$prefix/html/?.lua;;';
--- stream_server_config
content_by_lua_block {
function f()
local port = $TEST_NGINX_MEMCACHED_PORT
local foo = require "foo"
local udp = foo.get_udp(port)
local data, err = udp:receive()
if not data then
ngx.log(ngx.ERR, "failed to receive data: ", err)
return ngx.exit(500)
end
ngx.print("received ", #data, " bytes: ", data)
end
for i = 1, 170 do
assert(ngx.timer.at(0, f))
end
}
--- user_files
>>> foo.lua
module("foo", package.seeall)
local udp
function get_udp(port)
if not udp then
udp = ngx.socket.udp()
udp:settimeout(100) -- 100ms
local ok, err = udp:setpeername("127.0.0.1", port)
if not ok then
ngx.log(ngx.ERR, "failed to connect: ", err)
return ngx.exit(500)
end
end
return udp
end
--- stream_response
--- error_log eval
qr/content_by_lua\(nginx\.conf:\d+\):7: bad request/
=== TEST 6: connect again immediately
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.udp()
local port = $TEST_NGINX_MEMCACHED_PORT
local ok, err = sock:setpeername("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
ok, err = sock:setpeername("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected again: ", ok)
local req = "\0\1\0\0\0\1\0\0flush_all\r\n"
local ok, err = sock:send(req)
if not ok then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", ok)
local line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- stream_response eval
"connected: 1
connected again: 1
request sent: 1
received: \0\1\0\0\0\1\0\0OK\r\n
close: 1 nil
"
--- no_error_log
[error]
--- error_log eval
["lua reuse socket upstream", "lua udp socket reconnect without shutting down"]
--- log_level: debug
=== TEST 7: recv timeout
--- stream_server_config
content_by_lua_block {
local port = $TEST_NGINX_MEMCACHED_PORT
local sock = ngx.socket.udp()
sock:settimeout(100) -- 100 ms
local ok, err = sock:setpeername("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local line, err = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive: ", err)
end
-- ok, err = sock:close()
-- ngx.say("close: ", ok, " ", err)
}
--- stream_response
connected: 1
failed to receive: timeout
--- error_log
lua udp socket read timed out
=== TEST 8: with an explicit receive buffer size argument
--- stream_server_config
content_by_lua_block {
local socket = ngx.socket
-- local socket = require "socket"
local udp = socket.udp()
local port = $TEST_NGINX_MEMCACHED_PORT
udp:settimeout(1000) -- 1 sec
local ok, err = udp:setpeername("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected")
local req = "\0\1\0\0\0\1\0\0flush_all\r\n"
local ok, err = udp:send(req)
if not ok then
ngx.say("failed to send: ", err)
return
end
local data, err = udp:receive(1400)
if not data then
ngx.say("failed to receive data: ", err)
return
end
ngx.print("received ", #data, " bytes: ", data)
}
--- stream_response eval
"connected\nreceived 12 bytes: \x{00}\x{01}\x{00}\x{00}\x{00}\x{01}\x{00}\x{00}OK\x{0d}\x{0a}"
--- no_error_log
[error]
--- log_level: debug
--- error_log
lua udp socket receive buffer size: 1400
=== TEST 9: read timeout and re-receive
--- stream_server_config
content_by_lua_block {
local udp = ngx.socket.udp()
udp:settimeout(30)
local ok, err = udp:setpeername("127.0.0.1", 19232)
if not ok then
ngx.say("failed to setpeername: ", err)
return
end
local ok, err = udp:send("blah")
if not ok then
ngx.say("failed to send: ", err)
return
end
for i = 1, 2 do
local data, err = udp:receive()
if err == "timeout" then
-- continue
else
if not data then
ngx.say("failed to receive: ", err)
return
end
ngx.say("received: ", data)
return
end
end
ngx.say("timed out")
}
--- udp_listen: 19232
--- udp_reply: hello world
--- udp_reply_delay: 45ms
--- stream_response
received: hello world
--- error_log
lua udp socket read timed out
=== TEST 10: access the google DNS server (using IP addr)
--- stream_server_config
content_by_lua_block {
local socket = ngx.socket
-- local socket = require "socket"
local udp = socket.udp()
udp:settimeout(2000) -- 2 sec
local ok, err = udp:setpeername("$TEST_NGINX_RESOLVER", 53)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local req = "\0}\1\0\0\1\0\0\0\0\0\0\3www\6google\3com\0\0\1\0\1"
-- ngx.print(req)
-- do return end
local ok, err = udp:send(req)
if not ok then
ngx.say("failed to send: ", err)
return
end
local data, err = udp:receive()
if not data then
ngx.say("failed to receive data: ", err)
return
end
if string.match(data, "\3www\6google\3com") then
ngx.say("received a good response.")
else
ngx.say("received a bad response: ", #data, " bytes: ", data)
end
}
--- stream_response
received a good response.
--- no_error_log
[error]
--- log_level: debug
--- error_log
lua udp socket receive buffer size: 8192
=== TEST 11: access the google DNS server (using domain names)
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
content_by_lua_block {
-- avoid flushing google in "check leak" testing mode:
local counter = package.loaded.counter
if not counter then
counter = 1
elseif counter >= 2 then
return ngx.exit(503)
else
counter = counter + 1
end
package.loaded.counter = counter
local socket = ngx.socket
-- local socket = require "socket"
local udp = socket.udp()
udp:settimeout(2000) -- 2 sec
local ok, err = udp:setpeername("google-public-dns-a.google.com", 53)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local req = "\0}\1\0\0\1\0\0\0\0\0\0\3www\6google\3com\0\0\1\0\1"
-- ngx.print(req)
-- do return end
local ok, err = udp:send(req)
if not ok then
ngx.say("failed to send: ", err)
return
end
local data, err = udp:receive()
if not data then
ngx.say("failed to receive data: ", err)
return
end
if string.match(data, "\3www\6google\3com") then
ngx.say("received a good response.")
else
ngx.say("received a bad response: ", #data, " bytes: ", data)
end
}
--- stream_response
received a good response.
--- no_error_log
[error]
--- log_level: debug
--- error_log
lua udp socket receive buffer size: 8192
=== TEST 12: datagram unix domain socket
--- stream_server_config
content_by_lua_block {
local socket = ngx.socket
-- local socket = require "socket"
local udp = socket.udp()
udp:settimeout(2000) -- 1 sec
local ok, err = udp:setpeername("unix:a.sock")
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected")
local req = "hello,\nserver"
local ok, err = udp:send(req)
if not ok then
ngx.say("failed to send: ", err)
return
end
local data, err = udp:receive()
if not data then
ngx.say("failed to receive data: ", err)
return
end
ngx.print("received ", #data, " bytes: ", data)
}
--- udp_listen: a.sock
--- udp_reply
hello,
client
--- stream_response
connected
received 14 bytes: hello,
client
--- stap2
probe syscall.socket, syscall.connect {
print(name, "(", argstr, ")")
}
probe syscall.socket.return, syscall.connect.return {
println(" = ", retstr)
}
--- no_error_log
[error]
[crit]
--- skip_eval: 3: $^O ne 'linux'
=== TEST 13: bad request tries to setpeer
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
content_by_lua_block {
local test = require "test"
local sock = test.new_sock()
local ok, err = sock:setpeername("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to set peer: ", err)
else
ngx.say("peer set")
end
function f()
local sock = test.get_sock()
sock:setpeername("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
end
ngx.timer.at(0, f)
ngx.sleep(0.001)
}
--- user_files
>>> test.lua
module("test", package.seeall)
local sock
function new_sock()
sock = ngx.socket.udp()
return sock
end
function get_sock()
return sock
end
--- stream_response
peer set
--- error_log eval
qr/runtime error: content_by_lua\(nginx\.conf:\d+\):12: bad request/
--- no_error_log
[alert]
=== TEST 14: bad request tries to send
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
content_by_lua_block {
local test = require "test"
local sock = test.new_sock()
local ok, err = sock:setpeername("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to set peer: ", err)
else
ngx.say("peer set")
end
function f()
local sock = test.get_sock()
sock:send("a")
end
ngx.timer.at(0, f)
ngx.sleep(0.001)
}
--- user_files
>>> test.lua
module("test", package.seeall)
local sock
function new_sock()
sock = ngx.socket.udp()
return sock
end
function get_sock()
return sock
end
--- stream_response
peer set
--- error_log eval
qr/runtime error: content_by_lua\(nginx\.conf:\d+\):12: bad request/
--- no_error_log
[alert]
=== TEST 15: bad request tries to receive
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
content_by_lua_block {
local test = require "test"
local sock = test.new_sock()
local ok, err = sock:setpeername("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to set peer: ", err)
else
ngx.say("peer set")
end
local function f()
local sock = test.get_sock()
sock:receive()
end
ngx.timer.at(0, f)
ngx.sleep(0.001)
}
--- user_files
>>> test.lua
module("test", package.seeall)
local sock
function new_sock()
sock = ngx.socket.udp()
return sock
end
function get_sock()
return sock
end
--- stream_response
peer set
--- error_log eval
qr/runtime error: content_by_lua\(nginx\.conf:\d+\):13: bad request/
--- no_error_log
[alert]
=== TEST 16: bad request tries to close
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
content_by_lua_block {
local test = require "test"
local sock = test.new_sock()
local ok, err = sock:setpeername("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to set peer: ", err)
else
ngx.say("peer set")
end
local function f()
local sock = test.get_sock()
sock:close()
end
ngx.timer.at(0, f)
ngx.sleep(0.001)
}
--- user_files
>>> test.lua
module("test", package.seeall)
local sock
function new_sock()
sock = ngx.socket.udp()
return sock
end
function get_sock()
return sock
end
--- stream_response
peer set
--- error_log eval
qr/runtime error: content_by_lua\(nginx\.conf:\d+\):12: bad request/
--- no_error_log
[alert]
=== TEST 17: the upper bound of port range should be 2^16 - 1
--- stream_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.udp()
local ok, err = sock:setpeername("127.0.0.1", 65536)
if not ok then
ngx.say("failed to connect: ", err)
end
}
--- stream_response
failed to connect: bad port number: 65536
--- no_error_log
[error]
=== TEST 18: send boolean and nil
--- stream_server_config
content_by_lua_block {
local socket = ngx.socket
local udp = socket.udp()
local port = ngx.var.port
udp:settimeout(1000) -- 1 sec
local ok, err = udp:setpeername("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local function send(data)
local bytes, err = udp:send(data)
if not bytes then
ngx.say("failed to send: ", err)
return
end
ngx.say("sent ok")
end
send(true)
send(false)
send(nil)
}
--- stream_response
sent ok
sent ok
sent ok
--- no_error_log
[error]
--- grep_error_log eval
qr/sendto: fd:\d+ \d+ of \d+/
--- grep_error_log_out eval
qr/sendto: fd:\d+ 4 of 4
sendto: fd:\d+ 5 of 5
sendto: fd:\d+ 3 of 3/
--- log_level: debug
=== TEST 19: UDP socket GC'ed in preread phase without Lua content phase
--- stream_server_config
preread_by_lua_block {
do
local udpsock = ngx.socket.udp()
local res, err = udpsock:setpeername("127.0.0.1", 1234)
if not res then
ngx.log(ngx.ERR, err)
end
end
ngx.timer.at(0, function()
collectgarbage()
ngx.log(ngx.WARN, "GC cycle done")
end)
}
return 1;
--- stream_response chomp
1
--- no_error_log
[error]
--- error_log
cleanup lua udp socket upstream request
GC cycle done

View file

@ -1,94 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_process_enabled(1);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2 + 2);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: get_phase in init_by_lua
--- stream_config
init_by_lua_block { phase = ngx.get_phase() }
--- stream_server_config
content_by_lua_block {
ngx.say(phase)
}
--- stream_response
init
=== TEST 2: get_phase in access_by_lua
TODO
--- SKIP
--- stream_server_config
access_by_lua_block {
ngx.say(ngx.get_phase())
ngx.exit(200)
}
--- stream_response
access
=== TEST 3: get_phase in content_by_lua
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.get_phase())
}
--- stream_response
content
=== TEST 4: get_phase in log_by_lua_block
TODO
--- SKIP
--- stream_server_config
echo "OK";
log_by_lua_block {
ngx.log(ngx.ERR, ngx.get_phase())
}
--- error_log
log
=== TEST 5: get_phase in ngx.timer callback
--- stream_server_config
content_by_lua_block {
local function f()
ngx.log(ngx.WARN, "current phase: ", ngx.get_phase())
end
local ok, err = ngx.timer.at(0, f)
if not ok then
ngx.log(ngx.ERR, "failed to add timer: ", err)
end
}
--- no_error_log
[error]
--- error_log
current phase: timer
=== TEST 6: get_phase in init_worker_by_lua
--- stream_config
init_worker_by_lua_block { phase = ngx.get_phase() }
--- stream_server_config
content_by_lua_block {
ngx.say(phase)
}
--- stream_response
init_worker
--- no_error_log
[error]

View file

@ -1,94 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: log socket errors off (tcp)
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
lua_socket_connect_timeout 1ms;
lua_socket_log_errors off;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.2", 12345)
ngx.say(err)
}
--- config
--- stream_response
timeout
--- no_error_log
[error]
=== TEST 2: log socket errors on (tcp)
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
lua_socket_connect_timeout 1ms;
lua_socket_log_errors on;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.2", 12345)
ngx.say(err)
}
--- config
--- stream_response
timeout
--- error_log
stream lua tcp socket connect timed out, when connecting to 127.0.0.2:12345
=== TEST 3: log socket errors on (udp)
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
lua_socket_log_errors on;
lua_socket_read_timeout 1ms;
content_by_lua_block {
local sock = ngx.socket.udp()
local ok, err = sock:setpeername("127.0.0.2", 12345)
ok, err = sock:receive()
ngx.say(err)
}
--- config
--- stream_response
timeout
--- error_log
lua udp socket read timed out
=== TEST 4: log socket errors off (udp)
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
lua_socket_log_errors off;
lua_socket_read_timeout 1ms;
content_by_lua_block {
local sock = ngx.socket.udp()
local ok, err = sock:setpeername("127.0.0.2", 12345)
ok, err = sock:receive()
ngx.say(err)
}
--- config
--- stream_response
timeout
--- no_error_log
[error]

File diff suppressed because it is too large Load diff

View file

@ -1,819 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;use t::StapThread;
our $GCScript = $t::StapThread::GCScript;
our $StapScript = $t::StapThread::StapScript;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4 + 1);
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= '11211';
#no_shuffle();
worker_connections(256);
no_long_string();
run_tests();
__DATA__
=== TEST 1: simple user thread without I/O
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello in thread")
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 2: ok
terminate 1: ok
delete thread 2
delete thread 1
--- stream_response
before
hello in thread
after
--- no_error_log
[error]
=== TEST 2: two simple user threads without I/O
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("in thread 1")
end
function g()
ngx.say("in thread 2")
end
ngx.say("before 1")
ngx.thread.spawn(f)
ngx.say("after 1")
ngx.say("before 2")
ngx.thread.spawn(g)
ngx.say("after 2")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 2: ok
create 3 in 1
spawn user thread 3 in 1
terminate 3: ok
terminate 1: ok
delete thread 2
delete thread 3
delete thread 1
--- stream_response
before 1
in thread 1
after 1
before 2
in thread 2
after 2
--- no_error_log
[error]
=== TEST 3: simple user thread with sleep
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("before sleep")
ngx.sleep(0.1)
ngx.say("after sleep")
end
ngx.say("before thread create")
ngx.thread.spawn(f)
ngx.say("after thread create")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
--- stream_response
before thread create
before sleep
after thread create
after sleep
--- no_error_log
[error]
=== TEST 4: two simple user threads with sleep
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("1: before sleep")
ngx.sleep(0.2)
ngx.say("1: after sleep")
end
function g()
ngx.say("2: before sleep")
ngx.sleep(0.1)
ngx.say("2: after sleep")
end
ngx.say("1: before thread create")
ngx.thread.spawn(f)
ngx.say("1: after thread create")
ngx.say("2: before thread create")
ngx.thread.spawn(g)
ngx.say("2: after thread create")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
create 3 in 1
spawn user thread 3 in 1
terminate 1: ok
delete thread 1
terminate 3: ok
delete thread 3
terminate 2: ok
delete thread 2
--- wait: 0.1
--- stream_response
1: before thread create
1: before sleep
1: after thread create
2: before thread create
2: before sleep
2: after thread create
2: after sleep
1: after sleep
--- no_error_log
[error]
=== TEST 5: error in user thread
--- stream_server_config
content_by_lua_block {
function f()
ngx.blah()
end
ngx.thread.spawn(f)
ngx.say("after")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 2: fail
terminate 1: ok
delete thread 2
delete thread 1
--- stream_response
after
--- error_log eval
qr/stream lua user thread aborted: runtime error: content_by_lua\(nginx\.conf:\d+\):3: attempt to call field 'blah' \(a nil value\)/
=== TEST 6: nested user threads
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("before g")
ngx.thread.spawn(g)
ngx.say("after g")
end
function g()
ngx.say("hello in g()")
end
ngx.say("before f")
ngx.thread.spawn(f)
ngx.say("after f")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
create 3 in 2
spawn user thread 3 in 2
terminate 3: ok
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 3
delete thread 2
--- stream_response
before f
before g
hello in g()
after f
after g
--- no_error_log
[error]
=== TEST 7: nested user threads (with I/O)
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("before g")
ngx.thread.spawn(g)
ngx.say("after g")
end
function g()
ngx.sleep(0.1)
ngx.say("hello in g()")
end
ngx.say("before f")
ngx.thread.spawn(f)
ngx.say("after f")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
create 3 in 2
spawn user thread 3 in 2
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
terminate 3: ok
delete thread 3
--- stream_response
before f
before g
after f
after g
hello in g()
--- no_error_log
[error]
=== TEST 8: coroutine status of a running user thread
--- stream_server_config
content_by_lua_block {
local co
function f()
co = coroutine.running()
ngx.sleep(0.1)
end
ngx.thread.spawn(f)
ngx.say("status: ", coroutine.status(co))
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
--- stream_response
status: running
--- no_error_log
[error]
=== TEST 9: coroutine status of a dead user thread
--- stream_server_config
content_by_lua_block {
local co
function f()
co = coroutine.running()
end
ngx.thread.spawn(f)
ngx.say("status: ", coroutine.status(co))
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 2: ok
terminate 1: ok
delete thread 2
delete thread 1
--- stream_response
status: zombie
--- no_error_log
[error]
=== TEST 10: coroutine status of a "normal" user thread
--- stream_server_config
content_by_lua_block {
local co
function f()
co = coroutine.running()
local co2 = coroutine.create(g)
coroutine.resume(co2)
end
function g()
ngx.sleep(0.1)
end
ngx.thread.spawn(f)
ngx.say("status: ", coroutine.status(co))
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
create 3 in 2
terminate 1: ok
delete thread 1
terminate 3: ok
terminate 2: ok
delete thread 2
--- stream_response
status: normal
--- no_error_log
[error]
=== TEST 11: creating user threads in a user coroutine
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("before g")
ngx.thread.spawn(g)
ngx.say("after g")
end
function g()
ngx.say("hello in g()")
end
ngx.say("before f")
local co = coroutine.create(f)
coroutine.resume(co)
ngx.say("after f")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
create 3 in 2
spawn user thread 3 in 2
terminate 3: ok
terminate 2: ok
delete thread 3
terminate 1: ok
delete thread 1
--- stream_response
before f
before g
hello in g()
after g
after f
--- no_error_log
[error]
=== TEST 12: manual time slicing between a user thread and the entry thread
--- stream_server_config
content_by_lua_block {
local yield = coroutine.yield
function f()
local self = coroutine.running()
ngx.say("f 1")
yield(self)
ngx.say("f 2")
yield(self)
ngx.say("f 3")
end
local self = coroutine.running()
ngx.say("0")
yield(self)
ngx.say("1")
ngx.thread.spawn(f)
ngx.say("2")
yield(self)
ngx.say("3")
yield(self)
ngx.say("4")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 2: ok
terminate 1: ok
delete thread 2
delete thread 1
--- stream_response
0
1
f 1
2
f 2
3
f 3
4
--- no_error_log
[error]
=== TEST 13: manual time slicing between two user threads
--- stream_server_config
content_by_lua_block {
local yield = coroutine.yield
function f()
local self = coroutine.running()
ngx.say("f 1")
yield(self)
ngx.say("f 2")
yield(self)
ngx.say("f 3")
end
function g()
local self = coroutine.running()
ngx.say("g 1")
yield(self)
ngx.say("g 2")
yield(self)
ngx.say("g 3")
end
ngx.thread.spawn(f)
ngx.thread.spawn(g)
ngx.say("done")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
create 3 in 1
spawn user thread 3 in 1
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
terminate 3: ok
delete thread 3
--- stream_response
f 1
g 1
f 2
done
g 2
f 3
g 3
--- no_error_log
[error]
=== TEST 14: entry thread and a user thread flushing at the same time
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello in thread")
coroutine.yield(coroutine.running)
ngx.flush(true)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
ngx.flush(true)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
--- stream_response
before
hello in thread
after
--- no_error_log
[error]
=== TEST 15: two user threads flushing at the same time
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello from f")
ngx.flush(true)
end
function g()
ngx.say("hello from g")
ngx.flush(true)
end
ngx.thread.spawn(f)
ngx.thread.spawn(g)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out_like
^(?:create 2 in 1
spawn user thread 2 in 1
create 3 in 1
spawn user thread 3 in 1
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
terminate 3: ok
delete thread 3|create 2 in 1
spawn user thread 2 in 1
terminate 2: ok
create 3 in 1
spawn user thread 3 in 1
terminate 3: ok
terminate 1: ok
delete thread 2
delete thread 3
delete thread 1)$
--- stream_response
hello from f
hello from g
--- no_error_log
[error]
=== TEST 16: user threads + ngx.socket.tcp
--- stream_server_config
content_by_lua_block {
function f()
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local bytes, err = sock:send("flush_all\r\n")
if not bytes then
ngx.say("failed to send query: ", err)
return
end
local line, err = sock:receive()
if not line then
ngx.say("failed to receive: ", err)
return
end
ngx.say("received: ", line)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
--- stream_response
before
after
received: OK
--- no_error_log
[error]
=== TEST 17: user threads + ngx.socket.udp
--- stream_server_config
content_by_lua_block {
function f()
local sock = ngx.socket.udp()
local ok, err = sock:setpeername("127.0.0.1", 12345)
local bytes, err = sock:send("blah")
if not bytes then
ngx.say("failed to send query: ", err)
return
end
local line, err = sock:receive()
if not line then
ngx.say("failed to receive: ", err)
return
end
ngx.say("received: ", line)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out_like chop
^(?:create 2 in 1
spawn user thread 2 in 1
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
|create 2 in 1
spawn user thread 2 in 1
terminate 2: ok
terminate 1: ok
delete thread 2
delete thread 1
)$
--- udp_listen: 12345
--- udp_query: blah
--- udp_reply: hello udp
--- stream_response_like chop
^(?:before
after
received: hello udp
|before
received: hello udp
after)$
--- no_error_log
[error]
=== TEST 18: simple user thread with ngx.req.socket()
--- stream_server_config
content_by_lua_block {
function f()
local sock = assert(ngx.req.socket())
local body, err = sock:receive(11)
if not body then
ngx.say("failed to read body: ", err)
return
end
ngx.say("body: ", body)
end
ngx.say("before")
ngx.flush(true)
ngx.thread.spawn(f)
ngx.say("after")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out_like chop
^(?:create 2 in 1
spawn user thread 2 in 1
terminate 2: ok
terminate 1: ok
delete thread 2
delete thread 1|create 2 in 1
spawn user thread 2 in 1
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2)$
--- stream_request chomp
hello world
--- stream_response_like chop
^(?:before
body: hello world
after|before
after
body: hello world)$
--- no_error_log
[error]
=== TEST 19: simple user thread with args
--- stream_server_config
content_by_lua_block {
function f(a, b)
ngx.say("hello ", a, " and ", b)
end
ngx.say("before")
ngx.thread.spawn(f, "foo", 3.14)
ngx.say("after")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 2: ok
terminate 1: ok
delete thread 2
delete thread 1
--- stream_response
before
hello foo and 3.14
after
--- no_error_log
[error]
=== TEST 20: simple user thread without I/O
--- stream_server_config
content_by_lua_block {
function f()
ngx.sleep(0.1)
ngx.say("f")
end
ngx.thread.spawn(f)
collectgarbage()
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
--- stream_response
f
--- no_error_log
[error]

View file

@ -1,923 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;use t::StapThread;
our $GCScript = $t::StapThread::GCScript;
our $StapScript = $t::StapThread::StapScript;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4);
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= '11211';
$ENV{TEST_NGINX_REDIS_PORT} ||= '6379';
#no_shuffle();
no_long_string();
run_tests();
__DATA__
=== TEST 1: exit in user thread (entry thread is still pending to run)
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello in thread")
ngx.exit(0)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
ngx.sleep(1)
ngx.say("end")
}
--- stap2 eval: $::StapScript
--- stap eval
<<'_EOC_' . $::GCScript;
global timers
M(timer-add) {
if ($arg2 == 1000) {
timers[$arg1] = $arg2
printf("add timer %d\n", $arg2)
}
}
M(timer-del) {
tm = timers[$arg1]
if (tm == 1000) {
printf("delete timer %d\n", tm)
delete timers[$arg1]
}
}
M(timer-expire) {
tm = timers[$arg1]
if (tm == 1000) {
printf("expire timer %d\n", timers[$arg1])
delete timers[$arg1]
}
}
_EOC_
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 2: ok
delete thread 2
delete thread 1
--- stream_response
before
hello in thread
--- no_error_log
[error]
=== TEST 2: exit in user thread (entry thread is still pending on ngx.sleep)
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello in thread")
ngx.sleep(0.1)
ngx.exit(0)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
ngx.sleep(1)
ngx.say("end")
}
--- stap2 eval: $::StapScript
--- stap eval
<<'_EOC_' . $::GCScript;
global timers
F(ngx_http_free_request) {
println("free request")
}
M(timer-add) {
if ($arg2 == 1000 || $arg2 == 100) {
timers[$arg1] = $arg2
printf("add timer %d\n", $arg2)
}
}
M(timer-del) {
tm = timers[$arg1]
if (tm == 1000 || tm == 100) {
printf("delete timer %d\n", tm)
delete timers[$arg1]
}
/*
if (tm == 1000) {
print_ubacktrace()
}
*/
}
M(timer-expire) {
tm = timers[$arg1]
if (tm == 1000 || tm == 100) {
printf("expire timer %d\n", timers[$arg1])
delete timers[$arg1]
}
}
F(ngx_http_lua_sleep_cleanup) {
println("lua sleep cleanup")
}
_EOC_
--- stap_out
create 2 in 1
spawn user thread 2 in 1
add timer 100
add timer 1000
expire timer 100
terminate 2: ok
delete thread 2
lua sleep cleanup
delete timer 1000
delete thread 1
free request
--- stream_response
before
hello in thread
after
--- no_error_log
[error]
=== TEST 3: exit in a user thread (another user thread is still pending on ngx.sleep)
--- stream_server_config
content_by_lua_block {
function f()
ngx.sleep(0.1)
ngx.say("f")
ngx.exit(0)
end
function g()
ngx.sleep(1)
ngx.say("g")
end
ngx.thread.spawn(f)
ngx.thread.spawn(g)
ngx.say("end")
}
--- stap2 eval: $::StapScript
--- stap eval
<<'_EOC_' . $::GCScript;
global timers
F(ngx_http_free_request) {
println("free request")
}
M(timer-add) {
if ($arg2 == 1000 || $arg2 == 100) {
timers[$arg1] = $arg2
printf("add timer %d\n", $arg2)
}
}
M(timer-del) {
tm = timers[$arg1]
if (tm == 1000 || tm == 100) {
printf("delete timer %d\n", tm)
delete timers[$arg1]
}
/*
if (tm == 1000) {
print_ubacktrace()
}
*/
}
M(timer-expire) {
tm = timers[$arg1]
if (tm == 1000 || tm == 100) {
printf("expire timer %d\n", timers[$arg1])
delete timers[$arg1]
}
}
F(ngx_http_lua_sleep_cleanup) {
println("lua sleep cleanup")
}
_EOC_
--- stap_out
create 2 in 1
spawn user thread 2 in 1
add timer 100
create 3 in 1
spawn user thread 3 in 1
add timer 1000
terminate 1: ok
delete thread 1
expire timer 100
terminate 2: ok
delete thread 2
lua sleep cleanup
delete timer 1000
delete thread 3
free request
--- stream_response
end
f
--- no_error_log
[error]
=== TEST 4: exit in user thread (entry already quits)
--- stream_server_config
content_by_lua_block {
function f()
ngx.sleep(0.1)
ngx.say("exiting the user thread")
ngx.exit(0)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 1: ok
delete thread 1
terminate 2: ok
delete thread 2
--- wait: 0.1
--- stream_response
before
after
exiting the user thread
--- no_error_log
[error]
=== TEST 5: exit in user thread (entry thread is still pending on the DNS resolver for ngx.socket.tcp)
--- stream_server_config
resolver 127.0.0.2:12345;
resolver_timeout 12s;
content_by_lua_block {
function f()
ngx.say("hello in thread")
ngx.sleep(0.001)
ngx.exit(0)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
local sock = ngx.socket.tcp()
local ok, err = sock:connect("agentzh.org", 80)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("end")
}
--- stap2 eval: $::StapScript
--- stap eval
<<'_EOC_' . $::GCScript;
global timers
F(ngx_http_free_request) {
println("free request")
}
F(ngx_resolve_name) {
printf("resolving %s\n", user_string_n($ctx->name->data, $ctx->name->len))
}
M(timer-add) {
if ($arg2 == 12000 || $arg2 == 1) {
timers[$arg1] = $arg2
printf("add timer %d\n", $arg2)
}
}
M(timer-del) {
tm = timers[$arg1]
if (tm == 12000 || tm == 1) {
printf("delete timer %d\n", tm)
delete timers[$arg1]
}
/*
if (tm == 12000) {
print_ubacktrace()
}
*/
}
M(timer-expire) {
tm = timers[$arg1]
if (tm == 12000 || tm == 1) {
printf("expire timer %d\n", timers[$arg1])
delete timers[$arg1]
}
}
F(ngx_http_lua_tcp_resolve_cleanup) {
println("lua tcp resolve cleanup")
}
_EOC_
--- stap_out
create 2 in 1
spawn user thread 2 in 1
add timer 1
resolving agentzh.org
add timer 12000
expire timer 1
terminate 2: ok
delete thread 2
lua tcp resolve cleanup
delete timer 12000
delete thread 1
free request
--- stream_response
before
hello in thread
after
--- no_error_log
[error]
=== TEST 6: exit in user thread (entry thread is still pending on the DNS resolver for ngx.socket.udp)
--- stream_server_config
resolver 127.0.0.2:12345;
resolver_timeout 12s;
content_by_lua_block {
function f()
ngx.say("hello in thread")
ngx.sleep(0.001)
ngx.exit(0)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
local sock = ngx.socket.udp()
local ok, err = sock:setpeername("agentzh.org", 80)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("end")
}
--- stap2 eval: $::StapScript
--- stap eval
<<'_EOC_' . $::GCScript;
global timers
F(ngx_http_free_request) {
println("free request")
}
F(ngx_resolve_name) {
printf("resolving %s\n", user_string_n($ctx->name->data, $ctx->name->len))
}
M(timer-add) {
if ($arg2 == 12000 || $arg2 == 1) {
timers[$arg1] = $arg2
printf("add timer %d\n", $arg2)
}
}
M(timer-del) {
tm = timers[$arg1]
if (tm == 12000 || tm == 1) {
printf("delete timer %d\n", tm)
delete timers[$arg1]
}
/*
if (tm == 12000) {
print_ubacktrace()
}
*/
}
M(timer-expire) {
tm = timers[$arg1]
if (tm == 12000 || tm == 1) {
printf("expire timer %d\n", timers[$arg1])
delete timers[$arg1]
}
}
F(ngx_http_lua_udp_resolve_cleanup) {
println("lua udp resolve cleanup")
}
_EOC_
--- stap_out
create 2 in 1
spawn user thread 2 in 1
add timer 1
resolving agentzh.org
add timer 12000
expire timer 1
terminate 2: ok
delete thread 2
lua udp resolve cleanup
delete timer 12000
delete thread 1
free request
--- stream_response
before
hello in thread
after
--- no_error_log
[error]
=== TEST 7: exit in user thread (entry thread is still pending on tcpsock:connect)
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello in thread")
ngx.sleep(0.1)
ngx.exit(0)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
local sock = ngx.socket.tcp()
sock:settimeout(12000)
local ok, err = sock:connect("127.0.0.2", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("end")
}
--- stap2 eval: $::StapScript
--- stap eval
<<'_EOC_' . $::GCScript;
global timers
F(ngx_http_free_request) {
println("free request")
}
M(timer-add) {
if ($arg2 == 12000 || $arg2 == 100) {
timers[$arg1] = $arg2
printf("add timer %d\n", $arg2)
}
}
M(timer-del) {
tm = timers[$arg1]
if (tm == 12000 || tm == 100) {
printf("delete timer %d\n", tm)
delete timers[$arg1]
}
/*
if (tm == 12000) {
print_ubacktrace()
}
*/
}
M(timer-expire) {
tm = timers[$arg1]
if (tm == 12000 || tm == 100) {
printf("expire timer %d\n", timers[$arg1])
delete timers[$arg1]
}
}
F(ngx_http_lua_coctx_cleanup) {
println("lua tcp socket cleanup")
}
_EOC_
--- stap_out
create 2 in 1
spawn user thread 2 in 1
add timer 100
add timer 12000
expire timer 100
terminate 2: ok
delete thread 2
lua tcp socket cleanup
delete timer 12000
delete thread 1
free request
--- stream_response
before
hello in thread
after
--- no_error_log
[error]
=== TEST 8: exit in user thread (entry thread is still pending on tcpsock:receive)
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello in thread")
ngx.sleep(0.1)
ngx.exit(0)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_REDIS_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local bytes, ok = sock:send("blpop not_exists 2\\r\\n")
if not bytes then
ngx.say("failed to send: ", err)
return
end
sock:settimeout(12000)
local data, err = sock:receive()
if not data then
ngx.say("failed to receive: ", err)
return
end
ngx.say("end")
}
--- stap2 eval: $::StapScript
--- stap eval
<<'_EOC_' . $::GCScript;
global timers
F(ngx_http_free_request) {
println("free request")
}
M(timer-add) {
if ($arg2 == 12000 || $arg2 == 100) {
timers[$arg1] = $arg2
printf("add timer %d\n", $arg2)
}
}
M(timer-del) {
tm = timers[$arg1]
if (tm == 12000 || tm == 100) {
printf("delete timer %d\n", tm)
delete timers[$arg1]
}
}
M(timer-expire) {
tm = timers[$arg1]
if (tm == 12000 || tm == 100) {
printf("expire timer %d\n", timers[$arg1])
delete timers[$arg1]
}
}
F(ngx_http_lua_coctx_cleanup) {
println("lua tcp socket cleanup")
}
_EOC_
--- stap_out
create 2 in 1
spawn user thread 2 in 1
add timer 100
add timer 12000
expire timer 100
terminate 2: ok
delete thread 2
lua tcp socket cleanup
delete timer 12000
delete thread 1
free request
--- stream_response
before
hello in thread
after
--- no_error_log
[error]
=== TEST 9: exit in user thread (entry thread is still pending on tcpsock:receiveuntil's iterator)
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello in thread")
ngx.sleep(0.1)
ngx.exit(0)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_REDIS_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local bytes, ok = sock:send("blpop not_exists 2\\r\\n")
if not bytes then
ngx.say("failed to send: ", err)
return
end
local it, err = sock:receiveuntil("\\r\\n")
if not it then
ngx.say("failed to receive until: ", err)
return
end
sock:settimeout(12000)
local data, err = it()
if not data then
ngx.say("failed to receive: ", err)
return
end
ngx.say("end")
}
--- stap2 eval: $::StapScript
--- stap eval
<<'_EOC_' . $::GCScript;
global timers
F(ngx_http_free_request) {
println("free request")
}
M(timer-add) {
if ($arg2 == 12000 || $arg2 == 100) {
timers[$arg1] = $arg2
printf("add timer %d\n", $arg2)
}
}
M(timer-del) {
tm = timers[$arg1]
if (tm == 12000 || tm == 100) {
printf("delete timer %d\n", tm)
delete timers[$arg1]
}
}
M(timer-expire) {
tm = timers[$arg1]
if (tm == 12000 || tm == 100) {
printf("expire timer %d\n", timers[$arg1])
delete timers[$arg1]
}
}
F(ngx_http_lua_coctx_cleanup) {
println("lua tcp socket cleanup")
}
_EOC_
--- stap_out
create 2 in 1
spawn user thread 2 in 1
add timer 100
add timer 12000
expire timer 100
terminate 2: ok
delete thread 2
lua tcp socket cleanup
delete timer 12000
delete thread 1
free request
--- stream_response
before
hello in thread
after
--- no_error_log
[error]
=== TEST 10: exit in user thread (entry thread is still pending on udpsock:receive)
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello in thread")
ngx.sleep(0.1)
ngx.exit(0)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
local sock = ngx.socket.udp()
local ok, err = sock:setpeername("8.8.8.8", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end
sock:settimeout(12000)
local data, err = sock:receive()
if not data then
ngx.say("failed to receive: ", err)
return
end
ngx.say("end")
}
--- stap2 eval: $::StapScript
--- stap eval
<<'_EOC_' . $::GCScript;
global timers
F(ngx_http_free_request) {
println("free request")
}
M(timer-add) {
if ($arg2 == 12000 || $arg2 == 100) {
timers[$arg1] = $arg2
printf("add timer %d\n", $arg2)
}
}
M(timer-del) {
tm = timers[$arg1]
if (tm == 12000 || tm == 100) {
printf("delete timer %d\n", tm)
delete timers[$arg1]
}
}
M(timer-expire) {
tm = timers[$arg1]
if (tm == 12000 || tm == 100) {
printf("expire timer %d\n", timers[$arg1])
delete timers[$arg1]
}
}
F(ngx_http_lua_udp_socket_cleanup) {
println("lua udp socket cleanup")
}
_EOC_
--- stap_out
create 2 in 1
spawn user thread 2 in 1
add timer 100
add timer 12000
expire timer 100
terminate 2: ok
delete thread 2
lua udp socket cleanup
delete timer 12000
delete thread 1
free request
--- wait: 0.1
--- stream_response
before
hello in thread
after
--- no_error_log
[error]
=== TEST 11: exit in user thread (entry thread is still pending on reqsock:receive)
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello in thread")
ngx.sleep(0.1)
ngx.exit(0)
end
ngx.say("before")
ngx.thread.spawn(f)
ngx.say("after")
ngx.flush(true)
local sock = ngx.req.socket()
sock:settimeout(12000)
local data, err = sock:receive(1024)
if not data then
ngx.say("failed to receive: ", err)
return
end
ngx.say("end")
}
--- stap2 eval: $::StapScript
--- stap eval
<<'_EOC_' . $::GCScript;
global timers
F(ngx_http_free_request) {
println("free request")
}
M(timer-add) {
if ($arg2 == 12000 || $arg2 == 100) {
timers[$arg1] = $arg2
printf("add timer %d\n", $arg2)
}
}
M(timer-del) {
tm = timers[$arg1]
if (tm == 12000 || tm == 100) {
printf("delete timer %d\n", tm)
delete timers[$arg1]
}
}
M(timer-expire) {
tm = timers[$arg1]
if (tm == 12000 || tm == 100) {
printf("expire timer %d\n", timers[$arg1])
delete timers[$arg1]
}
}
F(ngx_http_lua_coctx_cleanup) {
println("lua tcp socket cleanup")
}
_EOC_
--- stap_out
create 2 in 1
spawn user thread 2 in 1
add timer 100
add timer 12000
expire timer 100
terminate 2: ok
delete thread 2
lua tcp socket cleanup
delete timer 12000
delete thread 1
free request
--- wait: 0.1
--- stream_response
before
hello in thread
after
--- no_error_log
[error]
--- timeout: 6

File diff suppressed because it is too large Load diff

View file

@ -1,373 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_process_enabled(1);
log_level('warn');
repeat_each(3);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
no_long_string();
#master_on();
#workers(2);
run_tests();
__DATA__
=== TEST 1: find zone
--- stream_config
lua_shared_dict dogs 1m;
--- stream_server_config
content_by_lua_block {
local ffi = require "ffi"
ffi.cdef[[
void *ngx_stream_lua_find_zone(char *data, size_t len);
]]
local buf = ffi.new("char[?]", 4)
ffi.copy(buf, "foo", 3)
local zone = ffi.C.ngx_stream_lua_find_zone(buf, 3)
ngx.say("foo zone: ", tonumber(ffi.cast("long", zone)) ~= 0 and "defined" or "undef")
ffi.copy(buf, "dogs", 4)
zone = ffi.C.ngx_stream_lua_find_zone(buf, 4)
ngx.say("dogs zone: ", tonumber(ffi.cast("long", zone)) ~= 0 and "defined" or "undef")
}
--- stream_response
foo zone: undef
dogs zone: defined
--- no_error_log
[error]
=== TEST 2: number typed value
--- stream_config
lua_shared_dict dogs 1m;
--- stream_server_config
content_by_lua_block {
local ffi = require "ffi"
ffi.cdef[[
typedef struct {
size_t len;
char *data;
} ngx_str_t;
typedef struct {
uint8_t type;
union {
int b; /* boolean */
double n; /* number */
ngx_str_t s; /* string */
} value;
} ngx_stream_lua_value_t;
void *ngx_stream_lua_find_zone(char *data, size_t len);
intptr_t ngx_stream_lua_shared_dict_get(void *zone, char *kdata, size_t klen, ngx_stream_lua_value_t *val);
]]
local dogs = ngx.shared.dogs
dogs:set("foo", 1234567)
dogs:set("bar", 3.14159)
local buf = ffi.new("char[?]", 4)
ffi.copy(buf, "dogs", 4)
zone = ffi.C.ngx_stream_lua_find_zone(buf, 4)
local val = ffi.new("ngx_stream_lua_value_t[?]", 1)
ffi.copy(buf, "foo", 3)
local rc = ffi.C.ngx_stream_lua_shared_dict_get(zone, buf, 3, val)
ngx.say("foo: rc=", tonumber(rc),
", type=", val[0].type,
", val=", tonumber(val[0].value.n))
ffi.copy(buf, "bar", 3)
local rc = ffi.C.ngx_stream_lua_shared_dict_get(zone, buf, 3, val)
ngx.say("bar: rc=", tonumber(rc),
", type=", val[0].type,
", val=", tonumber(val[0].value.n))
}
--- stream_response
foo: rc=0, type=3, val=1234567
bar: rc=0, type=3, val=3.14159
--- no_error_log
[error]
--- SKIP
=== TEST 3: boolean typed value
--- SKIP
--- stream_config
lua_shared_dict dogs 1m;
--- stream_server_config
content_by_lua_block {
local ffi = require "ffi"
ffi.cdef[[
typedef struct {
size_t len;
char *data;
} ngx_str_t;
typedef struct {
uint8_t type;
union {
int b; /* boolean */
double n; /* number */
ngx_str_t s; /* string */
} value;
} ngx_stream_lua_value_t;
void *ngx_stream_lua_find_zone(char *data, size_t len);
intptr_t ngx_stream_lua_shared_dict_get(void *zone, char *kdata, size_t klen, ngx_stream_lua_value_t *val);
]]
local dogs = ngx.shared.dogs
dogs:set("foo", true)
dogs:set("bar", false)
local buf = ffi.new("char[?]", 4)
ffi.copy(buf, "dogs", 4)
zone = ffi.C.ngx_stream_lua_find_zone(buf, 4)
local val = ffi.new("ngx_stream_lua_value_t[?]", 1)
ffi.copy(buf, "foo", 3)
local rc = ffi.C.ngx_stream_lua_shared_dict_get(zone, buf, 3, val)
ngx.say("foo: rc=", tonumber(rc),
", type=", tonumber(val[0].type),
", val=", tonumber(val[0].value.b))
local val = ffi.new("ngx_stream_lua_value_t[?]", 1)
ffi.copy(buf, "bar", 3)
local rc = ffi.C.ngx_stream_lua_shared_dict_get(zone, buf, 3, val)
ngx.say("bar: rc=", tonumber(rc),
", type=", tonumber(val[0].type),
", val=", tonumber(val[0].value.b))
}
--- stream_response
foo: rc=0, type=1, val=1
bar: rc=0, type=1, val=0
--- no_error_log
[error]
=== TEST 4: key not found
--- stream_config
lua_shared_dict dogs 1m;
--- stream_server_config
content_by_lua_block {
local ffi = require "ffi"
ffi.cdef[[
typedef struct {
size_t len;
char *data;
} ngx_str_t;
typedef struct {
uint8_t type;
union {
int b; /* boolean */
double n; /* number */
ngx_str_t s; /* string */
} value;
} ngx_stream_lua_value_t;
void *ngx_stream_lua_find_zone(char *data, size_t len);
intptr_t ngx_stream_lua_shared_dict_get(void *zone, char *kdata, size_t klen, ngx_stream_lua_value_t *val);
]]
local dogs = ngx.shared.dogs
dogs:flush_all()
local buf = ffi.new("char[?]", 4)
ffi.copy(buf, "dogs", 4)
zone = ffi.C.ngx_stream_lua_find_zone(buf, 4)
local val = ffi.new("ngx_stream_lua_value_t[?]", 1)
ffi.copy(buf, "foo", 3)
local rc = ffi.C.ngx_stream_lua_shared_dict_get(zone, buf, 3, val)
ngx.say("foo: rc=", tonumber(rc))
local val = ffi.new("ngx_stream_lua_value_t[?]", 1)
ffi.copy(buf, "bar", 3)
local rc = ffi.C.ngx_stream_lua_shared_dict_get(zone, buf, 3, val)
ngx.say("bar: rc=", tonumber(rc))
}
--- stream_response
foo: rc=-5
bar: rc=-5
--- no_error_log
[error]
--- SKIP
=== TEST 5: string typed value
--- stream_config
lua_shared_dict dogs 1m;
--- stream_server_config
content_by_lua_block {
local ffi = require "ffi"
ffi.cdef[[
typedef struct {
size_t len;
char *data;
} ngx_str_t;
typedef struct {
uint8_t type;
union {
int b; /* boolean */
double n; /* number */
ngx_str_t s; /* string */
} value;
} ngx_stream_lua_value_t;
void *ngx_stream_lua_find_zone(char *data, size_t len);
intptr_t ngx_stream_lua_shared_dict_get(void *zone, char *kdata, size_t klen, ngx_stream_lua_value_t *val);
]]
local dogs = ngx.shared.dogs
dogs:set("foo", "hello world")
dogs:set("bar", "")
local buf = ffi.new("char[?]", 4)
ffi.copy(buf, "dogs", 4)
zone = ffi.C.ngx_stream_lua_find_zone(buf, 4)
local s = ffi.new("char[?]", 20)
local val = ffi.new("ngx_stream_lua_value_t[?]", 1)
val[0].value.s.len = 20
val[0].value.s.data = s
ffi.copy(buf, "foo", 3)
local rc = ffi.C.ngx_stream_lua_shared_dict_get(zone, buf, 3, val)
ngx.say("foo: rc=", tonumber(rc),
", type=", tonumber(val[0].type),
", val=", ffi.string(val[0].value.s.data, val[0].value.s.len),
", len=", tonumber(val[0].value.s.len))
local val = ffi.new("ngx_stream_lua_value_t[?]", 1)
val[0].value.s.len = 20
val[0].value.s.data = s
ffi.copy(buf, "bar", 3)
local rc = ffi.C.ngx_stream_lua_shared_dict_get(zone, buf, 3, val)
ngx.say("bar: rc=", tonumber(rc),
", type=", tonumber(val[0].type),
", val=", ffi.string(val[0].value.s.data, val[0].value.s.len),
", len=", tonumber(val[0].value.s.len))
}
--- stream_response
foo: rc=0, type=4, val=hello world, len=11
bar: rc=0, type=4, val=, len=0
--- no_error_log
[error]
--- SKIP
=== TEST 6: nil typed value
--- stream_config
lua_shared_dict dogs 1m;
--- stream_server_config
content_by_lua_block {
local ffi = require "ffi"
ffi.cdef[[
typedef struct {
size_t len;
char *data;
} ngx_str_t;
typedef struct {
uint8_t type;
union {
int b; /* boolean */
double n; /* number */
ngx_str_t s; /* string */
} value;
} ngx_stream_lua_value_t;
void *ngx_stream_lua_find_zone(char *data, size_t len);
intptr_t ngx_stream_lua_shared_dict_get(void *zone, char *kdata, size_t klen, ngx_stream_lua_value_t *val);
]]
local dogs = ngx.shared.dogs
dogs:set("foo", nil)
local buf = ffi.new("char[?]", 4)
ffi.copy(buf, "dogs", 4)
zone = ffi.C.ngx_stream_lua_find_zone(buf, 4)
local val = ffi.new("ngx_stream_lua_value_t[?]", 1)
ffi.copy(buf, "foo", 3)
local rc = ffi.C.ngx_stream_lua_shared_dict_get(zone, buf, 3, val)
ngx.say("foo: rc=", tonumber(rc))
}
--- stream_response
foo: rc=-5
--- no_error_log
[error]
--- SKIP
=== TEST 7: find zone (multiple zones)
--- stream_config
lua_shared_dict dogs 1m;
lua_shared_dict cats 1m;
--- stream_server_config
content_by_lua_block {
local ffi = require "ffi"
ffi.cdef[[
void *ngx_stream_lua_find_zone(char *data, size_t len);
]]
local buf = ffi.new("char[?]", 4)
ffi.copy(buf, "cats", 4)
local zone = ffi.C.ngx_stream_lua_find_zone(buf, 4)
local cats = tostring(zone)
ffi.copy(buf, "dogs", 4)
zone = ffi.C.ngx_stream_lua_find_zone(buf, 4)
local dogs = tostring(zone)
ngx.say("dogs == cats ? ", dogs == cats)
-- ngx.say("dogs: ", dogs)
-- ngx.say("cats ", cats)
}
--- stream_response
dogs == cats ? false
--- no_error_log
[error]

View file

@ -1,573 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;use t::StapThread;
our $GCScript = <<_EOC_;
$t::StapThread::GCScript
F(ngx_http_lua_check_broken_connection) {
println("lua check broken conn")
}
F(ngx_http_lua_request_cleanup) {
println("lua req cleanup")
}
_EOC_
our $StapScript = $t::StapThread::StapScript;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4 + 13);
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= '11211';
$ENV{TEST_NGINX_REDIS_PORT} ||= '6379';
#no_shuffle();
no_long_string();
run_tests();
__DATA__
=== TEST 1: sleep + stop
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
ngx.sleep(1)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua req cleanup
delete thread 1
--- timeout: 0.1
--- wait: 1.1
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
--- error_log
stream client prematurely closed connection
=== TEST 2: sleep + stop (log handler still gets called)
TODO
--- SKIP
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
ngx.sleep(1)
log_by_lua_block {
ngx.log(ngx.NOTICE, "here in log by lua")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua req cleanup
delete thread 1
--- timeout: 0.2
--- abort
--- stream_response
--- no_error_log
[error]
--- error_log
stream client prematurely closed connection
here in log by lua
=== TEST 3: sleep + ignore
--- stream_server_config
lua_check_client_abort off;
content_by_lua_block {
ngx.sleep(1)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
terminate 1: ok
delete thread 1
lua req cleanup
--- wait: 1
--- timeout: 0.2
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
=== TEST 4: need body on + sleep + stop (log handler still gets called)
TODO
--- SKIP
--- stream_server_config
lua_check_client_abort on;
lua_need_request_body on;
content_by_lua_block {
ngx.sleep(1)
log_by_lua_block {
ngx.log(ngx.NOTICE, "here in log by lua")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua req cleanup
delete thread 1
--- timeout: 0.2
--- abort
--- stream_response
--- no_error_log
[error]
--- error_log
stream client prematurely closed connection
here in log by lua
=== TEST 5: ngx.req.socket + receive() + sleep + stop
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local sock = ngx.req.socket()
sock:receive()
ngx.sleep(1)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua req cleanup
delete thread 1
--- timeout: 0.2
--- abort
--- stream_request
hello
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
--- error_log
stream client prematurely closed connection
=== TEST 6: ngx.req.socket + receive(N) + sleep + stop
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local sock = ngx.req.socket()
sock:receive(5)
ngx.sleep(1)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua check broken conn
lua req cleanup
delete thread 1
--- wait: 0.1
--- timeout: 0.2
--- abort
--- stream_request chomp
hello
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
--- error_log
stream client prematurely closed connection
=== TEST 7: ngx.req.socket + receive(n) + sleep + stop
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local sock = ngx.req.socket()
sock:receive(2)
ngx.sleep(1)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out_like
^(?:lua check broken conn
terminate 1: ok
delete thread 1
lua req cleanup|lua check broken conn
lua req cleanup
delete thread 1)$
--- wait: 1
--- timeout: 0.2
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
=== TEST 8: ngx.req.socket + m * receive(n) + sleep + stop
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local sock = ngx.req.socket()
sock:receive(2)
sock:receive(2)
sock:receive(1)
ngx.sleep(0.5)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua check broken conn
lua req cleanup
delete thread 1
--- wait: 0.6
--- timeout: 0.2
--- abort
--- stream_request chomp
hello
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
--- error_log
stream client prematurely closed connection
=== TEST 9: ngx.req.socket + receiveuntil + sleep + stop
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local sock = ngx.req.socket()
local it = sock:receiveuntil("\n")
it()
ngx.sleep(1)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua req cleanup
delete thread 1
--- wait: 1
--- timeout: 0.2
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
--- error_log
stream client prematurely closed connection
=== TEST 10: ngx.req.socket + receiveuntil + it(n) + sleep + stop
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local sock = ngx.req.socket()
local it = sock:receiveuntil("\n")
it(2)
it(3)
ngx.sleep(1)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua check broken conn
lua req cleanup
delete thread 1
--- timeout: 0.2
--- wait: 0.1
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
--- error_log
stream client prematurely closed connection
=== TEST 11: cosocket + stop
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local sock, err = ngx.socket.tcp()
if not sock then
ngx.log(ngx.ERR, "failed to get socket: ", err)
return
end
ok, err = sock:connect("127.0.0.1", $TEST_NGINX_REDIS_PORT)
if not ok then
ngx.log(ngx.ERR, "failed to connect: ", err)
return
end
local bytes, err = sock:send("blpop nonexist 2\r\n")
if not bytes then
ngx.log(ngx.ERR, "failed to send query: ", err)
return
end
-- ngx.log(ngx.ERR, "about to receive")
local res, err = sock:receive()
if not res then
ngx.log(ngx.ERR, "failed to receive query: ", err)
return
end
ngx.log(ngx.ERR, "res: ", res)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua req cleanup
delete thread 1
--- wait: 1
--- timeout: 0.2
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
--- error_log
stream client prematurely closed connection
=== TEST 12: ngx.req.socket + receive all + ignore
--- stream_server_config
lua_check_client_abort off;
content_by_lua_block {
local sock = ngx.req.socket()
local res, err, part = sock:receive("*a")
if not res then
ngx.log(ngx.NOTICE, "failed to receive: ", err, ": ", part)
return
end
print("received data: ", res)
}
--- stream_request
hello
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
terminate 1: ok
delete thread 1
lua req cleanup
--- timeout: 0.2
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
--- error_log
received data: hello
=== TEST 13: ngx.req.socket + receive all + stop
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local sock = ngx.req.socket()
local res, err, part = sock:receive("*a")
if not res then
ngx.log(ngx.NOTICE, "failed to receive: ", err, ": ", part)
return
end
error("bad")
}
--- stream_request
hello
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
terminate 1: ok
delete thread 1
lua req cleanup
--- timeout: 0.2
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
=== TEST 14: ngx.req.read_body + sleep + stop (log handler still gets called)
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
ngx.req.read_body()
ngx.sleep(0.1)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
lua check broken conn
lua req cleanup
delete thread 1
--- shutdown: 1
--- stream_response
--- no_error_log
[error]
--- error_log
stream client prematurely closed connection
--- SKIP
=== TEST 15: sleep (default off)
--- stream_server_config
content_by_lua_block {
ngx.sleep(1)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
terminate 1: ok
delete thread 1
lua req cleanup
--- wait: 1
--- timeout: 0.2
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
[alert]
=== TEST 16: ngx.say
--- stream_server_config
#postpone_output 1;
content_by_lua_block {
ngx.sleep(0.2)
for i = 1, 2 do
local ok, err = ngx.say("hello")
if not ok then
ngx.log(ngx.WARN, "say failed: ", err)
return
end
end
}
--- wait: 0.2
--- timeout: 0.1
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
[alert]
--- error_log
say failed: nginx output filter error
=== TEST 17: ngx.print
--- stream_server_config
#postpone_output 1;
content_by_lua_block {
ngx.sleep(0.2)
for i = 1, 2 do
local ok, err = ngx.print("hello")
if not ok then
ngx.log(ngx.WARN, "print failed: ", err)
return
end
end
}
--- wait: 0.2
--- timeout: 0.1
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
[alert]
--- error_log
print failed: nginx output filter error
=== TEST 18: ngx.flush
--- stream_server_config
#postpone_output 1;
content_by_lua_block {
ngx.say("hello")
ngx.sleep(0.2)
local ok, err = ngx.flush()
if not ok then
ngx.log(ngx.WARN, "flush failed: ", err)
return
end
ngx.log(ngx.WARN, "flush succeeded")
}
--- wait: 0.2
--- timeout: 0.1
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
[alert]
--- error_log
flush succeeded
=== TEST 19: ngx.eof
--- stream_server_config
#postpone_output 1;
content_by_lua_block {
ngx.sleep(0.2)
local ok, err = ngx.eof()
if not ok then
ngx.log(ngx.WARN, "eof failed: ", err)
return
end
ngx.log(ngx.WARN, "eof succeeded")
}
--- wait: 0.2
--- timeout: 0.1
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
[alert]
--- error_log
eof succeeded

View file

@ -1,461 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;use t::StapThread;
our $GCScript = <<_EOC_;
$t::StapThread::GCScript
F(ngx_http_lua_check_broken_connection) {
println("lua check broken conn")
}
F(ngx_http_lua_request_cleanup) {
println("lua req cleanup")
}
_EOC_
our $StapScript = $t::StapThread::StapScript;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4 + 27);
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= '11211';
$ENV{TEST_NGINX_REDIS_PORT} ||= '6379';
#no_shuffle();
no_long_string();
run_tests();
__DATA__
=== TEST 1: ignore the client abort event in the user callback
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local ok, err = ngx.on_abort(function ()
ngx.log(ngx.NOTICE, "on abort called")
end)
if not ok then
error("cannot set on_abort: " .. err)
end
ngx.sleep(0.7)
ngx.log(ngx.NOTICE, "main handler done")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out_like chop
^create 2 in 1
lua check broken conn
terminate 2: ok
(?:lua check broken conn
)?terminate 1: ok
delete thread 2
delete thread 1
lua req cleanup
--- timeout: 0.2
--- abort
--- wait: 0.7
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
--- error_log
stream client prematurely closed connection
on abort called
main handler done
=== TEST 2: abort in the user callback
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local ok, err = ngx.on_abort(function ()
ngx.log(ngx.NOTICE, "on abort called")
ngx.exit(444)
end)
if not ok then
error("cannot set on_abort: " .. err)
end
ngx.sleep(0.7)
ngx.log(ngx.NOTICE, "main handler done")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
lua check broken conn
terminate 2: ok
lua req cleanup
delete thread 2
delete thread 1
--- timeout: 0.2
--- wait: 0.1
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
main handler done
--- error_log
stream client prematurely closed connection
on abort called
=== TEST 3: accessing cosocket in callback
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local ok, err = ngx.on_abort(function ()
ngx.log(ngx.NOTICE, "on abort called")
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_REDIS_PORT)
if not ok then
ngx.log(ngx.ERR, "failed to connect to redis: ", err)
ngx.exit(499)
end
local bytes, err = sock:send("flushall\r\n")
if not bytes then
ngx.log(ngx.ERR, "failed to send query: ", err)
ngx.exit(499)
end
local res, err = sock:receive()
if not res then
ngx.log(ngx.ERR, "failed to receive: ", err)
ngx.exit(499)
end
ngx.log(ngx.NOTICE, "callback done: ", res)
ngx.exit(499)
end)
if not ok then
error("cannot set on_abort: " .. err)
end
ngx.sleep(0.7)
ngx.log(ngx.NOTICE, "main handler done")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
lua check broken conn
terminate 2: ok
lua req cleanup
delete thread 2
delete thread 1
--- timeout: 0.2
--- abort
--- wait: 0.5
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
main handler done
--- error_log
stream client prematurely closed connection
on abort called
callback done: +OK
=== TEST 4: ignore the client abort event in the user callback (no check)
--- stream_server_config
lua_check_client_abort off;
content_by_lua_block {
local ok, err = ngx.on_abort(function ()
ngx.log(ngx.NOTICE, "on abort called")
end)
if not ok then
ngx.say("cannot set on_abort: ", err)
return
end
ngx.sleep(0.7)
ngx.log(ngx.NOTICE, "main handler done")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
terminate 1: ok
delete thread 1
lua req cleanup
--- timeout: 0.2
--- abort
--- stream_response
cannot set on_abort: lua_check_client_abort is off
--- no_error_log
stream client prematurely closed connection
on abort called
main handler done
=== TEST 5: regsiter on_abort callback but no client abortion
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local ok, err = ngx.on_abort(function ()
ngx.log(ngx.NOTICE, "on abort called")
end)
if not ok then
error("cannot set on_abort: " .. err)
end
ngx.say("done")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
terminate 1: ok
delete thread 1
lua req cleanup
delete thread 2
--- stream_response
done
--- no_error_log
[error]
stream client prematurely closed connection
on abort called
main handler done
=== TEST 6: ignore the client abort event in the user callback (uthread)
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local ok, err = ngx.on_abort(function ()
ngx.log(ngx.NOTICE, "on abort called")
end)
if not ok then
error("cannot set on_abort: " .. err)
end
ngx.thread.spawn(function ()
ngx.sleep(0.7)
ngx.log(ngx.NOTICE, "main handler done")
end)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
create 3 in 1
spawn user thread 3 in 1
terminate 1: ok
delete thread 1
lua check broken conn
terminate 2: ok
delete thread 2
terminate 3: ok
delete thread 3
lua req cleanup
--- timeout: 0.2
--- abort
--- wait: 0.7
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
--- error_log
stream client prematurely closed connection
on abort called
main handler done
=== TEST 7: abort in the user callback (uthread)
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local ok, err = ngx.on_abort(function ()
ngx.log(ngx.NOTICE, "on abort called")
ngx.exit(444)
end)
if not ok then
error("cannot set on_abort: " .. err)
end
ngx.thread.spawn(function ()
ngx.sleep(0.7)
ngx.log(ngx.NOTICE, "main handler done")
end)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
create 3 in 1
spawn user thread 3 in 1
terminate 1: ok
delete thread 1
lua check broken conn
terminate 2: ok
lua req cleanup
delete thread 2
delete thread 3
--- timeout: 0.2
--- wait: 0.1
--- abort
--- stream_response
receive stream response error: timeout
--- no_error_log
[error]
main handler done
--- error_log
stream client prematurely closed connection
on abort called
=== TEST 8: regsiter on_abort callback but no client abortion (uthread)
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local ok, err = ngx.on_abort(function ()
ngx.log(ngx.NOTICE, "on abort called")
end)
if not ok then
error("cannot set on_abort: " .. err)
end
ngx.thread.spawn(function ()
ngx.sleep(0.1)
ngx.say("done")
end)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
create 3 in 1
spawn user thread 3 in 1
terminate 1: ok
delete thread 1
terminate 3: ok
delete thread 3
lua req cleanup
delete thread 2
--- stream_response
done
--- no_error_log
[error]
stream client prematurely closed connection
on abort called
main handler done
=== TEST 9: regsiter on_abort callback multiple times
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local ok, err = ngx.on_abort(function ()
ngx.log(ngx.NOTICE, "on abort called")
end)
if not ok then
ngx.say("1: cannot set on_abort: " .. err)
return
end
local ok, err = ngx.on_abort(function ()
ngx.log(ngx.NOTICE, "on abort called")
end)
if not ok then
ngx.say("2: cannot set on_abort: " .. err)
return
end
ngx.thread.spawn(function ()
ngx.sleep(0.1)
ngx.say("done")
end)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
terminate 1: ok
delete thread 1
lua req cleanup
delete thread 2
--- stream_response
2: cannot set on_abort: duplicate call
--- no_error_log
[error]
=== TEST 10: regsiter on_abort callback but no client abortion (2 uthreads and 1 pending)
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local ok, err = ngx.on_abort(function ()
ngx.log(ngx.NOTICE, "on abort called")
end)
if not ok then
error("cannot set on_abort: " .. err)
end
ngx.thread.spawn(function ()
ngx.sleep(0.1)
ngx.say("done")
ngx.exit(200)
end)
ngx.thread.spawn(function ()
ngx.sleep(100)
end)
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
create 3 in 1
spawn user thread 3 in 1
create 4 in 1
spawn user thread 4 in 1
terminate 1: ok
delete thread 1
terminate 3: ok
lua req cleanup
delete thread 2
delete thread 3
delete thread 4
--- wait: 0.5
--- stream_response
done
--- no_error_log
[error]
stream client prematurely closed connection
on abort called
main handler done

File diff suppressed because it is too large Load diff

View file

@ -1,239 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 7);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: ngx.say()
--- stream_server_config
content_by_lua_block {
local function f()
ngx.say("hello")
end
local ok, err = ngx.timer.at(0.05, f)
if not ok then
ngx.say("failed to set timer: ", err)
return
end
ngx.say("registered timer")
}
--- config
--- stap2
F(ngx_stream_lua_timer_handler) {
println("lua timer handler")
}
--- stream_response
registered timer
--- wait: 0.1
--- no_error_log
[alert]
[crit]
--- error_log eval
[
qr/\[error\] .*? runtime error: content_by_lua\(nginx\.conf:\d+\):3: API disabled in the context of ngx\.timer/,
"lua ngx.timer expired",
"stream lua close fake stream connection"
]
=== TEST 2: ngx.print()
--- stream_server_config
content_by_lua_block {
local function f()
ngx.print("hello")
end
local ok, err = ngx.timer.at(0.05, f)
if not ok then
ngx.say("failed to set timer: ", err)
return
end
ngx.say("registered timer")
}
--- config
--- stap2
F(ngx_stream_lua_timer_handler) {
println("lua timer handler")
}
--- stream_response
registered timer
--- wait: 0.1
--- no_error_log
[alert]
[crit]
--- error_log eval
[
qr/\[error\] .*? runtime error: content_by_lua\(nginx\.conf:\d+\):3: API disabled in the context of ngx\.timer/,
"lua ngx.timer expired",
"stream lua close fake stream connection"
]
=== TEST 3: ngx.flush()
--- stream_server_config
content_by_lua_block {
local function f()
ngx.flush()
end
local ok, err = ngx.timer.at(0.05, f)
if not ok then
ngx.say("failed to set timer: ", err)
return
end
ngx.say("registered timer")
}
--- config
--- stap2
F(ngx_stream_lua_timer_handler) {
println("lua timer handler")
}
--- stream_response
registered timer
--- wait: 0.1
--- no_error_log
[alert]
[crit]
--- error_log eval
[
qr/\[error\] .*? runtime error: content_by_lua\(nginx\.conf:\d+\):3: API disabled in the context of ngx\.timer/,
"lua ngx.timer expired",
"stream lua close fake stream connection"
]
=== TEST 4: ngx.on_abort
--- stream_server_config
content_by_lua_block {
local function f()
ngx.on_abort(f)
end
local ok, err = ngx.timer.at(0.05, f)
if not ok then
ngx.say("failed to set timer: ", err)
return
end
ngx.say("registered timer")
}
--- config
--- stap2
F(ngx_stream_lua_timer_handler) {
println("lua timer handler")
}
--- stream_response
registered timer
--- wait: 0.1
--- no_error_log
[alert]
[crit]
--- error_log eval
[
qr/\[error\] .*? runtime error: content_by_lua\(nginx\.conf:\d+\):3: API disabled in the context of ngx\.timer/,
"lua ngx.timer expired",
"stream lua close fake stream connection"
]
=== TEST 5: ngx.eof
--- stream_server_config
content_by_lua_block {
local function f()
ngx.eof()
end
local ok, err = ngx.timer.at(0.05, f)
if not ok then
ngx.say("failed to set timer: ", err)
return
end
ngx.say("registered timer")
}
--- config
--- stap2
F(ngx_stream_lua_timer_handler) {
println("lua timer handler")
}
--- stream_response
registered timer
--- wait: 0.1
--- no_error_log
[alert]
[crit]
--- error_log eval
[
qr/\[error\] .*? runtime error: content_by_lua\(nginx\.conf:\d+\):3: API disabled in the context of ngx\.timer/,
"lua ngx.timer expired",
"stream lua close fake stream connection"
]
=== TEST 6: ngx.req.socket
--- stream_server_config
content_by_lua_block {
local function f()
local sock, err = ngx.req.socket()
if not sock then
ngx.log(ngx.ERR, "failed to get req sock: ", err)
end
end
local ok, err = ngx.timer.at(0.05, f)
if not ok then
ngx.say("failed to set timer: ", err)
return
end
ngx.say("registered timer")
}
--- config
--- stap2
F(ngx_stream_lua_timer_handler) {
println("lua timer handler")
}
--- stream_response
registered timer
--- wait: 0.1
--- no_error_log
[alert]
[crit]
--- error_log eval
[
qr/\[error\] .*? runtime error: content_by_lua\(nginx\.conf:\d+\):3: API disabled in the context of ngx\.timer/,
"lua ngx.timer expired",
"stream lua close fake stream connection"
]

File diff suppressed because it is too large Load diff

View file

@ -1,477 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
our $SkipReason;
BEGIN {
if ($ENV{TEST_NGINX_CHECK_LEAK}) {
$SkipReason = "unavailable for the hup tests";
} else {
$ENV{TEST_NGINX_USE_HUP} = 1;
undef $ENV{TEST_NGINX_USE_STAP};
}
}
use Test::Nginx::Socket::Lua::Stream $SkipReason ? (skip_all => $SkipReason) : ();
use t::StapThread;
our $GCScript = $t::StapThread::GCScript;
our $StapScript = $t::StapThread::StapScript;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * 73;
#no_diff();
no_long_string();
our $HtmlDir = html_dir;
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_HTML_DIR} = $HtmlDir;
worker_connections(1024);
run_tests();
__DATA__
=== TEST 1: single timer
--- stream_server_config
content_by_lua_block {
local f, err = io.open("$TEST_NGINX_SERVER_ROOT/logs/nginx.pid", "r")
if not f then
ngx.say("failed to open nginx.pid: ", err)
return
end
local pid = f:read()
-- ngx.say("master pid: [", pid, "]")
f:close()
local i = 0
local function f(premature)
i = i + 1
print("timer prematurely expired: ", premature)
print("in callback: hello, ", i)
end
local ok, err = ngx.timer.at(3, f)
if not ok then
ngx.say("failed to set timer: ", err)
return
end
ngx.say("registered timer")
os.execute("kill -HUP " .. pid)
}
--- config
--- stream_response
registered timer
--- wait: 0.3
--- no_error_log
[error]
[alert]
[crit]
in callback: hello, 2
timer prematurely expired: false
--- error_log
lua abort pending timers
lua ngx.timer expired
stream lua close fake stream connection
in callback: hello, 1
timer prematurely expired: true
=== TEST 2: multiple timers
--- stream_server_config
content_by_lua_block {
local f, err = io.open("$TEST_NGINX_SERVER_ROOT/logs/nginx.pid", "r")
if not f then
ngx.say("failed to open nginx.pid: ", err)
return
end
local pid = f:read()
-- ngx.say("master pid: [", pid, "]")
f:close()
local i = 0
local function f(premature)
i = i + 1
print("timer prematurely expired: ", premature)
print("in callback: hello, ", i, "!")
end
for i = 1, 10 do
local ok, err = ngx.timer.at(3, f)
if not ok then
ngx.say("failed to set timer: ", err)
return
end
end
ngx.say("registered timers")
os.execute("kill -HUP " .. pid)
}
--- config
--- stream_response
registered timers
--- wait: 0.3
--- no_error_log
[error]
[alert]
[crit]
in callback: hello, 11!
timer prematurely expired: false
--- error_log
lua abort pending timers
lua ngx.timer expired
stream lua close fake stream connection
in callback: hello, 1!
in callback: hello, 2!
in callback: hello, 3!
in callback: hello, 4!
in callback: hello, 5!
in callback: hello, 6!
in callback: hello, 7!
in callback: hello, 8!
in callback: hello, 9!
in callback: hello, 10!
timer prematurely expired: true
=== TEST 3: trying to add new timer after HUP reload
--- stream_server_config
content_by_lua_block {
local f, err = io.open("$TEST_NGINX_SERVER_ROOT/logs/nginx.pid", "r")
if not f then
ngx.say("failed to open nginx.pid: ", err)
return
end
local pid = f:read()
-- ngx.say("master pid: [", pid, "]")
f:close()
local function f(premature)
print("timer prematurely expired: ", premature)
local ok, err = ngx.timer.at(3, f)
if not ok then
print("failed to register a new timer after reload: ", err)
else
print("registered a new timer after reload")
end
end
local ok, err = ngx.timer.at(3, f)
if not ok then
ngx.say("failed to set timer: ", err)
return
end
ngx.say("registered timer")
os.execute("kill -HUP " .. pid)
}
--- config
--- stream_response
registered timer
--- wait: 0.2
--- no_error_log
[error]
[alert]
[crit]
in callback: hello, 2
timer prematurely expired: false
--- error_log
lua abort pending timers
lua ngx.timer expired
stream lua close fake stream connection
timer prematurely expired: true
failed to register a new timer after reload: process exiting, context: ngx.timer
=== TEST 4: trying to add new timer after HUP reload
--- stream_server_config
content_by_lua_block {
local f, err = io.open("$TEST_NGINX_SERVER_ROOT/logs/nginx.pid", "r")
if not f then
ngx.say("failed to open nginx.pid: ", err)
return
end
local pid = f:read()
-- ngx.say("master pid: [", pid, "]")
f:close()
local function g(premature)
print("g: timer prematurely expired: ", premature)
print("g: exiting=", ngx.worker.exiting())
end
local function f(premature)
print("f: timer prematurely expired: ", premature)
print("f: exiting=", ngx.worker.exiting())
local ok, err = ngx.timer.at(0, g)
if not ok then
print("f: failed to register a new timer after reload: ", err)
else
print("f: registered a new timer after reload")
end
end
local ok, err = ngx.timer.at(3, f)
if not ok then
ngx.say("failed to set timer: ", err)
return
end
ngx.say("registered timer")
os.execute("kill -HUP " .. pid)
}
--- config
--- stream_response
registered timer
--- wait: 0.2
--- no_error_log
[error]
[alert]
[crit]
in callback: hello, 2
failed to register a new timer after reload
--- error_log
lua abort pending timers
lua ngx.timer expired
stream lua close fake stream connection
f: timer prematurely expired: true
f: registered a new timer after reload
f: exiting=true
g: timer prematurely expired: false
g: exiting=true
=== TEST 5: HUP reload should abort pending timers
--- stream_server_config
content_by_lua_block {
local f, err = io.open("$TEST_NGINX_SERVER_ROOT/logs/nginx.pid", "r")
if not f then
ngx.say("failed to open nginx.pid: ", err)
return
end
local pid = f:read()
-- ngx.say("master pid: [", pid, "]")
f:close()
local function f(premature)
print("f: timer prematurely expired: ", premature)
print("f: exiting=", ngx.worker.exiting())
end
for i = 1, 100 do
local ok, err = ngx.timer.at(3 + i, f)
if not ok then
ngx.say("failed to set timer: ", err)
return
end
end
ngx.say("ok")
os.execute("kill -HUP " .. pid)
}
--- config
--- stream_response
ok
--- wait: 0.5
--- no_error_log
[error]
[alert]
[crit]
in callback: hello, 2
failed to register a new timer after reload
--- grep_error_log eval: qr/lua found \d+ pending timers/
--- grep_error_log_out
lua found 100 pending timers
=== TEST 6: HUP reload should abort pending timers (coroutine + cosocket)
TODO
--- SKIP
--- http_config
#lua_shared_dict test_dict 1m;
server {
listen $TEST_NGINX_RAND_PORT_1;
location = /foo {
echo 'foo';
}
}
--- stream_server_config
content_by_lua_block {
local stream_req = {"GET /foo HTTP/1.1", "Host: localhost:1234", "", ""}
stream_req = table.concat(stream_req, "\r\n")
-- Connect the socket
local sock = ngx.socket.tcp()
local ok,err = sock:connect("127.0.0.1", $TEST_NGINX_RAND_PORT_1)
if not ok then
ngx.log(ngx.ERR, err)
end
-- Send the request
local ok,err = sock:send(stream_req)
-- Get Headers
repeat
local line, err = sock:receive("*l")
until not line or string.find(line, "^%s*$")
function foo()
repeat
-- Get and read chunk
local line, err = sock:receive("*l")
local len = tonumber(line)
if len > 0 then
local chunk, err = sock:receive(len)
coroutine.yield(chunk)
sock:receive(2)
else
-- Read last newline
sock:receive(2)
end
until len == 0
end
co = coroutine.create(foo)
repeat
local chunk = select(2,coroutine.resume(co))
until chunk == nil
-- Breaks the timer
sock:setkeepalive()
ngx.say("ok")
log_by_lua_block {
local background_thread
background_thread = function(premature)
ngx.log(ngx.DEBUG, premature)
if premature then
ngx.shared["test_dict"]:delete("background_flag")
return
end
local ok, err = ngx.timer.at(1, background_thread)
local f, err = io.open("$TEST_NGINX_SERVER_ROOT/logs/nginx.pid", "r")
if not f then
ngx.say("failed to open nginx.pid: ", err)
return
end
local pid = f:read()
-- ngx.say("master pid: [", pid, "]")
f:close()
os.execute("kill -HUP " .. pid)
end
local dict = ngx.shared["test_dict"]
if dict:get("background_flag") == nil then
local ok, err = ngx.timer.at(0, background_thread)
if ok then
dict:set("test_dict", 1)
end
end
}
--- config
location = /foo {--- stream_response
ok
--- wait: 0.3
--- no_error_log
[error]
[alert]
[crit]
in callback: hello, 2
failed to register a new timer after reload
--- grep_error_log eval: qr/lua found \d+ pending timers/
--- grep_error_log_out
lua found 1 pending timers
=== TEST 7: HUP reload should abort pending timers (fuzz test)
--- stream_config
lua_max_pending_timers 8192;
--- stream_server_config
content_by_lua_block {
local job = function(premature, kill)
if premature then
return
end
if kill then
local f, err = assert(io.open("$TEST_NGINX_SERVER_ROOT/logs/nginx.pid", "r"))
local pid = f:read()
-- ngx.say("master pid: [", pid, "]")
f:close()
os.execute("kill -HUP " .. pid)
end
end
math.randomseed(ngx.time())
local rand = math.random
local newtimer = ngx.timer.at
for i = 1, 8191 do
local delay = rand(4096)
local ok, err = newtimer(delay, job, false)
if not ok then
ngx.say("failed to create timer at ", delay, ": ", err)
return
end
end
local ok, err = newtimer(0, job, true)
if not ok then
ngx.say("failed to create the killer timer: ", err)
return
end
ngx.say("ok")
}
--- config
--- stream_response
ok
--- wait: 0.3
--- no_error_log
[error]
[alert]
--- grep_error_log eval: qr/stream lua found \d+ pending timers/
--- grep_error_log_out
stream lua found 8191 pending timers
--- timeout: 20

View file

@ -1,39 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: ngx.config.debug
--- stream_server_config
content_by_lua_block {
ngx.say("debug: ", ngx.config.debug)
}
--- stream_response_like chop
^debug: (?:true|false)$
--- no_error_log
[error]
=== TEST 2: ngx.config.subystem
--- stream_server_config
content_by_lua_block {
ngx.say("subsystem: ", ngx.config.subsystem)
}
--- stream_response
subsystem: stream
--- no_error_log
[error]

View file

@ -1,67 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
#log_level("warn");
no_long_string();
run_tests();
__DATA__
=== TEST 1: \0
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.quote_sql_str("a\0b\0"))
}
--- config
--- stream_response
'a\0b\0'
--- no_error_log
[error]
=== TEST 2: \t
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.quote_sql_str("a\tb\t"))
}
--- config
--- stream_response
'a\tb\t'
--- no_error_log
[error]
=== TEST 3: \b
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.quote_sql_str("a\bb\b"))
}
--- config
--- stream_response
'a\bb\b'
--- no_error_log
[error]
=== TEST 4: \Z
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.quote_sql_str("a\026b\026"))
}
--- config
--- stream_response
'a\Zb\Z'
--- no_error_log
[error]

View file

@ -1,576 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => repeat_each() * 49;
our $HtmlDir = html_dir;
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
#log_level 'warn';
log_level 'debug';
no_long_string();
#no_diff();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
local data, err = sock:receive(5)
if not data then
ngx.log(ngx.ERR, "server: failed to receive: ", err)
return
end
local bytes, err = sock:send("1: received: " .. data .. "\n")
if not bytes then
ngx.log(ngx.ERR, "server: failed to send: ", err)
return
end
}
--- stream_request: hello
--- stream_response
1: received: hello
--- no_error_log
stream lua socket tcp_nodelay
[error]
=== TEST 2: multiple raw req sockets
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
local sock2, err = ngx.req.socket(true)
if not sock2 then
ngx.log(ngx.ERR, "server: failed to get raw req socket2: ", err)
return
end
}
--- stap2
F(ngx_stream_header_filter) {
println("header filter")
}
F(ngx_stream_lua_req_socket) {
println("lua req socket")
}
--- stream_response
--- error_log
server: failed to get raw req socket2: duplicate call
=== TEST 3: ngx.say after ngx.req.socket(true)
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
local ok, err = ngx.say("ok")
if not ok then
ngx.log(ngx.ERR, "failed to say: ", err)
return
end
}
--- stream_response
ok
--- no_error_log
[error]
=== TEST 4: ngx.print after ngx.req.socket(true)
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
local ok, err = ngx.print("ok")
if not ok then
ngx.log(ngx.ERR, "failed to print: ", err)
return
end
}
--- stream_response chomp
ok
--- no_error_log
[error]
=== TEST 5: ngx.eof after ngx.req.socket(true)
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
local ok, err = ngx.eof()
if not ok then
ngx.log(ngx.ERR, "failed to eof: ", err)
return
end
}
--- config
server_tokens off;
--- stream_response
--- no_error_log
[error]
=== TEST 6: ngx.flush after ngx.req.socket(true)
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
local ok, err = ngx.flush()
if not ok then
ngx.log(ngx.ERR, "failed to flush: ", err)
return
end
}
--- stream_response
--- no_error_log
[error]
=== TEST 7: receive timeout
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
sock:settimeout(100)
local data, err, partial = sock:receive(10)
if not data then
ngx.log(ngx.ERR, "server: 1: failed to receive: ", err, ", received: ", partial)
end
data, err, partial = sock:receive(10)
if not data then
ngx.log(ngx.ERR, "server: 2: failed to receive: ", err, ", received: ", partial)
end
ngx.exit(444)
}
--- stream_request chomp
ab
--- stream_response
--- wait: 0.1
--- error_log
stream lua tcp socket read timed out
server: 1: failed to receive: timeout, received: ab
server: 2: failed to receive: timeout, received:
--- no_error_log
[alert]
=== TEST 8: on_abort called during ngx.sleep()
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local ok, err = ngx.on_abort(function (premature)
ngx.log(ngx.WARN, "mysock handler aborted") end)
if not ok then
ngx.log(ngx.ERR, "failed to set on_abort handler: ", err)
return
end
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
local data, err = sock:receive(5)
if not data then
ngx.log(ngx.ERR, "server: failed to receive: ", err)
return
end
print("msg received: ", data)
local bytes, err = sock:send("1: received: " .. data .. "\n")
if not bytes then
ngx.log(ngx.ERR, "server: failed to send: ", err)
return
end
ngx.sleep(1)
}
--- stream_request chomp
hello
--- stream_response
receive stream response error: timeout
--- abort
--- timeout: 0.2
--- error_log
mysock handler aborted
msg received: hello
--- no_error_log
[error]
--- wait: 1.1
=== TEST 9: on_abort called during sock:receive()
--- stream_server_config
lua_check_client_abort on;
content_by_lua_block {
local ok, err = ngx.on_abort(function (premature) ngx.log(ngx.WARN, "mysock handler aborted") end)
if not ok then
ngx.log(ngx.ERR, "failed to set on_abort handler: ", err)
return
end
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
local data, err = sock:receive(5)
if not data then
ngx.log(ngx.ERR, "server: failed to receive: ", err)
return
end
print("msg received: ", data)
local bytes, err = sock:send("1: received: " .. data .. "\n")
if not bytes then
ngx.log(ngx.ERR, "server: failed to send: ", err)
return
end
local data, err = sock:receive()
if not data then
ngx.log(ngx.WARN, "failed to receive a line: ", err)
return
end
}
--- stream_response
receive stream response error: timeout
--- timeout: 0.2
--- abort
--- error_log
server: failed to receive: client aborted
--- wait: 0.1
=== TEST 10: receiveuntil
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
local reader = sock:receiveuntil("rld")
local data, err = reader()
if not data then
ngx.log(ngx.ERR, "server: failed to receive: ", err)
return
end
local bytes, err = sock:send("1: received: " .. data .. "\n")
if not bytes then
ngx.log(ngx.ERR, "server: failed to send: ", err)
return
end
local LINGERING_TIME = 30 -- 30 seconds
local LINGERING_TIMEOUT = 5000 -- 5 seconds
local ok, err = sock:shutdown("send")
if not ok then
ngx.log(ngx.ERR, "failed to shutdown ", err)
return
end
local deadline = ngx.time() + LINGERING_TIME
sock:settimeouts(nil, nil, LINGERING_TIMEOUT)
repeat
local data, _, partial = sock:receive(1024)
until (not data and not partial) or ngx.time() >= deadline
}
--- stream_request
hello, world
--- stream_response
1: received: hello, wo
--- error_log
stream lua shutdown socket write direction
attempt to receive data on a closed socket
=== TEST 11: request body not read yet
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
local data, err = sock:receive(5)
if not data then
ngx.log(ngx.ERR, "failed to receive: ", err)
return
end
local ok, err = sock:send("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n" .. data)
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
return
end
local res, err = sock:shutdown('send')
if not res then
ngx.log(ngx.ERR, "server: failed to shutdown: ", err)
return
end
}
--- stream_request
hello
--- stream_response eval
"HTTP/1.1 200 OK\r
Content-Length: 5\r
\r
hello"
--- no_error_log
[error]
=== TEST 12: read chunked request body with raw req socket
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "failed to new: ", err)
return
end
local function myerr(...)
ngx.log(ngx.ERR, ...)
return ngx.exit(400)
end
local num = tonumber
local MAX_CHUNKS = 1000
local eof = false
local chunks = {}
for i = 1, MAX_CHUNKS do
local line, err = sock:receive()
if not line then
myerr("failed to receive chunk size: ", err)
end
local size = num(line, 16)
if not size then
myerr("bad chunk size: ", line)
end
if size == 0 then -- last chunk
-- receive the last line
line, err = sock:receive()
if not line then
myerr("failed to receive last chunk: ", err)
end
if line ~= "" then
myerr("bad last chunk: ", line)
end
eof = true
break
end
local chunk, err = sock:receive(size)
if not chunk then
myerr("failed to receive chunk of size ", size, ": ", err)
end
local data, err = sock:receive(2)
if not data then
myerr("failed to receive chunk terminator: ", err)
end
if data ~= "\r\n" then
myerr("bad chunk terminator: ", data)
end
chunks[i] = chunk
end
if not eof then
myerr("too many chunks (more than ", MAX_CHUNKS, ")")
end
local concat = table.concat
local body = concat{"got ", #chunks, " chunks.\nrequest body: "}
.. concat(chunks) .. "\n"
local ok, err = sock:send(body)
if not ok then
myerr("failed to send response: ", err)
end
}
--- config
--- stream_request eval
"5\r
hey, \r
b\r
hello world\r
0\r
\r
"
--- stream_response
got 2 chunks.
request body: hey, hello world
--- no_error_log
[error]
[alert]
=== TEST 13: shutdown can only be called once and prevents all further output
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
local data, err = sock:receive(5)
if not data then
ngx.log(ngx.ERR, "failed to receive: ", err)
return
end
local ok, err = sock:send("it works\n")
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
return
end
local ok, err = sock:shutdown("send")
if not ok then
ngx.log(ngx.ERR, "failed to shutdown ", err)
return
end
ok, err = sock:shutdown("send")
if ok or err ~= "already shutdown" then
ngx.log(ngx.ERR, "shutdown called multiple times without proper error: ", err)
return
end
ok, err = ngx.say("this should not work")
if ok or err ~= "seen eof" then
ngx.log(ngx.ERR, "ngx.say completed without proper error: ", err)
return
end
ok, err = sock:send("this should not work")
if ok or err ~= "closed" then
ngx.log(ngx.ERR, "sock:send completed without proper error: ", err)
return
end
}
--- stream_request
hello
--- stream_response
it works
--- error_log
stream lua shutdown socket write direction
=== TEST 14: simulated lingering close
--- stream_server_config
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
local data, err = sock:receive(5)
if not data then
ngx.log(ngx.ERR, "failed to receive: ", err)
return
end
local ok, err = sock:shutdown("send")
if not ok then
ngx.log(ngx.ERR, "failed to shutdown ", err)
return
end
sock:settimeouts(nil, nil, 5000)
repeat
local data = sock:receive(1024)
until not data
}
--- stream_request
1234567890
--- error_log
stream lua shutdown socket write direction

View file

@ -1,102 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
BEGIN {
if (!defined $ENV{LD_PRELOAD}) {
$ENV{LD_PRELOAD} = '';
}
if ($ENV{LD_PRELOAD} !~ /\bmockeagain\.so\b/) {
$ENV{LD_PRELOAD} = "mockeagain.so $ENV{LD_PRELOAD}";
}
if ($ENV{MOCKEAGAIN} eq 'r') {
$ENV{MOCKEAGAIN} = 'rw';
} else {
$ENV{MOCKEAGAIN} = 'w';
}
$ENV{TEST_NGINX_EVENT_TYPE} = 'poll';
$ENV{MOCKEAGAIN_WRITE_TIMEOUT_PATTERN} = 'hello, world';
$ENV{TEST_NGINX_POSTPONE_OUTPUT} = 1;
}
use Test::Nginx::Socket::Lua::Stream;use t::StapThread;
our $GCScript = $t::StapThread::GCScript;
our $StapScript = $t::StapThread::StapScript;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3 + 2);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: pending response data
--- stream_server_config
#postpone_output 1;
content_by_lua_block {
ngx.say("hello")
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
}
--- config
server_tokens off;
--- stream_request
--- stap2
F(ngx_stream_header_filter) {
println("header filter")
}
F(ngx_stream_lua_req_socket) {
println("lua req socket")
}
--- stream_response
hello
--- error_log
server: failed to get raw req socket: pending data to write
=== TEST 2: send timeout
--- stream_server_config
#postpone_output 1;
content_by_lua_block {
local sock, err = ngx.req.socket(true)
if not sock then
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
return
end
sock:settimeout(100)
local ok, err = sock:send("hello, world!")
if not ok then
ngx.log(ngx.ERR, "server: failed to send: ", err)
end
ngx.exit(444)
}
--- config
server_tokens off;
--- stream_request
--- stream_response_like chomp
^received \d+ bytes of response data\.$
--- log_stream_response
--- error_log
stream lua tcp socket write timed out
server: failed to send: timeout
--- no_error_log
[alert]

View file

@ -1,28 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
#repeat_each(1);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: content_by_lua
--- stream_server_config
content_by_lua_block {
ngx.say("prefix: ", ngx.config.prefix())
}
--- stream_response_like chop
^prefix: \/\S+$
--- no_error_log
[error]

View file

@ -1,804 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3 + 1);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: sanity
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "([0-9]+)", "jo")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
end
ngx.say("not matched!")
end
}
--- stream_response
from: 8
to: 11
matched: 1234
--- no_error_log
[error]
=== TEST 2: empty matched string
--- stream_server_config
content_by_lua_block {
local s = "hello, world"
local from, to, err = ngx.re.find(s, "[0-9]*")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
end
ngx.say("not matched!")
end
}
--- stream_response
from: 1
to: 0
matched:
--- no_error_log
[error]
=== TEST 3: multiple captures (with o)
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "([a-z]+).*?([0-9]{2})[0-9]+", "o")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
ngx.say("not matched!")
end
}
--- stream_response
from: 1
to: 11
matched: hello, 1234
--- no_error_log
[error]
=== TEST 4: not matched
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "foo")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
ngx.say("not matched.")
end
}
--- stream_response
not matched.
--- no_error_log
[error]
=== TEST 5: case sensitive by default
--- stream_server_config
content_by_lua_block {
local from = ngx.re.find("hello, 1234", "HELLO")
if from then
ngx.say(from)
else
ngx.say("not matched.")
end
}
--- stream_response
not matched.
--- no_error_log
[error]
=== TEST 6: case insensitive
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "HELLO", "i")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
ngx.say("not matched.")
end
}
--- stream_response
from: 1
to: 5
matched: hello
--- no_error_log
[error]
=== TEST 7: UTF-8 mode
--- stream_server_config
content_by_lua_block {
local s = "hello章亦春"
local from, to, err = ngx.re.find(s, "HELLO.{2}", "iu")
if not from then
ngx.say("FAIL: ", err)
return
end
ngx.say(string.sub(s, from, to))
}
--- stream_response_like chop
^(?:FAIL: bad argument \#2 to '\?' \(pcre_compile\(\) failed: this version of PCRE is not compiled with PCRE_UTF8 support in "HELLO\.\{2\}" at "HELLO\.\{2\}"\)|hello章亦)$
--- no_error_log
[error]
=== TEST 8: multi-line mode (^ at line head)
--- stream_server_config
content_by_lua_block {
local s = "hello\nworld"
local from, to, err = ngx.re.find(s, "^world", "m")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
ngx.say("not matched.")
end
}
--- stream_response
from: 7
to: 11
matched: world
--- no_error_log
[error]
=== TEST 9: multi-line mode (. does not match \n)
--- stream_server_config
content_by_lua_block {
local s = "hello\nworld"
local from, to, err = ngx.re.find(s, ".*", "m")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
ngx.say("not matched.")
end
}
--- stream_response
from: 1
to: 5
matched: hello
--- no_error_log
[error]
=== TEST 10: single-line mode (^ as normal)
--- stream_server_config
content_by_lua_block {
local s = "hello\nworld"
local from, to, err = ngx.re.find(s, "^world", "s")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
ngx.say("not matched.")
end
}
--- stream_response
not matched.
--- no_error_log
[error]
=== TEST 11: single-line mode (dot all)
--- stream_server_config
content_by_lua_block {
local s = "hello\nworld"
local from, to, err = ngx.re.find(s, ".*", "s")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
ngx.say("not matched.")
end
}
--- stream_response
from: 1
to: 11
matched: hello
world
--- no_error_log
[error]
=== TEST 12: extended mode (ignore whitespaces)
--- stream_server_config
content_by_lua_block {
local s = "hello\nworld"
local from, to, err = ngx.re.find(s, "\\w \\w", "x")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
ngx.say("not matched.")
end
}
--- stream_response
from: 1
to: 2
matched: he
--- no_error_log
[error]
=== TEST 13: bad pattern
--- stream_server_config
content_by_lua_block {
local s = "hello\nworld"
local from, to, err = ngx.re.find(s, "(abc")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
else
ngx.say("not matched.")
end
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
=== TEST 14: bad option
--- stream_server_config
content_by_lua_block {
local s = "hello\nworld"
local from, to, err = ngx.re.find(s, ".*", "H")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
return
end
ngx.say("not matched.")
end
}
--- stream_response
--- error_log
unknown flag "H"
=== TEST 15: anchored match (failed)
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "([0-9]+)", "a")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
return
end
ngx.say("not matched.")
end
}
--- stream_response
not matched.
--- no_error_log
[error]
=== TEST 16: anchored match (succeeded)
--- stream_server_config
content_by_lua_block {
local s = "1234, hello"
local from, to, err = ngx.re.find(s, "([0-9]+)", "a")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
return
end
ngx.say("not matched.")
end
}
--- stream_response
from: 1
to: 4
matched: 1234
--- no_error_log
[error]
=== TEST 17: match with ctx but no pos
--- stream_server_config
content_by_lua_block {
local ctx = {}
local from, to = ngx.re.find("1234, hello", "([0-9]+)", "", ctx)
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("pos: ", ctx.pos)
else
ngx.say("not matched!")
ngx.say("pos: ", ctx.pos)
end
}
--- stream_response
from: 1
to: 4
pos: 5
--- no_error_log
[error]
=== TEST 18: match with ctx and a pos
--- stream_server_config
content_by_lua_block {
local ctx = { pos = 3 }
local from, to, err = ngx.re.find("1234, hello", "([0-9]+)", "", ctx)
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("pos: ", ctx.pos)
else
ngx.say("not matched!")
ngx.say("pos: ", ctx.pos)
end
}
--- stream_response
from: 3
to: 4
pos: 5
--- no_error_log
[error]
=== TEST 19: named subpatterns w/ extraction
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "(?<first>[a-z]+), [0-9]+")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
return
end
ngx.say("not matched.")
end
}
--- stream_response
from: 1
to: 11
matched: hello, 1234
--- no_error_log
[error]
=== TEST 20: bad UTF-8
--- stream_server_config
content_by_lua_block {
local target = "你好"
local regex = "你好"
local from, to, err = ngx.re.find(string.sub(target, 1, 4), regex, "u")
if err then
ngx.say("error: ", err)
return
end
if m then
ngx.say("matched: ", from)
else
ngx.say("not matched")
end
}
--- stream_response eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre_exec\(\) failed: -4\n"
:
"error: pcre_exec\(\) failed: -10\n"
--- no_error_log
[error]
=== TEST 21: UTF-8 mode without UTF-8 sequence checks
--- stream_server_config
content_by_lua_block {
local s = "你好"
local from, to, err = ngx.re.find(s, ".", "U")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
ngx.say("not matched.")
end
}
--- stap
probe process("$LIBPCRE_PATH").function("pcre_compile") {
printf("compile opts: %x\n", $options)
}
probe process("$LIBPCRE_PATH").function("pcre_exec") {
printf("exec opts: %x\n", $options)
}
--- stap_out
compile opts: 800
exec opts: 2000
--- stream_response
from: 1
to: 3
matched: 你
--- no_error_log
[error]
=== TEST 22: just hit match limit
--- stream_config
lua_regex_match_limit 5600;
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local re = [==[(?i:([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´\(\)]*)?\2|([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´\(\)]*)?(?!\6)([\d\w]+))]==]
s = string.rep([[ABCDEFG]], 10)
local start = ngx.now()
local from, to, err = ngx.re.find(s, re, "o")
--[[
ngx.update_time()
local elapsed = ngx.now() - start
ngx.say(elapsed, " sec elapsed.")
]]
if not from then
if err then
ngx.say("error: ", err)
return
end
ngx.say("failed to match.")
return
end
--- stream_response
failed to match.
--- no_error_log
[error]
=== TEST 23: just not hit match limit
--- stream_config
lua_regex_match_limit 5700;
--- stream_server_config
content_by_lua_file html/a.lua;
--- user_files
>>> a.lua
local re = [==[(?i:([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´\(\)]*)?\2|([\s'\"`´\(\)]*)?([\d\w]+)([\s'\"`´\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´\(\)]*)?(?!\6)([\d\w]+))]==]
s = string.rep([[ABCDEFG]], 10)
local start = ngx.now()
local from, to, err = ngx.re.find(s, re, "o")
--[[
ngx.update_time()
local elapsed = ngx.now() - start
ngx.say(elapsed, " sec elapsed.")
]]
if not from then
if err then
ngx.say("error: ", err)
return
end
ngx.say("failed to match")
return
end
--- stream_response
failed to match
--- no_error_log
[error]
=== TEST 24: specify the group (1)
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "([0-9])([0-9]+)", "jo", nil, 1)
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
end
ngx.say("not matched!")
end
}
--- stream_response
from: 8
to: 8
matched: 1
--- no_error_log
[error]
=== TEST 25: specify the group (0)
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "([0-9])([0-9]+)", "jo", nil, 0)
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
end
ngx.say("not matched!")
end
}
--- stream_response
from: 8
to: 11
matched: 1234
--- no_error_log
[error]
=== TEST 26: specify the group (2)
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "([0-9])([0-9]+)", "jo", nil, 2)
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
end
ngx.say("not matched!")
end
}
--- stream_response
from: 9
to: 11
matched: 234
--- no_error_log
[error]
=== TEST 27: specify the group (3)
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "([0-9])([0-9]+)", "jo", nil, 3)
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
return
end
ngx.say("not matched!")
end
}
--- stream_response
error: nth out of bound
--- no_error_log
[error]
=== TEST 28: specify the group (4)
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "([0-9])([0-9]+)", "jo", nil, 4)
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
return
end
ngx.say("not matched!")
end
}
--- stream_response
error: nth out of bound
--- no_error_log
[error]
=== TEST 29: nil submatch (2nd)
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "([0-9])|(hello world)", "jo", nil, 2)
if from or to then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
return
end
ngx.say("not matched!")
end
}
--- stream_response
not matched!
--- no_error_log
[error]
=== TEST 30: nil submatch (1st)
--- stream_server_config
content_by_lua_block {
local s = "hello, 1234"
local from, to, err = ngx.re.find(s, "(hello world)|([0-9])", "jo", nil, 1)
if from or to then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
return
end
ngx.say("not matched!")
end
}
--- stream_response
not matched!
--- no_error_log
[error]
=== TEST 31: ignore match limit in DFA mode
--- stream_config
lua_regex_match_limit 1;
--- stream_server_config
content_by_lua_block {
local s = "This is <something> <something else> <something further> no more"
local from, to, err = ngx.re.find(s, "<.*>", "d")
if from then
ngx.say("from: ", from)
ngx.say("to: ", to)
ngx.say("matched: ", string.sub(s, from, to))
else
if err then
ngx.say("error: ", err)
return
end
ngx.say("not matched!")
end
}
--- stream_response
from: 9
to: 56
matched: <something> <something else> <something further>
--- no_error_log
[error]

View file

@ -1,39 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
#repeat_each(1);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: nginx version
--- stream_server_config
content_by_lua_block {
ngx.say("version: ", ngx.config.nginx_version)
}
--- stream_response_like chop
^version: \d+$
--- no_error_log
[error]
=== TEST 2: ngx_lua_version
--- stream_server_config
content_by_lua_block {
ngx.say("version: ", ngx.config.ngx_lua_version)
}
--- stream_response_like chop
^version: \d+$
--- no_error_log
[error]

View file

@ -1,127 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: content_by_lua + ngx.worker.exiting
--- stream_server_config
content_by_lua_block {
ngx.say("worker exiting: ", ngx.worker.exiting())
}
--- stream_response
worker exiting: false
--- no_error_log
[error]
=== TEST 2: content_by_lua + ngx.worker.pid
TODO
--- SKIP
--- stream_server_config
content_by_lua_block {
local pid = ngx.worker.pid()
ngx.say("worker pid: ", pid)
if pid ~= tonumber(ngx.var.pid) then
ngx.say("worker pid is wrong.")
else
ngx.say("worker pid is correct.")
end
}
--- stream_response_like
worker pid: \d+
worker pid is correct\.
--- no_error_log
[error]
=== TEST 3: content_by_lua + ngx.worker.pid
--- stream_server_config
content_by_lua_block {
local pid = ngx.worker.pid()
ngx.say("worker pid: ", pid)
}
--- stream_response_like
^worker pid: \d+
--- no_error_log
[error]
=== TEST 4: init_worker_by_lua + ngx.worker.pid
TODO
--- SKIP
--- stream_config
init_worker_by_lua_block {
my_pid = ngx.worker.pid()
}
--- stream_server_config
content_by_lua_block {
ngx.say("worker pid: ", my_pid)
if my_pid ~= tonumber(ngx.var.pid) then
ngx.say("worker pid is wrong.")
else
ngx.say("worker pid is correct.")
end
}
--- stream_response_like
worker pid: \d+
worker pid is correct\.
--- no_error_log
[error]
=== TEST 5: init_worker_by_lua + ngx.worker.pid
--- stream_config
init_worker_by_lua_block {
my_pid = ngx.worker.pid()
}
--- stream_server_config
content_by_lua_block {
ngx.say("worker pid: ", my_pid)
}
--- stream_response_like
worker pid: \d+
--- no_error_log
[error]
=== TEST 6: content_by_lua + ngx.worker.pids
--- stream_server_config
content_by_lua_block {
local pid = ngx.worker.pid()
local pids = ngx.worker.pids()
ngx.say("worker pid: ", pid)
local count = ngx.worker.count()
if count ~= #pids then
ngx.say("worker pids is wrong.")
end
for i = 1, count do
if pids[i] == pid then
ngx.say("worker pid is correct.")
return
end
end
ngx.say("worker pid is wrong.")
}
--- stream_response_like
worker pid: \d+
worker pid is correct\.
--- no_error_log
[error]

View file

@ -1,63 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
#repeat_each(1);
plan tests => repeat_each() * (blocks() * 3 + 1);
$ENV{LUA_PATH} = "../lua-resty-core/lib/?.lua;../lua-resty-lrucache/lib/?.lua;/foo/bar/baz";
$ENV{LUA_CPATH} = "/baz/bar/foo";
#no_diff();
#no_long_string();
master_on();
no_shuffle();
check_accum_error_log();
run_tests();
__DATA__
=== TEST 1: LUA_PATH & LUA_CPATH env (code cache on)
--- main_config
env LUA_PATH;
env LUA_CPATH;
--- stream_server_config
content_by_lua_block {
ngx.say(package.path)
ngx.say(package.cpath)
}
--- stream_response_like
(?:\.\.\/lua-resty-core\/lib\/\?\.lua;\.\.\/lua-resty-lrucache\/lib\/\?\.lua;){1,2}\/foo\/bar\/baz
/baz/bar/foo
--- no_error_log
[error]
=== TEST 2: LUA_PATH & LUA_CPATH env (code cache off)
--- main_config
env LUA_PATH;
env LUA_CPATH;
--- stream_server_config
lua_code_cache off;
content_by_lua_block {
ngx.say(package.path)
ngx.say(package.cpath)
}
--- stream_response_like
(?:\.\.\/lua-resty-core\/lib\/\?\.lua;\.\.\/lua-resty-lrucache\/lib\/\?\.lua;){1,2}\/foo\/bar\/baz
/baz/bar/foo
--- no_error_log
[error]
--- error_log eval
qr/\[alert\] .*? lua_code_cache is off/

View file

@ -1,775 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(1);
plan tests => repeat_each() * (blocks() * 4 + 1);
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
sub read_file {
my $infile = shift;
open my $in, $infile
or die "cannot open $infile for reading: $!";
my $cert = do { local $/; <$in> };
close $in;
$cert;
}
our $DSTRootCertificate = read_file("t/cert/root-ca.crt");
our $ServerRoot = server_root();
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: set a global lua var
--- stream_config
init_worker_by_lua_block {
foo = ngx.md5("hello world")
}
--- stream_server_config
content_by_lua_block {
ngx.say("foo = ", foo)
}
--- stream_response
foo = 5eb63bbbe01eeed093cb22bb8f5acdc3
--- no_error_log
[error]
=== TEST 2: no ngx.say()
--- stream_config
init_worker_by_lua_block {
ngx.say("hello")
}
--- stream_server_config
content_by_lua_block {
ngx.say("foo = ", foo)
}
--- stream_response
foo = nil
--- error_log
API disabled in the context of init_worker_by_lua*
=== TEST 3: timer.at
--- stream_config
init_worker_by_lua_block {
_G.my_counter = 0
local function warn(...)
ngx.log(ngx.WARN, ...)
end
local function handler(premature)
warn("timer expired (premature: ", premature, "; counter: ",
_G.my_counter, ")")
_G.my_counter = _G.my_counter + 1
end
local ok, err = ngx.timer.at(0, handler)
if not ok then
ngx.log(ngx.ERR, "failed to create timer: ", err)
end
warn("created timer: ", ok)
}
--- stream_server_config
content_by_lua_block {
-- ngx.sleep(0.001)
ngx.say("my_counter = ", _G.my_counter)
_G.my_counter = _G.my_counter + 1
}
--- stream_response
my_counter = 1
--- grep_error_log eval: qr/warn\(\): [^,]*/
--- grep_error_log_out
warn(): created timer: 1
warn(): timer expired (premature: false; counter: 0)
--- no_error_log
[error]
=== TEST 4: timer.at + cosocket
--- stream_config
init_worker_by_lua_block {
_G.done = false
local function warn(...)
ngx.log(ngx.WARN, ...)
end
local function error(...)
ngx.log(ngx.ERR, ...)
end
local function handler(premature)
warn("timer expired (premature: ", premature, ")")
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
if not ok then
error("failed to connect: ", err)
_G.done = true
return
end
local req = "flush_all\r\n"
local bytes, err = sock:send(req)
if not bytes then
error("failed to send request: ", err)
_G.done = true
return
end
warn("request sent: ", bytes)
local line, err, part = sock:receive()
if line then
warn("received: ", line)
else
error("failed to receive a line: ", err, " [", part, "]")
end
_G.done = true
end
local ok, err = ngx.timer.at(0, handler)
if not ok then
error("failed to create timer: ", err)
end
warn("created timer: ", ok)
}
--- stream_server_config
content_by_lua_block {
local waited = 0
local sleep = ngx.sleep
while not _G.done do
local delay = 0.001
sleep(delay)
waited = waited + delay
if waited > 1 then
ngx.say("timed out")
return
end
end
ngx.say("ok")
}
--- stream_response
ok
--- grep_error_log eval: qr/warn\(\): [^,]*/
--- grep_error_log_out
warn(): created timer: 1
warn(): timer expired (premature: false)
warn(): request sent: 11
warn(): received: OK
--- log_level: debug
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket send timeout: 60000
lua tcp socket read timeout: 60000
--- no_error_log
[error]
=== TEST 5: init_worker_by_lua_file (simple global var)
--- stream_config
init_worker_by_lua_file html/foo.lua;
--- stream_server_config
content_by_lua_block {
ngx.say("foo = ", foo)
}
--- user_files
>>> foo.lua
foo = ngx.md5("hello world")
--- stream_response
foo = 5eb63bbbe01eeed093cb22bb8f5acdc3
--- no_error_log
[error]
=== TEST 6: timer.at + cosocket (by_lua_file)
--- main_config
env TEST_NGINX_MEMCACHED_PORT;
--- stream_config
init_worker_by_lua_file html/foo.lua;
--- user_files
>>> foo.lua
_G.done = false
local function warn(...)
ngx.log(ngx.WARN, ...)
end
local function error(...)
ngx.log(ngx.ERR, ...)
end
local function handler(premature)
warn("timer expired (premature: ", premature, ")")
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1",
os.getenv("TEST_NGINX_MEMCACHED_PORT"))
if not ok then
error("failed to connect: ", err)
_G.done = true
return
end
local req = "flush_all\r\n"
local bytes, err = sock:send(req)
if not bytes then
error("failed to send request: ", err)
_G.done = true
return
end
warn("request sent: ", bytes)
local line, err, part = sock:receive()
if line then
warn("received: ", line)
else
error("failed to receive a line: ", err, " [", part, "]")
end
_G.done = true
end
local ok, err = ngx.timer.at(0, handler)
if not ok then
error("failed to create timer: ", err)
end
warn("created timer: ", ok)
--- stream_server_config
content_by_lua_block {
local waited = 0
local sleep = ngx.sleep
while not _G.done do
local delay = 0.001
sleep(delay)
waited = waited + delay
if waited > 1 then
ngx.say("timed out")
return
end
end
ngx.say("ok")
}
--- stream_response
ok
--- grep_error_log eval: qr/warn\(\): [^,]*/
--- grep_error_log_out
warn(): created timer: 1
warn(): timer expired (premature: false)
warn(): request sent: 11
warn(): received: OK
--- log_level: debug
--- error_log
lua tcp socket connect timeout: 60000
lua tcp socket send timeout: 60000
lua tcp socket read timeout: 60000
--- no_error_log
[error]
=== TEST 7: ngx.ctx
--- stream_config
init_worker_by_lua_block {
ngx.ctx.foo = "hello world"
local function warn(...)
ngx.log(ngx.WARN, ...)
end
warn("foo = ", ngx.ctx.foo)
}
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
--- stream_response
ok
--- grep_error_log eval: qr/warn\(\): [^,]*/
--- grep_error_log_out
warn(): foo = hello world
--- no_error_log
[error]
=== TEST 8: print
--- stream_config
init_worker_by_lua_block {
print("md5 = ", ngx.md5("hello world"))
}
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
--- stream_response
ok
--- no_error_log
[error]
--- error_log
md5 = 5eb63bbbe01eeed093cb22bb8f5acdc3
=== TEST 9: unescape_uri
--- stream_config
init_worker_by_lua_block {
local function warn(...)
ngx.log(ngx.WARN, ...)
end
warn(ngx.unescape_uri("hello%20world"))
}
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
--- stream_response
ok
--- no_error_log
[error]
--- grep_error_log eval: qr/warn\(\): [^,]*/
--- grep_error_log_out
warn(): hello world
=== TEST 10: escape_uri
--- stream_config
init_worker_by_lua_block {
local function warn(...)
ngx.log(ngx.WARN, ...)
end
warn(ngx.escape_uri("hello world"))
}
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
--- stream_response
ok
--- no_error_log
[error]
--- grep_error_log eval: qr/warn\(\): [^,]*/
--- grep_error_log_out
warn(): hello%20world
=== TEST 11: ngx.re
--- stream_config
init_worker_by_lua_block {
local function warn(...)
ngx.log(ngx.WARN, ...)
end
warn((ngx.re.sub("hello world", "world", "XXX", "jo")))
}
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
--- stream_response
ok
--- no_error_log
[error]
--- grep_error_log eval: qr/warn\(\): [^,]*/
--- grep_error_log_out
warn(): hello XXX
=== TEST 12: ngx.time
--- stream_config
init_worker_by_lua_block {
local function warn(...)
ngx.log(ngx.WARN, ...)
end
warn("time: ", ngx.time())
}
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
--- stream_response
ok
--- no_error_log
[error]
--- grep_error_log eval: qr/warn\(\): .*?(?=, context)/
--- grep_error_log_out eval
qr/warn\(\): time: \d+/
=== TEST 13: cosocket with resolver
--- timeout: 10
--- stream_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
resolver_timeout 3s;
init_worker_by_lua_block {
-- global
logs = ""
done = false
local function say(...)
logs = logs .. table.concat({...}) .. "\n"
end
local function handler()
local sock = ngx.socket.tcp()
local port = 80
local ok, err = sock:connect("agentzh.org", port)
if not ok then
say("failed to connect: ", err)
done = true
return
end
say("connected: ", ok)
local req = "GET / HTTP/1.0\r\nHost: agentzh.org\r\nConnection: close\r\n\r\n"
-- req = "OK"
local bytes, err = sock:send(req)
if not bytes then
say("failed to send request: ", err)
done = true
return
end
say("request sent: ", bytes)
local line, err = sock:receive()
if line then
say("first line received: ", line)
else
say("failed to receive the first line: ", err)
end
line, err = sock:receive()
if line then
say("second line received: ", line)
else
say("failed to receive the second line: ", err)
end
done = true
end
local ok, err = ngx.timer.at(0, handler)
if not ok then
say("failed to create timer: ", err)
else
say("timer created")
end
}
--- stream_server_config
content_by_lua_block {
local i = 0
while not done and i < 3000 do
ngx.sleep(0.001)
i = i + 1
end
ngx.print(logs)
}
--- stream_response_like
timer created
connected: 1
request sent: 56
first line received: HTTP\/1\.1 200 OK
second line received: (?:Date|Server): .*?
--- no_error_log
[error]
--- timeout: 10
=== TEST 14: connection refused (tcp) - log_errors on by default
--- stream_config
init_worker_by_lua_block {
logs = ""
done = false
local function say(...)
logs = logs .. table.concat{...} .. "\n"
end
local function handler()
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", 16787)
if not ok then
say("failed to connect: ", err)
else
say("connect: ", ok, " ", err)
end
done = true
end
local ok, err = ngx.timer.at(0, handler)
if not ok then
say("failed to create timer: ", err)
else
say("timer created")
end
}
--- stream_server_config
content_by_lua_block {
local i = 0
while not done and i < 1000 do
ngx.sleep(0.001)
i = i + 1
end
ngx.print(logs)
}
--- stream_response
timer created
failed to connect: connection refused
--- error_log eval
qr/connect\(\) failed \(\d+: Connection refused\), context: ngx\.timer$/
=== TEST 15: connection refused (tcp) - log_errors explicitly on
--- stream_config
lua_socket_log_errors on;
init_worker_by_lua_block {
logs = ""
done = false
local function say(...)
logs = logs .. table.concat{...} .. "\n"
end
local function handler()
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", 16787)
if not ok then
say("failed to connect: ", err)
else
say("connect: ", ok, " ", err)
end
done = true
end
local ok, err = ngx.timer.at(0, handler)
if not ok then
say("failed to create timer: ", err)
else
say("timer created")
end
}
--- stream_server_config
content_by_lua_block {
local i = 0
while not done and i < 1000 do
ngx.sleep(0.001)
i = i + 1
end
ngx.print(logs)
}
--- stream_response
timer created
failed to connect: connection refused
--- error_log eval
qr/connect\(\) failed \(\d+: Connection refused\)/
=== TEST 16: connection refused (tcp) - log_errors explicitly off
--- stream_config
lua_socket_log_errors off;
init_worker_by_lua_block {
logs = ""
done = false
local function say(...)
logs = logs .. table.concat{...} .. "\n"
end
local function handler()
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", 16787)
if not ok then
say("failed to connect: ", err)
else
say("connect: ", ok, " ", err)
end
done = true
end
local ok, err = ngx.timer.at(0, handler)
if not ok then
say("failed to create timer: ", err)
else
say("timer created")
end
}
--- stream_server_config
content_by_lua_block {
local i = 0
while not done and i < 1000 do
ngx.sleep(0.001)
i = i + 1
end
ngx.print(logs)
}
--- stream_response
timer created
failed to connect: connection refused
--- no_error_log eval
[
'qr/connect\(\) failed \(\d+: Connection refused\)/',
'[error]',
]
=== TEST 17: init_by_lua + proxy_temp_path which has side effects in cf->cycle->paths
--- SKIP
--- stream_config eval
qq!
proxy_temp_path $::ServerRoot/proxy_temp;
init_worker_by_lua_block {
local a = 2 + 3
}
!
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
--- stream_response
ok
--- no_error_log
[error]
[alert]
[emerg]
=== TEST 18: syslog error log
--- stream_config
#error_log syslog:server=127.0.0.1:12345 error;
init_worker_by_lua_block {
done = false
os.execute("sleep 0.1")
ngx.log(ngx.ERR, "Bad bad bad")
done = true
}
--- stream_server_config
content_by_lua_block {
while not done do
ngx.sleep(0.001)
end
ngx.say("ok")
}
--- log_level: error
--- error_log_file: syslog:server=127.0.0.1:12345
--- udp_listen: 12345
--- udp_query eval: qr/Bad bad bad/
--- udp_reply: hello
--- wait: 0.1
--- stream_response
ok
--- error_log
Bad bad bad
--- skip_nginx: 4: < 1.7.1
=== TEST 19: fake module calls ngx_stream_conf_get_module_srv_conf in its merge_srv_conf callback (GitHub issue #554)
This also affects merge_loc_conf
--- stream_config
init_worker_by_lua_block { return }
--- stream_server_config
content_by_lua_block {
ngx.say('ok')
}
--- stream_response
ok
--- no_error_log
[error]
=== TEST 20: lua_ssl_trusted_certificate
--- stream_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
lua_ssl_trusted_certificate ../html/trusted.crt;
lua_ssl_verify_depth 2;
init_worker_by_lua_block {
local semaphore = require "ngx.semaphore"
local sem = semaphore:new(0)
package.loaded.sem = sem
local function test_ssl_verify()
local sock = ngx.socket.tcp()
sock:settimeout(2000)
local ok, err = sock:connect("openresty.org", 443)
if not ok then
ngx.log(ngx.ERR, "failed to connect: ", err)
return
end
ngx.log(ngx.WARN, "connected: ", ok)
local session, err = sock:sslhandshake(nil, "openresty.org", true)
if not session then
ngx.log(ngx.ERR, "failed to do SSL handshake: ", err)
return
end
ngx.log(ngx.WARN, "ssl handshake: ", type(session))
local ok, err = sock:close()
ngx.log(ngx.WARN, "close: ", ok, " ", err)
sem:post(1)
end
ngx.timer.at(0, test_ssl_verify)
}
--- stream_server_config
content_by_lua_block {
local sem = package.loaded.sem
local ok, err = sem:wait(3)
if not ok then
ngx.say("wait test_ssl_verify failed: ", err)
end
ngx.say('ok')
}
--- user_files eval
">>> trusted.crt
$::DSTRootCertificate"
--- stream_response
ok
--- no_error_log
[error]
--- error_log
connected: 1
ssl handshake: userdata
close: 1 nil

View file

@ -1,26 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3);
#no_diff();
#no_long_string();
run_tests();
__DATA__
=== TEST 1: nginx configure
--- stream_server_config
content_by_lua_block {
ngx.say(ngx.config.nginx_configure())
}
--- stream_response_like chop
^\s*\-\-[^-]+
--- no_error_log
[error]

File diff suppressed because it is too large Load diff

View file

@ -1,315 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;use t::StapThread;
our $GCScript = $t::StapThread::GCScript;
our $StapScript = $t::StapThread::StapScript;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 5 + 1);
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= '11211';
#no_shuffle();
no_long_string();
run_tests();
__DATA__
=== TEST 1: kill pending sleep
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello from f()")
ngx.sleep(1)
end
local t, err = ngx.thread.spawn(f)
if not t then
ngx.say("failed to spawn thread: ", err)
return
end
ngx.say("thread created: ", coroutine.status(t))
collectgarbage()
local ok, err = ngx.thread.kill(t)
if not ok then
ngx.say("failed to kill thread: ", err)
return
end
ngx.say("killed")
local ok, err = ngx.thread.kill(t)
if not ok then
ngx.say("failed to kill thread: ", err)
return
end
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
delete thread 2
terminate 1: ok
delete thread 1
--- stream_response
hello from f()
thread created: running
killed
failed to kill thread: already waited or killed
--- no_error_log
[error]
--- error_log
lua clean up the timer for pending ngx.sleep
=== TEST 2: already waited
--- stream_server_config
content_by_lua_block {
function f()
ngx.say("hello from f()")
ngx.sleep(0.001)
return 32
end
local t, err = ngx.thread.spawn(f)
if not t then
ngx.say("failed to spawn thread: ", err)
return
end
ngx.say("thread created: ", coroutine.status(t))
collectgarbage()
local ok, res = ngx.thread.wait(t)
if not ok then
ngx.say("failed to kill thread: ", res)
return
end
ngx.say("waited: ", res)
local ok, err = ngx.thread.kill(t)
if not ok then
ngx.say("failed to kill thread: ", err)
return
end
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 2: ok
delete thread 2
terminate 1: ok
delete thread 1
--- stream_response
hello from f()
thread created: running
waited: 32
failed to kill thread: already waited or killed
--- no_error_log
[error]
lua clean up the timer for pending ngx.sleep
=== TEST 3: kill pending resolver
--- stream_server_config
resolver 127.0.0.2:12345;
resolver_timeout 5ms;
content_by_lua_block {
function f()
local sock = ngx.socket.tcp()
sock:connect("some.agentzh.org", 80)
end
local t, err = ngx.thread.spawn(f)
if not t then
ngx.say("failed to spawn thread: ", err)
return
end
ngx.say("thread created: ", coroutine.status(t))
collectgarbage()
local ok, err = ngx.thread.kill(t)
if not ok then
ngx.say("failed to kill thread: ", err)
return
end
ngx.say("killed")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
delete thread 2
terminate 1: ok
delete thread 1
--- stream_response
thread created: running
killed
--- no_error_log
[error]
--- error_log
lua tcp socket abort resolver
=== TEST 4: kill pending connect
--- stream_server_config
resolver $TEST_NGINX_RESOLVER ipv6=off;
content_by_lua_block {
local ready = false
function f()
local sock = ngx.socket.tcp()
sock:connect("agentzh.org", 80)
sock:close()
ready = true
sock:settimeout(10000)
sock:connect("127.0.0.2", 12345)
end
local t, err = ngx.thread.spawn(f)
if not t then
ngx.say("failed to spawn thread: ", err)
return
end
ngx.say("thread created: ", coroutine.status(t))
collectgarbage()
while not ready do
ngx.sleep(0.001)
end
local ok, err = ngx.thread.kill(t)
if not ok then
ngx.say("failed to kill thread: ", err)
return
end
ngx.say("killed")
}
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
delete thread 2
terminate 1: ok
delete thread 1
--- stream_response
thread created: running
killed
--- no_error_log
[error]
lua tcp socket abort resolver
--- grep_error_log: stream lua finalize socket
--- grep_error_log_out
stream lua finalize socket
stream lua finalize socket
--- error_log
=== TEST 5: kill a thread already terminated
--- stream_server_config
content_by_lua_block {
function f()
return
end
local t, err = ngx.thread.spawn(f)
if not t then
ngx.say("failed to spawn thread: ", err)
return
end
ngx.say("thread created: ", coroutine.status(t))
collectgarbage()
local ok, err = ngx.thread.kill(t)
if not ok then
ngx.say("failed to kill thread: ", err)
return
end
ngx.say("killed")
}
--- stap2 eval: $::StapScript
--- stream_response
thread created: zombie
failed to kill thread: already terminated
--- no_error_log
[error]
[alert]
lua tcp socket abort resolver
--- error_log
=== TEST 6: kill self
--- stream_server_config
content_by_lua_block {
local ok, err = ngx.thread.kill(coroutine.running())
if not ok then
ngx.say("failed to kill main thread: ", err)
else
ngx.say("killed main thread.")
end
function f()
local ok, err = ngx.thread.kill(coroutine.running())
if not ok then
ngx.say("failed to kill user thread: ", err)
else
ngx.say("user thread thread.")
end
end
local t, err = ngx.thread.spawn(f)
if not t then
ngx.say("failed to spawn thread: ", err)
return
end
ngx.say("thread created: ", coroutine.status(t))
}
--- stap2 eval: $::StapScript
--- stream_response
failed to kill main thread: not user thread
failed to kill user thread: killer not parent
thread created: zombie
--- no_error_log
[error]
[alert]
stream lua tcp socket abort resolver
--- error_log

View file

@ -1,600 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3 + 2);
our $HtmlDir = html_dir;
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
#log_level 'warn';
log_level 'debug';
no_long_string();
#no_diff();
run_tests();
__DATA__
=== TEST 1: pipelined memcached requests (sent one byte at a time)
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_MEMCACHED_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "flush_all\r\nget foo\r\nget bar\r\n"
-- req = "OK"
local send_idx = 1
local function writer()
local sub = string.sub
while send_idx <= #req do
local bytes, err = sock:send(sub(req, send_idx, send_idx))
if not bytes then
ngx.say("failed to send request: ", err)
return
end
-- if send_idx % 2 == 0 then
ngx.sleep(0.001)
-- end
send_idx = send_idx + 1
end
-- ngx.say("request sent.")
end
local ok, err = ngx.thread.spawn(writer)
if not ok then
ngx.say("failed to spawn writer thread: ", err)
return
end
for i = 1, 3 do
local line, err, part = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive a line: ", err, " [", part, "]")
break
end
end
ok, err = sock:setkeepalive()
ngx.say("setkeepalive: ", ok, " ", err)
}
--- config
server_tokens off;
--- stream_response
connected: 1
received: OK
received: END
received: END
setkeepalive: 1 nil
--- no_error_log
[error]
=== TEST 2: read timeout errors won't affect writing
--- stream_server_config
lua_socket_log_errors off;
content_by_lua_block {
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_MEMCACHED_PORT
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "flush_all\r\n"
-- req = "OK"
local send_idx = 1
sock:settimeout(1)
local function writer()
local sub = string.sub
while send_idx <= #req do
local bytes, err = sock:send(sub(req, send_idx, send_idx))
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.sleep(0.001)
send_idx = send_idx + 1
end
-- ngx.say("request sent.")
end
local ok, err = ngx.thread.spawn(writer)
if not ok then
ngx.say("failed to spawn writer thread: ", err)
return
end
local data = ""
local ntm = 0
local done = false
for i = 1, 300 do
local line, err, part = sock:receive()
if not line then
if part then
data = data .. part
end
if err ~= "timeout" then
ngx.say("failed to receive: ", err)
return
end
ntm = ntm + 1
else
data = data .. line
ngx.say("received: ", data)
done = true
break
end
end
if not done then
ngx.say("partial read: ", data)
end
ngx.say("read timed out: ", ntm)
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
--- stream_response_like chop
^connected: 1
(?:received: OK|failed to send request: timeout
partial read: )
read timed out: [1-9]\d*
close: 1 nil$
--- no_error_log
[error]
=== TEST 3: writes are rejected while reads are not
--- stream_server_config
lua_socket_log_errors off;
content_by_lua_block {
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_RAND_PORT_1
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "flush_all\r\n"
-- req = "OK"
local send_idx = 1
local function writer()
local sub = string.sub
while send_idx <= #req do
local bytes, err = sock:send(sub(req, send_idx, send_idx))
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.sleep(0.001)
send_idx = send_idx + 1
end
-- ngx.say("request sent.")
end
local ok, err = ngx.thread.spawn(writer)
if not ok then
ngx.say("failed to spawn writer thread: ", err)
return
end
local data = ""
local ntm = 0
local done = false
for i = 1, 3 do
local res, err, part = sock:receive(1)
if not res then
ngx.say("failed to receive: ", err)
return
else
data = data .. res
end
ngx.sleep(0.001)
end
ngx.say("received: ", data)
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
--- stream_response_like chop
^connected: 1
received: OK!
close: (?:nil socket busy writing|1 nil
failed to send request: closed)$
--- tcp_listen: $TEST_NGINX_RAND_PORT_1
--- tcp_shutdown: 0
--- tcp_reply: OK!
--- tcp_no_close: 1
--- no_error_log
[error]
=== TEST 4: reads are rejected while writes are not
--- stream_server_config
lua_socket_log_errors off;
content_by_lua_block {
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_RAND_PORT_2
local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "flush_all\r\n"
-- req = "OK"
local send_idx = 1
local function writer()
local sub = string.sub
while send_idx <= #req do
local bytes, err = sock:send(sub(req, send_idx, send_idx))
if not bytes then
ngx.say("failed to send request: ", err)
return
end
-- ngx.say("sent: ", bytes)
ngx.sleep(0.001)
send_idx = send_idx + 1
end
ngx.say("request sent.")
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
end
local ok, err = ngx.thread.spawn(writer)
if not ok then
ngx.say("failed to spawn writer thread: ", err)
return
end
local data = ""
local ntm = 0
local done = false
for i = 1, 3 do
local res, err, part = sock:receive(1)
if not res then
ngx.say("failed to receive: ", err)
return
else
data = data .. res
end
ngx.sleep(0.001)
end
ngx.say("received: ", data)
}
--- config
server_tokens off;
--- stream_response
connected: 1
failed to receive: closed
request sent.
close: 1 nil
--- stap2
F(ngx_http_lua_socket_tcp_finalize_write_part) {
print_ubacktrace()
}
--- stap_out2
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_shutdown: 1
--- tcp_query eval: "flush_all\r\n"
--- tcp_query_len: 11
--- no_error_log
[error]
=== TEST 5: concurrent socket operations while connecting
--- stream_server_config
lua_socket_log_errors off;
resolver $TEST_NGINX_RESOLVER ipv6=off;
content_by_lua_block {
local sock = ngx.socket.tcp()
local function f()
ngx.sleep(0.001)
local res, err = sock:receive(1)
ngx.say("receive: ", res, " ", err)
local bytes, err = sock:send("hello")
ngx.say("send: ", bytes, " ", err)
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
local ok, err = sock:getreusedtimes()
ngx.say("getreusedtimes: ", ok, " ", err)
local ok, err = sock:setkeepalive()
ngx.say("setkeepalive: ", ok, " ", err)
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
ngx.say("connect: ", ok, " ", err)
end
local ok, err = ngx.thread.spawn(f)
if not ok then
ngx.say("failed to spawn writer thread: ", err)
return
end
sock:settimeout(300)
local ok, err = sock:connect("127.0.0.2", 12345)
ngx.say("connect: ", ok, " ", err)
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
--- stream_response
receive: nil socket busy connecting
send: nil socket busy connecting
close: nil socket busy connecting
getreusedtimes: 0 nil
setkeepalive: nil socket busy connecting
connect: nil socket busy connecting
connect: nil timeout
close: nil closed
--- no_error_log
[error]
=== TEST 6: concurrent operations while resolving
--- stream_server_config
lua_socket_log_errors off;
resolver 127.0.0.2:12345;
resolver_timeout 300ms;
content_by_lua_block {
local sock = ngx.socket.tcp()
local function f()
ngx.sleep(0.001)
local res, err = sock:receive(1)
ngx.say("receive: ", res, " ", err)
local bytes, err = sock:send("hello")
ngx.say("send: ", bytes, " ", err)
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
local ok, err = sock:getreusedtimes()
ngx.say("getreusedtimes: ", ok, " ", err)
local ok, err = sock:setkeepalive()
ngx.say("setkeepalive: ", ok, " ", err)
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
ngx.say("connect: ", ok, " ", err)
end
local ok, err = ngx.thread.spawn(f)
if not ok then
ngx.say("failed to spawn writer thread: ", err)
return
end
sock:settimeout(300)
local ok, err = sock:connect("some2.agentzh.org", 80)
ngx.say("connect: ", ok, " ", err)
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
--- stream_response
receive: nil closed
send: nil closed
close: nil closed
getreusedtimes: nil closed
setkeepalive: nil closed
connect: nil socket busy connecting
connect: nil some2.agentzh.org could not be resolved (110: Operation timed out)
close: nil closed
--- no_error_log
[error]
=== TEST 7: concurrent operations while reading (receive)
--- stream_server_config
lua_socket_log_errors off;
content_by_lua_block {
local sock = ngx.socket.tcp()
local ready = false
local function f()
while not ready do
ngx.sleep(0.001)
end
local res, err = sock:receive(1)
ngx.say("receive: ", res, " ", err)
local bytes, err = sock:send("flush_all")
ngx.say("send: ", bytes, " ", err)
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
local ok, err = sock:getreusedtimes()
ngx.say("getreusedtimes: ", ok, " ", err)
local ok, err = sock:setkeepalive()
ngx.say("setkeepalive: ", ok, " ", err)
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
ngx.say("connect: ", ok, " ", err)
end
local ok, err = ngx.thread.spawn(f)
if not ok then
ngx.say("failed to spawn writer thread: ", err)
return
end
sock:settimeout(300)
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
ngx.say("connect: ", ok, " ", err)
ready = true
local res, err = sock:receive(1)
ngx.say("receive: ", res, " ", err)
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
--- stream_response
connect: 1 nil
receive: nil socket busy reading
send: 9 nil
close: nil socket busy reading
getreusedtimes: 0 nil
setkeepalive: nil socket busy reading
connect: nil socket busy reading
receive: nil timeout
close: 1 nil
--- no_error_log
[error]
=== TEST 8: concurrent operations while reading (receiveuntil)
--- stream_server_config
lua_socket_log_errors off;
content_by_lua_block {
local ready = false
local sock = ngx.socket.tcp()
local function f()
while not ready do
ngx.sleep(0.001)
end
local res, err = sock:receive(1)
ngx.say("receive: ", res, " ", err)
local bytes, err = sock:send("flush_all")
ngx.say("send: ", bytes, " ", err)
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
local ok, err = sock:getreusedtimes()
ngx.say("getreusedtimes: ", ok, " ", err)
local ok, err = sock:setkeepalive()
ngx.say("setkeepalive: ", ok, " ", err)
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
ngx.say("connect: ", ok, " ", err)
end
local ok, err = ngx.thread.spawn(f)
if not ok then
ngx.say("failed to spawn writer thread: ", err)
return
end
sock:settimeout(300)
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT)
ngx.say("connect: ", ok, " ", err)
ready = true
local it, err = sock:receiveuntil("\r\n")
if not it then
ngx.say("receiveuntil() failed: ", err)
return
end
local res, err = it()
ngx.say("receiveuntil() iterator: ", res, " ", err)
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
--- stream_response
connect: 1 nil
receive: nil socket busy reading
send: 9 nil
close: nil socket busy reading
getreusedtimes: 0 nil
setkeepalive: nil socket busy reading
connect: nil socket busy reading
receiveuntil() iterator: nil timeout
close: 1 nil
--- no_error_log
[error]

File diff suppressed because it is too large Load diff

View file

@ -1,34 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_process_enabled(1);
#log_level('warn');
repeat_each(2);
plan tests => repeat_each() * 3;
#no_diff();
no_long_string();
#master_on();
#workers(2);
run_tests();
__DATA__
=== TEST 1: req
--- stream_server_config
content_by_lua_block {
local ffi = require "ffi"
local function tonum(ud)
return tonumber(ffi.cast("uintptr_t", ud))
end
ngx.say(string.format("content req=%#x", tonum(exdata())))
}
--- stream_response_like chop
^content req=0x[a-f0-9]{4,}
$
--- no_error_log
[error]

View file

@ -1,138 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
BEGIN {
if (!defined $ENV{LD_PRELOAD}) {
$ENV{LD_PRELOAD} = '';
}
if ($ENV{LD_PRELOAD} !~ /\bmockeagain\.so\b/) {
$ENV{LD_PRELOAD} = "mockeagain.so $ENV{LD_PRELOAD}";
}
if ($ENV{MOCKEAGAIN} eq 'r') {
$ENV{MOCKEAGAIN} = 'rw';
} else {
$ENV{MOCKEAGAIN} = 'w';
}
$ENV{TEST_NGINX_EVENT_TYPE} = 'poll';
$ENV{MOCKEAGAIN_WRITE_TIMEOUT_PATTERN} = 'slow';
}
use Test::Nginx::Socket::Lua::Stream;
log_level('debug');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4);
run_tests();
__DATA__
=== TEST 1: raw downstream cosocket used in two different threads. See issue #481
--- stream_server_config
lua_socket_read_timeout 1ms;
lua_socket_send_timeout 1s;
lua_socket_log_errors off;
#lua_lingering_timeout 1ms;
content_by_lua_block {
local function reader(req_socket)
-- First we receive in a blocking fashion so that ctx->downstream_co_ctx will be changed
local data, err, partial = req_socket:receive(1)
if err ~= "timeout" then
ngx.log(ngx.ERR, "Did not get timeout in the receiving thread!")
return
end
-- Now, sleep so that coctx->data is changed to sleep handler
ngx.sleep(1)
end
local function writer(req_socket)
-- send in a slow manner with a low timeout, so that the timeout handler will be
local bytes, err = req_socket:send("slow!!!")
if err ~= "timeout" then
return error("Did not get timeout in the sending thread!")
end
end
local req_socket, err = ngx.req.socket(true)
if req_socket == nil then
return error("Unable to get request socket:" .. (err or "nil"))
end
local writer_thread = ngx.thread.spawn(writer, req_socket)
local reader_thread = ngx.thread.spawn(reader, req_socket)
ngx.thread.wait(writer_thread)
ngx.thread.wait(reader_thread)
print("The two threads finished")
}
--- no_error_log
[error]
--- error_log: The two threads finished
--- wait: 0.1
--- log_stream_response
--- stream_response_like chomp
^received \d+ bytes of response data\.$
--- timeout: 10
=== TEST 2: normal downstream cosocket used in two different threads. See issue #481
--- stream_server_config
lua_socket_read_timeout 1ms;
lua_socket_send_timeout 300ms;
lua_socket_log_errors off;
content_by_lua_block {
local function reader(req_socket)
-- First we receive in a blocking fashion so that ctx->downstream_co_ctx will be changed
local data, err, partial = req_socket:receive(1)
if err ~= "timeout" then
ngx.log(ngx.ERR, "Did not get timeout in the receiving thread!")
return
end
-- Now, sleep so that coctx->data is changed to sleep handler
ngx.sleep(0.3)
end
local function writer(req_socket)
-- send in a slow manner with a low timeout, so that the timeout handler will be
print("sleep 0.3")
ngx.sleep(0.1)
print("say slow")
ngx.say("slow!!!")
print("flushing")
local ok, err = ngx.flush(true)
if not ok then
print("flushing failed: ", err)
end
end
local req_socket, err = ngx.req.socket()
if req_socket == nil then
return error("Unable to get request socket:" .. (err or "nil"))
end
local writer_thread = ngx.thread.spawn(writer, req_socket)
local reader_thread = ngx.thread.spawn(reader, req_socket)
ngx.thread.wait(writer_thread)
ngx.thread.wait(reader_thread)
print("The two threads finished")
}
--- no_error_log
[error]
--- error_log: The two threads finished
--- wait: 0.1
--- log_stream_response
--- stream_response
received 4 bytes of response data.
--- timeout: 3

View file

@ -1,399 +0,0 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua::Stream;
#worker_connections(1014);
#master_on();
#workers(2);
#log_level('warn');
repeat_each(2);
#repeat_each(1);
plan tests => repeat_each() * ((blocks() * 3) + 1);
#no_diff();
no_long_string();
run_tests();
__DATA__
=== TEST 1: content_by_lua_block (nested curly braces)
--- stream_server_config
content_by_lua_block {
local a = {
dogs = {32, 78, 96},
cat = "kitty",
}
ngx.say("a.dogs[1] = ", a.dogs[1])
ngx.say("a.dogs[2] = ", a.dogs[2])
ngx.say("a.dogs[3] = ", a.dogs[3])
ngx.say("a.cat = ", a.cat)
}
--- config
--- stream_response
a.dogs[1] = 32
a.dogs[2] = 78
a.dogs[3] = 96
a.cat = kitty
--- no_error_log
[error]
=== TEST 2: content_by_lua_block (curly braces in strings)
--- stream_server_config
content_by_lua_block {
ngx.say("}1, 2)")
ngx.say('{1, 2)')
}
--- config
--- stream_response
}1, 2)
{1, 2)
--- no_error_log
[error]
=== TEST 3: content_by_lua_block (curly braces in strings, with escaped terminators)
--- stream_server_config
content_by_lua_block {
ngx.say("\"}1, 2)")
ngx.say('\'{1, 2)')
}
--- config
--- stream_response
"}1, 2)
'{1, 2)
--- no_error_log
[error]
=== TEST 4: content_by_lua_block (curly braces in long brackets)
--- stream_server_config
content_by_lua_block {
--[[
{{{
}
]]
--[==[
}}}
{
]==]
ngx.say("ok")
}
--- config
--- stream_response
ok
--- no_error_log
[error]
=== TEST 5: content_by_lua_block ("nested" long brackets)
--- stream_server_config
content_by_lua_block {
--[[
]=]
' "
}
]]
ngx.say("ok")
}
--- config
--- stream_response
ok
--- no_error_log
[error]
=== TEST 6: content_by_lua_block (curly braces in line comments)
--- stream_server_config
content_by_lua_block {
--}} {}
ngx.say("ok")
}
--- config
--- stream_response
ok
--- no_error_log
[error]
=== TEST 7: content_by_lua_block (cosockets)
--- stream_server_config
content_by_lua_block {
local sock = ngx.socket.tcp()
local port = $TEST_NGINX_SERVER_PORT
local ok, err = sock:connect('127.0.0.1', port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say('connected: ', ok)
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
-- req = "OK"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
while true do
local line, err, part = sock:receive()
if line then
ngx.say("received: ", line)
else
ngx.say("failed to receive a line: ", err, " [", part, "]")
break
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
--- config
server_tokens off;
location = /foo {
content_by_lua_block { ngx.say("foo") }
more_clear_headers Date;
}
--- stream_response
connected: 1
request sent: 57
received: HTTP/1.1 200 OK
received: Server: nginx
received: Content-Type: text/plain
received: Content-Length: 4
received: Connection: close
received:
received: foo
failed to receive a line: closed []
close: 1 nil
--- no_error_log
[error]
=== TEST 8: all in one
--- stream_config
init_by_lua_block {
glob = "init by lua }here{"
}
init_worker_by_lua_block {
glob = glob .. ", init worker }here{"
}
--- stream_server_config
#access_by_lua_block {
#local s = ngx.var.a
#s = s .. '}access{\n'
#ngx.var.a = s
#}
content_by_lua_block {
s = [[}content{]]
ngx.ctx.a = s
ngx.say(s)
ngx.say("glob: ", glob)
}
log_by_lua_block {
print("log by lua running \"}{!\"")
}
--- config
--- stream_response
}content{
glob: init by lua }here{, init worker }here{
--- error_log
log by lua running "}{!"
--- no_error_log
[error]
=== TEST 9: missing ]] (string)
--- stream_server_config
content_by_lua_block {
ngx.say([[hello, world")
}
--- config
--- stream_response
hello, world
--- no_error_log
[error]
--- must_die
--- error_log eval
qr/\[emerg\] .*? Lua code block missing the closing long bracket "]]" in .*?\bnginx\.conf:22/
=== TEST 10: missing ]==] (string)
--- stream_server_config
content_by_lua_block {
ngx.say([==[hello, world")
}
--- config
--- stream_response
hello, world
--- no_error_log
[error]
--- must_die
--- error_log eval
qr/\[emerg\] .*? Lua code block missing the closing long bracket "]==]" in .*?\bnginx\.conf:22/
=== TEST 11: missing ]] (comment)
--- stream_server_config
content_by_lua_block {
ngx.say(--[[hello, world")
}
--- config
--- stream_response
hello, world
--- no_error_log
[error]
--- must_die
--- error_log eval
qr/\[emerg\] .*? Lua code block missing the closing long bracket "]]" in .*?\bnginx\.conf:22/
=== TEST 12: missing ]=] (comment)
--- stream_server_config
content_by_lua_block {
ngx.say(--[=[hello, world")
}
--- config
--- stream_response
hello, world
--- no_error_log
[error]
--- must_die
--- error_log eval
qr/\[emerg\] .*? Lua code block missing the closing long bracket "]=]" in .*?\bnginx\.conf:22/
=== TEST 13: missing }
FIXME: we need better diagnostics by actually loading the inlined Lua code while parsing
the *_by_lua_block directive.
--- stream_server_config
content_by_lua_block {
ngx.say("hello")
--- stream_response
hello, world
--- no_error_log
[error]
--- error_log eval
qr/\[emerg\] .*? "http" directive is not allowed here/
--- must_die
=== TEST 14: content_by_lua_block (compact)
--- stream_server_config
content_by_lua_block {ngx.say("hello, world", {"!"})}
--- config
--- stream_response
hello, world!
--- no_error_log
[error]
=== TEST 15: content_by_lua_block unexpected closing long brackets ignored (GitHub #748)
--- config
location = /t {
content_by_lua_block {
local t1, t2 = {"hello world"}, {1}
ngx.say(t1[t2[1]])
}
}
--- request
GET /t
--- response_body
hello world
--- no_error_log
[error]
=== TEST 16: ambiguous line comments inside a long bracket string (GitHub #596)
--- stream_server_config
content_by_lua_block {
ngx.say([[ok--]])
ngx.say([==[ok--]==])
ngx.say([==[ok-- ]==])
--[[ --]] ngx.say("done")
}
--- config
--- stream_response
ok--
ok--
ok--
done
--- no_error_log
[error]
=== TEST 17: double quotes in long brackets
TODO
--- SKIP
--- stream_server_config
access_by_lua_block { print([[Hey, it is "!]]) } content_by_lua_block { ngx.say([["]]) }
--- config
--- stream_response
"
--- error_log
Hey, it is "!
--- no_error_log
[error]
=== TEST 18: single quotes in long brackets
TODO
--- SKIP
--- stream_server_config
access_by_lua_block { print([[Hey, it is '!]]) } content_by_lua_block { ngx.say([[']]) }
--- config
--- stream_response
'
--- error_log
Hey, it is '!
--- no_error_log
[error]

Some files were not shown because too many files have changed in this diff Show more