1
0
Fork 0
knot-resolver/modules/daf/daf_http.test.lua
Daniel Baumann fbc604e215
Adding upstream version 5.7.5.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-21 13:56:17 +02:00

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