135 lines
4.8 KiB
Python
135 lines
4.8 KiB
Python
from pathlib import Path
|
|
import os
|
|
import subprocess
|
|
import tempfile
|
|
import tomllib
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def test_packaged_config_matches_linux_layout():
|
|
config = tomllib.loads((ROOT / "packaging/rustbox.toml").read_text())
|
|
assert config["host"] == "0.0.0.0"
|
|
assert config["data_dir"] == "/var/lib/rustbox"
|
|
assert config["log_dir"] == "/var/log/rustbox"
|
|
assert config["default_interface_skin"] == "apple-mail"
|
|
assert config["max_attachment_size_mb"] == 50
|
|
assert config["max_message_size_mb"] == 100
|
|
|
|
|
|
def test_systemd_hardening_and_paths():
|
|
unit = (ROOT / "packaging/rustbox.service").read_text()
|
|
for needle in (
|
|
"User=rustbox",
|
|
"Group=rustbox",
|
|
"WorkingDirectory=/var/lib/rustbox",
|
|
"ExecStart=/usr/local/bin/rustbox",
|
|
"StateDirectory=rustbox",
|
|
"LogsDirectory=rustbox",
|
|
"ProtectSystem=strict",
|
|
"ProtectHome=true",
|
|
"NoNewPrivileges=true",
|
|
"StandardOutput=null",
|
|
):
|
|
assert needle in unit
|
|
|
|
|
|
def test_logrotate_keeps_seven_daily_rotations():
|
|
data = (ROOT / "packaging/rustbox.logrotate").read_text()
|
|
assert "/var/log/rustbox/rustbox.log" in data
|
|
assert "daily" in data
|
|
assert "rotate 7" in data
|
|
assert "create 0600 rustbox rustbox" in data
|
|
|
|
|
|
def test_package_runtime_dependencies_are_explicit():
|
|
script = (ROOT / "scripts/prepare-package.sh").read_text()
|
|
for needle in (
|
|
"- gnupg",
|
|
"- libssl3 | libssl3t64",
|
|
"- gnupg2",
|
|
"- openssl-libs",
|
|
"- gpg2",
|
|
"- libopenssl3",
|
|
):
|
|
assert needle in script
|
|
|
|
|
|
def test_docker_context_excludes_secrets_and_state():
|
|
data = (ROOT / ".dockerignore").read_text().splitlines()
|
|
assert ".env" in data
|
|
assert "gpg/" in data
|
|
assert "data/" in data
|
|
|
|
|
|
def test_repository_public_port_is_18965():
|
|
env = (ROOT / ".env.example").read_text()
|
|
compose = (ROOT / "docker-compose.yml").read_text()
|
|
start = (ROOT / "start.sh").read_text()
|
|
assert "HTTP_PORT=18965" in env
|
|
assert "127.0.0.1:18965" in env
|
|
assert "${HTTP_PORT:-18965}:8080" in compose
|
|
assert "DEFAULT_HTTP_PORT=18965" in start
|
|
|
|
|
|
def test_all_three_linux_families_are_always_published():
|
|
build = (ROOT / "scripts/build-release.sh").read_text()
|
|
init = (ROOT / "scripts/init-storage.sh").read_text()
|
|
compose = (ROOT / "docker-compose.yml").read_text()
|
|
assert "BUILD_SUSE" not in build
|
|
assert "BUILD_SUSE" not in compose
|
|
for name in ("DEBIAN-BUILD-INFO.txt", "RHEL-BUILD-INFO.txt", "SUSE-BUILD-INFO.txt"):
|
|
assert name in build
|
|
assert name in init
|
|
|
|
|
|
def test_rustup_installation_and_runtime_cargo_home_are_consistent():
|
|
dockerfile = (ROOT / "Dockerfile").read_text()
|
|
assert "CARGO_HOME=/opt/cargo" in dockerfile
|
|
runtime_env = dockerfile.split("ENV DATA_DIR=/var/lib/rustbox-package-builder", 1)[1]
|
|
assert "CARGO_HOME=/var/lib/rustbox-package-builder/cargo" not in runtime_env
|
|
assert "CARGO_TARGET_DIR=/tmp/rustbox-package-builder/cargo-target" in runtime_env
|
|
assert "CARGO_TARGET_DIR=/var/lib/rustbox-package-builder/cargo/target" not in runtime_env
|
|
|
|
|
|
|
|
def test_build_cache_cleanup_and_package_retention_defaults():
|
|
env = (ROOT / ".env.example").read_text()
|
|
compose = (ROOT / "docker-compose.yml").read_text()
|
|
entrypoint = (ROOT / "scripts/entrypoint.sh").read_text()
|
|
build = (ROOT / "scripts/build-release.sh").read_text()
|
|
|
|
assert "PACKAGE_RETENTION=10" in env
|
|
assert "CLEAN_BUILD_CACHE=1" in env
|
|
assert 'PACKAGE_RETENTION: "${PACKAGE_RETENTION:-10}"' in compose
|
|
assert 'CLEAN_BUILD_CACHE: "${CLEAN_BUILD_CACHE:-1}"' in compose
|
|
assert 'rm -rf -- "$DATA_DIR/work/out" "$DATA_DIR/work/package" "$DATA_DIR/cargo/target"' in entrypoint
|
|
assert 'trap cleanup_build_artifacts EXIT' in build
|
|
assert 'aptly -config="$APTLY_CONF" db cleanup' in build
|
|
assert 'cp -al "$DATA_DIR/packages/rpm/x86_64/." "$RELEASE_DIR/rpm/x86_64/"' in build
|
|
|
|
|
|
def test_prune_package_files_keeps_only_newest_ten():
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
root = Path(tmp)
|
|
pkg = root / "deb"
|
|
pkg.mkdir()
|
|
for idx in range(12):
|
|
path = pkg / f"rustbox_0.2.{idx}-1_amd64.deb"
|
|
path.write_bytes(str(idx).encode())
|
|
ts = 1_700_000_000 + idx
|
|
os.utime(path, (ts, ts))
|
|
|
|
script = "\n".join([
|
|
"set -Eeuo pipefail",
|
|
f"source {ROOT / 'scripts/lib.sh'}",
|
|
f"prune_package_files {pkg} 'rustbox_*.deb' 10",
|
|
])
|
|
subprocess.run(["bash", "-lc", script], check=True)
|
|
|
|
remaining = sorted(p.name for p in pkg.glob("*.deb"))
|
|
assert len(remaining) == 10
|
|
assert "rustbox_0.2.0-1_amd64.deb" not in remaining
|
|
assert "rustbox_0.2.1-1_amd64.deb" not in remaining
|
|
assert "rustbox_0.2.11-1_amd64.deb" in remaining
|