Collection of cookbooks for Podman Quadlets
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

119 lines
4.8 KiB

"""Test PostgreSQL backup creation and VirtioFS storage.
These tests verify that:
- The backup oneshot service can be triggered manually and runs to completion.
- The expected backup artefacts land in the VirtioFS share (accessible from
the test runner's host filesystem without SSH).
- The backup retention policy removes stale backups.
Note: tests within a module share a single VM (module-scoped fixture), so
the order of test execution matters here: the backup files checked in later
tests are created by the earlier trigger test.
"""
import time
from pathlib import Path
# ---------------------------------------------------------------------------
# Trigger and completion
# ---------------------------------------------------------------------------
def test_create_database_and_table(postgresql_vm, test_ssh_key):
"""Create a test database and table with some data to ensure the backup has
something to capture."""
postgresql_vm.ssh_run(
"podman exec postgresql-server psql -U postgres -c \"CREATE DATABASE test;\"",
test_ssh_key,
)
postgresql_vm.ssh_run(
"podman exec postgresql-server psql -U postgres -d test -c \"CREATE TABLE witness (id SERIAL PRIMARY KEY, version VARCHAR); INSERT INTO witness (version) SELECT version();\"",
test_ssh_key,
)
def test_trigger_backup(postgresql_vm, test_ssh_key):
"""Starting postgresql-backup.service must succeed (no immediate error)."""
postgresql_vm.ssh_run(
"systemctl start postgresql-backup.service",
test_ssh_key,
)
def test_backup_completes_successfully(postgresql_vm, test_ssh_key):
"""postgresql-backup.service must finish in ``inactive`` state (not ``failed``)."""
state = postgresql_vm.wait_for_unit_done(
"postgresql-backup.service", test_ssh_key, timeout=120
)
assert state == "inactive", (
f"Backup service ended in unexpected state {state!r}. "
"Run: systemctl status postgresql-backup.service --no-pager"
)
# ---------------------------------------------------------------------------
# VirtioFS artefacts (verified from the host — no SSH required)
# ---------------------------------------------------------------------------
def test_backup_directory_exists_in_virtiofs(virtiofs_dir: Path):
"""The postgresql/backup sub-directory must exist in the VirtioFS share."""
backup_root = virtiofs_dir / "postgresql" / "backup"
assert backup_root.is_dir(), f"Backup directory not found on host: {backup_root}"
def test_at_least_one_backup_present(virtiofs_dir: Path):
"""At least one timestamped backup sub-directory must exist."""
backup_root = virtiofs_dir / "postgresql" / "backup"
backups = sorted(backup_root.iterdir())
assert backups, f"No backup sub-directories found under {backup_root}"
def test_backup_manifest_present(virtiofs_dir: Path):
"""The latest backup must contain a ``backup_manifest`` file (pg_basebackup)."""
backup_root = virtiofs_dir / "postgresql" / "backup"
latest = sorted(backup_root.iterdir())[-1]
assert (latest / "backup_manifest").exists(), (
f"backup_manifest missing in {latest}"
)
def test_backup_base_tar_present(virtiofs_dir: Path):
"""The latest backup must contain a ``base.tar`` cluster archive."""
backup_root = virtiofs_dir / "postgresql" / "backup"
latest = sorted(backup_root.iterdir())[-1]
assert (latest / "base.tar").exists(), f"base.tar missing in {latest}"
def test_database_dump_present(virtiofs_dir: Path):
"""At least one ``dump-test.sql.gz`` file must exist alongside the cluster backup."""
backup_root = virtiofs_dir / "postgresql" / "backup"
latest = sorted(backup_root.iterdir())[-1]
dumps = list(latest.glob("dump-test.sql.gz"))
assert dumps, f"No dump-test.sql.gz files found in {latest}"
# ---------------------------------------------------------------------------
# Retention policy
# ---------------------------------------------------------------------------
def test_backup_retention_enforced(postgresql_vm, test_ssh_key, virtiofs_dir: Path):
"""After triggering several extra backups the count must stay within the
configured retention limit (POSTGRES_BACKUP_RETENTION=7)."""
retention = 7
# Trigger ten additional backups so the rotation code has something to do.
for _ in range(10):
postgresql_vm.ssh_run(
"systemctl start postgresql-backup.service", test_ssh_key
)
state = postgresql_vm.wait_for_unit_done(
"postgresql-backup.service", test_ssh_key, timeout=120
)
assert state == "inactive"
time.sleep(1) # ensure distinct timestamp directories
backup_root = virtiofs_dir / "postgresql" / "backup"
count = len(list(backup_root.iterdir()))
assert count <= retention, (
f"Retention policy failed: {count} backups present, expected ≤ {retention}"
)