From: Otto Date: Mon, 29 Nov 2021 08:47:40 +0000 (+0100) Subject: Smarter and faster startup and teardown of auth and rec X-Git-Tag: rec-4.7.0-alpha0~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=70542ce30b70560fa47b61e6830de0d8536aa9e1;p=thirdparty%2Fpdns.git Smarter and faster startup and teardown of auth and rec 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. --- diff --git a/regression-tests.recursor-dnssec/recursortests.py b/regression-tests.recursor-dnssec/recursortests.py index f2602a23cd..0c99bc309a 100644 --- a/regression-tests.recursor-dnssec/recursortests.py +++ b/regression-tests.recursor-dnssec/recursortests.py @@ -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: