diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:26:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:26:00 +0000 |
commit | 830407e88f9d40d954356c3754f2647f91d5c06a (patch) | |
tree | d6a0ece6feea91f3c656166dbaa884ef8a29740e /modules/daf/daf_http.test.lua | |
parent | Initial commit. (diff) | |
download | knot-resolver-98d55686c8af309ef910d45b4aa72db5092f465c.tar.xz knot-resolver-98d55686c8af309ef910d45b4aa72db5092f465c.zip |
Adding upstream version 5.6.0.upstream/5.6.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'modules/daf/daf_http.test.lua')
-rw-r--r-- | modules/daf/daf_http.test.lua | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/modules/daf/daf_http.test.lua b/modules/daf/daf_http.test.lua new file mode 100644 index 0000000..20d5f90 --- /dev/null +++ b/modules/daf/daf_http.test.lua @@ -0,0 +1,216 @@ +-- 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 |