Skip to content

Commit

Permalink
add usage and description for db_proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
liverpool8056 committed Mar 25, 2024
1 parent 798a869 commit ff7c582
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 47 deletions.
79 changes: 38 additions & 41 deletions spec/02-integration/08-status_api/05-metrics_api_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,45 @@ local helpers = require "spec.helpers"

for _, strategy in helpers.all_strategies() do
describe("Metrics API - with strategy #" .. strategy, function()
describe("`/metrics` endpoint", function()
local client
local db_port = strategy == "postgres" and 5432 or 9042
local db_proxy = helpers.db_proxy.new({ db_port = db_port })

setup(function()
assert(db_proxy:start())

assert(helpers.start_kong({
database = strategy,
pg_port = db_proxy.db_proxy_port,
status_listen = "127.0.0.1:9500",
db_cache_warmup_entities = "workspaces",
nginx_conf = "spec/fixtures/custom_nginx.template",
}))

client = helpers.http_client("127.0.0.1", 9500, 60000)
end)

lazy_teardown(function()
if client then client:close() end
assert(helpers.stop_kong())
assert(db_proxy:stop())
end)

if strategy == "postgres" then
describe("`/metrics` endpoint", function()
local client
local db_port = strategy == "postgres" and 5432 or 9042
local db_proxy = helpers.db_proxy.new({ db_port = db_port })

setup(function()
assert(db_proxy:start())

assert(helpers.start_kong({
database = strategy,
pg_port = db_proxy.db_proxy_port,
status_listen = "127.0.0.1:9500",
db_cache_warmup_entities = "workspaces",
nginx_conf = "spec/fixtures/custom_nginx.template",
}))

client = helpers.http_client("127.0.0.1", 9500, 60000)
end)

lazy_teardown(function()
if client then client:close() end
assert(helpers.stop_kong())
assert(db_proxy:stop())
end)

it(" can work even if database is down", function()
local res = assert(client:send {
method = "GET",
path = "/metrics"
})
assert.res_status(200, res)
assert.res_status(200, db_proxy:status(false))

res = assert(client:send {
method = "GET",
path = "/metrics"
})
assert.res_status(200, res)
end)
it(" can work even if database is down", function()
local res = assert(client:send {
method = "GET",
path = "/metrics"
})
assert.res_status(200, res)
assert.res_status(200, db_proxy:status(false))

res = assert(client:send {
method = "GET",
path = "/metrics"
})
assert.res_status(200, res)
end)
end
end)
end)
end
61 changes: 55 additions & 6 deletions spec/helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4157,15 +4157,41 @@ do
end

--------------
-- database proxy
-- These function are used to create a database proxy, which can be used to change the database behavior,
-- such as imitate a database outage, or a performance decrease.

-- A kong based database proxy class for the simulation of database abnormal behavior.
-- @section db_proxy
-- @usage
-- local helpers = require "spec.helpers"
-- local db_port = 5432
-- local db_proxy = helpers.db_proxy.new({ db_port = db_port })
-- assert(db_proxy:start())
-- db_proxy:status(false)
-- db_proxy:delay(5)
-- db_proxy:stop()
local db_proxy = {}
local db_proxy_mt = {
__index = db_proxy,
}

--- Creates a db_proxy.
-- @function db_proxy
-- @field db_port The actual port of the database.
-- @field db_proxy_port The proxy port of the database.
-- @field api_port The port of the api server of the database
-- proxy by which you can control the behavior of the db proxy
-- to simulate abnormal cases.
-- @field tcp_port The port of the tcp server of the database
-- proxy. When invoking the api of the db proxy, it will transfer
-- the config through this port, so that the config will take
-- effects. Thus it is used internally.
-- @param opts (table) Specifies the ports of the database proxy.
-- The opts.db_port is the only one required, but all the others
-- are optional.
-- @return db proxy
-- @see db_proxy:start
-- @see db_proxy:stop
-- @see db_proxy:get_fixtures
-- @see db_proxy:delay
-- @see db_proxy:status
function db_proxy.new(opts)
opts = opts or {}

Expand All @@ -4183,22 +4209,30 @@ function db_proxy.new(opts)
return setmetatable(self, db_proxy_mt)
end

-- Start the db proxy.
-- @function db_proxy:start
-- @param opts(optional) Same as the opts used in `start_kong`.
-- Strongly recommend not feed this parameter.
function db_proxy:start(opts)
local kong_conf = type(opts) == "table" and opts or {
prefix = "servroot_db_proxy",
database = "off",
role = "data_plane",
nginx_conf = "spec/fixtures/custom_nginx.template",
-- this is unused, but required for the the template to include a stream {} block
-- this is unused, but required for the template to include a http {} block
proxy_listen = "0.0.0.0:" .. get_available_port(),
-- this is unused, but required for the template to include a stream {} block
-- and this won't occupy 5555 port actually.
stream_listen = "0.0.0.0:5555",
proxy_listen = "0.0.0.0:16666",
}

self.prefix = kong_conf.prefix

return start_kong(kong_conf, nil, nil, self:get_fixtures())
end

-- Stop the db proxy.
-- @function db_proxy:stop
function db_proxy:stop()
if self.client then
self.client:close()
Expand All @@ -4207,6 +4241,8 @@ function db_proxy:stop()
return stop_kong(self.prefix, true)
end

-- Get the fixtures of the db proxy.
-- @function db_proxy:get_fixtures
function db_proxy:get_fixtures()
return {
http_mock = {
Expand Down Expand Up @@ -4317,6 +4353,12 @@ function db_proxy:get_fixtures()
}
end

-- Set the delay for the db proxy to simulate a slow network.
-- Notice: you have to assert the success of execution of
-- this function by yourself like:
-- `assert.res_status(200, db_proxy:delay(10))`.
-- @function db_proxy:delay
-- @param delay (number) The delay in seconds.
function db_proxy:delay(delay)
if type(delay) ~= "number" then
error("delay must be a number and greater than 0")
Expand All @@ -4329,6 +4371,13 @@ function db_proxy:delay(delay)
return self.client:post("/db_proxy_conf", { delay = delay })
end

-- Set the status for the db proxy to simulate an outage.
-- Notice: you have to assert the success of execution of
-- this function by yourself like:
-- `assert.res_status(200, db_proxy:status(false))`.
-- @function db_proxy:status
-- @param status (boolean) The status of the database,
-- false means an outage.
function db_proxy:status(on_off)
if type(on_off) ~= 'boolean' then
error("on_off must be a boolean")
Expand Down

0 comments on commit ff7c582

Please sign in to comment.