From 6f08b673d00526b9cb1fe596181eec4c4c735496 Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Thu, 24 Feb 2022 00:33:44 +0100 Subject: [PATCH] TT#165251 NGCPRedis class Unify redis interaction in a class * allow passing partial config via new() config will be merged using defined defaults so missing keys will be appended using values from defaults Change-Id: I486637e99e0e36fbe1f5a06c703c6b7d2fa77d77 --- ngcp/api_client.lua | 29 ++++---- ngcp/config.lua | 105 +++++++++++++++-------------- ngcp/cp.lua | 3 +- ngcp/dlgcnt.lua | 133 +++++++++++++++++-------------------- ngcp/dlglist.lua | 119 +++++++++++++++------------------ ngcp/dp.lua | 3 +- ngcp/fp.lua | 3 +- ngcp/loop.lua | 60 +++++++---------- ngcp/ngcp.lua | 10 +-- ngcp/pp.lua | 3 +- ngcp/pprof.lua | 3 +- ngcp/pref.lua | 3 +- ngcp/push.lua | 93 +++++++++++--------------- ngcp/recentcalls.lua | 85 ++++++++++-------------- ngcp/redis.lua | 66 ++++++++++++++++++ ngcp/rp.lua | 3 +- ngcp/up.lua | 3 +- ngcp/utils.lua | 16 +++++ tests/ngcp.lua | 6 ++ tests/ngcp_dlgcnt.lua | 79 ++++++---------------- tests/ngcp_dlglist.lua | 6 +- tests/ngcp_loop.lua | 2 +- tests/ngcp_recentcalls.lua | 66 ++++++++++-------- tests/ngcp_redis.lua | 86 ++++++++++++++++++++++++ tests/utils.lua | 15 +++++ 25 files changed, 551 insertions(+), 449 deletions(-) create mode 100644 ngcp/redis.lua create mode 100644 tests/ngcp_redis.lua diff --git a/ngcp/api_client.lua b/ngcp/api_client.lua index 15d144f..02ce039 100644 --- a/ngcp/api_client.lua +++ b/ngcp/api_client.lua @@ -1,5 +1,5 @@ -- --- Copyright 2017 SipWise Team +-- Copyright 2017-2022 SipWise Team -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -27,6 +27,13 @@ local utils = require 'ngcp.utils' local utable = utils.table _ENV = NGCPAPIClient +local defaults = { + ip = '127.0.0.1', + port = 1442, + user = 'system', + pass = 'password', +} + -- class NGCPAPIClient local NGCPAPIClient_MT = { __index = NGCPAPIClient } @@ -34,24 +41,18 @@ NGCPAPIClient_MT.__tostring = function (t) return string.format("config:%s", utable.tostring(t.config)) end -function NGCPAPIClient.new() - local t = NGCPAPIClient.init(); +function NGCPAPIClient.new(config) + local t = NGCPAPIClient.init(utils.merge_defaults(config, defaults)) setmetatable( t, NGCPAPIClient_MT ) - return t; + return t end -function NGCPAPIClient.init() - local t = { - config = { - ip = '127.0.0.1', - port = 1442, - user = 'system', - pass = 'password', - }, +function NGCPAPIClient.init(config) + return { + config = config, c = curl.easy_init(), j = require 'cjson' - }; - return t; + } end function NGCPAPIClient:request(method, request) diff --git a/ngcp/config.lua b/ngcp/config.lua index 824eee1..f08276e 100644 --- a/ngcp/config.lua +++ b/ngcp/config.lua @@ -1,5 +1,5 @@ -- --- Copyright 2015-2020 SipWise Team +-- Copyright 2015-2022 SipWise Team -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -17,68 +17,71 @@ -- On Debian systems, the complete text of the GNU General -- Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". -- - +local utils = require 'ngcp.utils' -- load drivers local driver = require "luasql.mysql" -- luacheck: ignore luasql if not luasql then luasql = driver end + +local defaults = { + db_host = "127.0.0.1", + db_port = 3306, + db_username = "kamailio", + db_pass = "somepasswd", + db_database = "kamailio", + default = { + contract = { + }, + fax = { + }, + peer = { + sst_enable = "yes", + sst_expires = 300, + sst_min_timer = 90, + sst_max_timer = 7200, + sst_refresh_method = "UPDATE_FALLBACK_INVITE", + outbound_from_user = "npn", + inbound_upn = "from_user", + inbound_npn = "from_user", + inbound_uprn = "from_user", + ip_header = "P-NGCP-Src-Ip", + }, + dom = { + sst_enable = "yes", + sst_expires = 300, + sst_min_timer = 90, + sst_max_timer = 7200, + sst_refresh_method = "UPDATE_FALLBACK_INVITE", + outbound_from_user = "npn", + inbound_upn = "from_user", + inbound_uprn = "from_user", + ip_header = "P-NGCP-Src-Ip", + }, + -- just for prefs that are only on usr level + usr = { + account_id = 0, + ext_subscriber_id = "", + ext_contract_id = "", + ringtimeout = 180, + } + }, + -- blob prefs to be loaded automaticaly + blob_prefs = { + emergency_provider_info = true, + emergency_location_object = true, + } +} + -- class NGCPConfig local NGCPConfig = { __class__ = 'NGCPConfig' } local NGCPConfig_MT = { __index = NGCPConfig } -- luacheck: globals KSR - function NGCPConfig:new() - local t = { - db_host = "127.0.0.1", - db_port = 3306, - db_username = "kamailio", - db_pass = "somepasswd", - db_database = "kamailio", - default = { - contract = { - }, - fax = { - }, - peer = { - sst_enable = "yes", - sst_expires = 300, - sst_min_timer = 90, - sst_max_timer = 7200, - sst_refresh_method = "UPDATE_FALLBACK_INVITE", - outbound_from_user = "npn", - inbound_upn = "from_user", - inbound_npn = "from_user", - inbound_uprn = "from_user", - ip_header = "P-NGCP-Src-Ip", - }, - dom = { - sst_enable = "yes", - sst_expires = 300, - sst_min_timer = 90, - sst_max_timer = 7200, - sst_refresh_method = "UPDATE_FALLBACK_INVITE", - outbound_from_user = "npn", - inbound_upn = "from_user", - inbound_uprn = "from_user", - ip_header = "P-NGCP-Src-Ip", - }, - -- just for prefs that are only on usr level - usr = { - account_id = 0, - ext_subscriber_id = "", - ext_contract_id = "", - ringtimeout = 180, - } - }, - -- blob prefs to be loaded automaticaly - blob_prefs = { - emergency_provider_info = true, - emergency_location_object = true, - } - } + function NGCPConfig:new(config) + local t = utils.merge_defaults(config, defaults) setmetatable( t, NGCPConfig_MT ) return t end diff --git a/ngcp/cp.lua b/ngcp/cp.lua index fef135a..7da11d1 100644 --- a/ngcp/cp.lua +++ b/ngcp/cp.lua @@ -38,9 +38,8 @@ SELECT location_id FROM provisioning.voip_contract_locations cl JOIN -- luacheck: globals KSR function NGCPContractPrefs:new(config) local instance = NGCPContractPrefs:create() - self.config = config -- creates xavp usr - instance:init() + instance:init(config) return instance end diff --git a/ngcp/dlgcnt.lua b/ngcp/dlgcnt.lua index ac5a8f7..e4ee248 100644 --- a/ngcp/dlgcnt.lua +++ b/ngcp/dlgcnt.lua @@ -1,5 +1,5 @@ -- --- Copyright 2014-2020 SipWise Team +-- Copyright 2014-2022 SipWise Team -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -20,13 +20,28 @@ local NGCPDlgCounters = { __class__ = 'NGCPDlgCounters' } -local redis = require 'redis'; +local NGCPRedis = require 'ngcp.redis'; local utils = require 'ngcp.utils'; local utable = utils.table; _ENV = NGCPDlgCounters --- class NGCPDlgCounters +local defaults = { + central = { + host = '127.0.0.1', + port = 6379, + db = 3 + }, + pair = { + host = '127.0.0.1', + port = 6379, + db = 4 + }, + check_pair_dup = false, + allow_negative = false +} + + -- class NGCPDlgCounters local NGCPDlgCounters_MT = { __index = NGCPDlgCounters } NGCPDlgCounters_MT.__tostring = function (t) @@ -35,55 +50,27 @@ NGCPDlgCounters_MT.__tostring = function (t) utable.tostring(t.pair)); end -- luacheck: globals KSR - function NGCPDlgCounters.new() - local t = NGCPDlgCounters.init(); - setmetatable( t, NGCPDlgCounters_MT ); - return t; - end - - function NGCPDlgCounters.init() - local t = { - config = { - central = { - host = '127.0.0.1', - port = 6379, - db = "3" - }, - pair = { - host = '127.0.0.1', - port = 6379, - db = "4" - }, - check_pair_dup = false, - allow_negative = false - }, - central = {}, - pair = {} - }; - return t; - end - - function NGCPDlgCounters._test_connection(client) - if not client then return nil end - local ok, _ = pcall(client.ping, client); - return ok + function NGCPDlgCounters.new(config) + local t = NGCPDlgCounters.init(utils.merge_defaults(config, defaults)) + setmetatable( t, NGCPDlgCounters_MT ) + return t end - function NGCPDlgCounters._connect(config) - local client = redis.connect(config.host,config.port); - client:select(config.db); - KSR.dbg(string.format("connected to redis server %s:%d at %s\n", - config.host, config.port, config.db)); - return client; + function NGCPDlgCounters.init(config) + return { + config = config, + central = NGCPRedis.new(config.central), + pair = NGCPRedis.new(config.pair) + } end function NGCPDlgCounters._decr(self, key) - local res = self.central:decr(key); + local res = self.central.client:decr(key); if res == 0 then - self.central:del(key); + self.central.client:del(key); KSR.dbg(string.format("central:del[%s] counter is 0\n", key)); elseif res < 0 and not self.config.allow_negative then - self.central:del(key); + self.central.client:del(key); KSR.warn(string.format("central:del[%s] counter was %s\n", key, tostring(res))); else @@ -94,10 +81,10 @@ end end function NGCPDlgCounters:exists(callid) - if not self._test_connection(self.pair) then - self.pair = self._connect(self.config.pair); + if not self.pair:test_connection() then + self.pair:connect() end - local res = self.pair:llen(callid) + local res = self.pair.client:llen(callid) if res > 0 then return true else @@ -106,44 +93,44 @@ end end function NGCPDlgCounters:is_in_set(callid, key) - if not self._test_connection(self.pair) then - self.pair = self._connect(self.config.pair); + if not self.pair:test_connection() then + self.pair:connect() end - local res = self.pair:lrange(callid, 0, -1); + local res = self.pair.client:lrange(callid, 0, -1); return utable.contains(res, key); end function NGCPDlgCounters:is_in_set_regex(callid, key) - if not self._test_connection(self.pair) then - self.pair = self._connect(self.config.pair); + if not self.pair:test_connection() then + self.pair:connect() end - local res = self.pair:lrange(callid, 0, -1); + local res = self.pair.client:lrange(callid, 0, -1); return utable.contains_regex(res, key); end function NGCPDlgCounters:set(callid, key) - if not self._test_connection(self.central) then - self.central = self._connect(self.config.central); + if not self.central:test_connection() then + self.central:connect() end - local res = self.central:incr(key); + local res = self.central.client:incr(key); KSR.dbg(string.format("central:incr[%s]=>%s\n", key, tostring(res))); - if not self._test_connection(self.pair) then - self.pair = self._connect(self.config.pair); + if not self.pair:test_connection() then + self.pair:connect() end if self.config.check_pair_dup and self:is_in_set(callid, key) then local msg = "pair:check_pair_dup[%s]=>[%s] already there!\n"; KSR.warn(msg:format(callid, key)); end - local pos = self.pair:lpush(callid, key); + local pos = self.pair.client:lpush(callid, key); KSR.dbg(string.format("pair:lpush[%s]=>[%s] %s\n", callid, key, tostring(pos))); end function NGCPDlgCounters:del_key(callid, key) - if not self._test_connection(self.pair) then - self.pair = self._connect(self.config.pair); + if not self.pair:test_connection() then + self.pair:connect() end - local num = self.pair:lrem(callid, 1, key); + local num = self.pair.client:lrem(callid, 1, key); if num == 0 then local msg = "pair:lrem[%s]=>[%s] no such key found in list, " .. "skipping decrement\n"; @@ -151,35 +138,35 @@ end return false; end KSR.dbg(string.format("pair:lrem[%s]=>[%s] %d\n", callid, key, num)); - if not self._test_connection(self.central) then - self.central = self._connect(self.config.central); + if not self.central:test_connection() then + self.central:connect() end self:_decr(key); end function NGCPDlgCounters:del(callid) - if not self._test_connection(self.pair) then - self.pair = self._connect(self.config.pair); + if not self.pair:test_connection() then + self.pair:connect() end - local key = self.pair:lpop(callid); + local key = self.pair.client:lpop(callid); if not key then error(string.format("callid:%s list empty", callid)); end - if not self._test_connection(self.central) then - self.central = self._connect(self.config.central); + if not self.central:test_connection() then + self.central:connect() end while key do self:_decr(key); KSR.dbg(string.format("pair:lpop[%s]=>[%s]\n", callid, key)); - key = self.pair:lpop(callid); + key = self.pair.client:lpop(callid); end end function NGCPDlgCounters:get(key) - if not self._test_connection(self.central) then - self.central = self._connect(self.config.central); + if not self.central:test_connection() then + self.central:connect() end - local res = self.central:get(key); + local res = self.central.client:get(key); KSR.dbg(string.format("central:get[%s]=>%s\n", key, tostring(res))); return res; end diff --git a/ngcp/dlglist.lua b/ngcp/dlglist.lua index 9b1ed55..44a8091 100644 --- a/ngcp/dlglist.lua +++ b/ngcp/dlglist.lua @@ -1,5 +1,5 @@ -- --- Copyright 2015-2020 SipWise Team +-- Copyright 2015-2022 SipWise Team -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -20,12 +20,26 @@ local NGCPDlgList = { __class__ = 'NGCPDlgList' } -local redis = require 'redis'; +local NGCPRedis = require 'ngcp.redis'; local utils = require 'ngcp.utils'; local utable = utils.table _ENV = NGCPDlgList +local defaults = { + central = { + host = '127.0.0.1', + port = 6379, + db = 3 + }, + pair = { + host = '127.0.0.1', + port = 6379, + db = 4 + }, + check_pair_dup = false +} + -- class NGCPDlgList local NGCPDlgList_MT = { __index = NGCPDlgList } @@ -35,52 +49,25 @@ NGCPDlgList_MT.__tostring = function (t) utable.tostring(t.pair)); end -- luacheck: globals KSR - function NGCPDlgList.new() - local t = NGCPDlgList.init(); - setmetatable( t, NGCPDlgList_MT ); - return t; - end - - function NGCPDlgList.init() - local t = { - config = { - central = { - host = '127.0.0.1', - port = 6379, - db = "3" - }, - pair = { - host = '127.0.0.1', - port = 6379, - db = "4" - }, - check_pair_dup = false - }, - central = {}, - pair = {} - }; - return t; - end - - local function _test_connection(client) - if not client then return nil end - local ok, _ = pcall(client.ping, client); - return ok + function NGCPDlgList.new(config) + local t = NGCPDlgList.init(utils.merge_defaults(config, defaults)) + setmetatable( t, NGCPDlgList_MT ) + return t end - local function _connect(config) - local client = redis.connect(config.host,config.port); - client:select(config.db); - KSR.dbg(string.format("connected to redis server %s:%d at %s\n", - config.host, config.port, config.db)); - return client; + function NGCPDlgList.init(config) + return { + config = config, + central = NGCPRedis.new(config.central), + pair = NGCPRedis.new(config.pair) + } end function NGCPDlgList._del(self, key, callid) - self.central:lrem(key, 0, callid); - local num = self.central:llen(key); + self.central.client:lrem(key, 0, callid); + local num = self.central.client:llen(key); if num == 0 then - self.central:del(key); + self.central.client:del(key); KSR.dbg(string.format("central[%s] is empty. Removed\n", key)); else KSR.dbg(string.format("central:lrem[%s]=>[%s]\n", key, tostring(num))); @@ -89,10 +76,10 @@ end end function NGCPDlgList:exists(callid) - if not _test_connection(self.pair) then - self.pair = _connect(self.config.pair); + if not self.pair:test_connection() then + self.pair:connect() end - local res = self.pair:llen("list:"..callid) + local res = self.pair.client:llen("list:"..callid) if res > 0 then return true else @@ -101,61 +88,61 @@ end end function NGCPDlgList:is_in_set(callid, key) - if not _test_connection(self.pair) then - self.pair = _connect(self.config.pair); + if not self.pair:test_connection() then + self.pair:connect() end - local res = self.pair:lrange("list:"..callid, 0, -1); + local res = self.pair.client:lrange("list:"..callid, 0, -1); return utable.contains(res, key); end function NGCPDlgList:add(callid, key) - if not _test_connection(self.central) then - self.central = _connect(self.config.central); + if not self.central:test_connection() then + self.central:connect() end - local pos = self.central:rpush(key, callid); + local pos = self.central.client:rpush(key, callid); KSR.dbg(string.format("central:rpush[%s]=>[%s] %s\n", key, callid, tostring(pos))); - if not _test_connection(self.pair) then - self.pair = _connect(self.config.pair); + if not self.pair:test_connection() then + self.pair:connect() end if self.config.check_pair_dup and self:is_in_set(callid, key) then KSR.warn(string.format("pair:check_pair_dup[%s]=>[%s] already there!\n", callid, key)); end - pos = self.pair:lpush("list:"..callid, key); + pos = self.pair.client:lpush("list:"..callid, key); KSR.dbg(string.format("pair:lpush[list:%s]=>[%s] %s\n", callid, key, tostring(pos))); end function NGCPDlgList:del(callid, key) - if not _test_connection(self.pair) then - self.pair = _connect(self.config.pair); + if not self.pair:test_connection() then + self.pair:connect() end - local num = self.pair:lrem("list:"..callid, 0, key); + local num = self.pair.client:lrem("list:"..callid, 0, key); if num == 0 then KSR.dbg(string.format("pair:lrem[list:%s] no such key %s found in list\n", callid, key)); return false; end KSR.dbg(string.format("pair:lrem[%s]=>[%s] %d\n", callid, key, num)); - if not _test_connection(self.central) then - self.central = _connect(self.config.central); + if not self.central:test_connection() then + self.central:connect() end self:_del(key, callid); end function NGCPDlgList:destroy(callid) - if not _test_connection(self.pair) then - self.pair = _connect(self.config.pair); + if not self.pair:test_connection() then + self.pair:connect() end - local key = self.pair:lpop("list:"..callid); + local key = self.pair.client:lpop("list:"..callid); if not key then - self.pair:del("list:"..callid); + self.pair.client:del("list:"..callid); error(string.format("callid:%s list empty", callid)); end - if not _test_connection(self.central) then - self.central = _connect(self.config.central); + if not self.central:test_connection() then + self.central:connect() end while key do self:_del(key, callid); KSR.dbg(string.format("pair:lpop[%s]=>[%s]\n", callid, key)); - key = self.pair:lpop("list:"..callid); + key = self.pair.client:lpop("list:"..callid); end end -- class diff --git a/ngcp/dp.lua b/ngcp/dp.lua index f23e2eb..1f833b8 100644 --- a/ngcp/dp.lua +++ b/ngcp/dp.lua @@ -30,9 +30,8 @@ NGCPDomainPrefs.query = "SELECT * FROM %s WHERE domain ='%s'" -- luacheck: globals KSR function NGCPDomainPrefs:new(config) local instance = NGCPDomainPrefs:create() - self.config = config -- creates xavp usr - instance:init() + instance:init(config) return instance end diff --git a/ngcp/fp.lua b/ngcp/fp.lua index 6be35c9..d7f9874 100644 --- a/ngcp/fp.lua +++ b/ngcp/fp.lua @@ -32,9 +32,8 @@ NGCPFaxPrefs.query = "SELECT fp.* FROM %s fp, provisioning.voip_subscribers s".. -- luacheck: globals KSR function NGCPFaxPrefs:new(config) local instance = NGCPFaxPrefs:create() - self.config = config -- creates xavp usr - instance:init() + instance:init(config) return instance end diff --git a/ngcp/loop.lua b/ngcp/loop.lua index 94f93e4..21f6a48 100644 --- a/ngcp/loop.lua +++ b/ngcp/loop.lua @@ -1,5 +1,5 @@ -- --- Copyright 2016-2020 SipWise Team +-- Copyright 2016-2022 SipWise Team -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -20,12 +20,20 @@ local NGCPLoop = { __class__ = 'NGCPLoop' } -local redis = require 'redis'; +local NGCPRedis = require 'ngcp.redis'; local utils = require 'ngcp.utils'; local utable = utils.table _ENV = NGCPLoop +local defaults = { + host = '127.0.0.1', + port = 6379, + db = 3, + expire = 5, + max = 5 +} + -- class NGCPLoop local NGCPLoop_MT = { __index = NGCPLoop } @@ -34,49 +42,29 @@ NGCPLoop_MT.__tostring = function (t) utable.tostring(t.config)); end -- luacheck: globals KSR - function NGCPLoop.new() - local t = NGCPLoop.init(); - setmetatable( t, NGCPLoop_MT ); - return t; - end - - function NGCPLoop.init() - local t = { - config = { - host = '127.0.0.1', - port = 6379, - db = "3", - expire = 5, - max = 5 - }, - client = {} - }; - return t; + function NGCPLoop.new(config) + local t = NGCPLoop.init(utils.merge_defaults(config, defaults)) + setmetatable( t, NGCPLoop_MT ) + return t end - local function _test_connection(client) - if not client then return nil end - local ok, _ = pcall(client.ping, client); - return ok - end - - local function _connect(config) - local client = redis.connect(config.host,config.port); - client:select(config.db); - KSR.dbg(string.format("connected to redis server %s:%d at %s\n", - config.host, config.port, config.db)); - return client; + function NGCPLoop.init(config) + return { + config = config, + redis = NGCPRedis.new(config) + } end function NGCPLoop:add(fu, tu, ru) - if not _test_connection(self.client) then - self.client = _connect(self.config); + if not self.redis:test_connection() then + self.redis:connect() end + local key = string.format("%s;%s;%s", tostring(fu), tostring(tu), tostring(ru)); - local res = self.client:incr(key); + local res = self.redis.client:incr(key); if res == 1 then - self.client:expire(key, self.config.expire); + self.redis.client:expire(key, self.config.expire); end KSR.dbg(string.format("[%s]=>[%s] expires:%s\n", key, tostring(res), tostring(self.config.expires))); diff --git a/ngcp/ngcp.lua b/ngcp/ngcp.lua index e57e74a..7e31195 100644 --- a/ngcp/ngcp.lua +++ b/ngcp/ngcp.lua @@ -1,5 +1,5 @@ -- --- Copyright 2013-2020 SipWise Team +-- Copyright 2013-2022 SipWise Team -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -41,14 +41,14 @@ function NGCP:__tostring() return output end -function NGCP:new() +function NGCP:new(config) local instance = NGCP:create() - instance:init() + instance:init(config) return instance end -function NGCP:init() - self.config = NGCPConfig:new() +function NGCP:init(config) + self.config = NGCPConfig:new(config) self.prefs = { dom = NGCPDomainPrefs:new(self.config), prof = NGCPProfilePrefs:new(self.config), diff --git a/ngcp/pp.lua b/ngcp/pp.lua index fdfb328..a452f28 100644 --- a/ngcp/pp.lua +++ b/ngcp/pp.lua @@ -30,9 +30,8 @@ NGCPPeerPrefs.query = "SELECT * FROM %s WHERE uuid = '%s'" -- luacheck: globals KSR function NGCPPeerPrefs:new(config) local instance = NGCPPeerPrefs:create() - self.config = config -- creates xavp usr - instance:init() + instance:init(config) return instance end diff --git a/ngcp/pprof.lua b/ngcp/pprof.lua index 7da49d4..7296921 100644 --- a/ngcp/pprof.lua +++ b/ngcp/pprof.lua @@ -31,9 +31,8 @@ NGCPProfilePrefs.query = "SELECT prefs.* FROM provisioning.voip_subscribers ".. -- luacheck: globals KSR function NGCPProfilePrefs:new(config) local instance = NGCPProfilePrefs:create() - self.config = config -- creates xavp usr - instance:init() + instance:init(config) return instance end diff --git a/ngcp/pref.lua b/ngcp/pref.lua index 9318211..b839a9e 100644 --- a/ngcp/pref.lua +++ b/ngcp/pref.lua @@ -36,7 +36,8 @@ function NGCPPrefs.__tostring(self) return output end -- luacheck: globals KSR -function NGCPPrefs:init() +function NGCPPrefs:init(config) + self.config = config for _,v in pairs(self.levels) do NGCPXAvp.init(v, self.group) end diff --git a/ngcp/push.lua b/ngcp/push.lua index def9329..7bc742d 100644 --- a/ngcp/push.lua +++ b/ngcp/push.lua @@ -1,5 +1,5 @@ -- --- Copyright 2021 SipWise Team +-- Copyright 2022 SipWise Team -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -21,12 +21,21 @@ local NGCPPush = { __class__ = 'NGCPPush' } -local redis = require 'redis'; +local NGCPRedis = require 'ngcp.redis'; local curl = require 'curl' local utils = require 'ngcp.utils' local utable = utils.table local separator = "#" +local defaults = { + url = 'http://127.0.0.1:45059/push', + central = { + host = '127.0.0.1', + port = 6379, + db = 3 + }, +} + -- class NGCPPush local NGCPPush_MT = { __index = NGCPPush } @@ -34,40 +43,18 @@ NGCPPush_MT.__tostring = function (t) return string.format("config:%s", utable.tostring(t.config)) end -function NGCPPush.new() - local t = NGCPPush.init(); +function NGCPPush.new(config) + local t = NGCPPush.init(utils.merge_defaults(config, defaults)); setmetatable( t, NGCPPush_MT ) return t; end -function NGCPPush.init() - local t = { - config = { - url = 'http://127.0.0.1:45059/push', - central = { - host = '127.0.0.1', - port = 6379, - db = "3" - }, - }, +function NGCPPush.init(config) + return { + config = config, c = curl.easy_init(), - client = {}, - }; - return t; -end - -function NGCPPush:_test_connection() - if not self.client then return nil end - local ok, _ = pcall(self.client.ping, self.client); - return ok -end - -function NGCPPush:_connect() - local config = self.config.central - self.client = redis.connect(config.host, config.port); - self.client:select(config.db); - KSR.dbg(string.format("connected to redis server %s:%d at %s\n", - config.host, config.port, config.db)); + redis = NGCPRedis.new(config.central) + } end function NGCPPush:len(key, node) @@ -89,22 +76,22 @@ local function value_base(v) end function NGCPPush:add(v) - if not self:_test_connection() then - self:_connect(); + if not self.redis:test_connection() then + self.redis:connect() end local val_base = value_base(v) local val = v.callid.. separator ..val_base - local pos = self.client:lpush(v.key, val) + local pos = self.redis.client:lpush(v.key, val) KSR.dbg(string.format("lpush[%s]=>[%s] %s\n", v.key, val, tostring(pos))); val = v.key .. separator .. val_base - pos = self.client:lpush(v.callid, val) + pos = self.redis.client:lpush(v.callid, val) KSR.dbg(string.format("lpush[%s]=>[%s] %s\n", v.callid, val, tostring(pos))); if v.expire then - self.client:expire(v.key, v.expire) - self.client:expire(v.callid, v.expire) + self.redis.client:expire(v.key, v.expire) + self.redis.client:expire(v.callid, v.expire) KSR.dbg(string.format( "set expire %d for keys:[%s, %s]", v.expire, v.key, v.callid)); end @@ -123,54 +110,54 @@ local function insert_val(res, v, key_name) end function NGCPPush:get(key) - if not self:_test_connection() then - self:_connect(); + if not self.redis:test_connection() then + self.redis:connect() end local res = {} - for _,v in pairs(self.client:lrange(key, 0, -1)) do + for _,v in pairs(self.redis.client:lrange(key, 0, -1)) do insert_val(res, v, "callid") end return res end function NGCPPush:callid_get(callid) - if not self:_test_connection() then - self:_connect(); + if not self.redis:test_connection() then + self.redis:connect() end local res = {} - for _,v in pairs(self.client:lrange(callid, 0, -1)) do + for _,v in pairs(self.redis.client:lrange(callid, 0, -1)) do insert_val(res, v, "key") end return res end function NGCPPush:del(v) - if not self:_test_connection() then - self:_connect(); + if not self.redis:test_connection() then + self.redis:connect() end local val_base = value_base(v) local val = v.callid.. separator ..val_base - local res = self.client:lrem(v.key, 0, val) + local res = self.redis.client:lrem(v.key, 0, val) KSR.dbg(string.format("lrem[%s] all [%s] %s\n", v.key, val, tostring(res))); - if self.client:llen(v.key) == 0 then + if self.redis.client:llen(v.key) == 0 then self:clear(v.key) end val = v.key .. separator .. val_base - res = self.client:lrem(v.callid, 0, val) + res = self.redis.client:lrem(v.callid, 0, val) KSR.dbg(string.format("lrem[%s] all [%s] %s\n", v.callid, val, tostring(res))); - if self.client:llen(v.callid) == 0 then - self.client:del(v.callid) + if self.redis.client:llen(v.callid) == 0 then + self.redis.client:del(v.callid) end end function NGCPPush:clear(key) - if not self:_test_connection() then - self:_connect(); + if not self.redis:test_connection() then + self.redis:connect() end - local res = self.client:del(key) + local res = self.redis.client:del(key) KSR.dbg(string.format("del[%s] %s\n", key, tostring(res))); end diff --git a/ngcp/recentcalls.lua b/ngcp/recentcalls.lua index 5723d0d..8d088a3 100644 --- a/ngcp/recentcalls.lua +++ b/ngcp/recentcalls.lua @@ -1,5 +1,5 @@ -- --- Copyright 2015-2020 SipWise Team +-- Copyright 2015-2022 SipWise Team -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -20,63 +20,50 @@ local NGCPRecentCalls = { __class__ = 'NGCPRecentCalls' } -local redis = require 'redis'; +local NGCPRedis = require 'ngcp.redis'; local utils = require 'ngcp.utils'; local utable = utils.table _ENV = NGCPRecentCalls +local defaults = { + central = { + host = '127.0.0.1', + port = 6379, + db = 7 + }, + expire = 7200, + out_expire = 86400 +} + -- class NGCPRecentCalls local NGCPRecentCalls_MT = { __index = NGCPRecentCalls } NGCPRecentCalls_MT.__tostring = function (t) - return string.format("config:%s central:%s", - utable.tostring(t.config), utable.tostring(t.central)) + return string.format("config:%s redis:%s", + utable.tostring(t.config), utable.tostring(t.redis)) end -- luacheck: globals KSR - function NGCPRecentCalls.new() - local t = NGCPRecentCalls.init(); + function NGCPRecentCalls.new(config) + local t = NGCPRecentCalls.init(utils.merge_defaults(config, defaults)) setmetatable( t, NGCPRecentCalls_MT ) - return t; - end - - function NGCPRecentCalls.init() - local t = { - config = { - central = { - host = '127.0.0.1', - port = 6379, - db = "7" - }, - expire = 7200, - out_expire = 86400 - }, - central = {}, - }; - return t; - end - - function NGCPRecentCalls._test_connection(client) - if not client then return nil end - local ok, _ = pcall(client.ping, client) - return ok + return t end - function NGCPRecentCalls._connect(config) - local client = redis.connect(config.host,config.port) - client:select(config.db) - KSR.info(string.format("connected to redis server %s:%d at %s\n", - config.host, config.port, config.db)) - return client + function NGCPRecentCalls.init(config) + return { + config = config, + redis = NGCPRedis.new(config.central) + } end function NGCPRecentCalls:set_by_key(key, callid, uuid, start_time, duration, caller, callee, source) - if not self._test_connection(self.central) then - self.central = self._connect(self.config.central) + if not self.redis:test_connection() then + self.redis:connect() end - local res = self.central:hmset(key, + local res = self.redis.client:hmset(key, "callid", callid, "uuid", uuid, "start_time", start_time, @@ -85,7 +72,7 @@ end "callee", callee, "source", source) if res then - self.central:expire(key, self.config.expire) + self.redis.client:expire(key, self.config.expire) end local msg = "central:hset[%s]=>[%s] callid: %s uuid: %s " .. "start_time: %s duration: %s caller: %s callee: %s source: %s expire: %d\n" @@ -99,13 +86,13 @@ end end function NGCPRecentCalls:set_element_by_key(key, element, value) - if not self._test_connection(self.central) then - self.central = self._connect(self.config.central) + if not self.redis:test_connection() then + self.redis:connect() end - local res = self.central:hmset(key, element, value) + local res = self.redis.client:hmset(key, element, value) if res then - self.central:expire(key, self.config.out_expire) + self.redis.client:expire(key, self.config.out_expire) end KSR.info(string.format("central:hset[%s]=>[%s] %s: %s expire: %d\n", key, tostring(res), @@ -115,11 +102,11 @@ end end function NGCPRecentCalls:get_element_by_key(key, element) - if not self._test_connection(self.central) then - self.central = self._connect(self.config.central) + if not self.redis:test_connection() then + self.redis:connect() end - local res = self.central:hgetall(key) + local res = self.redis.client:hgetall(key) if res then KSR.info(string.format("central:hget[%s]=>[%s]\n", key, tostring(res[element]))) @@ -131,11 +118,11 @@ end end function NGCPRecentCalls:del_by_key(key) - if not self._test_connection(self.central) then - self.central = self._connect(self.config.central) + if not self.redis:test_connection() then + self.redis:connect() end - self.central:del(key) + self.redis.client:del(key) KSR.info(string.format("central:del[%s] removed\n", key)); return 0 diff --git a/ngcp/redis.lua b/ngcp/redis.lua new file mode 100644 index 0000000..21ae64b --- /dev/null +++ b/ngcp/redis.lua @@ -0,0 +1,66 @@ +-- +-- Copyright 2022 SipWise Team +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This package is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- . +-- On Debian systems, the complete text of the GNU General +-- Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". +-- +-- luacheck: globals KSR +local utils = require 'ngcp.utils' +local redis = require 'redis'; +local utable = utils.table +local NGCPRedis = utils.inheritsFrom() + +_ENV = NGCPRedis + +local defaults = { + host = 'localhost', + port = 6379, + db = 0 +} + +-- class NGCPRedis +NGCPRedis.__tostring = function (t) + return string.format("config:%s", utable.tostring(t.config)) +end + +function NGCPRedis.new(config) + local t = NGCPRedis:create() + t.config = utils.merge_defaults(config, defaults) + return t; +end + +function NGCPRedis:test_connection() + if not self.client then return nil end + local ok, _ = pcall(self.client.ping, self.client) + if not ok then + KSR.info(string.format("close redis server[%d]\n", + self.client.network.socket:getfd())) + self.client.network.socket:close() + self.client = nil + end + return ok +end + +function NGCPRedis:connect() + self.client = redis.connect(self.config.host, self.config.port) + self.client:select(self.config.db) + KSR.info(string.format("connected to redis server[%d] %s:%s at %s\n", + self.client.network.socket:getfd(), + self.config.host, tostring(self.config.port), tostring(self.config.db))) + return self.client +end + +return NGCPRedis diff --git a/ngcp/rp.lua b/ngcp/rp.lua index 3d3bb70..7ee0561 100644 --- a/ngcp/rp.lua +++ b/ngcp/rp.lua @@ -34,9 +34,8 @@ NGCPRealPrefs.group = "real_prefs" -- luacheck: globals KSR function NGCPRealPrefs:new(config) local instance = NGCPRealPrefs:create() - self.config = config -- creates xavp usr - instance:init() + instance:init(config) return instance end diff --git a/ngcp/up.lua b/ngcp/up.lua index 1d057e3..85699cd 100644 --- a/ngcp/up.lua +++ b/ngcp/up.lua @@ -30,9 +30,8 @@ NGCPUserPrefs.query = "SELECT * FROM %s WHERE uuid ='%s' ORDER BY id DESC" -- luacheck: globals KSR function NGCPUserPrefs:new(config) local instance = NGCPUserPrefs:create() - self.config = config -- creates xavp usr - instance:init() + instance:init(config) return instance end diff --git a/ngcp/utils.lua b/ngcp/utils.lua index 00ce944..1476193 100644 --- a/ngcp/utils.lua +++ b/ngcp/utils.lua @@ -82,6 +82,22 @@ function utils.math.random() -- luacheck: ignore math math.random = utils.math.random +function utils.merge_defaults(param, defaults) + if not defaults then + error("nil defaults") + elseif param == nil then + param = {} + end + for k, v in pairs(defaults) do + if param[k] == nil then + param[k] = v + elseif type(v) == "table" and type(param[k]) == "table" then + param[k] = utils.merge_defaults(param[k], v) + end + end + return param +end + -- copy a table function ut.deepcopy(object) local lookup_table = {} diff --git a/tests/ngcp.lua b/tests/ngcp.lua index dbb64e9..8f66d56 100644 --- a/tests/ngcp.lua +++ b/tests/ngcp.lua @@ -78,6 +78,12 @@ TestNGCP = {} --class lu.assertIsNil(self.ngcp.config.con) end + function TestNGCP:test_custom_config() + local ngcp = NGCP:new({db_port=1111}) + lu.assertEquals(ngcp.config.db_port, 1111) + lu.assertEquals(ngcp.config.default.usr.ringtimeout, 180) + end + function TestNGCP:test_config_get_defaults_all() local defaults = NGCPConfig.get_defaults(self.ngcp.config, 'peer') lu.assertItemsEquals(defaults, self.ngcp.config.default.peer) diff --git a/tests/ngcp_dlgcnt.lua b/tests/ngcp_dlgcnt.lua index fd6529a..83b2665 100644 --- a/tests/ngcp_dlgcnt.lua +++ b/tests/ngcp_dlgcnt.lua @@ -39,43 +39,8 @@ TestNGCPDlgCnt = {} --class self.dlg = NGCPDlg.new() lu.assertEvalToTrue(self.dlg) - self.dlg.central = self.central; - self.dlg.pair = self.pair - end - - function TestNGCPDlgCnt:test_connection_ok() - local prev = self.central - self.central:ping() ;mc :returns(true) - - mc:replay() - local ok = self.dlg._test_connection(self.central) - mc:verify() - - lu.assertTrue(ok) - lu.assertIs(prev, self.central) - end - - function TestNGCPDlgCnt:test_connection_fail() - local prev = self.central - self.central:ping() ;mc :error("error") - - mc:replay() - local res = self.dlg._test_connection(self.central) - mc:verify() - - lu.assertFalse(res) - lu.assertIs(prev, self.central) - end - - function TestNGCPDlgCnt:test_connect_ok() - local c = self.dlg.config - self.fake_redis.connect(c.pair.host,c.pair.port) ;mc :returns(self.pair) - self.pair:select(c.pair.db) ;mc :returns(true) - - mc:replay() - local res = self.dlg._connect(c.pair) - mc:verify() - lu.assertIs(res, self.pair) + self.dlg.central.client = self.central; + self.dlg.pair.client = self.pair end function TestNGCPDlgCnt:test_set_1() @@ -120,8 +85,8 @@ TestNGCPDlgCnt = {} --class self.dlg:del("callid0") mc:verify() - lu.assertIs(self.dlg.central, self.central) - lu.assertIs(self.dlg.pair, self.pair) + lu.assertIs(self.dlg.central.client, self.central) + lu.assertIs(self.dlg.pair.client, self.pair) end function TestNGCPDlgCnt:test_del_zero() @@ -137,8 +102,8 @@ TestNGCPDlgCnt = {} --class self.dlg:del("callid0") mc:verify() - lu.assertIs(self.dlg.central, self.central) - lu.assertIs(self.dlg.pair, self.pair) + lu.assertIs(self.dlg.central.client, self.central) + lu.assertIs(self.dlg.pair.client, self.pair) end function TestNGCPDlgCnt:test_del_negative() @@ -156,8 +121,8 @@ TestNGCPDlgCnt = {} --class self.dlg:del("callid0") mc:verify() - lu.assertIs(self.dlg.central, self.central) - lu.assertIs(self.dlg.pair, self.pair) + lu.assertIs(self.dlg.central.client, self.central) + lu.assertIs(self.dlg.pair.client, self.pair) end function TestNGCPDlgCnt:test_del_negative_ok() @@ -174,8 +139,8 @@ TestNGCPDlgCnt = {} --class self.dlg:del("callid0") mc:verify() - lu.assertIs(self.dlg.central, self.central) - lu.assertIs(self.dlg.pair, self.pair) + lu.assertIs(self.dlg.central.client, self.central) + lu.assertIs(self.dlg.pair.client, self.pair) end function TestNGCPDlgCnt:test_del_multy() @@ -200,8 +165,8 @@ TestNGCPDlgCnt = {} --class self.dlg:del("callid0") mc:verify() - lu.assertIs(self.dlg.central, self.central) - lu.assertIs(self.dlg.pair, self.pair) + lu.assertIs(self.dlg.central.client, self.central) + lu.assertIs(self.dlg.pair.client, self.pair) end function TestNGCPDlgCnt:test_is_in_set_fail() @@ -212,8 +177,8 @@ TestNGCPDlgCnt = {} --class local res = self.dlg:is_in_set("callid0", "fake") mc:verify() - lu.assertIs(self.dlg.central, self.central) - lu.assertIs(self.dlg.pair, self.pair) + lu.assertIs(self.dlg.central.client, self.central) + lu.assertIs(self.dlg.pair.client, self.pair) lu.assertFalse(res) end @@ -225,8 +190,8 @@ TestNGCPDlgCnt = {} --class local res = self.dlg:is_in_set("callid0", "fake") mc:verify() - lu.assertIs(self.dlg.central, self.central) - lu.assertIs(self.dlg.pair, self.pair) + lu.assertIs(self.dlg.central.client, self.central) + lu.assertIs(self.dlg.pair.client, self.pair) lu.assertTrue(res) end @@ -238,8 +203,8 @@ TestNGCPDlgCnt = {} --class local res = self.dlg:is_in_set_regex("callid0", "^user:") mc:verify() - lu.assertIs(self.dlg.central, self.central) - lu.assertIs(self.dlg.pair, self.pair) + lu.assertIs(self.dlg.central.client, self.central) + lu.assertIs(self.dlg.pair.client, self.pair) lu.assertTrue(res) end @@ -251,8 +216,8 @@ TestNGCPDlgCnt = {} --class local res = self.dlg:is_in_set_regex("callid0", "^ser:") mc:verify() - lu.assertIs(self.dlg.central, self.central) - lu.assertIs(self.dlg.pair, self.pair) + lu.assertIs(self.dlg.central.client, self.central) + lu.assertIs(self.dlg.pair.client, self.pair) lu.assertFalse(res) end @@ -267,8 +232,8 @@ TestNGCPDlgCnt = {} --class self.dlg:del_key("callid0", "key1") mc:verify() - lu.assertIs(self.dlg.central, self.central) - lu.assertIs(self.dlg.pair, self.pair) + lu.assertIs(self.dlg.central.client, self.central) + lu.assertIs(self.dlg.pair.client, self.pair) end -- class TestNGCPDlgCnt diff --git a/tests/ngcp_dlglist.lua b/tests/ngcp_dlglist.lua index c79b417..04c254e 100644 --- a/tests/ngcp_dlglist.lua +++ b/tests/ngcp_dlglist.lua @@ -1,5 +1,5 @@ -- --- Copyright 2013-2020 SipWise Team +-- Copyright 2013-2022 SipWise Team -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -41,8 +41,8 @@ function TestNGCPDlgList:setUp() self.dlg = NGCPDlgList.new() lu.assertEvalToTrue(self.dlg) - self.dlg.central = self.central; - self.dlg.pair = self.pair + self.dlg.central.client = self.central; + self.dlg.pair.client = self.pair end function TestNGCPDlgList:test_exists_ok() diff --git a/tests/ngcp_loop.lua b/tests/ngcp_loop.lua index 04b994b..bb3a677 100644 --- a/tests/ngcp_loop.lua +++ b/tests/ngcp_loop.lua @@ -40,7 +40,7 @@ function TestNGCPLoop:setUp() self.loop = NGCPLoop.new() lu.assertNotNil(self.loop) - self.loop.client = self.client; + self.loop.redis.client = self.client; self.loop.config.max = 5; self.loop.config.expire = 1; end diff --git a/tests/ngcp_recentcalls.lua b/tests/ngcp_recentcalls.lua index be7a790..6d5556f 100644 --- a/tests/ngcp_recentcalls.lua +++ b/tests/ngcp_recentcalls.lua @@ -1,5 +1,5 @@ -- --- Copyright 2014-2020 SipWise Team +-- Copyright 2014-2022 SipWise Team -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -39,32 +39,16 @@ TestNGCPRecentCalls = {} --class self.rcalls = NGCPRecentCalls.new() lu.assertNotNil(self.rcalls) - - self.rcalls.central = self.central; + lu.assertNotNil(self.rcalls.redis) + lu.assertNotNil(self.rcalls.redis.config) + self.rcalls.redis.client = self.central; end - function TestNGCPRecentCalls:test_connection_ok() - local prev = self.central - self.central:ping() ;mc :returns(true) - - mc:replay() - local ok = self.rcalls._test_connection(self.central) - mc:verify() - - lu.assertTrue(ok) - lu.assertIs(prev, self.central) - end - - function TestNGCPRecentCalls:test_connection_fail() - local prev = self.central - self.central:ping() ;mc :error("error") - - mc:replay() - local res = self.rcalls._test_connection(self.central) - mc:verify() - - lu.assertFalse(res) - lu.assertIs(prev, self.central) + function TestNGCPRecentCalls:test_config() + local NGCPRecentCalls = require 'ngcp.recentcalls' + rcalls = NGCPRecentCalls.new({central = {db = 10}}) + lu.assertEquals(rcalls.config.central.db, 10) + lu.assertNotNil(rcalls.config.central.port) end function TestNGCPRecentCalls:test_set_by_key() @@ -98,8 +82,38 @@ TestNGCPRecentCalls = {} --class mc:verify() lu.assertTrue(res) - lu.assertIs(self.rcalls.central, self.central) + lu.assertIs(self.rcalls.redis.client, self.central) end + function TestNGCPRecentCalls:test_set_by_key_ko() + local ttl = 7200 + local key = "431110001" + local uuid = "9bcb88b6-541a-43da-8fdc-816f5557ff93" + local callid = "12345-67890" + local start_time = "1439911398" + local duration = 11 + local caller = "437712345" + local callee = "437754321" + local source = "SIPWISE_1" + + self.central:ping() ;mc :returns(true) + self.central:hmset(key, "callid", callid, + "uuid", uuid, + "start_time", start_time, + "duration", duration, + "caller", caller, + "callee", callee, + "source", source) ;mc :returns(false) + + mc:replay() + local res = self.rcalls:set_by_key(key, + callid, uuid, + start_time, duration, + caller, callee, + source) + mc:verify() + lu.assertFalse(res) + lu.assertIs(self.rcalls.redis.client, self.central) + end -- class TestNGCPRecentCalls --EOF diff --git a/tests/ngcp_redis.lua b/tests/ngcp_redis.lua new file mode 100644 index 0000000..6cca368 --- /dev/null +++ b/tests/ngcp_redis.lua @@ -0,0 +1,86 @@ +-- +-- Copyright 2022 SipWise Team +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This package is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- . +-- On Debian systems, the complete text of the GNU General +-- Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". +-- + +local lu = require('luaunit') +local lemock = require('lemock') +local ksrMock = require 'mocks.ksr' +local utils = require 'ngcp.utils' + +KSR = ksrMock:new() + +local mc + +-- luacheck: ignore TestNGCPRedis +TestNGCPRedis = {} --class + + function TestNGCPRedis:setUp() + mc = lemock.controller() + self.fake_redis = mc:mock() + local fake_client = utils.inheritsFrom(mc:mock()) + self.socket = mc:mock() + fake_client.network = { socket = self.socket } + self.client = fake_client:create() + + package.loaded.redis = self.fake_redis + local NGCPRedis = require 'ngcp.redis' + + self.ngcp_redis = NGCPRedis.new() + lu.assertNotNil(self.ngcp_redis) + lu.assertNotNil(self.ngcp_redis.config) + self.ngcp_redis.client = self.client; + end + + function TestNGCPRedis:test_connection_ok() + local prev = self.client + self.client:ping() ;mc :returns(true) + + mc:replay() + local ok = self.ngcp_redis:test_connection() + mc:verify() + + lu.assertTrue(ok) + lu.assertIs(prev, self.ngcp_redis.client) + end + + function TestNGCPRedis:test_connection_fail() + local prev = self.client + self.client:ping() ;mc :error("error") + self.socket:getfd() ;mc:returns(3) + self.socket:close() ;mc:returns(true) + + mc:replay() + local res = self.ngcp_redis:test_connection() + mc:verify() + + lu.assertFalse(res) + lu.assertNil(self.ngcp_redis.client) + end + + function TestNGCPRedis:test_connect_ok() + local c = self.ngcp_redis.config + self.fake_redis.connect(c.host, c.port) ;mc :returns(self.client) + self.client:select(c.db) ;mc :returns(true) + self.socket:getfd() ;mc:returns(3) + + mc:replay() + local res = self.ngcp_redis:connect() + mc:verify() + lu.assertIs(res, self.client) + end diff --git a/tests/utils.lua b/tests/utils.lua index 981b363..ed9e6ab 100644 --- a/tests/utils.lua +++ b/tests/utils.lua @@ -229,3 +229,18 @@ TestUtils = {} utils.table.merge(tmp, {1,2,3,5,4}) lu.assertEquals(tmp, {1,2,3,5,4}) end + + function TestUtils:test_merge_defaults() + lu.assertError(utils.merge_defaults, {}) + local defaults = { uno = 1, dos = "dos" } + + local res = utils.merge_defaults({uno = "uno", tres = 3}, defaults) + lu.assertItemsEquals(res, {uno= "uno", dos = "dos", tres = 3}) + + res = utils.merge_defaults({other={ok = true}}, defaults) + lu.assertItemsEquals(res, {uno= 1, dos = "dos", other = {ok = true}}) + + defaults = {simple = 1, complex = { db = 1, other = 2 }} + res = utils.merge_defaults({complex = {other=false}}, defaults) + lu.assertItemsEquals(res, {simple= 1, complex = { db = 1, other = false }}) + end