#!/usr/bin/env python3 """Run source-upgrade preservation/refusal regressions in disposable directories.""" from pathlib import Path import shutil import sqlite3 import sys import tempfile ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(ROOT)) from scripts.deploy.upgrade import upgrade def fixture(parent): target = parent / "installed" target.mkdir() (target / "Cargo.toml").write_text('[package]\nname = "rust-proxy"\nversion = "0.33.7"\n') (target / "src").mkdir() (target / "src" / "obsolete.rs").write_text("// old managed source\n") (target / "data").mkdir() with sqlite3.connect(target / "data" / "fixture.sqlite") as db: db.execute("CREATE TABLE preserved(value TEXT)") db.execute("INSERT INTO preserved VALUES ('configuration and preferences')") (target / ".env").write_text("LOCAL_FIXTURE=1\n") (target / "langs").mkdir() (target / "langs" / "custom.json").write_text('{"custom": true}\n') return target def main(): with tempfile.TemporaryDirectory(prefix="rustproxy-upgrade-test-", dir=ROOT.parent) as temporary: parent = Path(temporary) target = fixture(parent) try: upgrade(ROOT, target, stopped=False) except ValueError: pass else: raise AssertionError("upgrade must require stopped confirmation") assert (target / "src" / "obsolete.rs").is_file() print("PASS upgrade refuses missing --stopped without modifying source") if sys.platform != "win32": import fcntl with (target / "data" / "process.lock").open("w+") as lock: fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB) try: upgrade(ROOT, target, stopped=True) except ValueError: pass else: raise AssertionError("upgrade must refuse a live process lock") print("PASS upgrade refuses a data directory locked by a live process") backup = upgrade(ROOT, target, stopped=True) assert (target / ".env").read_text() == "LOCAL_FIXTURE=1\n" assert (target / "langs" / "custom.json").read_text() == '{"custom": true}\n' with sqlite3.connect(target / "data" / "fixture.sqlite") as db: assert db.execute("SELECT value FROM preserved").fetchone() == ("configuration and preferences",) assert not (target / "src" / "obsolete.rs").exists() assert (backup / "src" / "obsolete.rs").is_file() assert (target / "Cargo.toml").read_bytes() == (ROOT / "Cargo.toml").read_bytes() assert (target / "src" / "proxy" / "cache_plan.rs").is_file() print("PASS upgrade preserves SQLite, environment and custom language; backs up old source and replaces managed tree") if sys.platform != "win32": shutil.rmtree(target / "src") (target / "src").symlink_to(backup / "src", target_is_directory=True) try: upgrade(ROOT, target, stopped=True) except ValueError: pass else: raise AssertionError("upgrade must refuse a managed symlink") assert (backup / "src" / "obsolete.rs").is_file() print("PASS upgrade refuses managed symlinks without changing their targets") if __name__ == "__main__": main()