"""The Hub backup/restore scripts must actually run on the Linux host. Both failures below were found by running the scripts on the production VM, not by reading them. """ from pathlib import Path ROOT = Path(__file__).parents[1] HUB = ROOT / "deploy" / "hub" def test_shell_scripts_are_forced_to_lf(): # With core.autocrlf=true on the Windows release machine, `git archive` # shipped CRLF and `sh` failed on the first line ("set: Illegal option -"). rules = [line.split() for line in (ROOT / ".gitattributes").read_text(encoding="utf-8").splitlines() if line.strip() and not line.startswith("#")] assert ["*.sh", "text", "eol=lf"] in rules assert ["*.service", "text", "eol=lf"] in rules for script in [*HUB.glob("*.sh"), *HUB.glob("*.service")]: assert b"\r" not in script.read_bytes(), script.name def test_hub_port_restriction_uses_docker_user_chain(): # Docker-published ports bypass UFW/INPUT; only DOCKER-USER filters them. # --ctdir ORIGINAL keeps the container's replies out of the DROP rule. script = (HUB / "restrict_hub_port.sh").read_text(encoding="utf-8") assert "DOCKER-USER" in script and "--ctdir ORIGINAL" in script and "--ctorigdstport" in script unit = (HUB / "gti-fiscal-hub-port.service").read_text(encoding="utf-8") assert "After=docker.service" in unit and "PartOf=docker.service" in unit def test_backup_retention_does_not_delete_on_the_host(): # Docker creates the bind-mounted backup directory as root, so a host-side # rm by the deploy user fails once retention kicks in. lines = [line.strip() for line in (HUB / "backup.sh").read_text(encoding="utf-8").splitlines() if not line.strip().startswith("#")] retention = [line for line in lines if "rm -f" in line] assert retention and all(line.startswith("$COMPOSE exec -T postgres") for line in retention)