Files
ReachableCEO 54cc5f7308 feat(apisix): add Cloudron package
- 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>
2025-09-04 09:42:47 -05:00

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