predixy/test/signal_handling.py
2026-01-15 12:33:33 +01:00

91 lines
2.6 KiB
Python

#!/usr/bin/env python3
#
# Start a temporary predixy instance and verify SIGTERM shuts it down cleanly.
#
import os
import signal
import socket
import subprocess
import tempfile
import time
from test_util import parse_args, exit_with_result
def wait_for_port(host, port, timeout=5.0):
deadline = time.time() + timeout
while time.time() < deadline:
try:
with socket.create_connection((host, port), timeout=0.5):
return True
except Exception:
time.sleep(0.05)
return False
def start_predixy(root, redis_port):
predixy_bin = os.path.join(root, "src", "predixy")
if not os.path.exists(predixy_bin):
raise RuntimeError("predixy binary not found")
listen_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_sock.bind(("127.0.0.1", 0))
listen_port = listen_sock.getsockname()[1]
listen_sock.close()
tmp_dir = tempfile.TemporaryDirectory()
conf_path = os.path.join(tmp_dir.name, "predixy_test.conf")
with open(conf_path, "w") as f:
f.write(
"Name PredixySignalTest\n"
f"Bind 127.0.0.1:{listen_port}\n"
"WorkerThreads 1\n"
"ClientTimeout 3\n"
"LogVerbSample 0\n"
"LogDebugSample 0\n"
"LogInfoSample 10000\n"
"LogNoticeSample 1\n"
"LogWarnSample 1\n"
"LogErrorSample 1\n"
"\n"
"StandaloneServerPool {\n"
" RefreshMethod fixed\n"
" Group test {\n"
f" + 127.0.0.1:{redis_port}\n"
" }\n"
"}\n"
)
proc = subprocess.Popen([predixy_bin, conf_path],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
if not wait_for_port("127.0.0.1", listen_port, timeout=5.0):
proc.terminate()
tmp_dir.cleanup()
raise RuntimeError("predixy did not start")
return proc, tmp_dir
def run_test(project_root, redis_port):
proc, tmp_dir = start_predixy(project_root, redis_port)
try:
proc.send_signal(signal.SIGTERM)
try:
proc.wait(timeout=5.0)
except subprocess.TimeoutExpired:
print("FAIL: predixy did not exit after SIGTERM")
proc.kill()
return False
finally:
tmp_dir.cleanup()
return True
if __name__ == "__main__":
args = parse_args("Signal handling test", default_port=6380)
root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
success = run_test(root, args.port)
exit_with_result(success, "signal handling", "signal handling")