diff --git a/ngcp/loop.lua b/ngcp/loop.lua new file mode 100644 index 0000000..de91382 --- /dev/null +++ b/ngcp/loop.lua @@ -0,0 +1,94 @@ +-- +-- Copyright 2016 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 NGCPLoop = { + __class__ = 'NGCPLoop' +} +local redis = require 'redis'; +local utils = require 'ngcp.utils'; +local utable = utils.table + +_ENV = NGCPLoop + +-- class NGCPLoop +local NGCPLoop_MT = { __index = NGCPLoop } + +NGCPLoop_MT.__tostring = function (t) + return string.format("config:%s", + utable.tostring(t.config)); +end + + 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; + 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); + sr.log("dbg", string.format("connected to redis server %s:%d at %s\n", + config.host, config.port, config.db)); + return client; + end + + function NGCPLoop:add(fu, tu, ru) + if not _test_connection(self.client) then + self.client = _connect(self.config); + end + local key = string.format("%s;%s;%s", tostring(fu), tostring(tu), tostring(ru)); + local res = self.client:incr(key); + if res == 1 then + self.client:expire(key, self.config.expire); + end + sr.log("dbg", string.format("[%s]=>[%s] expires:%s\n", key, tostring(res), tostring(self.config.expires))); + return res; + end + + function NGCPLoop:detect(fu, tu, ru) + local num = self:add(fu, tu, ru) + if num >= self.config.max then + return true + end + return false + end +-- class + +return NGCPLoop +--EOF diff --git a/tests/ngcp_loop.lua b/tests/ngcp_loop.lua new file mode 100644 index 0000000..ae752f4 --- /dev/null +++ b/tests/ngcp_loop.lua @@ -0,0 +1,113 @@ +-- +-- Copyright 2016 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 lemock = require('lemock') +require('luaunit') + +local srMock = require 'mocks.sr' +sr = srMock:new() + +local mc + +-- luacheck: ignore TestNGCPLoop +TestNGCPLoop = {} --class + +function TestNGCPLoop:setUp() + mc = lemock.controller() + self.fake_redis = mc:mock() + self.client = mc:mock() + + package.loaded.redis = self.fake_redis + local NGCPLoop = require 'ngcp.loop' + + self.loop = NGCPLoop.new() + assertTrue(self.loop) + + self.loop.client = self.client; + self.loop.config.max = 5; + self.loop.config.expire = 1; +end + +function TestNGCPLoop:test_add() + local fu = "AAA@dom.com"; + local tu = "BBB@domB.com"; + local ru = "CCC@domC.com"; + local key = string.format("%s;%s;%s", fu, tu, ru); + + self.client:ping() ;mc :returns(true) + self.client:incr(key) ;mc :returns(1) + self.client:expire(key, self.loop.config.expire) ;mc :returns(1) + + mc:replay() + local res = self.loop:add(fu, tu, ru) + mc:verify() + + assertEquals(res, 1) +end + +function TestNGCPLoop:test_detect_false() + local fu = "AAA@dom.com"; + local tu = "BBB@domB.com"; + local ru = "CCC@domC.com"; + local key = string.format("%s;%s;%s", fu, tu, ru); + + self.client:ping() ;mc :returns(true) + self.client:incr(key) ;mc :returns(1) + self.client:expire(key, self.loop.config.expire) ;mc :returns(1) + + mc:replay() + local res = self.loop:detect(fu, tu, ru) + mc:verify() + + assertFalse(res) +end + +function TestNGCPLoop:test_detect_ko() + local fu = "AAA@dom.com"; + local tu = "BBB@domB.com"; + local ru = "CCC@domC.com"; + local key = string.format("%s;%s;%s", fu, tu, ru); + + self.client:ping() ;mc :returns(true) + self.client:incr(key) ;mc :returns(2) + + mc:replay() + local res = self.loop:detect(fu, tu, ru) + mc:verify() + + assertFalse(res) +end + +function TestNGCPLoop:test_detect() + local fu = "AAA@dom.com"; + local tu = "BBB@domB.com"; + local ru = "CCC@domC.com"; + local key = string.format("%s;%s;%s", fu, tu, ru); + + self.client:ping() ;mc :returns(true) + self.client:incr(key) ;mc :returns(self.loop.config.max) + + mc:replay() + local res = self.loop:detect(fu, tu, ru) + mc:verify() + + assertTrue(res) +end +-- class