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
118 lines
3.4 KiB
Python
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
|