From: Remi Gacogne Date: Tue, 7 May 2024 13:24:34 +0000 (+0200) Subject: dnsdist: Add a regression test for Dynamic rules SetTag action X-Git-Tag: rec-5.1.0-beta1~27^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bfacd1108f08333238538b7e9d627a098102b6bf;p=thirdparty%2Fpdns.git dnsdist: Add a regression test for Dynamic rules SetTag action --- diff --git a/regression-tests.dnsdist/test_DynBlocksRatio.py b/regression-tests.dnsdist/test_DynBlocksRatio.py index 72d90bb8e9..d239a3ad3d 100644 --- a/regression-tests.dnsdist/test_DynBlocksRatio.py +++ b/regression-tests.dnsdist/test_DynBlocksRatio.py @@ -55,3 +55,90 @@ class TestDynBlockGroupCacheMissRatio(DynBlocksTest): """ name = 'cachemissratio.group.dynblocks.tests.powerdns.com.' self.doTestCacheMissRatio(name, 3, 17) + +class TestDynBlockGroupCacheMissRatioSetTag(DynBlocksTest): + + # we need this period to be quite long because we request the valid + # queries to be still looked at to reach the 20 queries count! + _dynBlockPeriod = 6 + _config_params = ['_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] + _config_template = """ + local dbr = dynBlockRulesGroup() + dbr:setCacheMissRatio(0.8, %d, "Exceeded cache miss ratio", %d, 20, 0.0, DNSAction.SetTag, 0.0, { tagName='dyn-miss-ratio', tagValue='hit' }) + + -- on a cache miss, and if the cache miss ratio threshold was exceeded, send a REFUSED response + addCacheMissAction(TagRule('dyn-miss-ratio', 'hit'), RCodeAction(DNSRCode.REFUSED)) + + function maintenance() + dbr:apply() + end + + newServer{address="127.0.0.1:%s"} + local pc = newPacketCache(1000, {maxTTL=86400, minTTL=1}) + getPool(""):setCache(pc) + """ + + def testDynBlocksCacheMissRatio(self): + """ + Dyn Blocks (group): Cache miss ratio with SetTag + """ + name = 'cachemissratio-settag.group.dynblocks.tests.powerdns.com.' + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.1') + + cacheHits = 3 + cacheMisses = 17 + for idx in range(cacheMisses): + query = dns.message.make_query(str(idx) + '.' + name, 'A', 'IN') + response = dns.message.make_response(query) + response.answer.append(rrset) + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + query = dns.message.make_query('0.' + name, 'A', 'IN') + response = dns.message.make_response(query) + response.answer.append(rrset) + for _ in range(cacheHits): + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + + waitForMaintenanceToRun() + + # we should now get REFUSED for cache misses for up to self._dynBlockDuration + self._dynBlockPeriod + + # cache miss + query = dns.message.make_query(str(cacheMisses + 1) + '.' + name, 'A', 'IN') + # dnsdist sets RA = RD for TC responses + query.flags &= ~dns.flags.RD + expectedResponse = dns.message.make_response(query) + expectedResponse.set_rcode(dns.rcode.REFUSED) + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False, timeout=0.5) + self.assertEqual(receivedResponse, expectedResponse) + + # but a cache hit should be OK + query = dns.message.make_query('0.' + name, 'A', 'IN') + expectedResponse = dns.message.make_response(query) + expectedResponse.answer.append(rrset) + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False, timeout=0.5) + self.assertEqual(receivedResponse, expectedResponse) + + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) + + # this one should succeed + query = dns.message.make_query(str(cacheMisses + 2) + '.' + name, 'A', 'IN') + response = dns.message.make_response(query) + response.answer.append(rrset) + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse)