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

307 lines
9.1 KiB
Lua

local helpers = require "spec.helpers"
local utils = require "pl.utils"
local http = require "resty.http"
local constants = require "kong.constants"
local strip = require("kong.tools.string").strip
local function count_server_blocks(filename)
local file = assert(utils.readfile(filename))
local _, count = file:gsub("[%\n%s]+server%s{%s*\n","")
return count
end
local function get_listeners(filename)
local file = assert(utils.readfile(filename))
local result = {}
for block in file:gmatch("[%\n%s]+server%s+(%b{})") do
local server_name = block:match("[%\n%s]server_name%s(.-);")
server_name = server_name and strip(server_name) or "stream"
local server = result[server_name] or {}
result[server_name] = server
for listen in block:gmatch("[%\n%s]listen%s(.-);") do
listen = strip(listen)
table.insert(server, listen)
server[listen] = #server
end
end
return result
end
describe("Proxy interface listeners", function()
before_each(function()
helpers.get_db_utils(nil, {})
end)
after_each(function()
helpers.stop_kong()
end)
it("disabled", function()
assert(helpers.start_kong({
proxy_listen = "off",
admin_listen = "0.0.0.0:9001",
admin_gui_listen = "off",
}))
assert.equals(2, count_server_blocks(helpers.test_conf.nginx_kong_conf))
assert.is_nil(get_listeners(helpers.test_conf.nginx_kong_conf).kong)
end)
it("multiple", function()
assert(helpers.start_kong({
proxy_listen = "127.0.0.1:9001, 127.0.0.1:9002",
admin_listen = "0.0.0.0:9000",
admin_gui_listen = "off",
}))
assert.equals(3, count_server_blocks(helpers.test_conf.nginx_kong_conf))
assert.same({
["127.0.0.1:9001"] = 1,
["127.0.0.1:9002"] = 2,
[1] = "127.0.0.1:9001",
[2] = "127.0.0.1:9002",
}, get_listeners(helpers.test_conf.nginx_kong_conf).kong)
for i = 9001, 9002 do
local client = assert(http.new())
assert(client:connect("127.0.0.1", i))
local res = assert(client:request {
method = "GET",
path = "/"
})
res:read_body()
client:close()
assert.equals(404, res.status)
end
end)
end)
describe("#stream proxy interface listeners", function()
before_each(function()
helpers.get_db_utils()
end)
after_each(function()
helpers.stop_kong()
end)
it("disabled", function()
assert(helpers.start_kong({
stream_listen = "off",
}))
assert.equals(1, count_server_blocks(helpers.test_conf.nginx_kong_stream_conf))
assert.is_nil(get_listeners(helpers.test_conf.nginx_kong_stream_conf).kong)
end)
it("multiple", function()
assert(helpers.start_kong({
stream_listen = "127.0.0.1:9011, 127.0.0.1:9012",
}))
local stream_events_sock_path = "unix:" .. helpers.test_conf.socket_path .. "/" .. constants.SOCKETS.STREAM_WORKER_EVENTS
if helpers.test_conf.database == "off" then
local stream_config_sock_path = "unix:" .. helpers.test_conf.socket_path .. "/" .. constants.SOCKETS.STREAM_CONFIG
assert.equals(3, count_server_blocks(helpers.test_conf.nginx_kong_stream_conf))
assert.same({
["127.0.0.1:9011"] = 1,
["127.0.0.1:9012"] = 2,
[stream_config_sock_path] = 3,
[stream_events_sock_path] = 4,
[1] = "127.0.0.1:9011",
[2] = "127.0.0.1:9012",
[3] = stream_config_sock_path,
[4] = stream_events_sock_path,
}, get_listeners(helpers.test_conf.nginx_kong_stream_conf).stream)
else
assert.equals(2, count_server_blocks(helpers.test_conf.nginx_kong_stream_conf))
assert.same({
["127.0.0.1:9011"] = 1,
["127.0.0.1:9012"] = 2,
[stream_events_sock_path] = 3,
[1] = "127.0.0.1:9011",
[2] = "127.0.0.1:9012",
[3] = stream_events_sock_path,
}, get_listeners(helpers.test_conf.nginx_kong_stream_conf).stream)
end
for i = 9011, 9012 do
local sock = ngx.socket.tcp()
assert(sock:connect("127.0.0.1", i))
assert(sock:send("hi"))
sock:close()
end
end)
end)
local function reload_router(flavor)
helpers = require("spec.internal.module").reload_helpers(flavor)
end
-- TODO: remove it when we confirm it is not needed
local function gen_route(flavor, r)
return r
end
for _, flavor in ipairs({ "traditional", "traditional_compatible", "expressions" }) do
for _, strategy in helpers.each_strategy() do
if strategy ~= "off" then
describe("[stream" .. ", flavor = " .. flavor .. "]", function()
reload_router(flavor)
local MESSAGE = "echo, ping, pong. echo, ping, pong. echo, ping, pong.\n"
lazy_setup(function()
local bp = helpers.get_db_utils(strategy, {
"routes",
"services",
"plugins",
})
local service = assert(bp.services:insert {
host = helpers.mock_upstream_host,
port = helpers.mock_upstream_stream_port,
protocol = "tcp",
})
assert(bp.routes:insert(gen_route(flavor, {
destinations = {
{ port = 19000 },
},
protocols = {
"tcp",
},
service = service,
})))
assert(bp.routes:insert(gen_route(flavor, {
protocols = { "tcp" },
service = service,
destinations = {
{ ip = "0.0.0.0", port = 19004 },
{ ip = "0.0.0.0", port = 19005 },
{ ip = "0.0.0.0", port = 19006 },
{ ip = "0.0.0.0", port = 19007 },
{ ip = "0.0.0.0" },
{ port = 19004 },
}
})))
assert(bp.routes:insert(gen_route(flavor, {
protocols = { "tcp" },
service = service,
destinations = {
{ ip = "0.0.0.0", port = 19004 },
{ ip = "0.0.0.0", port = 19005 },
{ ip = "0.0.0.0", port = 19006 },
{ ip = "0.0.0.0", port = 19007 },
{ ip = "0.0.0.0" },
{ port = 19004 },
}
})))
assert(bp.routes:insert(gen_route(flavor, {
protocols = { "tcp" },
service = service,
destinations = {
{ ip = "0.0.0.0", port = 19004 },
{ ip = "0.0.0.0", port = 19005 },
{ ip = "0.0.0.0", port = 19006 },
{ ip = "0.0.0.0", port = 19007 },
{ ip = "0.0.0.0" },
{ port = 19004 },
}
})))
assert(bp.routes:insert(gen_route(flavor, {
protocols = { "tcp" },
service = service,
destinations = {
{ ip = "0.0.0.0", port = 19004 },
{ ip = "0.0.0.0", port = 19005 },
{ ip = "0.0.0.0", port = 19006 },
{ ip = "0.0.0.0", port = 19007 },
{ ip = "0.0.0.0" },
{ port = 19004 },
}
})))
assert(bp.routes:insert(gen_route(flavor, {
protocols = { "tcp" },
service = service,
destinations = {
{ ip = "0.0.0.0", port = 19004 },
{ ip = "0.0.0.0", port = 19005 },
{ ip = "0.0.0.0", port = 19006 },
{ ip = "0.0.0.0", port = 19007 },
{ ip = "0.0.0.0" },
{ port = 19004 },
}
})))
assert(helpers.start_kong({
router_flavor = flavor,
database = strategy,
stream_listen = helpers.get_proxy_ip(false) .. ":19000, " ..
helpers.get_proxy_ip(false) .. ":18000, " ..
helpers.get_proxy_ip(false) .. ":17000",
port_maps = "19000:18000",
plugins = "bundled,ctx-tests",
nginx_conf = "spec/fixtures/custom_nginx.template",
proxy_listen = "off",
admin_listen = "off",
}))
end)
lazy_teardown(function()
helpers.stop_kong()
end)
it("routes by destination port without port map", function()
local tcp_client = ngx.socket.tcp()
assert(tcp_client:connect(helpers.get_proxy_ip(false), 19000))
assert(tcp_client:send(MESSAGE))
local body = assert(tcp_client:receive("*a"))
assert.equal(MESSAGE, body)
assert(tcp_client:close())
end)
it("uses port maps configuration to route by destination port", function()
local tcp_client = ngx.socket.tcp()
assert(tcp_client:connect(helpers.get_proxy_ip(false), 18000))
assert(tcp_client:send(MESSAGE))
local body = assert(tcp_client:receive("*a"))
assert.equal(MESSAGE, body)
assert(tcp_client:close())
end)
it("fails to route when no port map is specified and route is not found", function()
local tcp_client = ngx.socket.tcp()
assert(tcp_client:connect(helpers.get_proxy_ip(false), 17000))
assert(tcp_client:send(MESSAGE))
local body, err = tcp_client:receive("*a")
if not err then
assert.equal("", body)
else
assert.equal("connection reset by peer", err)
end
assert(tcp_client:close())
end)
it("destinations has more than 3 items", function()
assert.logfile().has.no.line("invalid order function for sorting", true)
end)
end)
end
end
end -- for flavor