From 9657081d330a75de390dc4410a65aaebb9c20331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20=C4=8Cun=C3=A1t?= <vladimir.cunat@nic.cz> Date: Tue, 30 Jun 2020 16:05:32 +0200 Subject: [PATCH] tests check_answer(): support checking RDATA Also allow using empty set as an alternative to NODATA pseudo-RCODE, and migrate RPZ tests to this merged function. --- modules/policy/policy.rpz.test.lua | 34 ++++-------------------------- tests/config/test_utils.lua | 27 +++++++++++++++++++++++- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/modules/policy/policy.rpz.test.lua b/modules/policy/policy.rpz.test.lua index 846b642b0..761282fb6 100644 --- a/modules/policy/policy.rpz.test.lua +++ b/modules/policy/policy.rpz.test.lua @@ -14,41 +14,15 @@ local function prepare_cache() c:commit() end -local function rrset_to_texts(rr) - local rr_text = {} - for w in rr:txt_dump():gmatch("%S+") do table.insert(rr_text, w) end - return rr_text -end - -local function check_answer(desc, qname, qtype, expected_rcode, expected_rdata) - qtype_str = kres.tostring.type[qtype] - callback = function(pkt) - same(pkt:rcode(), expected_rcode, - desc .. ': expecting answer for query ' .. qname .. ' ' .. qtype_str - .. ' with rcode ' .. kres.tostring.rcode[expected_rcode]) - - if expected_rdata then - rr_text = rrset_to_texts(pkt:rrsets(kres.section.ANSWER)[1]) - ok(rr_text[4] == expected_rdata, - desc ..': checking rdata of answer for ' .. qname .. ' ' .. qtype_str) - else - -- check empty section - ok(pkt:rrsets(kres.section.ANSWER)[1] == nil, - desc ..': checking empty answer section for ' .. qname .. ' ' .. qtype_str) - end - - end - - resolve(qname, qtype, kres.class.IN, {}, callback) -end +local check_answer = require('test_utils').check_answer local function test_rpz() check_answer('"CNAME ." return NXDOMAIN', 'nxdomain.', kres.type.A, kres.rcode.NXDOMAIN) check_answer('"CNAME *." return NODATA', - 'nodata.', kres.type.A, kres.rcode.NOERROR) + 'nodata.', kres.type.A, kres.rcode.NOERROR, {}) check_answer('"CNAME *. on wildcard" return NODATA', - 'nodata.nxdomain.', kres.type.A, kres.rcode.NOERROR) + 'nodata.nxdomain.', kres.type.A, kres.rcode.NOERROR, {}) check_answer('"CNAME rpz-drop." be dropped', 'rpzdrop.', kres.type.A, kres.rcode.SERVFAIL) check_answer('"CNAME rpz-passthru" return A rrset', @@ -60,7 +34,7 @@ local function test_rpz() check_answer('"A 192.168.7.7" with suffixed zone name in owner return local A rrset', 'testdomain.rra.', kres.type.A, kres.rcode.NOERROR, '192.168.7.7') check_answer('non existing AAAA on rra domain return NODATA', - 'rra.', kres.type.AAAA, kres.rcode.NOERROR) + 'rra.', kres.type.AAAA, kres.rcode.NOERROR, {}) check_answer('"A 192.168.8.8" and domain with uppercase and lowercase letters', 'case.sensitive.', kres.type.A, kres.rcode.NOERROR, '192.168.8.8') check_answer('"A 192.168.8.8" and domain with uppercase and lowercase letters', diff --git a/tests/config/test_utils.lua b/tests/config/test_utils.lua index 8d159c9ca..afc713b28 100644 --- a/tests/config/test_utils.lua +++ b/tests/config/test_utils.lua @@ -39,11 +39,26 @@ function M.not_contains(table, value, message) return contains(fail, pass, table, value, message) end +local function rrset_to_texts(rr) + local rr_text = {} + for w in rr:txt_dump():gmatch("%S+") do table.insert(rr_text, w) end + return rr_text +end M.NODATA = -1 -- Resolve a name and check the answer. Do *not* return until finished. -function M.check_answer(desc, qname, qtype, expected_rcode) +-- expected_rdata is one string or a table of strings in presentation format +-- (not tested beyond IP addresses; TODO: handle ordering somehow?) +function M.check_answer(desc, qname, qtype, expected_rcode, expected_rdata) + if expected_rdata ~= nil and type(expected_rdata) ~= 'table' then + expected_rdata = { expected_rdata } + end + local qtype_str = kres.tostring.type[qtype] local wire_rcode = expected_rcode + if expected_rcode == kres.rcode.NOERROR and type(expected_rdata) == 'table' + and #expected_rdata == 0 then + expected_rcode = M.NODATA + end if expected_rcode == M.NODATA then wire_rcode = kres.rcode.NOERROR end local done = false @@ -54,6 +69,16 @@ function M.check_answer(desc, qname, qtype, expected_rcode) ok((pkt:ancount() > 0) == (expected_rcode == kres.rcode.NOERROR), desc ..': checking number of answers for ' .. qname .. ' ' .. qtype_str) + + if expected_rdata then + local ans_rrs = pkt:rrsets(kres.section.ANSWER) + ok(#expected_rdata == #ans_rrs, + desc .. ': checking number of answer records for ' .. qname .. ' ' .. qtype_str) + for i = 1, #ans_rrs do + ok(rrset_to_texts(ans_rrs[i])[4] == expected_rdata[i], + desc .. ': checking rdata of answer for ' .. qname .. ' ' .. qtype_str) + end + end done = true end resolve(qname, qtype, kres.class.IN, {}, callback) -- GitLab