Files
awoooi/scripts/backup/tests/test_backup_common_retention_contract.py
Your Name e614f061f7
Some checks failed
CD Pipeline / select-latest-carrier (push) Successful in 49s
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m28s
CD Pipeline / revalidate-deploy-carrier (push) Successful in 27s
CD Pipeline / build-and-deploy (push) Failing after 17m18s
CD Pipeline / revalidate-post-deploy-carrier (push) Has been skipped
CD Pipeline / post-deploy-checks (push) Has been skipped
E2E Health Check / e2e-health (push) Successful in 48s
AI 技術雷達監控 / ai-technology-watch (push) Successful in 1m4s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 0s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 22s
fix(backup): verify host188 recovery end to end
2026-07-18 19:12:42 +08:00

118 lines
3.4 KiB
Python

from __future__ import annotations
import os
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
COMMON = ROOT / "scripts" / "backup" / "common.sh"
def test_latest_only_retention_uses_keep_last_one_and_explicit_password(tmp_path: Path) -> None:
bin_dir = tmp_path / "bin"
bin_dir.mkdir()
event_log = tmp_path / "restic.args"
restic = bin_dir / "restic"
restic.write_text(
'#!/bin/sh\nprintf "%s\\n" "$*" >> "$TEST_EVENT_LOG"\n',
encoding="utf-8",
)
restic.chmod(0o755)
backup_base = tmp_path / "backup"
password_file = backup_base / "scripts" / ".restic-password"
password_file.parent.mkdir(parents=True)
password_file.write_text("test-only\n", encoding="utf-8")
env = os.environ.copy()
env.update(
{
"BACKUP_BASE": str(backup_base),
"RESTIC_PASSWORD_FILE": str(password_file),
"PATH": f"{bin_dir}:{env['PATH']}",
"TEST_EVENT_LOG": str(event_log),
}
)
subprocess.run(
[
"bash",
"-c",
f'source "{COMMON}"; BACKUP_RETENTION_MODE=latest '
'BACKUP_KEEP_LAST=1 cleanup_old_backups "$BACKUP_BASE/demo"',
],
env=env,
check=True,
text=True,
capture_output=True,
)
args = event_log.read_text(encoding="utf-8")
assert "forget --keep-last 1 --prune --password-file" in args
def test_retention_rejects_invalid_keep_last_before_restic(tmp_path: Path) -> None:
backup_base = tmp_path / "backup"
env = os.environ.copy()
env["BACKUP_BASE"] = str(backup_base)
result = subprocess.run(
[
"bash",
"-c",
f'source "{COMMON}"; BACKUP_RETENTION_MODE=latest '
'BACKUP_KEEP_LAST=0 cleanup_old_backups "$BACKUP_BASE/demo"',
],
env=env,
text=True,
capture_output=True,
)
assert result.returncode == 64
assert "BACKUP_KEEP_LAST" in result.stdout
def test_verify_backup_reads_the_requested_snapshot_before_repository_check(
tmp_path: Path,
) -> None:
bin_dir = tmp_path / "bin"
bin_dir.mkdir()
event_log = tmp_path / "restic.args"
restic = bin_dir / "restic"
restic.write_text(
"""#!/bin/sh
printf '%s\n' "$*" >> "$TEST_EVENT_LOG"
case " $* " in
*" snapshots "*) printf '%s\n' '[{"short_id":"abcdef12"}]' ;;
*" ls "*) printf '%s\n' '{"type":"file","path":"/backup/data.dump"}' ;;
*" check "*) ;;
esac
""",
encoding="utf-8",
)
restic.chmod(0o755)
backup_base = tmp_path / "backup"
password_file = backup_base / "scripts" / ".restic-password"
password_file.parent.mkdir(parents=True)
password_file.write_text("test-only\n", encoding="utf-8")
env = os.environ.copy()
env.update(
{
"BACKUP_BASE": str(backup_base),
"RESTIC_PASSWORD_FILE": str(password_file),
"PATH": f"{bin_dir}:{env['PATH']}",
"TEST_EVENT_LOG": str(event_log),
}
)
subprocess.run(
["bash", "-c", f'source "{COMMON}"; verify_backup /repo abcdef12'],
env=env,
check=True,
text=True,
capture_output=True,
)
calls = event_log.read_text(encoding="utf-8")
assert "snapshots abcdef12 --json" in calls
assert "ls abcdef12 --json" in calls
assert "check --read-data-subset=1%" in calls