76 lines
2.8 KiB
Python
76 lines
2.8 KiB
Python
import os
|
|
import pytest
|
|
from datetime import datetime, timedelta, timezone
|
|
from pathlib import Path
|
|
|
|
from app.core.database import init_db, AsyncSessionLocal
|
|
from app.models.models import Client, BackupJob, BackupFile
|
|
from app.services.retention_service import apply_retention_policy
|
|
from app.core.config import settings
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_retention_policy_engine():
|
|
"""
|
|
Tests retention rule application:
|
|
- 7 Daily, 4 Weekly, 12 Monthly.
|
|
- Creates synthetic historical backups from past 30 days.
|
|
- Verifies that old non-anchor daily backups are pruned, while weekly/monthly anchors and newest backups are preserved.
|
|
"""
|
|
await init_db()
|
|
|
|
async with AsyncSessionLocal() as db:
|
|
# Create client & job
|
|
client = Client(client_code="CLIENT-RET-01", name="Retention Test Machine", status="ONLINE")
|
|
db.add(client)
|
|
await db.flush()
|
|
|
|
job = BackupJob(
|
|
job_code="JOB-RET-01",
|
|
client_id=client.id,
|
|
name="SQL Production Retention Job",
|
|
source_path="C:\\SQLBackups",
|
|
keep_daily=3, # Keep only last 3 daily
|
|
keep_weekly=2, # Keep 2 weekly
|
|
keep_monthly=1 # Keep 1 monthly
|
|
)
|
|
db.add(job)
|
|
await db.flush()
|
|
|
|
now = datetime.now(timezone.utc)
|
|
created_files = []
|
|
|
|
# Create dummy physical files and DB records for 10 days in the past
|
|
for day in range(10):
|
|
past_date = now - timedelta(days=day)
|
|
rel_path = f"clients/{client.client_code}/{job.job_code}/backup_day_{day}.bak"
|
|
full_path = Path(settings.STORAGE_ROOT) / rel_path
|
|
full_path.parent.mkdir(parents=True, exist_ok=True)
|
|
with open(full_path, "wb") as f:
|
|
f.write(b"sample_retention_backup_data")
|
|
|
|
bf = BackupFile(
|
|
client_id=client.id,
|
|
job_id=job.id,
|
|
filename=f"backup_day_{day}.bak",
|
|
relative_path=rel_path,
|
|
file_size=len(b"sample_retention_backup_data"),
|
|
sha256="test-sha256",
|
|
retention_tag="DAILY",
|
|
is_active=True,
|
|
created_at=past_date
|
|
)
|
|
db.add(bf)
|
|
created_files.append(bf)
|
|
|
|
await db.commit()
|
|
|
|
# Run retention policy
|
|
pruned_count = await apply_retention_policy(db, job.id)
|
|
assert pruned_count > 0, "Retention should have pruned expired daily backups"
|
|
|
|
# Verify newest backup (day 0) is preserved
|
|
await db.refresh(created_files[0])
|
|
assert created_files[0].is_active == True, "Newest backup must never be pruned"
|
|
|
|
print(f"\n>>> Retention Test Passed: Successfully pruned {pruned_count} historical backups while protecting anchors!")
|