]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix cache tests. Clean tests backends. 3458/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 25 Feb 2016 16:51:24 +0000 (17:51 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 25 Feb 2016 16:51:24 +0000 (17:51 +0100)
Several issues:
- the cache tests used a vey small cache, not large enough for the
number of responses we expected to cache during the test suite
- this was hidden by the default response from the backends
matching what the test expected
- and by the backends not counting properly what looked like a
health check but wasn't.

regression-tests.dnsdist/dnscrypt.py
regression-tests.dnsdist/dnsdisttests.py
regression-tests.dnsdist/pylintrc [new file with mode: 0644]
regression-tests.dnsdist/test_Caching.py
regression-tests.dnsdist/test_CheckConfig.py
regression-tests.dnsdist/test_EdnsClientSubnet.py
regression-tests.dnsdist/test_Spoofing.py

index 60070bb4e59cd788d8c912577c358165f6bf479c..f46bd6df785e0a69662840477fbf01b03039ef26 100644 (file)
@@ -1,13 +1,13 @@
 #!/usr/bin/env python2
-import dns
-import dns.message
 import socket
 import struct
 import time
+import dns
+import dns.message
 import libnacl
 import libnacl.utils
 
-class DNSCryptResolverCertificate:
+class DNSCryptResolverCertificate(object):
     DNSCRYPT_CERT_MAGIC = '\x44\x4e\x53\x43'
     DNSCRYPT_ES_VERSION = '\x00\x01'
     DNSCRYPT_PROTOCOL_MIN_VERSION = '\x00\x00'
@@ -44,7 +44,7 @@ class DNSCryptResolverCertificate:
         validUntil = struct.unpack_from("!I", orig[48:52])[0]
         return DNSCryptResolverCertificate(serial, validFrom, validUntil, resolverPK, clientMagic)
 
-class DNSCryptClient:
+class DNSCryptClient(object):
     DNSCRYPT_NONCE_SIZE = 24
     DNSCRYPT_MAC_SIZE = 16
     DNSCRYPT_PADDED_BLOCK_SIZE = 64
index 4f186de94a423d809fad651f2e5405f9294b83c4..816b61d683b57e9b3ef17f8269e3b68f4e4a38ee 100644 (file)
@@ -112,12 +112,34 @@ class DNSDistTest(unittest.TestCase):
                 cls._dnsdist.wait()
 
     @classmethod
-    def ResponderIncrementCounter(cls):
+    def _ResponderIncrementCounter(cls):
         if threading.currentThread().name in cls._responsesCounter:
             cls._responsesCounter[threading.currentThread().name] += 1
         else:
             cls._responsesCounter[threading.currentThread().name] = 1
 
+    @classmethod
+    def _getResponse(cls, request):
+        response = None
+        if len(request.question) != 1:
+            print("Skipping query with question count %d" % (len(request.question)))
+            return None
+        healthcheck = not str(request.question[0].name).endswith('tests.powerdns.com.')
+        if not healthcheck:
+            cls._ResponderIncrementCounter()
+            if not cls._toResponderQueue.empty():
+                response = cls._toResponderQueue.get(True, cls._queueTimeout)
+                if response:
+                    response = copy.copy(response)
+                    response.id = request.id
+                    cls._fromResponderQueue.put(request, True, cls._queueTimeout)
+
+        if not response:
+            # unexpected query, or health check
+            response = dns.message.make_response(request)
+
+        return response
+
     @classmethod
     def UDPResponder(cls, port):
         sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
@@ -126,38 +148,9 @@ class DNSDistTest(unittest.TestCase):
         while True:
             data, addr = sock.recvfrom(4096)
             request = dns.message.from_wire(data)
-            answered = False
-            if len(request.question) != 1:
-                print("Skipping query with question count %d" % (len(request.question)))
+            response = cls._getResponse(request)
+            if not response:
                 continue
-            if str(request.question[0].name).endswith('tests.powerdns.com.') and not cls._toResponderQueue.empty():
-                response = cls._toResponderQueue.get(True, cls._queueTimeout)
-                if response:
-                    response = copy.copy(response)
-                    response.id = request.id
-                    cls._fromResponderQueue.put(request, True, cls._queueTimeout)
-                    cls.ResponderIncrementCounter()
-                    answered = True
-
-            if not answered:
-                # unexpected query, or health check
-                response = dns.message.make_response(request)
-                rrset = None
-                if request.question[0].rdclass == dns.rdataclass.IN:
-                    if request.question[0].rdtype == dns.rdatatype.A:
-                        rrset = dns.rrset.from_text(request.question[0].name,
-                                                    3600,
-                                                    request.question[0].rdclass,
-                                                    request.question[0].rdtype,
-                                                    '127.0.0.1')
-                    elif request.question[0].rdtype == dns.rdatatype.AAAA:
-                        rrset = dns.rrset.from_text(request.question[0].name,
-                                                    3600,
-                                                    request.question[0].rdclass,
-                                                    request.question[0].rdtype,
-                                                    '::1')
-                if rrset:
-                    response.answer.append(rrset)
 
             sock.settimeout(2.0)
             sock.sendto(response.to_wire(), addr)
@@ -176,44 +169,15 @@ class DNSDistTest(unittest.TestCase):
 
         sock.listen(100)
         while True:
-            answered = False
             (conn, _) = sock.accept()
             conn.settimeout(2.0)
             data = conn.recv(2)
             (datalen,) = struct.unpack("!H", data)
             data = conn.recv(datalen)
             request = dns.message.from_wire(data)
-            if len(request.question) != 1:
-                print("Skipping query with question count %d" % (len(request.question)))
+            response = cls._getResponse(request)
+            if not response:
                 continue
-            if str(request.question[0].name).endswith('tests.powerdns.com.') and not cls._toResponderQueue.empty():
-                response = cls._toResponderQueue.get(True, cls._queueTimeout)
-                if response:
-                    response = copy.copy(response)
-                    response.id = request.id
-                    cls._fromResponderQueue.put(request, True, cls._queueTimeout)
-                    cls.ResponderIncrementCounter()
-                    answered = True
-
-            if not answered:
-                # unexpected query, or health check
-                response = dns.message.make_response(request)
-                rrset = None
-                if request.question[0].rdclass == dns.rdataclass.IN:
-                    if request.question[0].rdtype == dns.rdatatype.A:
-                        rrset = dns.rrset.from_text(request.question[0].name,
-                                                    3600,
-                                                    request.question[0].rdclass,
-                                                    request.question[0].rdtype,
-                                                    '127.0.0.1')
-                    elif request.question[0].rdtype == dns.rdatatype.AAAA:
-                        rrset = dns.rrset.from_text(request.question[0].name,
-                                                    3600,
-                                                    request.question[0].rdclass,
-                                                    request.question[0].rdtype,
-                                                    '::1')
-                if rrset:
-                    response.answer.append(rrset)
 
             wire = response.to_wire()
             conn.send(struct.pack("!H", len(wire)))
@@ -294,4 +258,4 @@ class DNSDistTest(unittest.TestCase):
             self._toResponderQueue.get(False)
 
         while not self._fromResponderQueue.empty():
-            self._toResponderQueue.get(False)
+            self._fromResponderQueue.get(False)
diff --git a/regression-tests.dnsdist/pylintrc b/regression-tests.dnsdist/pylintrc
new file mode 100644 (file)
index 0000000..83a00d2
--- /dev/null
@@ -0,0 +1,2 @@
+[MESSAGES CONTROL]
+disable=invalid-name, missing-docstring, line-too-long, superfluous-parens
\ No newline at end of file
index ecb15edfcbe2e08c2e19f088c09676ad4320fb4b..e9335c4aefc482a9421553194d6175759268e577 100644 (file)
@@ -6,11 +6,12 @@ from dnsdisttests import DNSDistTest
 class TestCaching(DNSDistTest):
 
     _config_template = """
-    pc = newPacketCache(5, 86400, 1)
+    pc = newPacketCache(100, 86400, 1)
     getPool(""):setCache(pc)
     addAction(makeRule("nocache.cache.tests.powerdns.com."), SkipCacheAction())
     newServer{address="127.0.0.1:%s"}
     """
+
     def testCached(self):
         """
         Cache: Served from cache
@@ -366,3 +367,74 @@ class TestCachingWithExistingEDNS(DNSDistTest):
             total += TestCachingWithExistingEDNS._responsesCounter[key]
 
         self.assertEquals(total, misses)
+
+class TestCachingCacheFull(DNSDistTest):
+
+    _config_template = """
+    pc = newPacketCache(1, 86400, 1)
+    getPool(""):setCache(pc)
+    newServer{address="127.0.0.1:%s"}
+    """
+    def testCacheFull(self):
+        """
+        Cache: No new entries are cached when the cache is full
+
+        """
+        misses = 0
+        name = 'cachenotfullyet.cache.tests.powerdns.com.'
+        query = dns.message.make_query(name, 'A', 'IN')
+        response = dns.message.make_response(query)
+        rrset = dns.rrset.from_text(name,
+                                    3600,
+                                    dns.rdataclass.IN,
+                                    dns.rdatatype.A,
+                                    '127.0.0.1')
+        response.answer.append(rrset)
+
+        # Miss
+        (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+        self.assertTrue(receivedQuery)
+        self.assertTrue(receivedResponse)
+        receivedQuery.id = query.id
+        self.assertEquals(query, receivedQuery)
+        self.assertEquals(response, receivedResponse)
+        misses += 1
+
+        # next queries should hit the cache
+        (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+        self.assertEquals(receivedResponse, response)
+
+        # ok, now the cache is full, send another query
+        name = 'cachefull.cache.tests.powerdns.com.'
+        query = dns.message.make_query(name, 'AAAA', 'IN')
+        response = dns.message.make_response(query)
+        rrset = dns.rrset.from_text(name,
+                                    3600,
+                                    dns.rdataclass.IN,
+                                    dns.rdatatype.AAAA,
+                                    '::1')
+        response.answer.append(rrset)
+
+        # Miss
+        (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+        self.assertTrue(receivedQuery)
+        self.assertTrue(receivedResponse)
+        receivedQuery.id = query.id
+        self.assertEquals(query, receivedQuery)
+        self.assertEquals(response, receivedResponse)
+        misses += 1
+
+        # next queries should NOT hit the cache
+        (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+        self.assertTrue(receivedQuery)
+        self.assertTrue(receivedResponse)
+        receivedQuery.id = query.id
+        self.assertEquals(query, receivedQuery)
+        self.assertEquals(response, receivedResponse)
+        misses += 1
+
+        total = 0
+        for key in TestCachingCacheFull._responsesCounter:
+            total += TestCachingCacheFull._responsesCounter[key]
+
+        self.assertEquals(total, misses)
index 2034fc8511d89b1e189b27e65d41dd2d5b2cb9e6..71a7132bce4ea25d607ff3830ef304acebaacd72 100644 (file)
@@ -6,7 +6,8 @@ import sys
 
 class TestCheckConfig(unittest.TestCase):
 
-    def tryDNSDist(self, configTemplate, shouldBeSuccessful=True):
+    @staticmethod
+    def tryDNSDist(configTemplate, shouldBeSuccessful=True):
         conffile = 'dnsdist_test.conf'
         with open(conffile, 'w') as conf:
             conf.write("-- Autogenerated by dnsdisttests.py\n")
index 020545825db0bff1fc46e79bf2a511e260a84f56..3b4386a8ca0cd7089cfb0c14244a327905a1db7d 100644 (file)
@@ -13,15 +13,6 @@ class TestEdnsClientSubnetNoOverride(DNSDistTest):
 
     _config_template = """
     truncateTC(true)
-    block=newDNSName("powerdns.org.")
-    function blockFilter(dq)
-        if(dq.qname:isPartOf(block))
-        then
-            print("Blocking *.powerdns.org")
-            return true
-        end
-        return false
-    end
     newServer{address="127.0.0.1:%s", useClientSubnet=true}
     """
 
@@ -142,15 +133,6 @@ class TestEdnsClientSubnetOverride(DNSDistTest):
 
     _config_template = """
     truncateTC(true)
-    block=newDNSName("powerdns.org.")
-    function blockFilter(dq)
-        if(dq.qname:isPartOf(block))
-        then
-            print("Blocking *.powerdns.org")
-            return true
-        end
-        return false
-    end
     setECSOverride(true)
     setECSSourcePrefixV4(24)
     setECSSourcePrefixV6(56)
index 0af9a109ecfd4b97916e7a57707a3b4327d1485f..cc817462d4fe7cce3a1d87eaff148f64a1b896ab 100644 (file)
@@ -241,14 +241,14 @@ class TestSpoofingSpoof(DNSDistTest):
         # dnsdist set RA = RD for spoofed responses
         query.flags &= ~dns.flags.RD
         expectedResponse = dns.message.make_response(query)
-        
+
         rrset = dns.rrset.from_text(name,
                                     60,
                                     dns.rdataclass.IN,
                                     dns.rdatatype.A,
                                     '192.0.2.2', '192.0.2.1')
         expectedResponse.answer.append(rrset)
-        
+
         rrset = dns.rrset.from_text(name,
                                     60,
                                     dns.rdataclass.IN,