* don't use globals, don't use module https://www.lua.org/manual/5.2/manual.html#8.2 * be aware that ngcp-klish/ngcp.lua is NOT a module * clean luacheck errors/warnings * remove lua-uri dependency * migrate tests from lua-unit and lua-lemock to lua-busted WARNING: ngcp-klish/ngcp.lua is outdated and most not work with actual kamailio config Change-Id: I10c6b674bc68ac07c3f02db072d6bff5ba2267a1changes/68/39068/3
parent
32ffcc894e
commit
595a5caacc
@ -0,0 +1,6 @@
|
||||
return {
|
||||
default = {
|
||||
lua = "/usr/bin/lua5.2",
|
||||
helper = "./spec/helper.lua",
|
||||
},
|
||||
}
|
@ -0,0 +1 @@
|
||||
results/
|
@ -1 +1 @@
|
||||
ngcp-klish/*lua usr/share/lua/5.1/ngcp-klish
|
||||
ngcp-klish/*lua usr/share/lua/5.2/ngcp-klish
|
||||
|
@ -0,0 +1,65 @@
|
||||
--
|
||||
-- Copyright 2020 SipWise Team <development@sipwise.com>
|
||||
--
|
||||
-- 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 <http://www.gnu.org/licenses/>.
|
||||
-- .
|
||||
-- On Debian systems, the complete text of the GNU General
|
||||
-- Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
--
|
||||
|
||||
describe("bencode", function()
|
||||
local bencode
|
||||
|
||||
setup(function()
|
||||
bencode = require("ngcp-klish.bencode")
|
||||
end)
|
||||
|
||||
it("should encode a number", function()
|
||||
assert.same('i345e', bencode.encode(345))
|
||||
end)
|
||||
|
||||
it("should encode a string", function()
|
||||
assert.same('7:g5323_1', bencode.encode('g5323_1'))
|
||||
end)
|
||||
|
||||
it("should encode a list of numbers", function()
|
||||
assert.same('li1ei2ei3ee', bencode.encode({1,2,3}))
|
||||
end)
|
||||
|
||||
it("should encode a dict with mixed values",function()
|
||||
assert.same(
|
||||
'd3:dosi2e4:tres5:three3:unoi1ee',
|
||||
bencode.encode({uno=1,dos=2,tres='three'})
|
||||
)
|
||||
end)
|
||||
|
||||
it("should decode a number", function()
|
||||
assert.same(345, bencode.decode('i345e'))
|
||||
end)
|
||||
|
||||
it("should decode a string", function()
|
||||
assert.same('g5323_1', bencode.decode('7:g5323_1'))
|
||||
end)
|
||||
|
||||
it("should decode a list of numbers", function()
|
||||
assert.same({1,2,3}, bencode.decode('li1ei2ei3ee'))
|
||||
end)
|
||||
|
||||
it("should decode a dict with mixed values",function()
|
||||
assert.same(
|
||||
{uno=1,dos=2,tres='three'},
|
||||
bencode.decode('d3:dosi2e4:tres5:three3:unoi1ee')
|
||||
)
|
||||
end)
|
||||
end)
|
@ -0,0 +1,156 @@
|
||||
--
|
||||
-- Copyright 2020 SipWise Team <development@sipwise.com>
|
||||
--
|
||||
-- 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 <http://www.gnu.org/licenses/>.
|
||||
-- .
|
||||
-- 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 assert = require("luassert")
|
||||
local say = require("say")
|
||||
|
||||
-- https://github.com/bluebird75/luaunit/blob/master/luaunit.lua
|
||||
local function _is_table_equals(actual, expected, cycleDetectTable)
|
||||
local type_a, type_e = type(actual), type(expected)
|
||||
|
||||
if type_a ~= type_e then
|
||||
return false -- different types won't match
|
||||
end
|
||||
|
||||
if type_a ~= 'table' then
|
||||
-- other typtes compare directly
|
||||
return actual == expected
|
||||
end
|
||||
|
||||
cycleDetectTable = cycleDetectTable or { actual={}, expected={} }
|
||||
if cycleDetectTable.actual[ actual ] then
|
||||
-- oh, we hit a cycle in actual
|
||||
if cycleDetectTable.expected[ expected ] then
|
||||
-- uh, we hit a cycle at the same time in expected
|
||||
-- so the two tables have similar structure
|
||||
return true
|
||||
end
|
||||
|
||||
-- cycle was hit only in actual, the structure differs from expected
|
||||
return false
|
||||
end
|
||||
|
||||
if cycleDetectTable.expected[ expected ] then
|
||||
-- no cycle in actual, but cycle in expected
|
||||
-- the structure differ
|
||||
return false
|
||||
end
|
||||
|
||||
-- at this point, no table cycle detected, we are
|
||||
-- seeing this table for the first time
|
||||
|
||||
-- mark the cycle detection
|
||||
cycleDetectTable.actual[ actual ] = true
|
||||
cycleDetectTable.expected[ expected ] = true
|
||||
|
||||
|
||||
local actualKeysMatched = {}
|
||||
for k, v in pairs(actual) do
|
||||
actualKeysMatched[k] = true -- Keep track of matched keys
|
||||
if not _is_table_equals(v, expected[k], cycleDetectTable) then
|
||||
-- table differs on this key
|
||||
-- clear the cycle detection before returning
|
||||
cycleDetectTable.actual[ actual ] = nil
|
||||
cycleDetectTable.expected[ expected ] = nil
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
for k, _ in pairs(expected) do
|
||||
if not actualKeysMatched[k] then
|
||||
-- Found a key that we did not see in "actual" -> mismatch
|
||||
-- clear the cycle detection before returning
|
||||
cycleDetectTable.actual[ actual ] = nil
|
||||
cycleDetectTable.expected[ expected ] = nil
|
||||
return false
|
||||
end
|
||||
-- Otherwise actual[k] was already matched against v = expected[k].
|
||||
end
|
||||
|
||||
-- all key match, we have a match !
|
||||
cycleDetectTable.actual[ actual ] = nil
|
||||
cycleDetectTable.expected[ expected ] = nil
|
||||
return true
|
||||
end
|
||||
local is_equal = _is_table_equals
|
||||
|
||||
local function table_findkeyof(t, element)
|
||||
-- Return the key k of the given element in table t, so that t[k] == element
|
||||
-- (or `nil` if element is not present within t). Note that we use our
|
||||
-- 'general' is_equal comparison for matching, so this function should
|
||||
-- handle table-type elements gracefully and consistently.
|
||||
if type(t) == "table" then
|
||||
for k, v in pairs(t) do
|
||||
if is_equal(v, element) then
|
||||
return k
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function _is_table_items_equals(actual, expected )
|
||||
local type_a, type_e = type(actual), type(expected)
|
||||
|
||||
if type_a ~= type_e then
|
||||
return false
|
||||
|
||||
elseif (type_a == 'table') --[[and (type_e == 'table')]] then
|
||||
for _, v in pairs(actual) do
|
||||
if table_findkeyof(expected, v) == nil then
|
||||
return false -- v not contained in expected
|
||||
end
|
||||
end
|
||||
for _, v in pairs(expected) do
|
||||
if table_findkeyof(actual, v) == nil then
|
||||
return false -- v not contained in actual
|
||||
end
|
||||
end
|
||||
return true
|
||||
|
||||
elseif actual ~= expected then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
--- end
|
||||
|
||||
local function set_failure_message(state, message)
|
||||
if message ~= nil then
|
||||
state.failure_message = message
|
||||
end
|
||||
end
|
||||
|
||||
local function equal_items(state, arguments)
|
||||
if _is_table_items_equals(arguments[1], arguments[2]) then
|
||||
return true
|
||||
end
|
||||
set_failure_message(state, arguments[3])
|
||||
return false
|
||||
end
|
||||
|
||||
say:set_namespace("en")
|
||||
say:set("assertion.equal_items.positive",
|
||||
"Expected objects have same items.\nPassed in:\n%s\nExpected:\n%s")
|
||||
say:set("assertion.equal_items.negative",
|
||||
"Expected objects don't have same items.\nPassed in:\n%s\nDid not expect:\n%s")
|
||||
assert:register("assertion", "equal_items", equal_items,
|
||||
"assertion.equal_items.positive", "assertion.equal_items.negative")
|
@ -0,0 +1,140 @@
|
||||
--
|
||||
-- Copyright 2020 SipWise Team <development@sipwise.com>
|
||||
--
|
||||
-- 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 <http://www.gnu.org/licenses/>.
|
||||
-- .
|
||||
-- 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 bencode = require 'ngcp-klish.bencode'
|
||||
|
||||
local function msg_decode(received)
|
||||
local _,q = string.find(received, '^([^_]+_%d+)')
|
||||
local seq, message
|
||||
if q then
|
||||
seq = received:sub(1,q)
|
||||
message = received:sub(q+2)
|
||||
end
|
||||
return seq, assert(bencode.decode(message))
|
||||
end
|
||||
|
||||
local function msg_encode(seq, type, command, param)
|
||||
local message = {}
|
||||
message[type] = command
|
||||
if not param then param = {} end
|
||||
for k,v in pairs(param) do
|
||||
message[k]=v
|
||||
end
|
||||
message = assert(bencode.encode(message))
|
||||
return string.format('%s %s', seq, message)
|
||||
end
|
||||
|
||||
describe("helper functions", function()
|
||||
it("should encode", function()
|
||||
assert.same(
|
||||
'5323_1 d7:command4:pinge',
|
||||
msg_encode("5323_1", 'command', 'ping')
|
||||
)
|
||||
end)
|
||||
|
||||
it("should decode", function()
|
||||
local seq, msg = msg_decode('5323_1 d6:result4:ponge')
|
||||
assert.same('5323_1', seq)
|
||||
assert.same({result='pong'}, msg)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("rtpengine", function()
|
||||
local rtp, mp
|
||||
local socket
|
||||
|
||||
setup(function()
|
||||
end)
|
||||
|
||||
before_each(function()
|
||||
socket = {
|
||||
dns = {
|
||||
toip = true
|
||||
},
|
||||
udp = true
|
||||
}
|
||||
package.loaded['ngcp-klish.rtpengine'] = nil
|
||||
package.loaded.socket = nil
|
||||
package.preload['socket'] = function ()
|
||||
return socket
|
||||
end
|
||||
rtp = require("ngcp-klish.rtpengine")
|
||||
mp = rtp:new()
|
||||
end)
|
||||
|
||||
it("should provide uniq cookies", function()
|
||||
assert.same(tostring(mp._uniq).."_1", mp:cookie())
|
||||
assert.same(tostring(mp._uniq).."_2", mp:cookie())
|
||||
end)
|
||||
|
||||
it("should resolve host when server is called", function()
|
||||
socket.dns.toip = function(server)
|
||||
assert.same("fake.local", server)
|
||||
return "172.0.0.1"
|
||||
end
|
||||
assert.same('127.0.0.1', mp._ip)
|
||||
mp:server("fake.local")
|
||||
assert.same('172.0.0.1', mp._ip)
|
||||
end)
|
||||
|
||||
it("should have a default port", function()
|
||||
assert.same(2223, mp._port)
|
||||
end)
|
||||
|
||||
it("should support ping command", function()
|
||||
local cookie = tostring(mp._uniq).."_1"
|
||||
local message = msg_encode(cookie, 'command', 'ping')
|
||||
local response = msg_encode(cookie, 'result', 'pong')
|
||||
|
||||
local t = {
|
||||
sendto = function(_, msg, ip, port)
|
||||
assert.same(message, msg)
|
||||
assert.same(mp._ip, ip)
|
||||
assert.same(mp._port, port)
|
||||
return true
|
||||
end,
|
||||
receive = function(_) return(response) end
|
||||
}
|
||||
socket.udp = function() return t end
|
||||
assert.is_true(mp:ping())
|
||||
end)
|
||||
|
||||
it("should support query command", function()
|
||||
local cookie = tostring(mp._uniq).."_1"
|
||||
local param = {}
|
||||
param['call-id'] = 'callid1'
|
||||
local message = msg_encode(cookie, 'command', 'query', param)
|
||||
-- luacheck: ignore
|
||||
local respose_param = {created=1381997760,totals={input={rtcp={bytes=11054,packets=113,errors=0},rtp={bytes=3909179,packets=26195,errors=0}},output={rtcp={bytes=9048,packets=116,errors=0},rtp={bytes=0,packets=0,errors=0}}},streams={{{status="confirmed peer address",codec="unknown",stats={rtcp={counters={bytes=10976,packets=112,errors=0},["local port"]=30001,["advertised peer address"]={family="IPv4",port=50005,address="10.15.20.191"},["peer address"]={family="IPv4",port=50005,address="10.15.20.191"}},rtp={counters={bytes=3908936,packets=26194,errors=0},["local port"]=30000,["advertised peer address"]={family="IPv4",port=50004,address="10.15.20.191"},["peer address"]={family="IPv4",port=50004,address="10.15.20.191"}}},
|
||||
tag="callid1"},{status="known but unconfirmed peer address",stats={rtcp={counters={bytes=8970,packets=115,errors=0},["local port"]=30003,["advertised peer address"]={family="IPv4",port=50007,address="10.15.20.191"},["peer address"]={family="IPv4",port=50007,address="10.15.20.191"}},rtp={counters={bytes=0,packets=0,errors=0},["local port"]=30002,["advertised peer address"]={family="IPv4",port=50006,address="10.15.20.191"},["peer address"]={family="IPv4",port=50006,address="10.15.20.191"}}},tag="7A4FE68B-525F9CC000060653-E28A0700"}},{{status="known but unconfirmed peer address",codec="unknown",stats={rtcp={counters={bytes=78,packets=1,errors=0},["local port"]=0,["advertised peer address"]={family="IPv6",port=0,address="::"},["peer address"]={family="IPv6",port=0,address="::"}},rtp={counters={bytes=243,packets=1,errors=0},["local port"]=0,["advertised peer address"]={family="IPv6",port=0,address="::"},["peer address"]={family="IPv6",port=0,address="::"}}},tag=""},{status="known but unconfirmed peer address",stats={rtcp={counters={bytes=78,packets=1,errors=0},["local port"]=0,["advertised peer address"]={family="IPv6",port=0,address="::"},["peer address"]={family="IPv6",port=0,address="::"}},rtp={counters={bytes=0,packets=0,errors=0},["local port"]=0,["advertised peer address"]={family="IPv6",port=0,address="::"},["peer address"]={family="IPv6",port=0,address="::"}}},tag=""}}}}
|
||||
local response = msg_encode(cookie, 'result', 'ok', respose_param)
|
||||
|
||||
local t = {
|
||||
sendto = function(_, msg, ip, port)
|
||||
assert.same(message, msg)
|
||||
assert.same(mp._ip, ip)
|
||||
assert.same(mp._port, port)
|
||||
return true
|
||||
end,
|
||||
receive = function(_) return(response) end
|
||||
}
|
||||
socket.udp = function() return t end
|
||||
assert.same('ok', mp:query('callid1').result)
|
||||
end)
|
||||
end)
|
@ -0,0 +1,172 @@
|
||||
--
|
||||
-- Copyright 2020 SipWise Team <development@sipwise.com>
|
||||
--
|
||||
-- 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 <http://www.gnu.org/licenses/>.
|
||||
-- .
|
||||
-- On Debian systems, the complete text of the GNU General
|
||||
-- Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
--
|
||||
|
||||
describe("utils", function()
|
||||
local ut
|
||||
local simple_hash
|
||||
local simple_list
|
||||
local complex_hash
|
||||
|
||||
setup(function()
|
||||
ut = require("ngcp-klish.utils")
|
||||
end)
|
||||
|
||||
before_each(function()
|
||||
simple_hash = {
|
||||
one = 1, two = 2, three = 3
|
||||
}
|
||||
simple_list = {
|
||||
1, 2, 3
|
||||
}
|
||||
complex_hash = {
|
||||
cone = simple_list,
|
||||
ctwo = simple_hash
|
||||
}
|
||||
end)
|
||||
|
||||
describe("table", function()
|
||||
it("deepcopy", function()
|
||||
local res = ut.table.deepcopy(simple_hash)
|
||||
assert.same(res, simple_hash)
|
||||
assert.is_not(res, simple_hash)
|
||||
end)
|
||||
|
||||
it("contains should find the value", function()
|
||||
assert.True(ut.table.contains(simple_hash, 3))
|
||||
end)
|
||||
|
||||
it("contains should not find the value", function()
|
||||
assert.False(ut.table.contains(simple_hash, 4))
|
||||
end)
|
||||
|
||||
it("contains should not find anything in nil", function()
|
||||
assert.False(ut.table.contains(nil))
|
||||
end)
|
||||
|
||||
it("contains should throw an error with a string", function()
|
||||
local f = function()
|
||||
ut.table.contains("hola", 1)
|
||||
end
|
||||
assert.has_error(f,
|
||||
"bad argument #1 to 'pairs' (table expected, got string)")
|
||||
end)
|
||||
|
||||
it("add", function ()
|
||||
assert.same(simple_list, {1,2,3})
|
||||
ut.table.add(simple_list, 1)
|
||||
assert.same(simple_list, {1,2,3})
|
||||
ut.table.add(simple_list, 5)
|
||||
assert.same(simple_list, {1,2,3,5})
|
||||
ut.table.add(simple_list, 4)
|
||||
assert.same(simple_list, {1,2,3,5,4})
|
||||
end)
|
||||
|
||||
it("tostring", function()
|
||||
local f = function()
|
||||
ut.table.tostring("nil")
|
||||
end
|
||||
assert.has_error(f)
|
||||
assert.same(ut.table.tostring(simple_list), "{1,2,3}")
|
||||
assert.not_nil(ut.table.tostring(simple_hash))
|
||||
assert.not_nil(ut.table.tostring(complex_hash))
|
||||
end)
|
||||
end) -- end table
|
||||
|
||||
it("implode", function()
|
||||
assert.same(ut.implode(',', simple_list, "'"), "'1','2','3'")
|
||||
end)
|
||||
|
||||
it("implode should error with nil string", function()
|
||||
local f = function()
|
||||
ut.implode(nil, simple_list, "'")
|
||||
end
|
||||
assert.has_error(f)
|
||||
end)
|
||||
|
||||
it("implode should error with nil table", function()
|
||||
local f = function()
|
||||
ut.implode(',', nil, "'")
|
||||
end
|
||||
assert.has_error(f)
|
||||
end)
|
||||
|
||||
it("explode", function()
|
||||
assert.equal_items(ut.explode(',',"1,2,3"), {'1','2','3'})
|
||||
assert.equal_items(ut.explode('=>',"1=>2=>3"), {'1','2','3'})
|
||||
end)
|
||||
|
||||
describe("string", function()
|
||||
|
||||
it("starts should error with nil", function()
|
||||
local f = function()
|
||||
ut.string.stats(nil, "g")
|
||||
end
|
||||
assert.has_error(f)
|
||||
assert.has_error(function() ut.string.stats("goga", nil) end)
|
||||
end)
|
||||
|
||||
it("starts", function()
|
||||
assert.True(ut.string.starts("goga", "g"))
|
||||
assert.True(ut.string.starts("goga", "go"))
|
||||
assert.True(ut.string.starts("goga", "gog"))
|
||||
assert.True(ut.string.starts("goga", "goga"))
|
||||
assert.False(ut.string.starts("goga", "a"))
|
||||
assert.True(ut.string.starts("$goga", "$"))
|
||||
assert.True(ut.string.starts("(goga)", "("))
|
||||
end)
|
||||
|
||||
it("ends should error with nil", function()
|
||||
assert.has_error(function() ut.string.ends(nil, "g") end)
|
||||
assert.has_error(function() ut.string.ends("goga", nil) end)
|
||||
end)
|
||||
|
||||
it("ends", function()
|
||||
assert.True(ut.string.ends("goga", "a"))
|
||||
assert.True(ut.string.ends("goga", "ga"))
|
||||
assert.True(ut.string.ends("goga", "oga"))
|
||||
assert.True(ut.string.ends("goga", "goga"))
|
||||
assert.False(ut.string.ends("goga", "f"))
|
||||
end)
|
||||
end) -- end string
|
||||
|
||||
describe("uri_get_username", function()
|
||||
it("should wotk with dns", function()
|
||||
assert.same(
|
||||
'vseva',
|
||||
ut.uri_get_username('sip:vseva@fake.local')
|
||||
)
|
||||
end)
|
||||
|
||||
it("should wotk with ipv4", function()
|
||||
assert.same(
|
||||
'vseva',
|
||||
ut.uri_get_username('sip:vseva@127.0.0.1:50602')
|
||||
)
|
||||
end)
|
||||
|
||||
it("should wotk with ipv6", function()
|
||||
local t = 'sip:vseva@[2620:0:2ef0:7070:250:60ff:fe03:32b7]:5060;transport=tcp'
|
||||
assert.same(
|
||||
'vseva',
|
||||
ut.uri_get_username(t)
|
||||
)
|
||||
end)
|
||||
end)
|
||||
end)
|
@ -1,57 +0,0 @@
|
||||
--
|
||||
-- Copyright 2013 SipWise Team <development@sipwise.com>
|
||||
--
|
||||
-- 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 <http://www.gnu.org/licenses/>.
|
||||
-- .
|
||||
-- On Debian systems, the complete text of the GNU General
|
||||
-- Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
--
|
||||
require 'luaunit'
|
||||
require 'ngcp-klish.bencode'
|
||||
|
||||
Test = {}
|
||||
function Test:test_encode_number()
|
||||
assertEquals(bencode.encode(345), 'i345e')
|
||||
end
|
||||
|
||||
function Test:test_encode_string()
|
||||
assertEquals(bencode.encode('g5323_1'), '7:g5323_1')
|
||||
end
|
||||
|
||||
function Test:test_encode_list()
|
||||
assertEquals(bencode.encode({1,2,3}),
|
||||
'li1ei2ei3ee')
|
||||
end
|
||||
|
||||
function Test:test_encode_dict()
|
||||
assertEquals(bencode.encode({uno=1,dos=2,tres='three'}),
|
||||
'd3:dosi2e4:tres5:three3:unoi1ee')
|
||||
end
|
||||
|
||||
function Test:test_decode_number()
|
||||
assertEquals(bencode.decode('i345e'), 345)
|
||||
end
|
||||
|
||||
function Test:test_decode_string()
|
||||
assertEquals(bencode.decode('7:g5323_1'), 'g5323_1')
|
||||
end
|
||||
|
||||
function Test:test_decode_list()
|
||||
assertEquals(bencode.decode('li1ei2ei3ee'), {1,2,3})
|
||||
end
|
||||
|
||||
function Test:test_decode_dict()
|
||||
assertEquals(bencode.decode('d3:dosi2e4:tres5:three3:unoi1ee'),
|
||||
{uno=1,dos=2,tres='three'})
|
||||
end
|
@ -1,130 +0,0 @@
|
||||
--
|
||||
-- Copyright 2013 SipWise Team <development@sipwise.com>
|
||||
--
|
||||
-- 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 <http://www.gnu.org/licenses/>.
|
||||
-- .
|
||||
-- On Debian systems, the complete text of the GNU General
|
||||
-- Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
--
|
||||
require 'luaunit'
|
||||
require 'lemock'
|
||||
require 'ngcp-klish.bencode'
|
||||
|
||||
local mc, udp, socket
|
||||
local MP
|
||||
|
||||
local function msg_decode(received)
|
||||
local _,q = string.find(received, '^([^_]+_%d+)')
|
||||
local seq, message
|
||||
if q then
|
||||
seq = received:sub(1,q)
|
||||
message = received:sub(q+2)
|
||||
end
|
||||
return seq, assert(bencode.decode(message))
|
||||
end
|
||||
|
||||
local function msg_encode(seq, type, command, param)
|
||||
local message = {}
|
||||
message[type] = command
|
||||
if not param then param = {} end
|
||||
for k,v in pairs(param) do
|
||||
message[k]=v
|
||||
end
|
||||
message = assert(bencode.encode(message))
|
||||
return string.format('%s %s', seq, message)
|
||||
end
|
||||
|
||||
Test = {}
|
||||
function Test:test_encode()
|
||||
assertEquals('5323_1 d7:command4:pinge',
|
||||
msg_encode("5323_1", 'command', 'ping'))
|
||||
end
|
||||
|
||||
function Test:test_decode()
|
||||
local seq, msg = msg_decode('5323_1 d6:result4:ponge')
|
||||
assertEquals(seq, '5323_1')
|
||||
assertEquals(msg, {result='pong'})
|
||||
end
|
||||
|
||||
TestMP = {}
|
||||
function TestMP:setUp()
|
||||
mc = lemock.controller()
|
||||
udp = mc:mock()
|
||||
socket = {
|
||||
dns={ toip=mc:mock() },
|
||||
udp= udp
|
||||
}
|
||||
package.loaded['ngcp-klish.rtpengine'] = nil
|
||||
package.loaded.socket = nil
|
||||
package.preload['socket'] = function ()
|
||||
return socket
|
||||
end
|
||||
MP = require 'ngcp-klish.rtpengine'
|
||||
self.mp = MP:new()
|
||||
end
|
||||
|
||||
function TestMP:test()
|
||||
assertEquals(self.mp:cookie(), tostring(self.mp._uniq).."_1")
|
||||
assertEquals(self.mp:cookie(), tostring(self.mp._uniq).."_2")
|
||||
end
|
||||
|
||||
function TestMP:test_host()
|
||||
-- default
|
||||
assertEquals(self.mp._ip, '127.0.0.1')
|
||||
|
||||
socket.dns.toip('localhost') ;mc :returns('127.0.0.1')
|
||||
mc:replay()
|
||||
self.mp:server('localhost')
|
||||
mc:verify()
|
||||
assertEquals(self.mp._ip, '127.0.0.1')
|
||||
end
|
||||
|
||||
function TestMP:test_port()
|
||||
-- default
|
||||
assertEquals(self.mp._port, 2223)
|
||||
end
|
||||
|
||||
function TestMP:test_ping()
|
||||
local cookie = tostring(self.mp._uniq).."_1"
|
||||
local message = msg_encode(cookie, 'command', 'ping')
|
||||
local response = msg_encode(cookie, 'result', 'pong')
|
||||
|
||||
socket.udp() ;mc :returns(udp)
|
||||
udp:sendto(message, self.mp._ip, self.mp._port) ;mc :returns(true)
|
||||
udp:receive() ;mc :returns(response)
|
||||
|
||||
mc:replay()
|
||||
local res = self.mp:ping()
|
||||
mc:verify()
|
||||
assertTrue(res)
|
||||
end
|
||||
|
||||
function TestMP:test_query()
|
||||
local cookie = tostring(self.mp._uniq).."_1"
|
||||
local param = {}
|
||||
param['call-id'] = 'callid1'
|
||||
local message = msg_encode(cookie, 'command', 'query', param)
|
||||
local respose_param = {created=1381997760,totals={input={rtcp={bytes=11054,packets=113,errors=0},rtp={bytes=3909179,packets=26195,errors=0}},output={rtcp={bytes=9048,packets=116,errors=0},rtp={bytes=0,packets=0,errors=0}}},streams={{{status="confirmed peer address",codec="unknown",stats={rtcp={counters={bytes=10976,packets=112,errors=0},["local port"]=30001,["advertised peer address"]={family="IPv4",port=50005,address="10.15.20.191"},["peer address"]={family="IPv4",port=50005,address="10.15.20.191"}},rtp={counters={bytes=3908936,packets=26194,errors=0},["local port"]=30000,["advertised peer address"]={family="IPv4",port=50004,address="10.15.20.191"},["peer address"]={family="IPv4",port=50004,address="10.15.20.191"}}},
|
||||
tag="callid1"},{status="known but unconfirmed peer address",stats={rtcp={counters={bytes=8970,packets=115,errors=0},["local port"]=30003,["advertised peer address"]={family="IPv4",port=50007,address="10.15.20.191"},["peer address"]={family="IPv4",port=50007,address="10.15.20.191"}},rtp={counters={bytes=0,packets=0,errors=0},["local port"]=30002,["advertised peer address"]={family="IPv4",port=50006,address="10.15.20.191"},["peer address"]={family="IPv4",port=50006,address="10.15.20.191"}}},tag="7A4FE68B-525F9CC000060653-E28A0700"}},{{status="known but unconfirmed peer address",codec="unknown",stats={rtcp={counters={bytes=78,packets=1,errors=0},["local port"]=0,["advertised peer address"]={family="IPv6",port=0,address="::"},["peer address"]={family="IPv6",port=0,address="::"}},rtp={counters={bytes=243,packets=1,errors=0},["local port"]=0,["advertised peer address"]={family="IPv6",port=0,address="::"},["peer address"]={family="IPv6",port=0,address="::"}}},tag=""},{status="known but unconfirmed peer address",stats={rtcp={counters={bytes=78,packets=1,errors=0},["local port"]=0,["advertised peer address"]={family="IPv6",port=0,address="::"},["peer address"]={family="IPv6",port=0,address="::"}},rtp={counters={bytes=0,packets=0,errors=0},["local port"]=0,["advertised peer address"]={family="IPv6",port=0,address="::"},["peer address"]={family="IPv6",port=0,address="::"}}},tag=""}}}}
|
||||
local response = msg_encode(cookie, 'result', 'ok', respose_param)
|
||||
|
||||
socket.udp() ;mc :returns(udp)
|
||||
udp:sendto(message, self.mp._ip, self.mp._port) ;mc :returns(true)
|
||||
udp:receive() ;mc :returns(response)
|
||||
|
||||
mc:replay()
|
||||
local res = self.mp:query('callid1')
|
||||
mc:verify()
|
||||
assertEquals(res.result,'ok')
|
||||
end
|
@ -1,94 +1,19 @@
|
||||
#!/bin/bash
|
||||
set -u
|
||||
# This script is used for running the tests with proper arguments
|
||||
# from within Jenkins
|
||||
|
||||
PASS=0
|
||||
FAIL=0
|
||||
ID=0
|
||||
LUA=${LUA:-lua5.1}
|
||||
RESULTS=${RESULTS:-./results}
|
||||
set -e
|
||||
set -u
|
||||
set -x
|
||||
|
||||
if [ -d /results ]; then
|
||||
if [ -d /results ] ; then
|
||||
# Running from Jenkins (RW)
|
||||
RESULTS="/results"
|
||||
FORMAT=JUNIT
|
||||
cd "/code"
|
||||
else
|
||||
# Running locally in Docker
|
||||
FORMAT=TAP
|
||||
RESULTS="./results"
|
||||
mkdir -p "${RESULTS}"
|
||||
fi
|
||||
|
||||
case ${FORMAT} in
|
||||
TAP) EXT=tap; OUT_FORCE=true ;;
|
||||
JUNIT) EXT=xml; OUT_FORCE=false ;;
|
||||
TEXT) EXT=txt; OUT_FORCE=true ;;
|
||||
*) echo "ERROR: Unknown format ${FORMAT}"; exit 1 ;;
|
||||
esac
|
||||
|
||||
# unique id across files
|
||||
# See TT#4590
|
||||
function fix_id() {
|
||||
(( ID += 1))
|
||||
local tmp_id
|
||||
tmp_id=$(printf "%05d\\n" "$ID")
|
||||
sed -i "s/id=\"00001\"/id=\"$tmp_id\"/" "$1"
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
local tmpfile=$1
|
||||
local output=$2
|
||||
|
||||
if ${OUT_FORCE} ; then
|
||||
${LUA} - <"${tmpfile}" > "${output}"
|
||||
else
|
||||
${LUA} - --name "${output}" <"${tmpfile}"
|
||||
fi
|
||||
return $?
|
||||
}
|
||||
|
||||
function do_test() {
|
||||
local name="$1"
|
||||
local RES="${RESULTS}/${name}.${EXT}"
|
||||
|
||||
local tmpfile
|
||||
tmpfile=$(mktemp)
|
||||
|
||||
echo -n "testing ${name} -> ${RES}:"
|
||||
cat >"${tmpfile}" <<EOF
|
||||
EXPORT_ASSERT_TO_GLOBALS = true
|
||||
require "t/${name}"
|
||||
---- Control test output:
|
||||
local lu = LuaUnit
|
||||
lu:setOutputType('${FORMAT}')
|
||||
os.exit(lu:run())
|
||||
EOF
|
||||
|
||||
if run_test "${tmpfile}" "${RES}"; then
|
||||
((PASS++))
|
||||
echo "OK"
|
||||
else
|
||||
((FAIL++))
|
||||
echo "FAIL"
|
||||
fi
|
||||
|
||||
if [[ "${FORMAT}" == JUNIT ]] ; then
|
||||
fix_id "${RES}"
|
||||
fi
|
||||
rm -f "${tmpfile}"
|
||||
}
|
||||
|
||||
rm -rf "${RESULTS:-./results}"/*
|
||||
|
||||
if [[ -z "$*" ]]; then
|
||||
mapfile -t TESTS < <(find t -name '*.lua' -exec basename {} .lua \;)
|
||||
for t in "${TESTS[@]}"; do
|
||||
do_test "$t"
|
||||
done
|
||||
else
|
||||
for t in "${@}"; do
|
||||
do_test "$(basename "${t}" .lua)"
|
||||
done
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Finished test execution: ${PASS} passed, ${FAIL} failed"
|
||||
echo "Test results available at ${RESULTS}"
|
||||
busted -o junit > ${RESULTS}/test_busted.xml
|
||||
|
@ -1,31 +0,0 @@
|
||||
--
|
||||
-- Copyright 2013 SipWise Team <development@sipwise.com>
|
||||
--
|
||||
-- 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 <http://www.gnu.org/licenses/>.
|
||||
-- .
|
||||
-- On Debian systems, the complete text of the GNU General
|
||||
-- Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
--
|
||||
require('luaunit')
|
||||
local URI = require "uri"
|
||||
|
||||
TestUri = {}
|
||||
function TestUri:test()
|
||||
local u = URI:new('sip:username1:password@domain.com:5080;user=phone?header1=value1&header2=value2')
|
||||
assertEquals(u:username(), 'username1')
|
||||
assertEquals(u:port(), 5080)
|
||||
assertEquals(u:host(), 'domain.com')
|
||||
assertEquals(u:fragment(), 'user=phone')
|
||||
assertEquals(u:query(), 'header1=value1&header2=value2')
|
||||
end
|
@ -1,223 +0,0 @@
|
||||
--
|
||||
-- Copyright 2013 SipWise Team <development@sipwise.com>
|
||||
--
|
||||
-- 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 <http://www.gnu.org/licenses/>.
|
||||
-- .
|
||||
-- On Debian systems, the complete text of the GNU General
|
||||
-- Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
--
|
||||
require('luaunit')
|
||||
require 'ngcp-klish.utils'
|
||||
|
||||
TestUtils = {} --class
|
||||
|
||||
function TestUtils:setUp()
|
||||
self.simple_hash = {
|
||||
one = 1, two = 2, three = 3
|
||||
}
|
||||
self.simple_list = {
|
||||
1, 2, 3
|
||||
}
|
||||
self.complex_hash = {
|
||||
cone = self.simple_list,
|
||||
ctwo = self.simple_hash
|
||||
}
|
||||
end
|
||||
|
||||
function TestUtils:test_table_deepcopy()
|
||||
assertNotIs(table.deepcopy(self.simple_hash), self.simple_hash)
|
||||
-- if the parameter is not a table... it has to be the same
|
||||
assertIs(table.deepcopy("hola"), "hola")
|
||||
end
|
||||
|
||||
function TestUtils:test_table_contains()
|
||||
assertTrue(table.contains(self.simple_hash, 3))
|
||||
assertFalse(table.contains(self.simple_hash, 4))
|
||||
assertFalse(table.contains(nil))
|
||||
assertError(table.contains, "hola",1)
|
||||
end
|
||||
|
||||
function TestUtils:test_table_add()
|
||||
assertEquals(self.simple_list, {1,2,3})
|
||||
table.add(self.simple_list, 1)
|
||||
assertEquals(self.simple_list, {1,2,3})
|
||||
table.add(self.simple_list, 5)
|
||||
assertEquals(self.simple_list, {1,2,3,5})
|
||||
table.add(self.simple_list, 4)
|
||||
assertEquals(self.simple_list, {1,2,3,5,4})
|
||||
end
|
||||
|
||||
function TestUtils:test_table_tostring()
|
||||
assertError(table.tostring,nil)
|
||||
assertEquals(table.tostring(self.simple_list), "{1,2,3}")
|
||||
assertTrue(table.tostring(self.simple_hash))
|
||||
--print(table.tostring(self.simple_hash) .. "\n")
|
||||
assertTrue(table.tostring(self.complex_hash))
|
||||
--print(table.tostring(self.complex_hash))
|
||||
end
|
||||
|
||||
function TestUtils:test_implode()
|
||||
assertEquals(implode(',', self.simple_list, "'"), "'1','2','3'")
|
||||
assertError(implode, nil, self.simple_list, "'")
|
||||
assertError(implode, ',', nil, "'")
|
||||
end
|
||||
|
||||
function TestUtils:test_explode()
|
||||
assertItemsEquals(explode(',',"1,2,3"), {'1','2','3'})
|
||||
assertItemsEquals(explode('=>',"1=>2=>3"), {'1','2','3'})
|
||||
end
|
||||
|
||||
function TestUtils:test_starts()
|
||||
assertError(string.stats, nil, "g")
|
||||
assertTrue(string.starts("goga", "g"))
|
||||
assertTrue(string.starts("goga", "go"))
|
||||
assertTrue(string.starts("goga", "gog"))
|
||||
assertTrue(string.starts("goga", "goga"))
|
||||
assertFalse(string.starts("goga", "a"))
|
||||
assertError(string.starts, "goga", nil)
|
||||
assertTrue(string.starts("$goga", "$"))
|
||||
assertTrue(string.starts("(goga)", "("))
|
||||
end
|
||||
|
||||
function TestUtils:test_ends()
|
||||
assertError(string.ends, nil, "g")
|
||||
assertTrue(string.ends("goga", "a"))
|
||||
assertTrue(string.ends("goga", "ga"))
|
||||
assertTrue(string.ends("goga", "oga"))
|
||||
assertTrue(string.ends("goga", "goga"))
|
||||
assertFalse(string.ends("goga", "f"))
|
||||
assertError(string.ends, "goga", nil)
|
||||
end
|
||||
-- class TestUtils
|
||||
|
||||
TestStack = {}
|
||||
function TestStack:test()
|
||||
local s = Stack:new()
|
||||
assertEquals(type(s), 'table')
|
||||
assertEquals(s.__class__, 'Stack')
|
||||
end
|
||||
|
||||
function TestStack:test_size()
|
||||
local s = Stack:new()
|
||||
assertEquals(s:size(),0)
|
||||
s:push(1)
|
||||
assertEquals(s:size(),1)
|
||||
s:pop()
|
||||
assertEquals(s:size(),0)
|
||||
end
|
||||
|
||||
function TestStack:test_push()
|
||||
local s s = Stack:new()
|
||||
s:push(1)
|
||||
assertEquals(s:size(),1)
|
||||
end
|
||||
|
||||
function TestStack:test_pop()
|
||||
local s = Stack:new()
|
||||
assertEquals(s:pop(), nil)
|
||||
s:push(1)
|
||||
assertEquals(s:size(),1)
|
||||
assertEquals(s:pop(),1)
|
||||
assertEquals(s:size(),0)
|
||||
end
|
||||
|
||||
function TestStack:test_get()
|
||||
local s = Stack:new()
|
||||
s:push(1)
|
||||
assertEquals(s:get(0),1)
|
||||
s:push({1,2,3})
|
||||
assertEquals(s:get(0),{1,2,3})
|
||||
assertEquals(s:get(1),1)
|
||||
assertError(s.get, s, -1)
|
||||
assertIsNil(s:get(2))
|
||||
end
|
||||
|
||||
function TestStack:test_get_op()
|
||||
local s = Stack:new()
|
||||
s:push(1)
|
||||
assertEquals(s[0],1)
|
||||
s:push({1,2,3})
|
||||
assertEquals(s[0],{1,2,3})
|
||||
assertEquals(s[1],1)
|
||||
assertIsNil(s[2])
|
||||
end
|
||||
|
||||
function TestStack:test_set()
|
||||
local s = Stack:new()
|
||||
s:push(1)
|
||||
s:push({1,2,3})
|
||||
assertEquals(s:size(),2)
|
||||
assertEquals(s:get(0),{1,2,3})
|
||||
assertEquals(s:get(1),1)
|
||||
s:set(1, 2)
|
||||
assertEquals(s:size(),2)
|
||||
assertEquals(s:get(0),{1,2,3})
|
||||
assertEquals(s:get(1),2)
|
||||
s:set(2, 3)
|
||||
assertEquals(s:size(),2)
|
||||
assertEquals(s:get(0),{1,2,3})
|
||||
assertEquals(s:get(1),2)
|
||||
assertIsNil(s:get(2))
|
||||
assertError(s.set, s, "no", -1)
|
||||
assertError(s.set, s, -1, 2)
|
||||
end
|
||||
|
||||
function TestStack:test_set_op()
|
||||
local s = Stack:new()
|
||||
s:push(1)
|
||||
s:push({1,2,3})
|
||||
assertEquals(s:size(),2)
|
||||
assertEquals(s:get(0),{1,2,3})
|
||||
assertEquals(s:get(1),1)
|
||||
s[1] = 2
|
||||
assertEquals(s:size(),2)
|
||||
assertEquals(s:get(0),{1,2,3})
|
||||
assertEquals(s:get(1),2)
|
||||
s[0] = "new"
|
||||
assertEquals(s:size(),2)
|
||||
assertEquals(s:get(0),"new")
|
||||
assertEquals(s:get(1),2)
|
||||
s[1] = "old"
|
||||
assertEquals(s:get(0),"new")
|
||||
assertEquals(s:get(1),"old")
|
||||
assertEquals(s:size(),2)
|
||||
s[2] = "error"
|
||||
assertEquals(s:get(0),"new")
|
||||
assertEquals(s:get(1),"old")
|
||||
assertIsNil(s:get(2))
|
||||
assertEquals(s:size(),2)
|
||||
end
|
||||
|
||||
function TestStack:test_list()
|
||||
local s = Stack:new()
|
||||
local l = s:list()
|
||||
assertEquals(#l, 0)
|
||||
s:push(1)
|
||||
s:push({1,2,3})
|
||||
assertEquals(s:size(),2)
|
||||
l = s:list()
|
||||
assertItemsEquals(l[1],{1,2,3})
|
||||
assertEquals(l[2],1)
|
||||
assertEquals(s:size(),2)
|
||||
end
|
||||
|
||||
function TestStack:test_tostring()
|
||||
local s = Stack:new()
|
||||
s:push(1)
|
||||
assertEquals(tostring(s), "{1}")
|
||||
s:push(2)
|
||||
assertEquals(tostring(s), "{2,1}")
|
||||
end
|
||||
-- class TestStack
|
||||
--EOF
|
Loading…
Reference in new issue