Three changes to complete the repo-level work for Milestone 1 (0.11.6 → 0.12.6) plus a howto for the remaining manual/external tasks: 1. config/prosody.cfg.lua.template: re-add run_as_root = true. Production and the compose harness run as root (startup.sh writes into root-owned /etc/prosody/). Without it, mod_posix calls prosody.shutdown() during startup, which deactivates c2s (port 5222) before the shutdown itself errors out (prosody.main_thread is nil during module init), leaving Prosody running without c2s. 2. tests/test_08_image_patches.py: replace 3 stale patch-marker entries that checked for patches M1 intentionally dropped (moduleapi, mod_admin_telnet, muc.lib dumpTable) with markers that verify their config-based replacements (console_interfaces, http_interfaces) and the storagemanager.open() rewrite in mod_vnc_muc_fcm.lua. 3. upgrade-plan.md: update M1 status to reflect the post-M1 fixes (run_as_root, default_storage, stale tests), mark manual steps (DB migration, telnet console regression, external testsuite) with cross-references to m1-manual-tasks.md, and correct 0.12.5 → 0.12.6 throughout. 4. m1-manual-tasks.md: new file documenting the three manual tasks that require external infrastructure — DB schema migration (one-way, with rehearse-on-copy procedure), telnet console regression test (0.12 reimplemented the console on mod_admin_shell), and external testsuite run against a dev deployment. Verified: compose-harness testsuite — 80 passed, 5 skipped, 1 pre-existing failure (test_vcard_fallback: mod_vnc_vcard_fallback not enabled in config, unrelated to M1). Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/3>
109 lines
4.0 KiB
Python
109 lines
4.0 KiB
Python
"""Patch-application CI test.
|
|
|
|
The Dockerfile builder stage applies every `patches/*.patch` to the upstream
|
|
Prosody source with `patch -p1 --fuzz=0` before `make install`. A patch that
|
|
fails to apply aborts the build, but a accidentally-dropped patch file or a
|
|
config-based replacement that was forgotten would leave the upstream file
|
|
unpatched while the build still succeeds. These tests exec into the running
|
|
prosody container and grep each patched upstream file (or rendered config)
|
|
for the VNCtalk-specific marker, catching that regression without a live
|
|
connection.
|
|
|
|
Requires the compose stack to be up:
|
|
docker compose up -d --build postgres mocks prosody
|
|
|
|
If `docker compose exec prosody` is not available, the whole module is skipped.
|
|
"""
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import pytest
|
|
|
|
REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
|
|
|
# (test id, path inside the container, grep marker)
|
|
#
|
|
# Patches dropped at M1 and their replacements:
|
|
# - moduleapi.patch → mod_vnc_muc_fcm*.lua now call storagemanager.open()
|
|
# - mod_admin_telnet.patch → console_interfaces = { "*" } in the config
|
|
# - portmanager.patch → http_interfaces = { "*", "::" } in the config
|
|
# - muc.lib dumpTable → removed (debug helper, no replacement)
|
|
PATCH_MARKERS = [
|
|
("mod_mam_has_vnc_rest_message",
|
|
"/usr/local/lib/prosody/modules/mod_mam/mod_mam.lua",
|
|
"vnc-rest-message"),
|
|
("vnc_muc_fcm_uses_storagemanager",
|
|
"/usr/local/lib/prosody/modules/mod_vnc_muc_fcm.lua",
|
|
"storagemanager.open"),
|
|
("register_lib_has_vnc_muc_kick",
|
|
"/usr/local/lib/prosody/modules/muc/register.lib.lua",
|
|
"vnc-muc-kick"),
|
|
("config_has_console_interfaces",
|
|
"/etc/prosody/prosody.cfg.lua",
|
|
"console_interfaces"),
|
|
("config_has_http_interfaces",
|
|
"/etc/prosody/prosody.cfg.lua",
|
|
"http_interfaces"),
|
|
("portmanager_uses_network_default_read_size",
|
|
"/usr/local/lib/prosody/core/portmanager.lua",
|
|
"network_default_read_size"),
|
|
("mod_carbons_has_vnc_rest_hook",
|
|
"/usr/local/lib/prosody/modules/mod_carbons.lua",
|
|
"vnc-rest-message"),
|
|
("hidden_lib_present",
|
|
"/usr/local/lib/prosody/modules/muc/hidden.lib.lua",
|
|
"muc_room_allow_public"),
|
|
("mod_muc_unique_has_handle_iq_tobare",
|
|
"/usr/local/lib/prosody/modules/mod_muc_unique.lua",
|
|
"handle_iq_tobare"),
|
|
]
|
|
|
|
|
|
def _compose_available():
|
|
if not shutil.which("docker"):
|
|
return False
|
|
try:
|
|
res = subprocess.run(
|
|
["docker", "compose", "ps", "--services", "--filter", "status=running"],
|
|
cwd=REPO_ROOT, capture_output=True, text=True, timeout=20,
|
|
)
|
|
except (subprocess.SubprocessError, OSError):
|
|
return False
|
|
if res.returncode != 0:
|
|
return False
|
|
return "prosody" in res.stdout.split()
|
|
|
|
|
|
def _exec_grep(path, marker):
|
|
"""Return the grep match count (int) inside the prosody container, or -1."""
|
|
if not _compose_available():
|
|
return -1
|
|
# grep -Fc prints the match count (fixed-string match, so regex
|
|
# metacharacters in markers like '*' are treated literally).
|
|
res = subprocess.run(
|
|
["docker", "compose", "exec", "-T", "prosody",
|
|
"sh", "-c", f"grep -Fc -- {repr(marker)} {path}"],
|
|
cwd=REPO_ROOT, capture_output=True, text=True, timeout=30,
|
|
)
|
|
out = res.stdout.strip()
|
|
if res.returncode == 0 and out.isdigit():
|
|
return int(out)
|
|
return 0
|
|
|
|
|
|
@pytest.fixture(scope="module", autouse=True)
|
|
def require_compose():
|
|
if not _compose_available():
|
|
pytest.skip("compose stack not running (run: docker compose up -d prosody)", allow_module_level=True)
|
|
|
|
|
|
@pytest.mark.parametrize("test_id, path, marker", PATCH_MARKERS, ids=[m[0] for m in PATCH_MARKERS])
|
|
def test_patch_applied(test_id, path, marker):
|
|
count = _exec_grep(path, marker)
|
|
if count < 0:
|
|
pytest.skip("compose stack not available")
|
|
assert count > 0, (
|
|
f"Patch marker {marker!r} not found in {path} (grep count={count}). "
|
|
f"The patch or config replacement for '{test_id}' is missing or wrong."
|
|
)
|