Files
cc-ci/tests/rustdesk-server/custom/test_rendezvous_ports.py
T

54 lines
1.8 KiB
Python

"""rustdesk-server — rendezvous/relay port presence (the recipe's whole purpose).
The stock compose publishes hbbs's and hbbr's ports mode:host on the cc-ci node, so these
assertions run on-host against 127.0.0.1. A TCP accept on each port is the minimal real
signal that the corresponding listener is bound; the protocol layers above them are asserted
by the websocket-handshake and punch-hole tests.
"""
from __future__ import annotations
import socket
import time
# service -> port map from the stock compose (hbbs: 21115/21116(+udp)/21118, hbbr: 21117/21119)
PORTS = {
21115: "hbbs NAT-test",
21116: "hbbs rendezvous (tcp)",
21117: "hbbr relay",
21118: "hbbs websocket",
21119: "hbbr websocket",
}
def _connect(port: int, timeout: float = 5.0) -> bool:
try:
with socket.create_connection(("127.0.0.1", port), timeout=timeout):
return True
except OSError:
return False
def test_all_ports_listening(meta):
"""Every stock host-published port accepts a TCP connection (poll: freshly rolled tasks
rebind host-mode ports with a short window — mumble's READY_PROBE pattern, §5)."""
deadline = time.time() + meta.HTTP_TIMEOUT
pending = dict(PORTS)
while pending and time.time() < deadline:
for port in list(pending):
if _connect(port):
del pending[port]
if pending:
time.sleep(3)
assert not pending, (
f"ports not listening on 127.0.0.1: {pending} "
f"(waited {meta.HTTP_TIMEOUT}s; hbbs/hbbr host-mode binds)"
)
def test_rendezvous_port_stably_listening():
"""The core rendezvous port 21116 holds 3 consecutive accepts (no flapping rebind)."""
for _ in range(3):
assert _connect(21116), "hbbs rendezvous 21116 dropped a consecutive connect"
time.sleep(1)