Files
2026-07-13 12:32:21 +08:00

165 lines
5.1 KiB
Lua

local helpers = require "spec.helpers"
local cjson = require "cjson.safe"
for _, strategy in helpers.each_strategy() do
local postgres_only = strategy == "postgres" and describe or pending
postgres_only("postgres readonly connection", function()
local proxy_client, admin_client
lazy_setup(function()
local _, db = helpers.get_db_utils(strategy, {
"routes",
"services",
}) -- runs migrations
-- db RO permissions setup
local pg_ro_user = helpers.test_conf.pg_ro_user
local pg_db = helpers.test_conf.pg_database
db:schema_reset()
db.connector:query(string.format("CREATE user %s;", pg_ro_user))
db.connector:query(string.format([[
GRANT CONNECT ON DATABASE %s TO %s;
GRANT USAGE ON SCHEMA public TO %s;
ALTER DEFAULT PRIVILEGES FOR ROLE kong IN SCHEMA public GRANT SELECT ON TABLES TO %s;
]], pg_db, pg_ro_user, pg_ro_user, pg_ro_user))
helpers.bootstrap_database(db)
assert(helpers.start_kong({
database = strategy,
pg_ro_host = helpers.test_conf.pg_host,
nginx_conf = "spec/fixtures/custom_nginx.template",
}))
admin_client = helpers.admin_client()
proxy_client = helpers.proxy_client()
end)
lazy_teardown(function()
if admin_client then admin_client:close() end
if proxy_client then proxy_client:close() end
helpers.stop_kong()
end)
describe("proxy and admin API works", function()
local route_id
it("can change and retrieve config using Admin API", function()
local res = assert(admin_client:post("/services", {
body = { name = "mock-service", url = "https://127.0.0.1:15556/request", },
headers = {["Content-Type"] = "application/json"}
}))
assert.res_status(201, res)
res = assert(admin_client:get("/services/mock-service"))
local body = assert.res_status(200, res)
local json = cjson.decode(body)
assert.equals(json.path, "/request")
res = assert(admin_client:post("/services/mock-service/routes", {
body = { paths = { "/" }, },
headers = {["Content-Type"] = "application/json"}
}))
body = assert.res_status(201, res)
json = cjson.decode(body)
route_id = json.id
helpers.wait_until(function()
res = assert(proxy_client:send({
method = "GET",
path = "/",
}))
return pcall(function()
assert.res_status(200, res)
end)
end, 10)
end)
it("cache invalidation works on config change", function()
local res = assert(admin_client:send({
method = "DELETE",
path = "/routes/" .. route_id,
}))
assert.res_status(204, res)
helpers.wait_until(function()
res = assert(proxy_client:send({
method = "GET",
path = "/",
}))
return pcall(function()
assert.res_status(404, res)
end)
end, 10)
end)
end)
end)
postgres_only("postgres bad readonly connection", function()
local proxy_client, admin_client
lazy_setup(function()
helpers.get_db_utils(strategy, {
"routes",
"services",
}) -- runs migrations
assert(helpers.start_kong({
worker_consistency = "strict",
database = strategy,
pg_ro_host = helpers.test_conf.pg_host,
pg_ro_port = 9090, -- connection refused
}))
admin_client = helpers.admin_client()
proxy_client = helpers.proxy_client()
end)
lazy_teardown(function()
if admin_client then admin_client:close() end
if proxy_client then proxy_client:close() end
helpers.stop_kong()
end)
describe("read only operation breaks and read write operation works", function()
it("admin API bypasses readonly connection but proxy doesn't", function()
local res = assert(admin_client:post("/services", {
body = { name = "mock-service", url = "https://127.0.0.1:15556/request", },
headers = {["Content-Type"] = "application/json"}
}))
assert.res_status(201, res)
res = assert(admin_client:get("/services/mock-service"))
local body = assert.res_status(200, res)
local json = cjson.decode(body)
assert.equals(json.path, "/request")
res = assert(admin_client:post("/services/mock-service/routes", {
body = { paths = { "/" }, },
headers = {["Content-Type"] = "application/json"}
}))
assert.res_status(201, res)
helpers.wait_until(function()
res = assert(proxy_client:send({
method = "GET",
path = "/",
}))
return pcall(function()
assert.res_status(404, res)
assert.logfile().has.line("get_updated_router(): could not rebuild router: " ..
"could not load routes: [postgres] connection " ..
"refused (stale router will be used)", true)
end)
end, 10)
end)
end)
end)
end