from pathlib import Path import os import subprocess import tempfile import unittest ROOT = Path(__file__).resolve().parents[1] class CleanupRetentionTests(unittest.TestCase): def test_runtime_target_is_not_persistent_data(self): dockerfile = (ROOT / "Dockerfile").read_text() entrypoint = (ROOT / "scripts/entrypoint.sh").read_text() build = (ROOT / "scripts/build-release.sh").read_text() runtime = dockerfile.split("# Cargo registry/git cache stays persistent", 1)[1] self.assertIn("CARGO_HOME=/var/lib/package-builder/cargo", runtime) self.assertIn("CARGO_TARGET_DIR=/tmp/rust-package-builder/cargo-target", runtime) self.assertIn("GOCACHE=/tmp/rust-package-builder/go-cache", dockerfile) self.assertNotIn("CARGO_TARGET_DIR=/var/lib/package-builder/cargo/target", runtime) self.assertNotIn("GOCACHE=/var/lib/package-builder/go/cache", dockerfile) self.assertIn('export CARGO_TARGET_DIR="$BUILD_TMP_DIR/cargo-target"', entrypoint) self.assertIn('rm -rf -- "$DATA_DIR/cargo/target" "$DATA_DIR/go/cache"', entrypoint) self.assertIn('WORK="$BUILD_TMP_DIR/work/$BUILD_ID"', build) self.assertIn('if is_true "${CLEAN_BUILD_CACHE:-1}"; then', build) self.assertIn('rm -rf -- "$CARGO_TARGET_DIR" "${GOCACHE:-$BUILD_TMP_DIR/go-cache}"', build) def test_default_retention_is_ten_and_exported_to_compose(self): env = (ROOT / ".env.example").read_text() compose = (ROOT / "docker-compose.yml").read_text() entrypoint = (ROOT / "scripts/entrypoint.sh").read_text() self.assertIn("RELEASE_RETENTION=10", env) self.assertIn("PACKAGE_RETENTION=10", env) self.assertIn("CLEAN_BUILD_CACHE=1", env) self.assertIn('RELEASE_RETENTION: "${RELEASE_RETENTION:-10}"', compose) self.assertIn('PACKAGE_RETENTION: "${PACKAGE_RETENTION:-10}"', compose) self.assertIn('CLEAN_BUILD_CACHE: "${CLEAN_BUILD_CACHE:-1}"', compose) self.assertIn('RELEASE_RETENTION=${RELEASE_RETENTION:-10}', entrypoint) self.assertIn('PACKAGE_RETENTION=${PACKAGE_RETENTION:-10}', entrypoint) def test_linux_retention_and_aptly_cleanup_are_enabled(self): linux = (ROOT / "scripts/build-linux-release.sh").read_text() self.assertIn('package_retention=${PACKAGE_RETENTION:-10}', linux) self.assertIn("'rustproxy-docker-agent_*.deb'", linux) self.assertIn("'rustproxy-docker-agent-*.x86_64.rpm'", linux) self.assertIn('repo add -force-replace package-builder "$DATA_DIR/packages/deb"', linux) self.assertIn('snapshot list -raw', linux) self.assertIn('aptly -config="$APTLY_CONF" db cleanup', linux) self.assertIn('--link-dest="$CURRENT_TARGET/apt/"', linux) self.assertIn('--link-dest="$CURRENT_TARGET/rpm/"', linux) self.assertIn('--link-dest="$CURRENT_TARGET/suse/"', linux) def test_package_retention_keeps_ten_versions_per_product(self): with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) rpm = root / "rpm" rpm.mkdir() for idx in range(12): main = rpm / f"rustproxy-0.2.{idx}-1.x86_64.rpm" agent = rpm / f"rustproxy-docker-agent-0.2.{idx}-1.x86_64.rpm" main.write_bytes(b"main") agent.write_bytes(b"agent") ts = 1_700_000_000 + idx os.utime(main, (ts, ts)) os.utime(agent, (ts, ts)) script = "\n".join([ "set -Eeuo pipefail", f"source {ROOT / 'scripts/lib.sh'}", f"prune_package_files {rpm} 'rustproxy-*.x86_64.rpm' 10 'rustproxy-docker-agent-*.x86_64.rpm'", f"prune_package_files {rpm} 'rustproxy-docker-agent-*.x86_64.rpm' 10", ]) subprocess.run(["bash", "-lc", script], check=True) main = [p for p in rpm.glob("rustproxy-*.x86_64.rpm") if not p.name.startswith("rustproxy-docker-agent-")] agent = list(rpm.glob("rustproxy-docker-agent-*.x86_64.rpm")) self.assertEqual(len(main), 10) self.assertEqual(len(agent), 10) self.assertFalse((rpm / "rustproxy-0.2.0-1.x86_64.rpm").exists()) self.assertFalse((rpm / "rustproxy-docker-agent-0.2.0-1.x86_64.rpm").exists()) self.assertTrue((rpm / "rustproxy-0.2.11-1.x86_64.rpm").exists()) self.assertTrue((rpm / "rustproxy-docker-agent-0.2.11-1.x86_64.rpm").exists()) def test_release_retention_keeps_newest_ten(self): with tempfile.TemporaryDirectory() as tmp: releases = Path(tmp) / "releases" releases.mkdir() for idx in range(12): path = releases / f"release-{idx:02d}" path.mkdir() ts = 1_700_000_000 + idx os.utime(path, (ts, ts)) protected = releases / "release-11" script = "\n".join([ "set -Eeuo pipefail", f"source {ROOT / 'scripts/lib.sh'}", f"prune_release_dirs {releases} 10 {protected}", ]) subprocess.run(["bash", "-lc", script], check=True) remaining = sorted(p.name for p in releases.iterdir() if p.is_dir()) self.assertEqual(len(remaining), 10) self.assertNotIn("release-00", remaining) self.assertNotIn("release-01", remaining) self.assertIn("release-11", remaining) def test_packaging_revision_forces_one_new_linux_build(self): lib = (ROOT / "scripts/lib.sh").read_text() self.assertIn("PACKAGING_REVISION=7", lib) if __name__ == "__main__": unittest.main()