68 lines
3.1 KiB
Python
68 lines
3.1 KiB
Python
import json
|
|
import tempfile
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
from django.core.management import call_command
|
|
from django.test import TestCase, override_settings
|
|
from django.utils import timezone
|
|
|
|
from workflows.backup_ops import latest_backup_health_snapshot
|
|
|
|
|
|
class BackupReliabilityTests(TestCase):
|
|
@override_settings(BACKUP_OUTPUT_DIR=tempfile.gettempdir())
|
|
def test_latest_backup_health_reports_missing_when_no_bundle_exists(self):
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
with override_settings(BACKUP_OUTPUT_DIR=tmpdir):
|
|
snapshot = latest_backup_health_snapshot()
|
|
|
|
self.assertEqual(snapshot['status'], 'missing')
|
|
self.assertTrue(snapshot['is_stale'])
|
|
|
|
def test_latest_backup_health_reports_stale_when_verification_is_old(self):
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
backup_dir = Path(tmpdir) / 'backup_20260326_010101'
|
|
backup_dir.mkdir(parents=True)
|
|
(backup_dir / 'db.dump').write_text('db', encoding='utf-8')
|
|
(backup_dir / 'media.tar.gz').write_text('media', encoding='utf-8')
|
|
(backup_dir / 'backup_meta.json').write_text(
|
|
json.dumps(
|
|
{
|
|
'created_at': timezone.now().isoformat(),
|
|
'verify_status': 'verified',
|
|
'verified_at': (timezone.now() - timezone.timedelta(hours=72)).isoformat(),
|
|
}
|
|
),
|
|
encoding='utf-8',
|
|
)
|
|
|
|
with override_settings(BACKUP_OUTPUT_DIR=tmpdir):
|
|
snapshot = latest_backup_health_snapshot(stale_after_hours=48)
|
|
|
|
self.assertEqual(snapshot['status'], 'stale')
|
|
self.assertEqual(snapshot['bundle_name'], 'backup_20260326_010101')
|
|
|
|
@patch('workflows.management.commands.verify_latest_backup.verify_backup_bundle')
|
|
@patch('workflows.management.commands.verify_latest_backup.list_backup_bundles')
|
|
def test_verify_latest_backup_command_uses_existing_latest_bundle(self, list_bundles, verify_bundle):
|
|
list_bundles.return_value = [{'name': 'backup_20260326_020202'}]
|
|
verify_bundle.return_value = {'name': 'backup_20260326_020202', 'summary': 'ok'}
|
|
|
|
call_command('verify_latest_backup')
|
|
|
|
verify_bundle.assert_called_once_with('backup_20260326_020202')
|
|
|
|
@patch('workflows.management.commands.verify_latest_backup.verify_backup_bundle')
|
|
@patch('workflows.management.commands.verify_latest_backup.create_backup_bundle')
|
|
@patch('workflows.management.commands.verify_latest_backup.list_backup_bundles')
|
|
def test_verify_latest_backup_command_can_create_when_missing(self, list_bundles, create_bundle, verify_bundle):
|
|
list_bundles.return_value = []
|
|
create_bundle.return_value = {'name': 'backup_20260326_030303'}
|
|
verify_bundle.return_value = {'name': 'backup_20260326_030303', 'summary': 'ok'}
|
|
|
|
call_command('verify_latest_backup', create_if_missing=True)
|
|
|
|
create_bundle.assert_called_once()
|
|
verify_bundle.assert_called_once_with('backup_20260326_030303')
|