"""Check that a routine Nextcloud restart preserves installed app files.""" from pathlib import Path import shlex import subprocess import yaml ROOT = Path(__file__).resolve().parents[2] def functions(tmp_path: Path) -> str: """Extract the deployed shell functions into a synthetic filesystem.""" manifest = yaml.safe_load((ROOT / "services/nextcloud/deployment.yaml").read_text()) containers = manifest["spec"]["template"]["spec"]["initContainers"] script = next(c for c in containers if c["name"] == "install-nextcloud")["args"][0] start = script.index(" install_app() {") end = script.index(" ensure_mime_defaults\n", start) return script[start:end].replace("/var/www/html", str(tmp_path)) def test_existing_apps_need_no_download_or_reinstallation(tmp_path: Path): """Unchanged app files survive without network or CLI configuration calls.""" app = tmp_path / "custom_apps" / "synthetic" (app / "appinfo").mkdir(parents=True) (app / "appinfo/info.xml").write_text("") preserved = app / "keep.txt" preserved.write_text("original") shell = functions(tmp_path) + """ curl() { exit 91; } su() { exit 92; } install_app synthetic https://invalid.example/test.tar.gz ensure_app synthetic """ subprocess.run(["sh", "-eu", "-c", shell], check=True) assert preserved.read_text() == "original" def test_failed_download_preserves_existing_directory(tmp_path: Path): """A failed first install never removes an existing incomplete app tree.""" app = tmp_path / "custom_apps" / "synthetic" app.mkdir(parents=True) (app / "keep.txt").write_text("original") shell = functions(tmp_path) + """ curl() { return 1; } if install_app synthetic https://invalid.example/test.tar.gz; then exit 93; fi """ subprocess.run(["sh", "-eu", "-c", shell], check=True) assert (app / "keep.txt").read_text() == "original" assert not list((tmp_path / "custom_apps").glob(".bootstrap-*"))