373 lines
14 KiB
Perl
373 lines
14 KiB
Perl
# vim:set ft= ts=4 sw=4 et fdm=marker:
|
|
use Test::Nginx::Socket::Lua;
|
|
|
|
#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 ("ngx.say('hello');")
|
|
--- config
|
|
root html;
|
|
location /save_call {
|
|
content_by_lua '
|
|
ngx.req.read_body();
|
|
local b = ngx.req.get_body_data();
|
|
f = io.open(ngx.var.realpath_root.."/test.lua", "w");
|
|
-- luajit bytecode: sub(149,-1), lua bytecode: sub(1,147)
|
|
if jit then
|
|
if not string.find(jit.version, "LuaJIT 2.0") then
|
|
ngx.say("test skipped")
|
|
return
|
|
end
|
|
f:write(string.sub(b, 149));
|
|
else
|
|
f:write(string.sub(b, 1, 147));
|
|
end
|
|
f:close(); res = ngx.location.capture("/call");
|
|
ngx.print(res.body)
|
|
';
|
|
}
|
|
location /call {
|
|
content_by_lua_file $realpath_root/test.lua;
|
|
}
|
|
--- request eval
|
|
"POST /save_call
|
|
\x1b\x4c\x75\x61\x51\x00\x01\x04\x08\x04\x08\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x40\x74\x65\x73\x74\x2e\x6c\x75\x61\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x02\x05\x00\x00\x00\x05\x00\x00\x00\x06\x40\x40\x00\x41\x80\x00\x00\x1c\x40\x00\x01\x1e\x00\x80\x00\x03\x00\x00\x00\x04\x04\x00\x00\x00\x00\x00\x00\x00\x6e\x67\x78\x00\x04\x04\x00\x00\x00\x00\x00\x00\x00\x73\x61\x79\x00\x04\x06\x00\x00\x00\x00\x00\x00\x00\x68\x65\x6c\x6c\x6f\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
|
\x1b\x4c\x4a\x01\x02\x29\x02\x00\x02\x00\x03\x00\x05\x34\x00\x00\x00\x37\x00\x01\x00\x25\x01\x02\x00\x3e\x00\x02\x01\x47\x00\x01\x00\x0a\x68\x65\x6c\x6c\x6f\x08\x73\x61\x79\x08\x6e\x67\x78\x00"
|
|
--- response_body_like chop
|
|
^(?:hello|test skipped)$
|
|
--- no_error_log
|
|
[error]
|
|
|
|
|
|
|
|
=== TEST 2: luajit load lua bytecode or lua load luajit bytecode
|
|
--- config
|
|
root html;
|
|
location /save_call {
|
|
content_by_lua '
|
|
ngx.req.read_body();
|
|
local b = ngx.req.get_body_data();
|
|
f = io.open(ngx.var.realpath_root.."/test.lua", "w");
|
|
-- luajit bytecode: sub(149,-1), lua bytecode: sub(1,147)
|
|
if not package.loaded["jit"] then
|
|
f:write(string.sub(b, 149));
|
|
else
|
|
f:write(string.sub(b, 1, 147));
|
|
end
|
|
f:close(); res = ngx.location.capture("/call");
|
|
if res.status == 200 then
|
|
ngx.print(res.body)
|
|
else
|
|
ngx.say("error")
|
|
end
|
|
';
|
|
}
|
|
location /call {
|
|
content_by_lua_file $realpath_root/test.lua;
|
|
}
|
|
--- request eval
|
|
"POST /save_call
|
|
\x1b\x4c\x75\x61\x51\x00\x01\x04\x08\x04\x08\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x40\x74\x65\x73\x74\x2e\x6c\x75\x61\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x02\x05\x00\x00\x00\x05\x00\x00\x00\x06\x40\x40\x00\x41\x80\x00\x00\x1c\x40\x00\x01\x1e\x00\x80\x00\x03\x00\x00\x00\x04\x04\x00\x00\x00\x00\x00\x00\x00\x6e\x67\x78\x00\x04\x04\x00\x00\x00\x00\x00\x00\x00\x73\x61\x79\x00\x04\x06\x00\x00\x00\x00\x00\x00\x00\x68\x65\x6c\x6c\x6f\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
|
\x1b\x4c\x4a\x01\x02\x29\x02\x00\x02\x00\x03\x00\x05\x34\x00\x00\x00\x37\x00\x01\x00\x25\x01\x02\x00\x3e\x00\x02\x01\x47\x00\x01\x00\x0a\x68\x65\x6c\x6c\x6f\x08\x73\x61\x79\x08\x6e\x67\x78\x00"
|
|
--- response_body
|
|
error
|
|
--- error_log eval
|
|
qr/failed to load external Lua file ".*?test\.lua": bad byte-code header/
|
|
|
|
|
|
|
|
=== TEST 3: unknown bytecode version
|
|
--- config
|
|
root html;
|
|
location /save_call {
|
|
content_by_lua '
|
|
ngx.req.read_body();
|
|
local b = ngx.req.get_body_data();
|
|
f = io.open(ngx.var.realpath_root.."/test.lua", "w");
|
|
-- luajit bytecode: sub(149,-1), lua bytecode: sub(1,147)
|
|
if package.loaded["jit"] then
|
|
f:write(string.sub(b, 149));
|
|
else
|
|
f:write(string.sub(b, 1, 147));
|
|
end
|
|
f:close(); res = ngx.location.capture("/call");
|
|
if res.status == 200 then
|
|
ngx.print(res.body)
|
|
else
|
|
ngx.say("error")
|
|
end
|
|
';
|
|
}
|
|
location /call {
|
|
content_by_lua_file $realpath_root/test.lua;
|
|
}
|
|
--- request eval
|
|
"POST /save_call
|
|
\x1b\x4c\x75\x61\x52\x00\x01\x04\x08\x04\x08\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x40\x74\x65\x73\x74\x2e\x6c\x75\x61\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x02\x05\x00\x00\x00\x05\x00\x00\x00\x06\x40\x40\x00\x41\x80\x00\x00\x1c\x40\x00\x01\x1e\x00\x80\x00\x03\x00\x00\x00\x04\x04\x00\x00\x00\x00\x00\x00\x00\x6e\x67\x78\x00\x04\x04\x00\x00\x00\x00\x00\x00\x00\x73\x61\x79\x00\x04\x06\x00\x00\x00\x00\x00\x00\x00\x68\x65\x6c\x6c\x6f\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
|
\x1b\x4c\x4a\x80\x02\x29\x02\x00\x02\x00\x03\x00\x05\x34\x00\x00\x00\x37\x00\x01\x00\x25\x01\x02\x00\x3e\x00\x02\x01\x47\x00\x01\x00\x0a\x68\x65\x6c\x6c\x6f\x08\x73\x61\x79\x08\x6e\x67\x78\x00"
|
|
--- response_body
|
|
error
|
|
--- error_log
|
|
bytecode format version unsupported
|
|
|
|
|
|
|
|
=== TEST 4: bytecode (big endian)
|
|
--- config
|
|
root html;
|
|
location /save_call {
|
|
content_by_lua '
|
|
ngx.req.read_body();
|
|
local b = ngx.req.get_body_data();
|
|
f = io.open(ngx.var.realpath_root.."/test.lua", "w");
|
|
-- luajit bytecode: sub(149,-1), lua bytecode: sub(1,147)
|
|
local do_jit
|
|
if jit then
|
|
if not string.find(jit.version, "LuaJIT 2.0") then
|
|
ngx.say("test skipped")
|
|
return
|
|
end
|
|
|
|
do_jit = true; f:write(string.sub(b, 149));
|
|
else
|
|
f:write(string.sub(b, 1, 147));
|
|
end
|
|
f:close(); res = ngx.location.capture("/call");
|
|
if do_jit and res.status == 200 then
|
|
ngx.say("ok")
|
|
elseif not do_jit and res.status == 500 then
|
|
ngx.say("ok")
|
|
else
|
|
ngx.say("error")
|
|
end
|
|
';
|
|
}
|
|
location /call {
|
|
content_by_lua_file $realpath_root/test.lua;
|
|
}
|
|
--- request eval
|
|
"POST /save_call
|
|
\x1b\x4c\x75\x61\x51\x00\x00\x04\x08\x04\x08\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x40\x74\x65\x73\x74\x2e\x6c\x75\x61\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x02\x05\x00\x00\x00\x05\x00\x00\x00\x06\x40\x40\x00\x41\x80\x00\x00\x1c\x40\x00\x01\x1e\x00\x80\x00\x03\x00\x00\x00\x04\x04\x00\x00\x00\x00\x00\x00\x00\x6e\x67\x78\x00\x04\x04\x00\x00\x00\x00\x00\x00\x00\x73\x61\x79\x00\x04\x06\x00\x00\x00\x00\x00\x00\x00\x68\x65\x6c\x6c\x6f\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
|
\x1b\x4c\x4a\x01\x03\x29\x02\x00\x02\x00\x03\x00\x05\x00\x00\x00\x34\x00\x01\x00\x37\x00\x02\x01\x25\x01\x02\x00\x3e\x00\x01\x00\x47\x0a\x68\x65\x6c\x6c\x6f\x08\x73\x61\x79\x08\x6e\x67\x78\x00"
|
|
--- response_body_like chop
|
|
^(?:ok|test skipped)$
|
|
--- no_error_log
|
|
[error]
|
|
|
|
|
|
|
|
=== TEST 5: good header but bad body
|
|
--- config
|
|
root html;
|
|
location /save_call {
|
|
content_by_lua '
|
|
ngx.req.read_body();
|
|
local b = ngx.req.get_body_data();
|
|
f = io.open(ngx.var.realpath_root.."/test.lua", "w");
|
|
-- luajit bytecode: sub(149,-1), lua bytecode: sub(1,147)
|
|
local jit;
|
|
if package.loaded["jit"] then
|
|
jit = true;
|
|
f:write(string.sub(b, 149));
|
|
else
|
|
f:write(string.sub(b, 1, 147));
|
|
end
|
|
if not jit then
|
|
f:close(); res = ngx.location.capture("/call");
|
|
if res.status == 200 then
|
|
ngx.print("ok")
|
|
else
|
|
ngx.say("error")
|
|
end
|
|
else
|
|
-- luajit will get a segmentation fault with bad bytecode,
|
|
-- so here just skip this case for luajit
|
|
ngx.say("error")
|
|
end
|
|
';
|
|
}
|
|
location /call {
|
|
content_by_lua_file $realpath_root/test.lua;
|
|
}
|
|
--- request eval
|
|
"POST /save_call
|
|
\x1b\x4c\x75\x61\x51\x00\x01\x04\x08\x04\x08\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x40\x74\x65\x73\x74\x2e\x6c\x75\x61\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x02\x05\x00\x00\x00\xff\xff\xff\xff\x06\x40\x40\x00\x41\x80\x00\x00\x1c\x40\x00\x01\x1e\x00\x80\x00\x03\x00\x00\x00\x04\x04\x00\x00\x00\x00\x00\x00\x00\x6e\x67\x78\x00\x04\x04\x00\x00\x00\x00\x00\x00\x00\x73\x61\x79\x00\x04\x06\x00\x00\x00\x00\x00\x00\x00\x68\x65\x6c\x6c\x6f\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
|
\x1b\x4c\x4a\x01\x02\x29\x02\x00\x02\x00\x03\x00\x05\xff\xff\xff\xff\x37\x00\x01\x00\x25\x01\x02\x00\x3e\x00\x02\x01\x47\x00\x01\x00\x0a\x68\x65\x6c\x6c\x6f\x08\x73\x61\x79\x08\x6e\x67\x78\x00"
|
|
--- response_body
|
|
error
|
|
--- no_error_log
|
|
[error]
|
|
|
|
|
|
|
|
=== TEST 6: stripped(lua) & no stripped(luajit)
|
|
--- config
|
|
root html;
|
|
location /save_call {
|
|
content_by_lua '
|
|
ngx.req.read_body();
|
|
local b = ngx.req.get_body_data();
|
|
f = io.open(ngx.var.realpath_root.."/test.lua", "w");
|
|
-- luajit bytecode: sub(149,-1), lua bytecode: sub(1,147)
|
|
if jit then
|
|
if not string.find(jit.version, "LuaJIT 2.0") then
|
|
ngx.say("test skipped")
|
|
return
|
|
end
|
|
|
|
f:write(string.sub(b, 119));
|
|
else
|
|
f:write(string.sub(b, 1, 117));
|
|
end
|
|
f:close(); res = ngx.location.capture("/call");
|
|
ngx.print(res.body)
|
|
';
|
|
}
|
|
location /call {
|
|
content_by_lua_file $realpath_root/test.lua;
|
|
}
|
|
--- request eval
|
|
"POST /save_call
|
|
\x1b\x4c\x75\x61\x51\x00\x01\x04\x08\x04\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x02\x05\x00\x00\x00\x05\x00\x00\x00\x06\x40\x40\x00\x41\x80\x00\x00\x1c\x40\x00\x01\x1e\x00\x80\x00\x03\x00\x00\x00\x04\x04\x00\x00\x00\x00\x00\x00\x00\x6e\x67\x78\x00\x04\x04\x00\x00\x00\x00\x00\x00\x00\x73\x61\x79\x00\x04\x06\x00\x00\x00\x00\x00\x00\x00\x68\x65\x6c\x6c\x6f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
|
\x1b\x4c\x4a\x01\x00\x09\x40\x74\x65\x73\x74\x2e\x6c\x75\x61\x32\x02\x00\x02\x00\x03\x00\x05\x06\x00\x02\x34\x00\x00\x00\x37\x00\x01\x00\x25\x01\x02\x00\x3e\x00\x02\x01\x47\x00\x01\x00\x0a\x68\x65\x6c\x6c\x6f\x08\x73\x61\x79\x08\x6e\x67\x78\x01\x01\x01\x01\x01\x00\x00"
|
|
--- response_body_like chop
|
|
^(?:hello|test skipped)$
|
|
--- no_error_log
|
|
[error]
|
|
|
|
|
|
|
|
=== TEST 7: generate & load bytecode for LuaJIT (stripped)
|
|
--- config
|
|
location = /t {
|
|
content_by_lua '
|
|
local bcsave = require "jit.bcsave"
|
|
if jit then
|
|
local prefix = ngx.config.prefix()
|
|
local infile = prefix .. "html/a.lua"
|
|
local outfile = prefix .. "html/a.luac"
|
|
bcsave.start("-s", infile, outfile)
|
|
return ngx.exec("/call")
|
|
end
|
|
|
|
ngx.say("test skipped!")
|
|
';
|
|
}
|
|
location = /call {
|
|
content_by_lua_file html/a.luac;
|
|
}
|
|
--- request
|
|
GET /t
|
|
|
|
--- user_files
|
|
>>> a.lua
|
|
ngx.status = 201 ngx.say("hello from Lua!")
|
|
--- response_body_like chop
|
|
^(?:hello from Lua!|test skipped!)$
|
|
--- no_error_log
|
|
[error]
|
|
--- error_code: 201
|
|
|
|
|
|
|
|
=== TEST 8: generate & load bytecode for LuaJIT (not stripped)
|
|
--- config
|
|
location = /t {
|
|
content_by_lua '
|
|
local bcsave = require "jit.bcsave"
|
|
if jit then
|
|
local prefix = ngx.config.prefix()
|
|
local infile = prefix .. "html/a.lua"
|
|
local outfile = prefix .. "html/a.luac"
|
|
bcsave.start("-g", infile, outfile)
|
|
return ngx.exec("/call")
|
|
end
|
|
|
|
ngx.say("test skipped!")
|
|
';
|
|
}
|
|
location = /call {
|
|
content_by_lua_file html/a.luac;
|
|
}
|
|
--- request
|
|
GET /t
|
|
|
|
--- user_files
|
|
>>> a.lua
|
|
ngx.status = 201 ngx.say("hello from Lua!")
|
|
--- response_body_like chop
|
|
^(?:hello from Lua!|test skipped!)$
|
|
--- no_error_log
|
|
[error]
|
|
--- error_code: 201
|
|
|
|
|
|
|
|
=== TEST 9: bytecode (not stripped)
|
|
--- config
|
|
location = /t {
|
|
content_by_lua_block {
|
|
local f = assert(loadstring("a = a and a + 1 or 1 ngx.say('a = ', a)", "=code"))
|
|
local bc = string.dump(f)
|
|
local f = assert(io.open("t/servroot/html/a.luac", "w"))
|
|
f:write(bc)
|
|
f:close()
|
|
}
|
|
}
|
|
|
|
location = /t2 {
|
|
content_by_lua_file html/a.luac;
|
|
}
|
|
|
|
location = /main {
|
|
echo_location /t;
|
|
echo_location /t2;
|
|
}
|
|
--- request
|
|
GET /main
|
|
--- response_body
|
|
a = 1
|
|
--- no_error_log
|
|
[error]
|
|
|
|
|
|
|
|
=== TEST 10: bytecode (stripped)
|
|
--- config
|
|
location = /t {
|
|
content_by_lua_block {
|
|
local f = assert(loadstring("a = a and a + 1 or 1 ngx.say('a = ', a)", "=code"))
|
|
local bc = string.dump(f, true)
|
|
local f = assert(io.open("t/servroot/html/a.luac", "w"))
|
|
f:write(bc)
|
|
f:close()
|
|
}
|
|
}
|
|
|
|
location = /t2 {
|
|
content_by_lua_file html/a.luac;
|
|
}
|
|
|
|
location = /main {
|
|
echo_location /t;
|
|
echo_location /t2;
|
|
}
|
|
--- request
|
|
GET /main
|
|
--- response_body
|
|
a = 1
|
|
--- no_error_log
|
|
[error]
|