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..")
stdout=fdLog, stderr=fdLog,
env=cls._auth_env)
- time.sleep(2)
+ cls.waitForTCPSocket(ipaddress, 53)
if cls._auths[ipaddress].poll() is not None:
try:
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:
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
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: