253 lines
6.9 KiB
Lua
253 lines
6.9 KiB
Lua
local helpers
|
|
local buffer
|
|
local kong_global
|
|
local conf_loader
|
|
local declarative
|
|
local DB
|
|
|
|
local kong
|
|
|
|
|
|
local ngx_log = ngx.log
|
|
local ngx_debug = ngx.DEBUG
|
|
local lmdb_mlcache
|
|
do
|
|
local resty_mlcache = require "kong.resty.mlcache"
|
|
lmdb_mlcache = assert(resty_mlcache.new("lmdb_mlcache", "lmdb_mlcache", {
|
|
lru_size = 1000,
|
|
ttl = 0,
|
|
neg_ttl = 0,
|
|
resurrect_ttl = 30,
|
|
ipc = {
|
|
register_listeners = function(events)
|
|
ngx_log(ngx_debug, "register lmdb worker events ", tostring(events))
|
|
end,
|
|
broadcast = function(channel, data)
|
|
ngx_log(ngx_debug, "broadcast lmdb worker events ", tostring(channel), tostring(data))
|
|
end
|
|
},
|
|
}))
|
|
lmdb_mlcache:purge(true)
|
|
|
|
_G.lmdb_mlcache = lmdb_mlcache
|
|
end
|
|
|
|
local function mocking_lmdb_transaction()
|
|
local _lmdb_txn = {}
|
|
local _lmdb_txn_mt = { __index = _lmdb_txn }
|
|
function _lmdb_txn.begin(x)
|
|
ngx_log(ngx_debug, "new lmdb: ", x)
|
|
local self = {
|
|
cache = lmdb_mlcache,
|
|
DEFAULT_DB = "_default",
|
|
}
|
|
return setmetatable(self, _lmdb_txn_mt)
|
|
end
|
|
|
|
function _lmdb_txn:db_drop(delete, db)
|
|
ngx_log(ngx_debug, "drop db = ", db or self.DEFAULT_DB, ", delete = ", delete)
|
|
return true
|
|
end
|
|
|
|
function _lmdb_txn:set(key, value, db)
|
|
ngx_log(ngx_debug, "set db = ", db or self.DEFAULT_DB, ", ", key, " = ", value)
|
|
self.cache:set(key, nil, value)
|
|
return true
|
|
end
|
|
|
|
function _lmdb_txn:get(key, db)
|
|
ngx_log(ngx_debug, "get db = ", db or self.DEFAULT_DB, ", key = ", key)
|
|
return self.cache:get(key)
|
|
end
|
|
|
|
function _lmdb_txn:commit()
|
|
ngx_log(ngx_debug, "commit lmdb transactions")
|
|
return true
|
|
end
|
|
|
|
_G.package.loaded["resty.lmdb.transaction"] = _lmdb_txn
|
|
end
|
|
|
|
local function mocking_lmdb()
|
|
local _lmdb = {
|
|
cache = lmdb_mlcache,
|
|
DEFAULT_DB = "_default"
|
|
}
|
|
local _lmdb_mt = { __index = _lmdb, }
|
|
|
|
function _lmdb.get(key, db)
|
|
ngx_log(ngx_debug, "get db = ", db or _lmdb.DEFAULT_DB, ", key = ", key)
|
|
return _lmdb.cache:get(key)
|
|
end
|
|
|
|
setmetatable(_lmdb, _lmdb_mt)
|
|
|
|
_G.package.loaded["resty.lmdb"] = _lmdb
|
|
end
|
|
|
|
local function unmocking()
|
|
_G.package.loaded["resty.lmdb.transaction"] = nil
|
|
_G["resty.lmdb.transaction"] = nil
|
|
|
|
_G.package.loaded["resty.lmdb"] = nil
|
|
_G["resty.lmdb"] = nil
|
|
end
|
|
|
|
describe("#off preserve nulls", function()
|
|
local PLUGIN_NAME = "preserve-nulls"
|
|
local PASSWORD = "fti-110"
|
|
local YAML_CONTENTS = string.format([=[
|
|
_format_version: '3.0'
|
|
services:
|
|
- name: fti-110
|
|
url: http://localhost/ip
|
|
routes:
|
|
- name: fti-110
|
|
paths:
|
|
- /fti-110
|
|
plugins:
|
|
- name: basic-auth
|
|
config:
|
|
hide_credentials: false
|
|
- name: preserve-nulls
|
|
config:
|
|
request_header: "Hello-Foo"
|
|
response_header: "Bye-Bar"
|
|
large: ~
|
|
ttl: null
|
|
consumers:
|
|
- username: fti-110
|
|
custom_id: fti-110-cid
|
|
basicauth_credentials:
|
|
- username: fti-110
|
|
password: %s
|
|
keyauth_credentials:
|
|
- key: fti-5260
|
|
]=], PASSWORD)
|
|
|
|
lazy_setup(function()
|
|
mocking_lmdb_transaction()
|
|
require "resty.lmdb.transaction"
|
|
mocking_lmdb()
|
|
require "resty.lmdb"
|
|
|
|
helpers = require "spec.helpers"
|
|
kong = _G.kong
|
|
kong.core_cache = nil
|
|
|
|
buffer = require "string.buffer"
|
|
kong_global = require "kong.global"
|
|
conf_loader = require "kong.conf_loader"
|
|
declarative = require "kong.db.declarative"
|
|
DB = require "kong.db"
|
|
end)
|
|
|
|
lazy_teardown(function()
|
|
unmocking()
|
|
end)
|
|
|
|
it("when loading into LMDB", function()
|
|
local null = ngx.null
|
|
local concat = table.concat
|
|
|
|
local kong_config = assert(conf_loader(helpers.test_conf_path, {
|
|
database = "off",
|
|
plugins = "bundled," .. PLUGIN_NAME,
|
|
}))
|
|
|
|
local db = assert(DB.new(kong_config))
|
|
assert(db:init_connector())
|
|
db.plugins:load_plugin_schemas(kong_config.loaded_plugins)
|
|
db.vaults:load_vault_schemas(kong_config.loaded_vaults)
|
|
kong.db = db
|
|
|
|
local dc = assert(declarative.new_config(kong_config))
|
|
local dc_table, _, _, current_hash = assert(dc:unserialize(YAML_CONTENTS, "yaml"))
|
|
assert.are_equal(PASSWORD, dc_table.consumers[1].basicauth_credentials[1].password)
|
|
|
|
local entities, _, _, meta, new_hash = assert(dc:parse_table(dc_table, current_hash))
|
|
assert.is_not_falsy(meta._transform)
|
|
assert.are_equal(current_hash, new_hash)
|
|
|
|
for _,v in pairs(entities.plugins) do
|
|
if v.name == PLUGIN_NAME then
|
|
assert.are_equal(v.config.large, null)
|
|
assert.are_equal(v.config.ttl, null)
|
|
break
|
|
end
|
|
end
|
|
|
|
kong.configuration = kong_config
|
|
kong.worker_events = kong.worker_events or
|
|
kong.cache and kong.cache.worker_events or
|
|
assert(kong_global.init_worker_events(kong.configuration))
|
|
kong.cluster_events = kong.cluster_events or
|
|
kong.cache and kong.cache.cluster_events or
|
|
assert(kong_global.init_cluster_events(kong.configuration, kong.db))
|
|
kong.cache = kong.cache or
|
|
assert(kong_global.init_cache(kong.configuration, kong.cluster_events, kong.worker_events))
|
|
kong.core_cache = assert(kong_global.init_core_cache(kong.configuration, kong.cluster_events, kong.worker_events))
|
|
|
|
kong.cache.worker_events = kong.cache.worker_events or kong.worker_events
|
|
kong.cache.cluster_events = kong.cache.cluster_events or kong.cluster_events
|
|
|
|
assert(declarative.load_into_cache(entities, meta, current_hash))
|
|
|
|
local id, item = next(entities.basicauth_credentials)
|
|
|
|
-- format changed after rpc sync
|
|
-- item key
|
|
local cache_key = concat({
|
|
"I|",
|
|
"basicauth_credentials|",
|
|
item.ws_id,
|
|
"|",
|
|
id
|
|
})
|
|
|
|
local lmdb = require "resty.lmdb"
|
|
local value, err, hit_lvl = lmdb.get(cache_key)
|
|
assert.is_nil(err)
|
|
assert.are_equal(hit_lvl, 1)
|
|
|
|
local cached_item = buffer.decode(value)
|
|
assert.are_not_same(cached_item, item)
|
|
assert.are_equal(cached_item.id, item.id)
|
|
assert.are_equal(cached_item.username, item.username)
|
|
assert.are_not_equal(PASSWORD, cached_item.password)
|
|
assert.are_not_equal(cached_item.password, item.password)
|
|
|
|
for _, plugin in pairs(entities.plugins) do
|
|
if plugin.name == PLUGIN_NAME then
|
|
|
|
-- format changed after rpc sync
|
|
-- foreign key:
|
|
cache_key = concat({
|
|
"F|",
|
|
"plugins|",
|
|
"route|",
|
|
plugin.route.id,
|
|
"|",
|
|
plugin.ws_id,
|
|
"|",
|
|
plugin.id,
|
|
})
|
|
value, err, hit_lvl = lmdb.get(cache_key)
|
|
assert.is_nil(err)
|
|
assert.are_equal(hit_lvl, 1)
|
|
|
|
-- get value by the index key
|
|
cached_item = buffer.decode(lmdb.get(value))
|
|
|
|
assert.are_same(cached_item, plugin)
|
|
assert.are_equal(cached_item.config.large, null)
|
|
assert.are_equal(cached_item.config.ttl, null)
|
|
|
|
break
|
|
end
|
|
end
|
|
|
|
end)
|
|
|
|
end)
|