- Implements Apache APISIX packaging for Cloudron platform. - Includes Dockerfile, CloudronManifest.json, and start.sh. - Configured to use Cloudron's etcd addon. 🤖 Generated with Gemini CLI Co-Authored-By: Gemini <noreply@google.com>
558 lines
14 KiB
Perl
558 lines
14 KiB
Perl
#
|
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership.
|
|
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
# (the "License"); you may not use this file except in compliance with
|
|
# the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
use t::APISIX 'no_plan';
|
|
|
|
log_level('warn');
|
|
repeat_each(1);
|
|
no_long_string();
|
|
no_root_location();
|
|
no_shuffle();
|
|
|
|
add_block_preprocessor(sub {
|
|
my ($block) = @_;
|
|
|
|
if (!defined $block->request) {
|
|
$block->set_value("request", "GET /t");
|
|
}
|
|
|
|
my $user_yaml_config = <<_EOC_;
|
|
plugin_attr:
|
|
inspect:
|
|
delay: 1
|
|
hooks_file: "/tmp/apisix_inspect_hooks.lua"
|
|
_EOC_
|
|
$block->set_value("yaml_config", $user_yaml_config);
|
|
|
|
my $extra_init_worker_by_lua = $block->extra_init_worker_by_lua // "";
|
|
$extra_init_worker_by_lua .= <<_EOC_;
|
|
local function gen_funcs_invoke(...)
|
|
local code = ""
|
|
for _, func in ipairs({...}) do
|
|
code = code .. "test." .. func .. "();"
|
|
end
|
|
return code
|
|
end
|
|
function set_test_route(...)
|
|
func = func or 'run1'
|
|
local t = require("lib.test_admin").test
|
|
local code = [[{
|
|
"methods": ["GET"],
|
|
"uri": "/inspect",
|
|
"plugins": {
|
|
"serverless-pre-function": {
|
|
"phase": "rewrite",
|
|
"functions" : ["return function() local test = require(\\"lib.test_inspect\\");]]
|
|
.. gen_funcs_invoke(...)
|
|
.. [[ngx.say(\\"ok\\"); end"]
|
|
}
|
|
},
|
|
"upstream": {
|
|
"type": "roundrobin",
|
|
"nodes": {
|
|
"127.0.0.1:1980": 1
|
|
}
|
|
}
|
|
}]]
|
|
return t('/apisix/admin/routes/inspect', ngx.HTTP_PUT, code)
|
|
end
|
|
|
|
function do_request()
|
|
local http = require "resty.http"
|
|
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/inspect"
|
|
|
|
local httpc = http.new()
|
|
local res = httpc:request_uri(uri, {method = "GET"})
|
|
assert(res.body == "ok\\n")
|
|
end
|
|
|
|
function write_hooks(code, file)
|
|
local file = io.open(file or "/tmp/apisix_inspect_hooks.lua", "w")
|
|
file:write(code)
|
|
file:close()
|
|
end
|
|
_EOC_
|
|
$block->set_value("extra_init_worker_by_lua", $extra_init_worker_by_lua);
|
|
|
|
# note that it's different from APISIX.pm,
|
|
# here we enable no_error_log ignoreless of error_log.
|
|
if (!$block->no_error_log) {
|
|
$block->set_value("no_error_log", "[error]");
|
|
}
|
|
|
|
if (!$block->timeout) {
|
|
$block->set_value("timeout", "10");
|
|
}
|
|
});
|
|
|
|
add_cleanup_handler(sub {
|
|
unlink("/tmp/apisix_inspect_hooks.lua");
|
|
});
|
|
|
|
run_tests;
|
|
|
|
__DATA__
|
|
|
|
=== TEST 1: simple hook
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local code = set_test_route("run1")
|
|
if code >= 300 then
|
|
ngx.status = code
|
|
return
|
|
end
|
|
|
|
write_hooks([[
|
|
local dbg = require "apisix.inspect.dbg"
|
|
dbg.set_hook("t/lib/test_inspect.lua", 27, nil, function(info)
|
|
ngx.log(ngx.WARN, "var1=", info.vals.var1)
|
|
return true
|
|
end)
|
|
]])
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
do_request()
|
|
|
|
os.remove("/tmp/apisix_inspect_hooks.lua")
|
|
}
|
|
}
|
|
--- error_log
|
|
var1=hello
|
|
|
|
|
|
|
|
=== TEST 2: filename only
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local code = set_test_route("run1")
|
|
if code >= 300 then
|
|
ngx.status = code
|
|
return
|
|
end
|
|
|
|
write_hooks([[
|
|
local dbg = require "apisix.inspect.dbg"
|
|
dbg.set_hook("test_inspect.lua", 27, nil, function(info)
|
|
ngx.log(ngx.WARN, "var1=", info.vals.var1)
|
|
return true
|
|
end)
|
|
]])
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
do_request()
|
|
|
|
os.remove("/tmp/apisix_inspect_hooks.lua")
|
|
}
|
|
}
|
|
--- error_log
|
|
var1=hello
|
|
|
|
|
|
|
|
=== TEST 3: hook lifetime
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local code = set_test_route("run1")
|
|
if code >= 300 then
|
|
ngx.status = code
|
|
return
|
|
end
|
|
|
|
write_hooks([[
|
|
local dbg = require "apisix.inspect.dbg"
|
|
local hook1_times = 2
|
|
dbg.set_hook("test_inspect.lua", 27, nil, function(info)
|
|
ngx.log(ngx.WARN, "var1=", info.vals.var1)
|
|
hook1_times = hook1_times - 1
|
|
return hook1_times == 0
|
|
end)
|
|
]])
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
-- request 3 times, but hook triggered 2 times
|
|
for _ = 1,3 do
|
|
do_request()
|
|
end
|
|
|
|
os.remove("/tmp/apisix_inspect_hooks.lua")
|
|
}
|
|
}
|
|
--- error_log
|
|
var1=hello
|
|
var1=hello
|
|
|
|
|
|
|
|
=== TEST 4: multiple hooks
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local code = set_test_route("run1")
|
|
if code >= 300 then
|
|
ngx.status = code
|
|
return
|
|
end
|
|
|
|
write_hooks([[
|
|
local dbg = require "apisix.inspect.dbg"
|
|
dbg.set_hook("test_inspect.lua", 26, nil, function(info)
|
|
ngx.log(ngx.WARN, "var1=", info.vals.var1)
|
|
return true
|
|
end)
|
|
|
|
dbg.set_hook("test_inspect.lua", 27, nil, function(info)
|
|
ngx.log(ngx.WARN, "var2=", info.vals.var2)
|
|
return true
|
|
end)
|
|
]])
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
do_request()
|
|
|
|
-- note that we don't remove the hook file,
|
|
-- used for next test case
|
|
}
|
|
}
|
|
--- error_log
|
|
var1=hello
|
|
var2=world
|
|
|
|
|
|
|
|
=== TEST 5: hook file not removed, re-enabled by next startup
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local code = set_test_route("run1")
|
|
if code >= 300 then
|
|
ngx.status = code
|
|
return
|
|
end
|
|
|
|
do_request()
|
|
|
|
os.remove("/tmp/apisix_inspect_hooks.lua")
|
|
}
|
|
}
|
|
--- error_log
|
|
var1=hello
|
|
|
|
|
|
|
|
=== TEST 6: soft link
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local code = set_test_route("run1")
|
|
if code >= 300 then
|
|
ngx.status = code
|
|
return
|
|
end
|
|
|
|
write_hooks([[
|
|
local dbg = require "apisix.inspect.dbg"
|
|
dbg.set_hook("t/lib/test_inspect.lua", 27, nil, function(info)
|
|
ngx.log(ngx.WARN, "var1=", info.vals.var1)
|
|
return true
|
|
end)
|
|
]], "/tmp/test_real_tmp_file.lua")
|
|
|
|
os.execute("ln -sf /tmp/test_real_tmp_file.lua /tmp/apisix_inspect_hooks.lua")
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
do_request()
|
|
|
|
os.remove("/tmp/apisix_inspect_hooks.lua")
|
|
os.remove("/tmp/test_real_tmp_file.lua")
|
|
}
|
|
}
|
|
--- error_log
|
|
var1=hello
|
|
|
|
|
|
|
|
=== TEST 7: remove soft link would disable hooks
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local code = set_test_route("run1")
|
|
if code >= 300 then
|
|
ngx.status = code
|
|
return
|
|
end
|
|
|
|
write_hooks([[
|
|
local dbg = require "apisix.inspect.dbg"
|
|
dbg.set_hook("t/lib/test_inspect.lua", 27, nil, function(info)
|
|
ngx.log(ngx.WARN, "var1=", info.vals.var1)
|
|
return true
|
|
end)
|
|
]], "/tmp/test_real_tmp_file.lua")
|
|
|
|
os.execute("ln -sf /tmp/test_real_tmp_file.lua /tmp/apisix_inspect_hooks.lua")
|
|
|
|
ngx.sleep(1.5)
|
|
os.remove("/tmp/apisix_inspect_hooks.lua")
|
|
ngx.sleep(1.5)
|
|
|
|
do_request()
|
|
|
|
os.remove("/tmp/test_real_tmp_file.lua")
|
|
}
|
|
}
|
|
--- no_error_log
|
|
var1=hello
|
|
|
|
|
|
|
|
=== TEST 8: ensure we see all local variables till the hook line
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local code = set_test_route("run1")
|
|
if code >= 300 then
|
|
ngx.status = code
|
|
return
|
|
end
|
|
|
|
write_hooks([[
|
|
local dbg = require "apisix.inspect.dbg"
|
|
dbg.set_hook("t/lib/test_inspect.lua", 27, nil, function(info)
|
|
local count = 0
|
|
for k,v in pairs(info.vals) do
|
|
count = count + 1
|
|
end
|
|
ngx.log(ngx.WARN, "count=", count)
|
|
return true
|
|
end)
|
|
]])
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
do_request()
|
|
|
|
os.remove("/tmp/apisix_inspect_hooks.lua")
|
|
}
|
|
}
|
|
--- error_log
|
|
count=2
|
|
|
|
|
|
|
|
=== TEST 9: check upvalue of run2(), only upvalue used in function code are visible
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local code = set_test_route("run2")
|
|
if code >= 300 then
|
|
ngx.status = code
|
|
return
|
|
end
|
|
|
|
write_hooks([[
|
|
local dbg = require "apisix.inspect.dbg"
|
|
dbg.set_hook("t/lib/test_inspect.lua", 33, nil, function(info)
|
|
ngx.log(ngx.WARN, "upvar1=", info.uv.upvar1)
|
|
ngx.log(ngx.WARN, "upvar2=", info.uv.upvar2)
|
|
return true
|
|
end)
|
|
]])
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
do_request()
|
|
|
|
os.remove("/tmp/apisix_inspect_hooks.lua")
|
|
}
|
|
}
|
|
--- error_log
|
|
upvar1=2
|
|
upvar2=nil
|
|
|
|
|
|
|
|
=== TEST 10: check upvalue of run3(), now both upvar1 and upvar2 are visible
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local code = set_test_route("run3")
|
|
if code >= 300 then
|
|
ngx.status = code
|
|
return
|
|
end
|
|
|
|
write_hooks([[
|
|
local dbg = require "apisix.inspect.dbg"
|
|
dbg.set_hook("t/lib/test_inspect.lua", 37, nil, function(info)
|
|
ngx.log(ngx.WARN, "upvar1=", info.uv.upvar1)
|
|
ngx.log(ngx.WARN, "upvar2=", info.uv.upvar2)
|
|
return true
|
|
end)
|
|
]])
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
do_request()
|
|
|
|
os.remove("/tmp/apisix_inspect_hooks.lua")
|
|
}
|
|
}
|
|
--- error_log
|
|
upvar1=2
|
|
upvar2=yes
|
|
|
|
|
|
|
|
=== TEST 11: flush specific JIT cache
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local test = require("lib.test_inspect")
|
|
|
|
local t1 = test.hot1()
|
|
local t8 = test.hot2()
|
|
|
|
write_hooks([[
|
|
local test = require("lib.test_inspect")
|
|
local dbg = require "apisix.inspect.dbg"
|
|
dbg.set_hook("t/lib/test_inspect.lua", 47, test.hot1, function(info)
|
|
return false
|
|
end)
|
|
]])
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
local t2 = test.hot1()
|
|
local t9 = test.hot2()
|
|
|
|
assert(t2-t1 > t1, "hot1 consumes at least double times than before")
|
|
assert(t9-t8 < t8*0.8, "hot2 not affected")
|
|
|
|
os.remove("/tmp/apisix_inspect_hooks.lua")
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
local t3 = test.hot1()
|
|
local t4 = test.hot2()
|
|
assert(t3-t1 < t1*0.8, "hot1 jit recover")
|
|
assert(t4-t8 < t4*0.8, "hot2 jit recover")
|
|
}
|
|
}
|
|
|
|
|
|
|
|
=== TEST 12: flush the whole JIT cache
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local test = require("lib.test_inspect")
|
|
|
|
local t1 = test.hot1()
|
|
local t8 = test.hot2()
|
|
|
|
write_hooks([[
|
|
local test = require("lib.test_inspect")
|
|
local dbg = require "apisix.inspect.dbg"
|
|
dbg.set_hook("t/lib/test_inspect.lua", 47, nil, function(info)
|
|
return false
|
|
end)
|
|
]])
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
local t2 = test.hot1()
|
|
local t9 = test.hot2()
|
|
|
|
assert(t2-t1 > t1, "hot1 consumes at least double times than before")
|
|
assert(t9-t8 > t8, "hot2 consumes at least double times than before")
|
|
|
|
os.remove("/tmp/apisix_inspect_hooks.lua")
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
local t3 = test.hot1()
|
|
local t4 = test.hot2()
|
|
assert(t3-t1 < t1*0.8, "hot1 jit recover")
|
|
assert(t4-t8 < t4*0.8, "hot2 jit recover")
|
|
}
|
|
}
|
|
|
|
|
|
|
|
=== TEST 13: remove hook log
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local code = set_test_route("run1")
|
|
if code >= 300 then
|
|
ngx.status = code
|
|
return
|
|
end
|
|
|
|
write_hooks([[
|
|
local dbg = require "apisix.inspect.dbg"
|
|
dbg.set_hook("t/lib/test_inspect.lua", 27, nil, function(info)
|
|
return true
|
|
end)
|
|
]])
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
do_request()
|
|
|
|
os.remove("/tmp/apisix_inspect_hooks.lua")
|
|
}
|
|
}
|
|
--- error_log
|
|
inspect: remove hook: t/lib/test_inspect.lua#27
|
|
inspect: all hooks removed
|
|
|
|
|
|
|
|
=== TEST 14: jit should be recovered after all hooks are done
|
|
--- config
|
|
location /t {
|
|
content_by_lua_block {
|
|
local test = require("lib.test_inspect")
|
|
|
|
local t1 = test.hot1()
|
|
|
|
write_hooks([[
|
|
local test = require("lib.test_inspect")
|
|
local dbg = require "apisix.inspect.dbg"
|
|
dbg.set_hook("t/lib/test_inspect.lua", 47, test.hot1, function(info)
|
|
return true
|
|
end)
|
|
]])
|
|
|
|
ngx.sleep(1.5)
|
|
|
|
local t2 = test.hot1()
|
|
assert(t2-t1 < t1*0.8, "hot1 consumes at least double times than before")
|
|
}
|
|
}
|
|
--- error_log
|
|
inspect: remove hook: t/lib/test_inspect.lua#47
|
|
inspect: all hooks removed
|