]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Smarter and faster startup and teardown of auth and rec
authorOtto <otto.moerbeek@open-xchange.com>
Mon, 29 Nov 2021 08:47:40 +0000 (09:47 +0100)
committerOtto <otto.moerbeek@open-xchange.com>
Tue, 30 Nov 2021 09:56:41 +0000 (10:56 +0100)
Instead of having a fixed 1 or 2s delay, poll the TCP port to see
if rec or auth has started up in a semi-tight loop: a loop with a
small sleep.  For teardown we poll the wait status using poll() in
a similar loop.

regression-tests.recursor-dnssec/recursortests.py

index f2602a23cd52b121cd947a43cc55a4c2905d62dd..0c99bc309a6b5499a43dd97ce8b6d9f075e5f433 100644 (file)
@@ -521,6 +521,19 @@ distributor-threads={threads}""".format(confdir=confdir,
                 ipaddress = cls._PREFIX + '.' + auth_suffix
                 cls.startAuth(authconfdir, ipaddress)
 
+    @classmethod
+    def waitForTCPSocket(cls, ipaddress, port):
+        for try_number in range(0, 100):
+            try:
+                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+                sock.connect((ipaddress, port))
+                sock.close()
+                return
+            except Exception as err:
+                if err.errno != errno.ECONNREFUSED:
+                    print(f'Error occurred: {try_number} {err}', file=sys.stderr)
+            time.sleep(0.1)
+
     @classmethod
     def startAuth(cls, confdir, ipaddress):
         print("Launching pdns_server..")
@@ -539,7 +552,7 @@ distributor-threads={threads}""".format(confdir=confdir,
                                                      stdout=fdLog, stderr=fdLog,
                                                      env=cls._auth_env)
 
-        time.sleep(2)
+        cls.waitForTCPSocket(ipaddress, 53)
 
         if cls._auths[ipaddress].poll() is not None:
             try:
@@ -602,12 +615,7 @@ distributor-threads={threads}""".format(confdir=confdir,
             cls._recursor = subprocess.Popen(recursorcmd, close_fds=True,
                                              stdout=fdLog, stderr=fdLog)
 
-        if 'PDNSRECURSOR_FAST_TESTS' in os.environ:
-            delay = 0.5
-        else:
-            delay = cls._recursorStartupDelay
-
-        time.sleep(delay)
+        cls.waitForTCPSocket("127.0.0.1", port)
 
         if cls._recursor.poll() is not None:
             try:
@@ -664,38 +672,18 @@ distributor-threads={threads}""".format(confdir=confdir,
         pass
 
     @classmethod
-    def tearDownAuth(cls):
-        if 'PDNSRECURSOR_FAST_TESTS' in os.environ:
-            delay = 0.1
-        else:
-            delay = 1.0
-
-        for _, auth in cls._auths.items():
-            try:
-                auth.terminate()
-                if auth.poll() is None:
-                    time.sleep(delay)
-                    if auth.poll() is None:
-                        auth.kill()
-                    auth.wait()
-            except OSError as e:
-                if e.errno != errno.ESRCH:
-                    raise
-
-    @classmethod
-    def tearDownRecursor(cls):
-        if 'PDNSRECURSOR_FAST_TESTS' in os.environ:
-            delay = 0.1
-        else:
-            delay = 1.0
+    def killProcess(cls, p):
         try:
-            if cls._recursor:
-                cls._recursor.terminate()
-                if cls._recursor.poll() is None:
-                    time.sleep(delay)
-                    if cls._recursor.poll() is None:
-                        cls._recursor.kill()
-                    cls._recursor.wait()
+            p.terminate()
+            for count in range(10):
+                x = p.poll()
+                if x is not None:
+                    break
+                time.sleep(0.1)
+            if x is None:
+                print("kill...", p, file=sys.stderr)
+                p.kill()
+                p.wait()
         except OSError as e:
             # There is a race-condition with the poll() and
             # kill() statements, when the process is dead on the
@@ -703,6 +691,15 @@ distributor-threads={threads}""".format(confdir=confdir,
             if e.errno != errno.ESRCH:
                 raise
 
+    @classmethod
+    def tearDownAuth(cls):
+        for _, auth in cls._auths.items():
+            cls.killProcess(auth);
+
+    @classmethod
+    def tearDownRecursor(cls):
+        cls.killProcess(cls._recursor)
+
     @classmethod
     def sendUDPQuery(cls, query, timeout=2.0, decode=True, fwparams=dict()):
         if timeout: