249 lines
8.8 KiB
Lua
249 lines
8.8 KiB
Lua
------------------------------------------------------------------
|
|
-- Collection of utilities to help testing Kong features and plugins.
|
|
--
|
|
-- @copyright Copyright 2016-2022 Kong Inc. All rights reserved.
|
|
-- @license [Apache 2.0](https://opensource.org/licenses/Apache-2.0)
|
|
-- @module spec.hybrid
|
|
|
|
local helpers = require("spec.helpers")
|
|
local kong_table = require("kong.tools.table")
|
|
local reload_module = require("spec.internal.module").reload
|
|
local assert = require("luassert")
|
|
local asserts = reload_module("spec.internal.asserts") -- luacheck: ignore
|
|
local conf = require("spec.internal.conf")
|
|
|
|
local function get_patched_helpers(strategy, deploy, rpc, rpc_sync, opts)
|
|
local helpers = require("spec.helpers")
|
|
|
|
local _M = {}
|
|
local _prefix = nil
|
|
|
|
_M.data_plane = nil
|
|
_M.control_plane = nil
|
|
|
|
function _M.start_kong(env, tables, preserve_prefix, fixtures)
|
|
local ret, v
|
|
if deploy == "traditional" then
|
|
ret, v = helpers.start_kong(env, tables, preserve_prefix, fixtures)
|
|
if ret then
|
|
_prefix = env.prefix or conf.prefix
|
|
end
|
|
_M.data_plane = helpers.get_running_conf(_prefix)
|
|
|
|
else
|
|
local hybrid_envs = {
|
|
cluster_cert = "spec/fixtures/kong_clustering.crt",
|
|
cluster_cert_key = "spec/fixtures/kong_clustering.key",
|
|
lua_ssl_trusted_certificate = "spec/fixtures/kong_clustering.crt",
|
|
cluster_rpc = rpc,
|
|
cluster_rpc_sync = rpc_sync,
|
|
prefix = "",
|
|
role = "",
|
|
cluster_listen = "",
|
|
cluster_telemetry_listen = "",
|
|
cluster_control_plane = "",
|
|
cluster_telemetry_endpoint = "",
|
|
}
|
|
|
|
for k, v in pairs(hybrid_envs) do
|
|
assert.is_nil(env[k], "can't specify " .. k .. " in env of start_kong in hybrid mode")
|
|
end
|
|
|
|
if env.database then
|
|
assert.equal(env.database, strategy, "database must be the same as strategy in hybrid mode")
|
|
end
|
|
|
|
local cp_envs = kong_table.deep_merge(env, hybrid_envs)
|
|
cp_envs.database = strategy
|
|
cp_envs.role = "control_plane"
|
|
cp_envs.prefix = "servroot"
|
|
cp_envs.cluster_listen = "127.0.0.1:9005"
|
|
cp_envs.cluster_telemetry_listen = "127.0.0.1:9006"
|
|
cp_envs.cluster_control_plane = nil
|
|
cp_envs.cluster_telemetry_endpoint = nil
|
|
|
|
assert(helpers.start_kong(cp_envs, tables, preserve_prefix, fixtures))
|
|
|
|
local dp_envs = kong_table.deep_merge(env, hybrid_envs)
|
|
dp_envs.database = "off"
|
|
dp_envs.role = "data_plane"
|
|
dp_envs.prefix = "servroot2"
|
|
dp_envs.cluster_control_plane = "127.0.0.1:9005"
|
|
dp_envs.cluster_telemetry_endpoint = "127.0.0.1:9006"
|
|
dp_envs.cluster_listen = nil
|
|
dp_envs.cluster_telemetry_listen = nil
|
|
|
|
assert(helpers.start_kong(dp_envs, nil, preserve_prefix, nil))
|
|
|
|
_M.control_plane = helpers.get_running_conf("servroot")
|
|
_M.data_plane = helpers.get_running_conf("servroot2")
|
|
|
|
if rpc_sync == "on" and not opts.dont_wait_full_sync then
|
|
assert.logfile(_M.data_plane.nginx_err_logs).has.line("[kong.sync.v2] full sync ends", true, 10)
|
|
end
|
|
|
|
ret = true
|
|
end
|
|
|
|
if strategy ~= "off" then
|
|
-- this helpers function doesn't support DB-less mode
|
|
_M.wait_for_all_config_update()
|
|
end
|
|
|
|
return ret, v
|
|
end
|
|
|
|
function _M.stop_kong(prefix, preserve_prefix, preserve_dc, signal, nowait)
|
|
local ret, v
|
|
|
|
if deploy == "hybrid" then
|
|
assert.is_nil(prefix, "can't specify prefix in hybrid mode")
|
|
ret = helpers.stop_kong("servroot", preserve_prefix, preserve_dc, signal, nowait)
|
|
if ret then
|
|
ret = helpers.stop_kong("servroot2", preserve_prefix, preserve_dc, signal, nowait)
|
|
end
|
|
|
|
else
|
|
ret, v= helpers.stop_kong(prefix, preserve_prefix, preserve_dc, signal, nowait)
|
|
end
|
|
|
|
_prefix = nil
|
|
_M.control_plane = nil
|
|
_M.data_plane = nil
|
|
|
|
return ret, v
|
|
end
|
|
|
|
function _M.clean_logfile(logfile)
|
|
if not logfile and deploy == "hybrid" then
|
|
helpers.clean_logfile(helpers.get_running_conf("servroot").nginx_err_logs)
|
|
helpers.clean_logfile(helpers.get_running_conf("servroot2").nginx_err_logs)
|
|
|
|
else
|
|
helpers.clean_logfile(logfile)
|
|
end
|
|
end
|
|
|
|
function _M.get_prefix_for(role)
|
|
if deploy == "hybrid" then
|
|
role = role or "data_plane"
|
|
if role == "data_plane" then
|
|
return "servroot2"
|
|
else
|
|
return "servroot"
|
|
end
|
|
else
|
|
return _prefix
|
|
end
|
|
end
|
|
|
|
function _M.wait_for_all_config_update(wait_opts)
|
|
if strategy ~= "off" then
|
|
local copied_opts = kong_table.deep_copy(wait_opts) or {}
|
|
|
|
-- this helpers function doesn't support DB-less mode
|
|
helpers.wait_for_all_config_update(copied_opts)
|
|
end
|
|
end
|
|
|
|
function _M.format_tags()
|
|
local tags = "#" .. strategy .. " #" .. deploy
|
|
if rpc == "on" then
|
|
tags = tags .. " #rpc"
|
|
end
|
|
if rpc_sync == "on" then
|
|
tags = tags .. " #rpc_sync"
|
|
end
|
|
return tags
|
|
end
|
|
|
|
function _M.reload_helpers()
|
|
return get_patched_helpers(strategy, deploy, rpc, rpc_sync, opts)
|
|
end
|
|
|
|
return setmetatable(_M, { __index = helpers })
|
|
end
|
|
|
|
|
|
-- Run tests in different deployment topologies
|
|
-- @function run_for_each_deploy
|
|
-- @param opts (optional table) options for the runner
|
|
-- @param fn (function) test routine, receiving helpers, strategy, deploy, rpc, and rpc_sync
|
|
-- @return nil
|
|
--
|
|
-- This function is used to run tests across different deployment topologies.
|
|
-- It accepts an optional options table and a test function.
|
|
-- The options table can contain custom configurations, while the test function
|
|
-- will be called for each combination of strategy and deployment.
|
|
--
|
|
-- The test is run as follows:
|
|
-- 1. Iterates over each strategy obtained from opts.strategies_iterator() or helpers.each_strategy().
|
|
-- 2. For each strategy, iterates over two deployment types: "traditional" and "hybrid".
|
|
-- 3. For each deployment type, iterates over three RPC and RPC sync combinations: {"off", "off"}, {"on", "off"}, {"on", "on"}.
|
|
-- 4. For each combination, calls the test function fn, passing helpers, strategy, deploy, rpc, and rpc_sync as parameters.
|
|
--
|
|
-- opts: (table) custom configurations
|
|
-- - dont_wait_full_sync: (boolean) if true, the function won't wait for full sync to complete
|
|
-- - strategies_iterator: (function) If present, this function will be used to iterate over strategies.
|
|
--
|
|
-- The helpers passed into test function is a patched version of spec.helpers.
|
|
-- It contains the following modified functions and limitions:
|
|
-- - start_kong: will start Kong in hybrid mode if deploy is "hybrid"
|
|
-- - stop_kong: will stop Kong in hybrid mode if deploy is "hybrid"
|
|
-- - clean_logfile: will clean the logfile for hybrid deployment if deploy is "hybrid"
|
|
-- - get_prefix_for: will return the prefix for the specified role
|
|
-- - wait_for_all_config_update: will wait for all config updates to complete
|
|
-- - format_tags: will return a formatted string with deployment tags
|
|
-- - reload_helpers: will return a new helpers module
|
|
-- The original parameter will be passed as is to the original helpers functions.
|
|
-- Except in hybrid mode, there're some critical options that can't be specified
|
|
-- in the env table of start_kong. If these options are specified, the function will
|
|
-- raise an error. Additionally, all prefix options are not available in hybrid mode.
|
|
--
|
|
-- Additionally, patched helpers will contains following tables:
|
|
-- - data_plane: the running configuration of the data plane (or instance of traditional mode)
|
|
-- - control_plane: the running configuration of the control plane (only in hybrid mode)
|
|
local function run_for_each_deploy(opts, fn)
|
|
opts = opts or {}
|
|
local strategies_iterator = opts.strategies_iterator or helpers.each_strategy
|
|
|
|
for _, strategy in strategies_iterator() do
|
|
for _, deploy in ipairs({ "traditional", "hybrid" }) do
|
|
for _, v in ipairs({ {"off", "off"}, {"on", "off"}, {"on", "on"}, }) do
|
|
local rpc, rpc_sync = v[1], v[2]
|
|
|
|
if strategy == "off" then
|
|
if deploy == "hybrid" then
|
|
-- DB-less mode doesn't support hybrid deployments
|
|
goto continue
|
|
end
|
|
|
|
if not (rpc == "off" and rpc_sync == "off") then
|
|
-- no need to test this combination in DB-less deployments
|
|
-- so only test DB-less once
|
|
goto continue
|
|
end
|
|
end
|
|
|
|
if deploy == "traditional" and not (rpc == "off" and rpc_sync == "off") then
|
|
-- no need to test this combination in traditional deployments
|
|
-- so only test traditional once
|
|
goto continue
|
|
end
|
|
|
|
local helpers = get_patched_helpers(strategy, deploy, rpc, rpc_sync, opts)
|
|
|
|
-- Test body begins here
|
|
fn(helpers, strategy, deploy, rpc, rpc_sync)
|
|
-- Test body ends here
|
|
|
|
::continue::
|
|
end -- for _, v in ipairs({ {"off", "off"}, {"on", "off"}, {"on", "on"}, }) do
|
|
end -- for _, deploy in ipairs({ "traditional", "hybrid" }) do
|
|
end -- for _, strategy in helpers.each_strategy() do
|
|
end
|
|
|
|
return {
|
|
run_for_each_deploy = run_for_each_deploy,
|
|
}
|