]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
tests check_answer(): support checking RDATA
authorVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 30 Jun 2020 14:05:32 +0000 (16:05 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 30 Jun 2020 16:28:15 +0000 (18:28 +0200)
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
tests/config/test_utils.lua

index 846b642b069251c3421d784630a05b1e4156e761..761282fb6db75f194bd4703ccf234416cb30573e 100644 (file)
@@ -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',
index 8d159c9cac62e6fb258f1cf37651d298a0820d13..afc713b282dddf4623e2f437d73c410c92133279 100644 (file)
@@ -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)