216 lines
7.9 KiB
Lua
216 lines
7.9 KiB
Lua
-- SPDX-License-Identifier: GPL-3.0-or-later
|
|
-- check prerequisites
|
|
local has_http = pcall(require, 'kres_modules.http') and pcall(require, 'http.request')
|
|
if not has_http then
|
|
-- skipping daf module test because http its not installed
|
|
os.exit(77)
|
|
else
|
|
local path = worker.cwd..'/control/'..worker.pid
|
|
same(true, net.listen(path, nil, {kind = 'control'}),
|
|
'new control sockets were created so map() can work')
|
|
|
|
local request = require('http.request')
|
|
|
|
modules.load('http')
|
|
modules.load('daf')
|
|
|
|
local bound
|
|
for _ = 1,1000 do
|
|
bound, _err = pcall(net.listen, '127.0.0.1', math.random(40000, 49999), { kind = 'webmgmt'})
|
|
if bound then
|
|
break
|
|
end
|
|
end
|
|
assert(bound, 'unable to bind a port for HTTP module (1000 attempts)')
|
|
|
|
-- globals for this module
|
|
local _, host, port, baseuri
|
|
local function start_server()
|
|
local server_fd = next(http.servers)
|
|
assert(server_fd)
|
|
local server = http.servers[server_fd].server
|
|
ok(server ~= nil, 'creates server instance')
|
|
_, host, port = server:localname()
|
|
ok(host and port, 'binds to an interface')
|
|
baseuri = string.format('http://%s:%d/daf', host, port)
|
|
end
|
|
|
|
-- helper for returning useful values to test on
|
|
-- local function http_get(uri)
|
|
-- local headers, stream = assert(request.new_from_uri(uri):go(16))
|
|
-- local body = assert(stream:get_body_as_string())
|
|
-- return tonumber(headers:get(':status')), body, headers:get('content-type')
|
|
-- end
|
|
|
|
local function http_req(uri, method, reqbody)
|
|
local req = assert(request.new_from_uri(baseuri .. uri))
|
|
req.headers:upsert(':method', method)
|
|
req:set_body(reqbody)
|
|
local headers, stream = assert(req:go(16))
|
|
local ansbody = assert(stream:get_body_as_string())
|
|
return tonumber(headers:get(':status')), ansbody, headers:get('content-type')
|
|
end
|
|
|
|
local function http_get(uri)
|
|
return http_req(uri, 'GET')
|
|
end
|
|
|
|
-- compare two tables, expected value is specified as JSON
|
|
-- comparison relies on table_print which sorts table keys
|
|
local function compare_tables(expectedjson, gotjson, desc)
|
|
same(
|
|
table_print(fromjson(expectedjson)),
|
|
table_print(fromjson(gotjson)),
|
|
desc)
|
|
end
|
|
|
|
-- test whether http interface responds and binds
|
|
local function test_daf_api()
|
|
local code, body, mime
|
|
-- rule listing /daf
|
|
code, body, mime = http_get('/')
|
|
same(code, 200, 'rule listing return 200 OK')
|
|
same(body, '{}', 'daf rule list is empty after start')
|
|
same(mime, 'application/json', 'daf rule list has application/json content type')
|
|
-- get non-existing rule
|
|
code, body = http_req('/0', 'GET')
|
|
same(code, 404, 'non-existing rule retrieval returns 404')
|
|
same(body, '"No such rule"', 'explanatory message is present')
|
|
|
|
-- delete non-existing rule
|
|
code, body = http_req('/0', 'DELETE')
|
|
same(code, 404, 'non-existing rule deletion returns 404')
|
|
same(body, '"No such rule"', 'explanatory message is present')
|
|
|
|
-- bad PATCH
|
|
code = http_req('/0', 'PATCH')
|
|
same(code, 400, 'PATCH detects missing parameters')
|
|
|
|
-- bad POST
|
|
code = http_req('/', 'POST')
|
|
same(code, 500, 'POST without parameters is detected')
|
|
|
|
-- POST first new rule
|
|
code, body, mime = http_req('/', 'POST', 'src = 192.0.2.0 pass')
|
|
same(code, 200, 'first POST succeeds')
|
|
compare_tables(body,
|
|
'{"count":0,"active":true,"id":0,"info":"src = 192.0.2.0 pass"}',
|
|
'POST returns new rule in JSON')
|
|
same(mime, 'application/json', 'rule has application/json content type')
|
|
|
|
-- GET first rule
|
|
code, body, mime = http_req('/0', 'GET')
|
|
same(code, 200, 'GET for first rule succeeds')
|
|
compare_tables(body,
|
|
'{"count":0,"active":true,"id":0,"info":"src = 192.0.2.0 pass"}',
|
|
'POST returns new rule in JSON')
|
|
same(mime, 'application/json', 'rule has application/json content type')
|
|
|
|
-- POST second new rule
|
|
code, body, mime = http_req('/', 'POST', 'src = 192.0.2.1 pass')
|
|
same(code, 200, 'second POST succeeds')
|
|
compare_tables(body,
|
|
'{"count":0,"active":true,"id":1,"info":"src = 192.0.2.1 pass"}',
|
|
'POST returns new rule in JSON')
|
|
same(mime, 'application/json', 'rule has application/json content type')
|
|
|
|
-- GET second rule
|
|
code, body, mime = http_req('/1', 'GET')
|
|
same(code, 200, 'GET for second rule succeeds')
|
|
compare_tables(body,
|
|
'{"count":0,"active":true,"id":1,"info":"src = 192.0.2.1 pass"}',
|
|
'POST returns new rule in JSON')
|
|
same(mime, 'application/json', 'rule has application/json content type')
|
|
|
|
-- PATCH first rule
|
|
code, body, mime = http_req('/0/active/false', 'PATCH')
|
|
same(code, 200, 'PATCH for first rule succeeds')
|
|
same(body, 'true', 'PATCH returns success in body')
|
|
same(mime, 'application/json', 'PATCH return value has application/json content type')
|
|
|
|
-- GET modified first rule
|
|
code, body, mime = http_req('/0', 'GET')
|
|
same(code, 200, 'GET for first rule succeeds')
|
|
compare_tables(body,
|
|
'{"count":0,"active":false,"id":0,"info":"src = 192.0.2.0 pass"}',
|
|
'GET returns modified rule in JSON')
|
|
same(mime, 'application/json', 'rule has application/json content type')
|
|
|
|
-- GET both rules
|
|
code, body, mime = http_req('/', 'GET')
|
|
same(code, 200, 'GET for both rule succeeds')
|
|
compare_tables(body, [[
|
|
[
|
|
{"count":0,"active":false,"info":"src = 192.0.2.0 pass","id":0},
|
|
{"count":0,"active":true,"info":"src = 192.0.2.1 pass","id":1}]
|
|
]],
|
|
'GET returns both rules in JSON including modifications')
|
|
same(mime, 'application/json', 'rule list has application/json content type')
|
|
|
|
-- PATCH first rule back to original state
|
|
code, body, mime = http_req('/0/active/true', 'PATCH')
|
|
same(code, 200, 'PATCH for first rule succeeds')
|
|
same(body, 'true', 'PATCH returns success in body')
|
|
same(mime, 'application/json', 'PATCH return value has application/json content type')
|
|
|
|
-- GET modified (reversed) first rule
|
|
code, body, mime = http_req('/0', 'GET')
|
|
same(code, 200, 'GET for first rule succeeds')
|
|
compare_tables(body,
|
|
'{"count":0,"active":true,"id":0,"info":"src = 192.0.2.0 pass"}',
|
|
'GET returns modified rule in JSON')
|
|
same(mime, 'application/json', 'rule has application/json content type')
|
|
|
|
-- DELETE first rule
|
|
code, body, mime = http_req('/0', 'DELETE')
|
|
same(code, 200, 'DELETE for first rule succeeds')
|
|
same(body, 'true', 'DELETE returns success in body')
|
|
same(mime, 'application/json', 'DELETE return value has application/json content type')
|
|
|
|
-- GET deleted (first) rule
|
|
code, body = http_req('/0', 'GET')
|
|
same(code, 404, 'GET for deleted fails with 404')
|
|
same(body, '"No such rule"', 'failed GET contains explanatory message')
|
|
|
|
-- GET second rule
|
|
code, body, mime = http_req('/1', 'GET')
|
|
same(code, 200, 'GET for second rule still succeeds')
|
|
compare_tables(body,
|
|
'{"count":0,"active":true,"id":1,"info":"src = 192.0.2.1 pass"}',
|
|
'POST returns new rule in JSON')
|
|
same(mime, 'application/json', 'rule has application/json content type')
|
|
|
|
-- GET list of all rules
|
|
code, body, mime = http_req('/', 'GET')
|
|
same(code, 200, 'GET returns list with the remaining rule')
|
|
compare_tables(body,
|
|
'[{"count":0,"active":true,"id":1,"info":"src = 192.0.2.1 pass"}]',
|
|
'rule list contains only the remaining rule in JSON')
|
|
same(mime, 'application/json', 'rule has application/json content type')
|
|
|
|
-- try to DELETE first rule again
|
|
code, body = http_req('/0', 'DELETE')
|
|
same(code, 404, 'DELETE for already deleted rule fails with 404')
|
|
same(body, '"No such rule"', 'DELETE explains failure')
|
|
|
|
-- DELETE second rule
|
|
code, body, mime = http_req('/1', 'DELETE')
|
|
same(code, 200, 'DELETE for second rule succeeds')
|
|
same(body, 'true', 'DELETE returns success in body')
|
|
same(mime, 'application/json', 'DELETE return value has application/json content type')
|
|
|
|
-- GET (supposedly empty) list of all rules
|
|
code, body, mime = http_req('/', 'GET')
|
|
same(code, 200, 'GET returns list with the remaining rule')
|
|
compare_tables(body, '[]', 'rule list is now empty JSON list')
|
|
same(mime, 'application/json', 'rule has application/json content type')
|
|
end
|
|
|
|
-- plan tests
|
|
local tests = {
|
|
start_server,
|
|
test_daf_api,
|
|
}
|
|
|
|
return tests
|
|
end
|