# -*- coding: utf-8 -*- """每日备份与保留期测试: uv run python tests/test_maintenance.py""" import os import sqlite3 import sys import tempfile from pathlib import Path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.stdout.reconfigure(encoding="utf-8") from reaction_board.database import Database # noqa: E402 from reaction_board.services.maintenance import ( # noqa: E402 backup_daily, daily_backup_path, prune_daily_backups, ) def test_daily_backup_and_restore(): with tempfile.TemporaryDirectory() as tmp: db = Database(Path(tmp) / "app.db") db.initialize() try: db.write(lambda c: c.execute("INSERT INTO kv(k, v) VALUES ('x', '42')")) target = backup_daily(db, Path(tmp) / "backup", "2026-10-31") assert target == daily_backup_path(Path(tmp) / "backup", "2026-10-31") assert target.name == "app-20261031.db" assert target.exists() check = sqlite3.connect(target) try: assert check.execute("SELECT v FROM kv WHERE k='x'").fetchone()[0] == "42" finally: check.close() # 覆盖同日备份也安全 db.write(lambda c: c.execute("UPDATE kv SET v='43' WHERE k='x'")) backup_daily(db, Path(tmp) / "backup", "2026-10-31") check = sqlite3.connect(target) try: assert check.execute("SELECT v FROM kv WHERE k='x'").fetchone()[0] == "43" finally: check.close() finally: db.close() def test_prune_daily_backups_only(): with tempfile.TemporaryDirectory() as tmp: backup_dir = Path(tmp) old_daily = backup_dir / "app-20260101.db" fresh_daily = backup_dir / "app-20261031.db" old_migration = backup_dir / "app-pre-v1-20260101.db" other = backup_dir / "keep.txt" for path in (old_daily, fresh_daily, old_migration, other): path.write_bytes(b"x") now = 1_800_000_000 old_time = now - 20 * 86400 for path in (old_daily, old_migration): os.utime(path, (old_time, old_time)) os.utime(fresh_daily, (now, now)) removed = prune_daily_backups(backup_dir, keep_days=14, now=now) assert removed == [old_daily] assert fresh_daily.exists() assert old_migration.exists() # 迁移备份不属于日备份清理范围 assert other.exists() def main(): test_daily_backup_and_restore() test_prune_daily_backups_only() print("OK: 每日备份与保留期测试全部通过") if __name__ == "__main__": main()