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>
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
#
|
||||
# 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';
|
||||
|
||||
repeat_each(1);
|
||||
log_level('info');
|
||||
worker_connections(256);
|
||||
no_root_location();
|
||||
no_shuffle();
|
||||
|
||||
run_tests();
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: setup route
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local t = require("lib.test_admin").test
|
||||
local code, body = t('/apisix/admin/routes/1',
|
||||
ngx.HTTP_PUT,
|
||||
[[{
|
||||
"methods": ["GET"],
|
||||
"upstream": {
|
||||
"nodes": {
|
||||
"httpbin.org:80": 1,
|
||||
"mockbin.org:80": 1
|
||||
},
|
||||
"type": "roundrobin"
|
||||
},
|
||||
"uri": "/*"
|
||||
}]]
|
||||
)
|
||||
|
||||
if code >= 300 then
|
||||
ngx.status = code
|
||||
end
|
||||
ngx.say(body)
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
passed
|
||||
|
||||
|
||||
|
||||
=== TEST 2: hit the route
|
||||
--- request
|
||||
GET /status/403
|
||||
--- error_code: 403
|
||||
|
||||
|
||||
|
||||
=== TEST 3: hit control api
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
|
||||
local passed = true
|
||||
|
||||
for i = 1, 40 do
|
||||
local code, body, res = t.test('/v1/routes/1', ngx.HTTP_GET)
|
||||
if code ~= ngx.HTTP_OK then
|
||||
passed = code
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if passed then
|
||||
ngx.say("passed")
|
||||
else
|
||||
ngx.say("failed. got status code: ", passed)
|
||||
end
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
passed
|
||||
|
||||
|
||||
|
||||
=== TEST 4: hit the route again
|
||||
--- request
|
||||
GET /status/403
|
||||
--- error_code: 403
|
||||
|
||||
|
||||
|
||||
=== TEST 5: hit control api
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
|
||||
local passed = true
|
||||
|
||||
for i = 1, 40 do
|
||||
local code, body, res = t.test('/v1/routes/1', ngx.HTTP_GET)
|
||||
if code ~= ngx.HTTP_OK then
|
||||
passed = code
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if passed then
|
||||
ngx.say("passed")
|
||||
else
|
||||
ngx.say("failed. got status code: ", passed)
|
||||
end
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
passed
|
221
CloudronPackages/APISIX/apisix-source/t/control/discovery.t
Normal file
221
CloudronPackages/APISIX/apisix-source/t/control/discovery.t
Normal file
@@ -0,0 +1,221 @@
|
||||
#
|
||||
# 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';
|
||||
|
||||
repeat_each(1);
|
||||
no_long_string();
|
||||
no_root_location();
|
||||
no_shuffle();
|
||||
log_level("info");
|
||||
|
||||
|
||||
# Because this whole test file is only used to verify the configuration set or not,
|
||||
# but the configuration content is invalid, which contains non-exist consul server address,
|
||||
# so we have to ignore consul connect errors in some test cases.
|
||||
|
||||
|
||||
our $yaml_config = <<_EOC_;
|
||||
apisix:
|
||||
enable_control: true
|
||||
node_listen: 1984
|
||||
discovery:
|
||||
eureka:
|
||||
host:
|
||||
- "http://127.0.0.1:8761"
|
||||
prefix: "/eureka/"
|
||||
fetch_interval: 10
|
||||
weight: 80
|
||||
timeout:
|
||||
connect: 1500
|
||||
send: 1500
|
||||
read: 1500
|
||||
consul_kv:
|
||||
servers:
|
||||
- "http://127.0.0.1:8500"
|
||||
- "http://127.0.0.1:8600"
|
||||
dns:
|
||||
servers:
|
||||
- "127.0.0.1:1053"
|
||||
_EOC_
|
||||
|
||||
|
||||
run_tests();
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: test consul_kv dump_data api
|
||||
--- yaml_config eval: $::yaml_config
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
|
||||
local code, body, res = t.test('/v1/discovery/consul_kv/dump',
|
||||
ngx.HTTP_GET)
|
||||
local entity = json.decode(res)
|
||||
ngx.say(json.encode(entity.services))
|
||||
ngx.say(json.encode(entity.config))
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- error_code: 200
|
||||
--- response_body
|
||||
{}
|
||||
{"fetch_interval":3,"keepalive":true,"prefix":"upstreams","servers":["http://127.0.0.1:8500","http://127.0.0.1:8600"],"timeout":{"connect":2000,"read":2000,"wait":60},"token":"","weight":1}
|
||||
--- error_log
|
||||
connect consul
|
||||
|
||||
|
||||
|
||||
=== TEST 2: test eureka dump_data api
|
||||
--- yaml_config eval: $::yaml_config
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
|
||||
local code, body, res = t.test('/v1/discovery/eureka/dump',
|
||||
ngx.HTTP_GET, nil,
|
||||
[[{
|
||||
"config": {
|
||||
"fetch_interval": 10,
|
||||
"host": [
|
||||
"http://127.0.0.1:8761"
|
||||
],
|
||||
"prefix": "/eureka/",
|
||||
"timeout": {
|
||||
"connect": 1500,
|
||||
"read": 1500,
|
||||
"send": 1500
|
||||
},
|
||||
"weight": 80
|
||||
},
|
||||
"services": {}
|
||||
}]]
|
||||
)
|
||||
ngx.status = code
|
||||
ngx.say(body)
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- error_code: 200
|
||||
--- response_body
|
||||
passed
|
||||
--- error_log
|
||||
connect consul
|
||||
|
||||
|
||||
|
||||
=== TEST 3: test dns api
|
||||
--- yaml_config eval: $::yaml_config
|
||||
--- request
|
||||
GET /v1/discovery/dns/dump
|
||||
--- error_code: 404
|
||||
--- error_log
|
||||
connect consul
|
||||
|
||||
|
||||
|
||||
=== TEST 4: test unconfigured eureka dump_data api
|
||||
--- yaml_config
|
||||
apisix:
|
||||
enable_control: true
|
||||
node_listen: 1984
|
||||
discovery:
|
||||
consul_kv:
|
||||
servers:
|
||||
- "http://127.0.0.1:8500"
|
||||
- "http://127.0.0.1:8600"
|
||||
#END
|
||||
--- request
|
||||
GET /v1/discovery/eureka/dump
|
||||
--- error_code: 404
|
||||
--- error_log
|
||||
connect consul
|
||||
|
||||
|
||||
|
||||
=== TEST 5: prepare consul kv register nodes
|
||||
--- config
|
||||
location /consul1 {
|
||||
rewrite ^/consul1/(.*) /v1/kv/$1 break;
|
||||
proxy_pass http://127.0.0.1:8500;
|
||||
}
|
||||
|
||||
location /consul2 {
|
||||
rewrite ^/consul2/(.*) /v1/kv/$1 break;
|
||||
proxy_pass http://127.0.0.1:8600;
|
||||
}
|
||||
--- pipelined_requests eval
|
||||
[
|
||||
"DELETE /consul1/upstreams/?recurse=true",
|
||||
"DELETE /consul2/upstreams/?recurse=true",
|
||||
"PUT /consul1/upstreams/webpages/127.0.0.1:30511\n" . "{\"weight\": 1, \"max_fails\": 2, \"fail_timeout\": 1}",
|
||||
"PUT /consul1/upstreams/webpages/127.0.0.1:30512\n" . "{\"weight\": 1, \"max_fails\": 2, \"fail_timeout\": 1}",
|
||||
"PUT /consul2/upstreams/webpages/127.0.0.1:30513\n" . "{\"weight\": 1, \"max_fails\": 2, \"fail_timeout\": 1}",
|
||||
"PUT /consul2/upstreams/webpages/127.0.0.1:30514\n" . "{\"weight\": 1, \"max_fails\": 2, \"fail_timeout\": 1}",
|
||||
]
|
||||
--- response_body eval
|
||||
["true", "true", "true", "true", "true", "true"]
|
||||
|
||||
|
||||
|
||||
=== TEST 6: dump consul_kv services
|
||||
--- yaml_config eval: $::yaml_config
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
ngx.sleep(2)
|
||||
|
||||
local code, body, res = t.test('/v1/discovery/consul_kv/dump',
|
||||
ngx.HTTP_GET)
|
||||
local entity = json.decode(res)
|
||||
ngx.say(json.encode(entity.services))
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- error_code: 200
|
||||
--- response_body
|
||||
{"http://127.0.0.1:8500/v1/kv/upstreams/webpages/":[{"host":"127.0.0.1","port":30511,"weight":1},{"host":"127.0.0.1","port":30512,"weight":1}],"http://127.0.0.1:8600/v1/kv/upstreams/webpages/":[{"host":"127.0.0.1","port":30513,"weight":1},{"host":"127.0.0.1","port":30514,"weight":1}]}
|
||||
|
||||
|
||||
|
||||
=== TEST 7: clean consul kv register nodes
|
||||
--- config
|
||||
location /consul1 {
|
||||
rewrite ^/consul1/(.*) /v1/kv/$1 break;
|
||||
proxy_pass http://127.0.0.1:8500;
|
||||
}
|
||||
|
||||
location /consul2 {
|
||||
rewrite ^/consul2/(.*) /v1/kv/$1 break;
|
||||
proxy_pass http://127.0.0.1:8600;
|
||||
}
|
||||
--- pipelined_requests eval
|
||||
[
|
||||
"DELETE /consul1/upstreams/?recurse=true",
|
||||
"DELETE /consul2/upstreams/?recurse=true"
|
||||
]
|
||||
--- response_body eval
|
||||
["true", "true"]
|
66
CloudronPackages/APISIX/apisix-source/t/control/gc.t
Normal file
66
CloudronPackages/APISIX/apisix-source/t/control/gc.t
Normal file
@@ -0,0 +1,66 @@
|
||||
#
|
||||
# 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';
|
||||
|
||||
repeat_each(1);
|
||||
no_long_string();
|
||||
no_root_location();
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my ($block) = @_;
|
||||
|
||||
if (!$block->request) {
|
||||
$block->set_value("request", "GET /t");
|
||||
}
|
||||
|
||||
if (!$block->no_error_log) {
|
||||
$block->set_value("no_error_log", "[error]\n[alert]");
|
||||
}
|
||||
});
|
||||
|
||||
run_tests;
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: trigger full gc
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local t = require("lib.test_admin")
|
||||
local before = collectgarbage("count")
|
||||
do
|
||||
local tab = {}
|
||||
for i = 1, 10000 do
|
||||
tab[i] = {"a", 1}
|
||||
end
|
||||
end
|
||||
local after_alloc = collectgarbage("count")
|
||||
local code = t.test('/v1/gc',
|
||||
ngx.HTTP_POST
|
||||
)
|
||||
local after_gc = collectgarbage("count")
|
||||
if code == 200 then
|
||||
if after_alloc - after_gc > 0.9 * (after_alloc - before) then
|
||||
ngx.say("ok")
|
||||
else
|
||||
ngx.say(before, " ", after_alloc, " ", after_gc)
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
ok
|
305
CloudronPackages/APISIX/apisix-source/t/control/healthcheck.t
Normal file
305
CloudronPackages/APISIX/apisix-source/t/control/healthcheck.t
Normal file
@@ -0,0 +1,305 @@
|
||||
#
|
||||
# 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';
|
||||
|
||||
repeat_each(1);
|
||||
no_long_string();
|
||||
no_root_location();
|
||||
no_shuffle();
|
||||
log_level("info");
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my ($block) = @_;
|
||||
|
||||
if (!$block->request) {
|
||||
$block->set_value("request", "GET /t");
|
||||
}
|
||||
});
|
||||
|
||||
run_tests;
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: upstreams
|
||||
--- yaml_config
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
deployment:
|
||||
role: data_plane
|
||||
role_data_plane:
|
||||
config_provider: yaml
|
||||
--- apisix_yaml
|
||||
routes:
|
||||
-
|
||||
uris:
|
||||
- /hello
|
||||
upstream_id: 1
|
||||
upstreams:
|
||||
- nodes:
|
||||
"127.0.0.1:1980": 1
|
||||
"127.0.0.2:1988": 0
|
||||
type: roundrobin
|
||||
id: 1
|
||||
checks:
|
||||
active:
|
||||
http_path: "/status"
|
||||
healthy:
|
||||
interval: 1
|
||||
successes: 1
|
||||
unhealthy:
|
||||
interval: 1
|
||||
http_failures: 1
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local core = require("apisix.core")
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local http = require "resty.http"
|
||||
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello"
|
||||
local httpc = http.new()
|
||||
local res, err = httpc:request_uri(uri, {method = "GET"})
|
||||
|
||||
ngx.sleep(2.2)
|
||||
|
||||
local _, _, res = t.test('/v1/healthcheck',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
assert(#res == 1, "invalid number of results")
|
||||
table.sort(res[1].nodes, function(a, b)
|
||||
return a.ip < b.ip
|
||||
end)
|
||||
ngx.say(core.json.stably_encode(res[1].nodes))
|
||||
|
||||
local _, _, res = t.test('/v1/healthcheck/upstreams/1',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
table.sort(res.nodes, function(a, b)
|
||||
return a.ip < b.ip
|
||||
end)
|
||||
ngx.say(core.json.stably_encode(res.nodes))
|
||||
|
||||
local _, _, res = t.test('/v1/healthcheck/upstreams/1',
|
||||
ngx.HTTP_GET, nil, nil, {["Accept"] = "text/html"})
|
||||
local xml2lua = require("xml2lua")
|
||||
local xmlhandler = require("xmlhandler.tree")
|
||||
local handler = xmlhandler:new()
|
||||
local parser = xml2lua.parser(handler)
|
||||
parser.parse(parser, res)
|
||||
local matches = 0
|
||||
for _, td in ipairs(handler.root.html.body.table.tr) do
|
||||
if td.td then
|
||||
if td.td[4] == "127.0.0.2:1988" then
|
||||
assert(td.td[5] == "unhealthy", "127.0.0.2:1988 is not unhealthy")
|
||||
matches = matches + 1
|
||||
end
|
||||
if td.td[4] == "127.0.0.1:1980" then
|
||||
assert(td.td[5] == "healthy", "127.0.0.1:1980 is not healthy")
|
||||
matches = matches + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
assert(matches == 2, "unexpected html")
|
||||
}
|
||||
}
|
||||
--- grep_error_log eval
|
||||
qr/unhealthy TCP increment \(.+\) for '[^']+'/
|
||||
--- grep_error_log_out
|
||||
unhealthy TCP increment (1/2) for '127.0.0.2(127.0.0.2:1988)'
|
||||
unhealthy TCP increment (2/2) for '127.0.0.2(127.0.0.2:1988)'
|
||||
--- response_body
|
||||
[{"counter":{"http_failure":0,"success":0,"tcp_failure":0,"timeout_failure":0},"hostname":"127.0.0.1","ip":"127.0.0.1","port":1980,"status":"healthy"},{"counter":{"http_failure":0,"success":0,"tcp_failure":2,"timeout_failure":0},"hostname":"127.0.0.2","ip":"127.0.0.2","port":1988,"status":"unhealthy"}]
|
||||
[{"counter":{"http_failure":0,"success":0,"tcp_failure":0,"timeout_failure":0},"hostname":"127.0.0.1","ip":"127.0.0.1","port":1980,"status":"healthy"},{"counter":{"http_failure":0,"success":0,"tcp_failure":2,"timeout_failure":0},"hostname":"127.0.0.2","ip":"127.0.0.2","port":1988,"status":"unhealthy"}]
|
||||
|
||||
|
||||
|
||||
=== TEST 2: routes
|
||||
--- yaml_config
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
deployment:
|
||||
role: data_plane
|
||||
role_data_plane:
|
||||
config_provider: yaml
|
||||
--- apisix_yaml
|
||||
routes:
|
||||
-
|
||||
id: 1
|
||||
uris:
|
||||
- /hello
|
||||
upstream:
|
||||
nodes:
|
||||
"127.0.0.1:1980": 1
|
||||
"127.0.0.1:1988": 1
|
||||
type: roundrobin
|
||||
checks:
|
||||
active:
|
||||
http_path: "/status"
|
||||
host: "127.0.0.1"
|
||||
healthy:
|
||||
interval: 1
|
||||
successes: 1
|
||||
unhealthy:
|
||||
interval: 1
|
||||
http_failures: 1
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local http = require "resty.http"
|
||||
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello"
|
||||
local httpc = http.new()
|
||||
local res, err = httpc:request_uri(uri, {method = "GET"})
|
||||
|
||||
ngx.sleep(2.2)
|
||||
|
||||
local code, body, res = t.test('/v1/healthcheck',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
table.sort(res[1].nodes, function(a, b)
|
||||
return a.port < b.port
|
||||
end)
|
||||
ngx.say(json.encode(res))
|
||||
|
||||
local code, body, res = t.test('/v1/healthcheck/routes/1',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
table.sort(res.nodes, function(a, b)
|
||||
return a.port < b.port
|
||||
end)
|
||||
ngx.say(json.encode(res))
|
||||
}
|
||||
}
|
||||
--- grep_error_log eval
|
||||
qr/unhealthy TCP increment \(.+\) for '[^']+'/
|
||||
--- grep_error_log_out
|
||||
unhealthy TCP increment (1/2) for '127.0.0.1(127.0.0.1:1988)'
|
||||
unhealthy TCP increment (2/2) for '127.0.0.1(127.0.0.1:1988)'
|
||||
--- response_body
|
||||
[{"name":"/routes/1","nodes":[{"counter":{"http_failure":0,"success":0,"tcp_failure":0,"timeout_failure":0},"hostname":"127.0.0.1","ip":"127.0.0.1","port":1980,"status":"healthy"},{"counter":{"http_failure":0,"success":0,"tcp_failure":2,"timeout_failure":0},"hostname":"127.0.0.1","ip":"127.0.0.1","port":1988,"status":"unhealthy"}],"type":"http"}]
|
||||
{"name":"/routes/1","nodes":[{"counter":{"http_failure":0,"success":0,"tcp_failure":0,"timeout_failure":0},"hostname":"127.0.0.1","ip":"127.0.0.1","port":1980,"status":"healthy"},{"counter":{"http_failure":0,"success":0,"tcp_failure":2,"timeout_failure":0},"hostname":"127.0.0.1","ip":"127.0.0.1","port":1988,"status":"unhealthy"}],"type":"http"}
|
||||
|
||||
|
||||
|
||||
=== TEST 3: services
|
||||
--- yaml_config
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
deployment:
|
||||
role: data_plane
|
||||
role_data_plane:
|
||||
config_provider: yaml
|
||||
--- apisix_yaml
|
||||
routes:
|
||||
- id: 1
|
||||
service_id: 1
|
||||
uris:
|
||||
- /hello
|
||||
|
||||
services:
|
||||
-
|
||||
id: 1
|
||||
upstream:
|
||||
nodes:
|
||||
"127.0.0.1:1980": 1
|
||||
"127.0.0.1:1988": 1
|
||||
type: roundrobin
|
||||
checks:
|
||||
active:
|
||||
http_path: "/status"
|
||||
host: "127.0.0.1"
|
||||
port: 1988
|
||||
healthy:
|
||||
interval: 1
|
||||
successes: 1
|
||||
unhealthy:
|
||||
interval: 1
|
||||
http_failures: 1
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local http = require "resty.http"
|
||||
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello"
|
||||
local httpc = http.new()
|
||||
local res, err = httpc:request_uri(uri, {method = "GET"})
|
||||
|
||||
ngx.sleep(2.2)
|
||||
|
||||
local code, body, res = t.test('/v1/healthcheck',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
table.sort(res[1].nodes, function(a, b)
|
||||
return a.port < b.port
|
||||
end)
|
||||
ngx.say(json.encode(res))
|
||||
|
||||
local code, body, res = t.test('/v1/healthcheck/services/1',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
table.sort(res.nodes, function(a, b)
|
||||
return a.port < b.port
|
||||
end)
|
||||
ngx.say(json.encode(res))
|
||||
}
|
||||
}
|
||||
--- grep_error_log eval
|
||||
qr/unhealthy TCP increment \(.+\) for '[^']+'/
|
||||
--- grep_error_log_out
|
||||
unhealthy TCP increment (1/2) for '127.0.0.1(127.0.0.1:1988)'
|
||||
unhealthy TCP increment (2/2) for '127.0.0.1(127.0.0.1:1988)'
|
||||
--- response_body
|
||||
[{"name":"/services/1","nodes":[{"counter":{"http_failure":0,"success":0,"tcp_failure":2,"timeout_failure":0},"hostname":"127.0.0.1","ip":"127.0.0.1","port":1988,"status":"unhealthy"}],"type":"http"}]
|
||||
{"name":"/services/1","nodes":[{"counter":{"http_failure":0,"success":0,"tcp_failure":2,"timeout_failure":0},"hostname":"127.0.0.1","ip":"127.0.0.1","port":1988,"status":"unhealthy"}],"type":"http"}
|
||||
|
||||
|
||||
|
||||
=== TEST 4: no checkers
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local t = require("lib.test_admin")
|
||||
local code, body, res = t.test('/v1/healthcheck',
|
||||
ngx.HTTP_GET)
|
||||
ngx.print(res)
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
{}
|
||||
|
||||
|
||||
|
||||
=== TEST 5: no checker
|
||||
--- request
|
||||
GET /v1/healthcheck/routes/1
|
||||
--- error_code: 404
|
||||
--- response_body
|
||||
{"error_msg":"routes[1] not found"}
|
||||
|
||||
|
||||
|
||||
=== TEST 6: invalid src type
|
||||
--- request
|
||||
GET /v1/healthcheck/route/1
|
||||
--- error_code: 400
|
||||
--- response_body
|
||||
{"error_msg":"invalid src type route"}
|
55
CloudronPackages/APISIX/apisix-source/t/control/plugin-api.t
Normal file
55
CloudronPackages/APISIX/apisix-source/t/control/plugin-api.t
Normal file
@@ -0,0 +1,55 @@
|
||||
#
|
||||
# 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';
|
||||
|
||||
repeat_each(1);
|
||||
no_long_string();
|
||||
no_root_location();
|
||||
no_shuffle();
|
||||
log_level("info");
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my ($block) = @_;
|
||||
|
||||
if (!$block->request) {
|
||||
$block->set_value("request", "GET /t");
|
||||
}
|
||||
|
||||
if (!$block->no_error_log) {
|
||||
$block->set_value("no_error_log", "[error]\n[alert]");
|
||||
}
|
||||
});
|
||||
|
||||
run_tests;
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: sanity
|
||||
--- request
|
||||
GET /v1/plugin/example-plugin/hello
|
||||
--- response_body
|
||||
world
|
||||
|
||||
|
||||
|
||||
=== TEST 2: set Content-Type for table response
|
||||
--- request
|
||||
GET /v1/plugin/example-plugin/hello?json
|
||||
--- response_body
|
||||
{"msg":"world"}
|
||||
--- response_headers
|
||||
Content-Type: application/json
|
@@ -0,0 +1,113 @@
|
||||
#
|
||||
# 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';
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my ($block) = @_;
|
||||
|
||||
if (!$block->request) {
|
||||
$block->set_value("request", "GET /t");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
run_tests;
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: add plugin metadatas
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local t = require("lib.test_admin").test
|
||||
local code = t('/apisix/admin/plugin_metadata/example-plugin',
|
||||
ngx.HTTP_PUT,
|
||||
[[{
|
||||
"skey": "val",
|
||||
"ikey": 1
|
||||
}]]
|
||||
)
|
||||
if code >= 300 then
|
||||
ngx.status = code
|
||||
return
|
||||
end
|
||||
|
||||
local code = t('/apisix/admin/plugin_metadata/file-logger',
|
||||
ngx.HTTP_PUT,
|
||||
[[
|
||||
{"log_format": {"upstream_response_time": "$upstream_response_time"}}
|
||||
]]
|
||||
)
|
||||
if code >= 300 then
|
||||
ngx.status = code
|
||||
return
|
||||
end
|
||||
}
|
||||
}
|
||||
--- error_code: 200
|
||||
|
||||
|
||||
|
||||
=== TEST 2: dump all plugin metadatas
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local t = require("lib.test_admin").test
|
||||
local _, _, res = t('/v1/plugin_metadatas', ngx.HTTP_GET)
|
||||
local json = require("toolkit.json")
|
||||
res = json.decode(res)
|
||||
for _, metadata in ipairs(res) do
|
||||
if metadata.id == "file-logger" then
|
||||
ngx.say("check log_format: ", metadata.log_format.upstream_response_time == "$upstream_response_time")
|
||||
elseif metadata.id == "example-plugin" then
|
||||
ngx.say("check skey: ", metadata.skey == "val")
|
||||
ngx.say("check ikey: ", metadata.ikey == 1)
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
check log_format: true
|
||||
check skey: true
|
||||
check ikey: true
|
||||
|
||||
|
||||
|
||||
=== TEST 3: dump file-logger metadata
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local t = require("lib.test_admin").test
|
||||
local _, _, res = t('/v1/plugin_metadata/file-logger', ngx.HTTP_GET)
|
||||
local json = require("toolkit.json")
|
||||
metadata = json.decode(res)
|
||||
if metadata.id == "file-logger" then
|
||||
ngx.say("check log_format: ", metadata.log_format.upstream_response_time == "$upstream_response_time")
|
||||
end
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
check log_format: true
|
||||
|
||||
|
||||
|
||||
=== TEST 4: plugin without metadata
|
||||
--- request
|
||||
GET /v1/plugin_metadata/batch-requests
|
||||
--- error_code: 404
|
||||
--- response_body
|
||||
{"error_msg":"plugin metadata[batch-requests] not found"}
|
341
CloudronPackages/APISIX/apisix-source/t/control/plugins-reload.t
Normal file
341
CloudronPackages/APISIX/apisix-source/t/control/plugins-reload.t
Normal file
@@ -0,0 +1,341 @@
|
||||
#
|
||||
# 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';
|
||||
|
||||
repeat_each(1);
|
||||
no_long_string();
|
||||
no_root_location();
|
||||
no_shuffle();
|
||||
log_level("info");
|
||||
workers(2);
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my ($block) = @_;
|
||||
|
||||
$block;
|
||||
});
|
||||
|
||||
run_tests;
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: reload plugins
|
||||
--- yaml_config
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
enable_control: true
|
||||
control:
|
||||
ip: "127.0.0.1"
|
||||
port: 9090
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local t = require("lib.test_admin")
|
||||
|
||||
local code, body, res = t.test('/v1/plugins/reload',
|
||||
ngx.HTTP_PUT)
|
||||
ngx.say(res)
|
||||
ngx.sleep(1)
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
done
|
||||
--- error_log
|
||||
load plugin times: 2
|
||||
load plugin times: 2
|
||||
start to hot reload plugins
|
||||
start to hot reload plugins
|
||||
|
||||
|
||||
|
||||
=== TEST 2: reload plugins when attributes changed
|
||||
--- yaml_config
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
enable_admin: true
|
||||
node_listen: 1984
|
||||
plugins:
|
||||
- example-plugin
|
||||
plugin_attr:
|
||||
example-plugin:
|
||||
val: 0
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local core = require "apisix.core"
|
||||
ngx.sleep(0.1)
|
||||
local data = [[
|
||||
deployment:
|
||||
role: traditional
|
||||
role_traditional:
|
||||
config_provider: etcd
|
||||
admin:
|
||||
admin_key: null
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
enable_control: true
|
||||
control:
|
||||
ip: "127.0.0.1"
|
||||
port: 9090
|
||||
plugins:
|
||||
- example-plugin
|
||||
plugin_attr:
|
||||
example-plugin:
|
||||
val: 1
|
||||
]]
|
||||
require("lib.test_admin").set_config_yaml(data)
|
||||
|
||||
local t = require("lib.test_admin").test
|
||||
local code, _, org_body = t('/v1/plugins/reload',
|
||||
ngx.HTTP_PUT)
|
||||
|
||||
ngx.status = code
|
||||
ngx.say(org_body)
|
||||
ngx.sleep(0.1)
|
||||
|
||||
local data = [[
|
||||
deployment:
|
||||
role: traditional
|
||||
role_traditional:
|
||||
config_provider: etcd
|
||||
admin:
|
||||
admin_key: null
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
plugins:
|
||||
- example-plugin
|
||||
plugin_attr:
|
||||
example-plugin:
|
||||
val: 1
|
||||
]]
|
||||
require("lib.test_admin").set_config_yaml(data)
|
||||
|
||||
local t = require("lib.test_admin").test
|
||||
local code, _, org_body = t('/v1/plugins/reload',
|
||||
ngx.HTTP_PUT)
|
||||
ngx.say(org_body)
|
||||
ngx.sleep(0.1)
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
done
|
||||
done
|
||||
--- grep_error_log eval
|
||||
qr/example-plugin get plugin attr val: \d+/
|
||||
--- grep_error_log_out
|
||||
example-plugin get plugin attr val: 0
|
||||
example-plugin get plugin attr val: 0
|
||||
example-plugin get plugin attr val: 0
|
||||
example-plugin get plugin attr val: 1
|
||||
example-plugin get plugin attr val: 1
|
||||
example-plugin get plugin attr val: 1
|
||||
example-plugin get plugin attr val: 1
|
||||
example-plugin get plugin attr val: 1
|
||||
example-plugin get plugin attr val: 1
|
||||
|
||||
|
||||
|
||||
=== TEST 3: reload plugins to change prometheus' export uri
|
||||
--- yaml_config
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
plugins:
|
||||
- public-api
|
||||
- prometheus
|
||||
plugin_attr:
|
||||
prometheus:
|
||||
export_uri: /metrics
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local core = require "apisix.core"
|
||||
ngx.sleep(0.1)
|
||||
local t = require("lib.test_admin").test
|
||||
|
||||
-- setup public API route
|
||||
local code, body = t('/apisix/admin/routes/1',
|
||||
ngx.HTTP_PUT,
|
||||
[[{
|
||||
"plugins": {
|
||||
"public-api": {}
|
||||
},
|
||||
"uri": "/apisix/metrics"
|
||||
}]]
|
||||
)
|
||||
ngx.say(code)
|
||||
|
||||
local code, _, org_body = t('/apisix/metrics',
|
||||
ngx.HTTP_GET)
|
||||
ngx.say(code)
|
||||
|
||||
local data = [[
|
||||
deployment:
|
||||
role: traditional
|
||||
role_traditional:
|
||||
config_provider: etcd
|
||||
admin:
|
||||
admin_key: null
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
enable_control: true
|
||||
control:
|
||||
ip: "127.0.0.1"
|
||||
port: 9090
|
||||
plugins:
|
||||
- public-api
|
||||
- prometheus
|
||||
plugin_attr:
|
||||
prometheus:
|
||||
export_uri: /apisix/metrics
|
||||
]]
|
||||
require("lib.test_admin").set_config_yaml(data)
|
||||
|
||||
local code, _, org_body = t('/v1/plugins/reload',
|
||||
ngx.HTTP_PUT)
|
||||
|
||||
ngx.say(org_body)
|
||||
|
||||
ngx.sleep(0.1)
|
||||
local code, _, org_body = t('/apisix/metrics',
|
||||
ngx.HTTP_GET)
|
||||
ngx.say(code)
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
201
|
||||
404
|
||||
done
|
||||
200
|
||||
|
||||
|
||||
|
||||
=== TEST 4: reload plugins to disable skywalking
|
||||
--- yaml_config
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
enable_control: true
|
||||
control:
|
||||
ip: "127.0.0.1"
|
||||
port: 9090
|
||||
plugins:
|
||||
- skywalking
|
||||
plugin_attr:
|
||||
skywalking:
|
||||
service_name: APISIX
|
||||
service_instance_name: "APISIX Instance Name"
|
||||
endpoint_addr: http://127.0.0.1:12801
|
||||
report_interval: 1
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local core = require "apisix.core"
|
||||
ngx.sleep(1.2)
|
||||
local t = require("lib.test_admin").test
|
||||
|
||||
local data = [[
|
||||
deployment:
|
||||
role: traditional
|
||||
role_traditional:
|
||||
config_provider: etcd
|
||||
admin:
|
||||
admin_key: null
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
plugins:
|
||||
- prometheus
|
||||
]]
|
||||
require("lib.test_admin").set_config_yaml(data)
|
||||
|
||||
local code, _, org_body = t('/v1/plugins/reload',
|
||||
ngx.HTTP_PUT)
|
||||
|
||||
ngx.say(org_body)
|
||||
|
||||
ngx.sleep(2)
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
done
|
||||
--- no_error_log
|
||||
[alert]
|
||||
--- grep_error_log eval
|
||||
qr/Instance report fails/
|
||||
--- grep_error_log_out
|
||||
Instance report fails
|
||||
|
||||
|
||||
|
||||
=== TEST 5: wrong method to reload plugins
|
||||
--- request
|
||||
GET /v1/plugins/reload
|
||||
--- error_code: 404
|
||||
|
||||
|
||||
|
||||
=== TEST 6: wrong method to reload plugins
|
||||
--- request
|
||||
POST /v1/plugins/reload
|
||||
--- error_code: 404
|
||||
|
||||
|
||||
|
||||
=== TEST 7: reload plugin with data_plane deployment
|
||||
--- yaml_config
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
enable_admin: false
|
||||
deployment:
|
||||
role: data_plane
|
||||
role_data_plane:
|
||||
config_provider: yaml
|
||||
--- apisix_yaml
|
||||
routes:
|
||||
-
|
||||
uri: /hello
|
||||
upstream:
|
||||
nodes:
|
||||
"127.0.0.1:1980": 1
|
||||
type: roundrobin
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local t = require("lib.test_admin")
|
||||
|
||||
local code, body, res = t.test('/v1/plugins/reload',
|
||||
ngx.HTTP_PUT)
|
||||
ngx.say(res)
|
||||
ngx.sleep(1)
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
done
|
||||
--- error_log
|
||||
load plugin times: 2
|
||||
load plugin times: 2
|
||||
start to hot reload plugins
|
||||
start to hot reload plugins
|
142
CloudronPackages/APISIX/apisix-source/t/control/routes.t
Normal file
142
CloudronPackages/APISIX/apisix-source/t/control/routes.t
Normal file
@@ -0,0 +1,142 @@
|
||||
#
|
||||
# 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';
|
||||
|
||||
repeat_each(1);
|
||||
no_long_string();
|
||||
no_root_location();
|
||||
no_shuffle();
|
||||
log_level("info");
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my ($block) = @_;
|
||||
|
||||
if (!$block->yaml_config) {
|
||||
my $yaml_config = <<_EOC_;
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
deployment:
|
||||
role: data_plane
|
||||
role_data_plane:
|
||||
config_provider: yaml
|
||||
_EOC_
|
||||
|
||||
$block->set_value("yaml_config", $yaml_config);
|
||||
}
|
||||
|
||||
if (!$block->request) {
|
||||
$block->set_value("request", "GET /t");
|
||||
}
|
||||
});
|
||||
|
||||
run_tests;
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: routes
|
||||
--- apisix_yaml
|
||||
routes:
|
||||
-
|
||||
id: 1
|
||||
uris:
|
||||
- /hello
|
||||
upstream:
|
||||
nodes:
|
||||
"127.0.0.1:1980": 1
|
||||
type: roundrobin
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local code, body, res = t.test('/v1/routes',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
if res[1] then
|
||||
local data = {}
|
||||
data.uris = res[1].value.uris
|
||||
data.upstream = res[1].value.upstream
|
||||
ngx.say(json.encode(data))
|
||||
end
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
{"upstream":{"hash_on":"vars","nodes":[{"host":"127.0.0.1","port":1980,"weight":1}],"pass_host":"pass","scheme":"http","type":"roundrobin"},"uris":["/hello"]}
|
||||
|
||||
|
||||
|
||||
=== TEST 2: get route with id 1
|
||||
--- apisix_yaml
|
||||
routes:
|
||||
-
|
||||
id: 1
|
||||
uris:
|
||||
- /hello
|
||||
upstream:
|
||||
nodes:
|
||||
"127.0.0.1:1980": 1
|
||||
type: roundrobin
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local code, body, res = t.test('/v1/route/1',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
if res then
|
||||
local data = {}
|
||||
data.uris = res.value.uris
|
||||
data.upstream = res.value.upstream
|
||||
ngx.say(json.encode(data))
|
||||
end
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
{"upstream":{"hash_on":"vars","nodes":[{"host":"127.0.0.1","port":1980,"weight":1}],"pass_host":"pass","scheme":"http","type":"roundrobin"},"uris":["/hello"]}
|
||||
|
||||
|
||||
|
||||
=== TEST 3: routes with invalid id
|
||||
--- apisix_yaml
|
||||
routes:
|
||||
-
|
||||
id: 1
|
||||
uris:
|
||||
- /hello
|
||||
upstream:
|
||||
nodes:
|
||||
"127.0.0.1:1980": 1
|
||||
type: roundrobin
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local code, body, res = t.test('/v1/route/2',
|
||||
ngx.HTTP_GET)
|
||||
local data = {}
|
||||
data.status = code
|
||||
ngx.say(json.encode(data))
|
||||
return
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
{"status":404}
|
149
CloudronPackages/APISIX/apisix-source/t/control/schema.t
Normal file
149
CloudronPackages/APISIX/apisix-source/t/control/schema.t
Normal file
@@ -0,0 +1,149 @@
|
||||
#
|
||||
# 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';
|
||||
|
||||
repeat_each(1);
|
||||
no_long_string();
|
||||
no_root_location();
|
||||
no_shuffle();
|
||||
log_level("info");
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my ($block) = @_;
|
||||
|
||||
if (!$block->request) {
|
||||
$block->set_value("request", "GET /t");
|
||||
}
|
||||
|
||||
if (!$block->no_error_log) {
|
||||
$block->set_value("no_error_log", "[error]\n[alert]");
|
||||
}
|
||||
});
|
||||
|
||||
run_tests;
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: sanity
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local t = require("lib.test_admin")
|
||||
|
||||
local code, body, res = t.test('/v1/schema',
|
||||
ngx.HTTP_GET,
|
||||
nil,
|
||||
[[{
|
||||
"main": {
|
||||
"consumer": {"type":"object"},
|
||||
"consumer_group": {"type":"object"},
|
||||
"global_rule": {"type":"object"},
|
||||
"plugin_config": {"type":"object"},
|
||||
"plugins": {"type":"array"},
|
||||
"proto": {"type":"object"},
|
||||
"route": {"type":"object"},
|
||||
"service": {"type":"object"},
|
||||
"ssl": {"type":"object"},
|
||||
"stream_route": {"type":"object"},
|
||||
"upstream": {"type":"object"},
|
||||
"upstream_hash_header_schema": {"type":"string"},
|
||||
"upstream_hash_vars_schema": {"type":"string"},
|
||||
},]] .. [[
|
||||
"plugins": {
|
||||
"example-plugin": {
|
||||
"version": 0.1,
|
||||
"priority": 0,
|
||||
"schema": {
|
||||
"type":"object",
|
||||
"properties": {
|
||||
"_meta": {
|
||||
"properties": {
|
||||
"disable": {"type": "boolean"}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata_schema": {"type":"object"}
|
||||
},
|
||||
"basic-auth": {
|
||||
"type": "auth",
|
||||
"consumer_schema": {"type":"object"}
|
||||
}
|
||||
},
|
||||
"stream_plugins": {
|
||||
"mqtt-proxy": {
|
||||
"schema": {
|
||||
"type":"object",
|
||||
"properties": {
|
||||
"_meta": {
|
||||
"properties": {
|
||||
"disable": {"type": "boolean"}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"priority": 1000
|
||||
}
|
||||
}
|
||||
}]]
|
||||
)
|
||||
ngx.status = code
|
||||
ngx.say(body)
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
passed
|
||||
|
||||
|
||||
|
||||
=== TEST 2: confirm the scope of plugin
|
||||
--- extra_yaml_config
|
||||
plugins:
|
||||
- batch-requests
|
||||
- error-log-logger
|
||||
- server-info
|
||||
- example-plugin
|
||||
- node-status
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin").test
|
||||
|
||||
local code, message, res = t('/v1/schema',
|
||||
ngx.HTTP_GET
|
||||
)
|
||||
|
||||
if code >= 300 then
|
||||
ngx.status = code
|
||||
ngx.say(message)
|
||||
return
|
||||
end
|
||||
|
||||
res = json.decode(res)
|
||||
local global_plugins = {}
|
||||
local plugins = res["plugins"]
|
||||
for k, v in pairs(plugins) do
|
||||
if v.scope == "global" then
|
||||
global_plugins[k] = v.scope
|
||||
end
|
||||
end
|
||||
ngx.say(json.encode(global_plugins))
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
{"batch-requests":"global","error-log-logger":"global","node-status":"global","server-info":"global"}
|
188
CloudronPackages/APISIX/apisix-source/t/control/services.t
Normal file
188
CloudronPackages/APISIX/apisix-source/t/control/services.t
Normal file
@@ -0,0 +1,188 @@
|
||||
#
|
||||
# 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';
|
||||
|
||||
repeat_each(1);
|
||||
no_long_string();
|
||||
no_root_location();
|
||||
no_shuffle();
|
||||
log_level("info");
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my ($block) = @_;
|
||||
|
||||
if (!$block->yaml_config) {
|
||||
my $yaml_config = <<_EOC_;
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
deployment:
|
||||
role: data_plane
|
||||
role_data_plane:
|
||||
config_provider: yaml
|
||||
_EOC_
|
||||
|
||||
$block->set_value("yaml_config", $yaml_config);
|
||||
}
|
||||
|
||||
if (!$block->request) {
|
||||
$block->set_value("request", "GET /t");
|
||||
}
|
||||
});
|
||||
|
||||
run_tests;
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: services
|
||||
--- apisix_yaml
|
||||
services:
|
||||
-
|
||||
id: 200
|
||||
upstream:
|
||||
nodes:
|
||||
"127.0.0.1:1980": 1
|
||||
type: roundrobin
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local code, body, res = t.test('/v1/services',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
if res[1] then
|
||||
local data = {}
|
||||
data.id = res[1].value.id
|
||||
data.plugins = res[1].value.plugins
|
||||
data.upstream = res[1].value.upstream
|
||||
ngx.say(json.encode(data))
|
||||
end
|
||||
return
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
{"id":"200","upstream":{"hash_on":"vars","nodes":[{"host":"127.0.0.1","port":1980,"weight":1}],"pass_host":"pass","scheme":"http","type":"roundrobin"}}
|
||||
|
||||
|
||||
|
||||
=== TEST 2: multiple services
|
||||
--- apisix_yaml
|
||||
services:
|
||||
-
|
||||
id: 200
|
||||
upstream:
|
||||
nodes:
|
||||
"127.0.0.1:1980": 1
|
||||
type: roundrobin
|
||||
-
|
||||
id: 201
|
||||
upstream:
|
||||
nodes:
|
||||
"127.0.0.2:1980": 1
|
||||
type: roundrobin
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local core = require("apisix.core")
|
||||
local code, body, res = t.test('/v1/services',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
local g_data = {}
|
||||
for _, r in core.config_util.iterate_values(res) do
|
||||
local data = {}
|
||||
data.id = r.value.id
|
||||
data.plugins = r.value.plugins
|
||||
data.upstream = r.value.upstream
|
||||
core.table.insert(g_data, data)
|
||||
end
|
||||
ngx.say(json.encode(g_data))
|
||||
return
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
[{"id":"200","upstream":{"hash_on":"vars","nodes":[{"host":"127.0.0.1","port":1980,"weight":1}],"pass_host":"pass","scheme":"http","type":"roundrobin"}},{"id":"201","upstream":{"hash_on":"vars","nodes":[{"host":"127.0.0.2","port":1980,"weight":1}],"pass_host":"pass","scheme":"http","type":"roundrobin"}}]
|
||||
|
||||
|
||||
|
||||
=== TEST 3: get service with id 5
|
||||
--- apisix_yaml
|
||||
services:
|
||||
-
|
||||
id: 5
|
||||
plugins:
|
||||
limit-count:
|
||||
count: 2
|
||||
time_window: 60
|
||||
rejected_code: 503
|
||||
key: remote_addr
|
||||
upstream:
|
||||
nodes:
|
||||
"127.0.0.1:1980": 1
|
||||
type: roundrobin
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local code, body, res = t.test('/v1/service/5',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
if res then
|
||||
local data = {}
|
||||
data.id = res.value.id
|
||||
data.plugins = res.value.plugins
|
||||
data.upstream = res.value.upstream
|
||||
ngx.say(json.encode(data))
|
||||
end
|
||||
return
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
{"id":"5","plugins":{"limit-count":{"allow_degradation":false,"count":2,"key":"remote_addr","key_type":"var","policy":"local","rejected_code":503,"show_limit_quota_header":true,"time_window":60}},"upstream":{"hash_on":"vars","nodes":[{"host":"127.0.0.1","port":1980,"weight":1}],"pass_host":"pass","scheme":"http","type":"roundrobin"}}
|
||||
|
||||
|
||||
|
||||
=== TEST 4: services with invalid id
|
||||
--- apisix_yaml
|
||||
services:
|
||||
-
|
||||
id: 1
|
||||
upstream:
|
||||
nodes:
|
||||
"127.0.0.1:1980": 1
|
||||
type: roundrobin
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local code, body, res = t.test('/v1/service/2',
|
||||
ngx.HTTP_GET)
|
||||
local data = {}
|
||||
data.status = code
|
||||
ngx.say(json.encode(data))
|
||||
return
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
{"status":404}
|
146
CloudronPackages/APISIX/apisix-source/t/control/upstreams.t
Normal file
146
CloudronPackages/APISIX/apisix-source/t/control/upstreams.t
Normal file
@@ -0,0 +1,146 @@
|
||||
#
|
||||
# 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';
|
||||
|
||||
repeat_each(1);
|
||||
no_long_string();
|
||||
no_root_location();
|
||||
no_shuffle();
|
||||
log_level("info");
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my ($block) = @_;
|
||||
|
||||
if (!$block->yaml_config) {
|
||||
my $yaml_config = <<_EOC_;
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
deployment:
|
||||
role: data_plane
|
||||
role_data_plane:
|
||||
config_provider: yaml
|
||||
_EOC_
|
||||
|
||||
$block->set_value("yaml_config", $yaml_config);
|
||||
}
|
||||
|
||||
if (!$block->request) {
|
||||
$block->set_value("request", "GET /t");
|
||||
}
|
||||
});
|
||||
|
||||
run_tests;
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: dump all upstreams
|
||||
--- apisix_yaml
|
||||
upstreams:
|
||||
-
|
||||
id: 1
|
||||
nodes:
|
||||
"127.0.0.1:8001": 1
|
||||
type: roundrobin
|
||||
-
|
||||
id: 2
|
||||
nodes:
|
||||
"127.0.0.1:8002": 1
|
||||
type: roundrobin
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local code, body, res = t.test('/v1/upstreams',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
if res[2] and table.getn(res) == 2 then
|
||||
local data = {}
|
||||
data.nodes = res[2].value.nodes
|
||||
ngx.say(json.encode(data))
|
||||
end
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
{"nodes":[{"host":"127.0.0.1","port":8002,"weight":1}]}
|
||||
|
||||
|
||||
|
||||
=== TEST 2: dump specific upstream with id 1
|
||||
--- apisix_yaml
|
||||
upstreams:
|
||||
-
|
||||
id: 1
|
||||
nodes:
|
||||
"127.0.0.1:8001": 1
|
||||
type: roundrobin
|
||||
-
|
||||
id: 2
|
||||
nodes:
|
||||
"127.0.0.1:8002": 1
|
||||
type: roundrobin
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local code, body, res = t.test('/v1/upstream/1',
|
||||
ngx.HTTP_GET)
|
||||
res = json.decode(res)
|
||||
if res then
|
||||
local data = {}
|
||||
data.nodes = res.value.nodes
|
||||
ngx.say(json.encode(data))
|
||||
end
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
{"nodes":[{"host":"127.0.0.1","port":8001,"weight":1}]}
|
||||
|
||||
|
||||
|
||||
=== TEST 3: upstreams with invalid id
|
||||
--- apisix_yaml
|
||||
upstreams:
|
||||
-
|
||||
id: 1
|
||||
nodes:
|
||||
"127.0.0.1:8001": 1
|
||||
type: roundrobin
|
||||
-
|
||||
id: 2
|
||||
nodes:
|
||||
"127.0.0.1:8002": 1
|
||||
type: roundrobin
|
||||
#END
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local json = require("toolkit.json")
|
||||
local t = require("lib.test_admin")
|
||||
local code, body, res = t.test('/v1/upstream/3',
|
||||
ngx.HTTP_GET)
|
||||
local data = {}
|
||||
data.status = code
|
||||
ngx.say(json.encode(data))
|
||||
return
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
{"status":404}
|
Reference in New Issue
Block a user