Files
vnctalk-prosody/tests/test_04_infra.py
T
Stefan-Sanger 2046867241 docs: add AGENTS.md, patch analysis, and pytest integration suite
- Add AGENTS.md with repo-specific conventions, build steps, and quirks
- Add PATCHES_AND_MODULES.md documenting every upstream deviation
- Add tests/ with pytest/slixmpp integration suite for core, MUC,
  vnctalk extensions, and infrastructure verification
- Include pytest.ini and .gitignore

Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/3>
2026-07-15 17:58:02 +02:00

109 lines
4.4 KiB
Python

"""Infrastructure tests: telnet, healthcheck, ports, TLS."""
import asyncio
import os
import subprocess
import pytest
@pytest.mark.asyncio
class TestAdminTelnet:
async def test_telnet_port_open(self, xmpp_config):
"""Admin telnet port 5582 must accept TCP connections."""
import socket
host = xmpp_config["admin_telnet_host"]
port = xmpp_config["admin_telnet_port"]
try:
reader, writer = await asyncio.wait_for(
asyncio.open_connection(host, port), timeout=5
)
writer.close()
await writer.wait_closed()
except ConnectionRefusedError:
if xmpp_config.get("skip_live"):
pytest.skip("No server running (skip-live mode)")
raise
except (OSError, asyncio.TimeoutError) as e:
pytest.fail(f"Cannot connect to admin telnet {host}:{port}: {e}")
async def test_telnet_banner(self, xmpp_config):
"""Telnet should send a banner with null byte."""
host = xmpp_config["admin_telnet_host"]
port = xmpp_config["admin_telnet_port"]
try:
reader, writer = await asyncio.wait_for(
asyncio.open_connection(host, port), timeout=5
)
data = await asyncio.wait_for(reader.read(1024), timeout=5)
writer.close()
await writer.wait_closed()
assert b"Prosody" in data or b"\x00" in data, "Unexpected telnet banner"
except ConnectionRefusedError:
if xmpp_config.get("skip_live"):
pytest.skip("No server running (skip-live mode)")
raise
except (OSError, asyncio.TimeoutError) as e:
pytest.fail(f"Telnet banner check failed: {e}")
class TestHealthcheck:
"""Verify healthcheck.sh semantics."""
def test_healthcheck_script_exists(self):
script = os.path.join(os.path.dirname(__file__), "..", "config", "healthcheck.sh")
assert os.path.exists(script), "healthcheck.sh not found"
def test_healthcheck_exits_two_on_cert_mismatch(self, tmp_path, monkeypatch):
"""Simulate cert mismatch scenario: script must exit 2."""
# We cannot easily run the real script without the container layout,
# but we verify the script source contains the exit-2 logic.
script_path = os.path.join(os.path.dirname(__file__), "..", "config", "healthcheck.sh")
with open(script_path) as f:
source = f.read()
assert "exit 2" in source, "healthcheck.sh must exit 2 on cert mismatch"
assert "md5sum" in source or "sha" in source, "healthcheck should compare cert hashes"
@pytest.mark.asyncio
class TestPorts:
async def test_c2s_port_open(self, xmpp_config):
"""XMPP C2S port must accept TCP."""
import socket
host = xmpp_config["host"]
port = xmpp_config["port"]
try:
reader, writer = await asyncio.wait_for(
asyncio.open_connection(host, port), timeout=5
)
writer.close()
await writer.wait_closed()
except (ConnectionRefusedError, OSError, asyncio.TimeoutError) as e:
if xmpp_config.get("skip_live") and ("Connect call failed" in str(e) or isinstance(e, ConnectionRefusedError)):
pytest.skip("No server running (skip-live mode)")
pytest.fail(f"C2S port not reachable {host}:{port}: {e}")
async def test_http_port_open(self, xmpp_config):
"""HTTP port (BOSH/WebSocket) must accept TCP."""
import aiohttp
# Try BOSH URL host:port if given, else skip
url = xmpp_config.get("bosh_url") or xmpp_config.get("ws_url")
if not url:
pytest.skip("No HTTP URL configured")
from urllib.parse import urlparse
parsed = urlparse(url)
host = parsed.hostname
port = parsed.port or (443 if parsed.scheme == "https" else 80)
try:
reader, writer = await asyncio.wait_for(
asyncio.open_connection(host, port), timeout=5
)
writer.close()
await writer.wait_closed()
except ConnectionRefusedError:
if xmpp_config.get("skip_live"):
pytest.skip("No server running (skip-live mode)")
raise
except (OSError, asyncio.TimeoutError) as e:
pytest.fail(f"HTTP port not reachable {host}:{port}: {e}")