""" وضعیتِ کپیِ زنده‌ی دیتابیس در /api/health (config/health.py: _slot_state، _offsite_warnings). پرسشِ واقعی از pg_replication_slots این‌جا اجرا نمی‌شود (تست‌ها روی SQLite‌اند)؛ روی سرور با اسلاتِ واقعی دیده شد (docs/operations.md «بکاپ»). """ from datetime import datetime, timedelta, timezone from django.test import SimpleTestCase, override_settings from config import health class SlotStateTests(SimpleTestCase): def test_missing_slot(self): self.assertEqual(health._slot_state(None)['state'], 'slot_missing') def test_streaming_and_caught_up_is_ok(self): self.assertEqual(health._slot_state((True, 'reserved', 0)), {'state': 'ok', 'lagBytes': 0}) def test_inactive_slot_is_disconnected(self): self.assertEqual(health._slot_state((False, 'reserved', 0))['state'], 'disconnected') def test_lost_slot_wins_over_everything(self): self.assertEqual(health._slot_state((False, 'lost', None))['state'], 'lost') @override_settings(OFFSITE_WAL_MAX_LAG_BYTES=100) def test_lag_above_limit(self): self.assertEqual(health._slot_state((True, 'reserved', 101))['state'], 'lagging') self.assertEqual(health._slot_state((True, 'reserved', 100))['state'], 'ok') @override_settings(OFFSITE_SYNC_MAX_AGE_SECONDS=600) class PushedStateTests(SimpleTestCase): """بکاپِ رمزشده‌ی ۲۱۶ (_pushed_state). پرسشِ pg_stat_archiver و خواندنِ فایل روی سرور دیده شد، نه این‌جا.""" T0 = datetime(2026, 10, 17, 16, 0, tzinfo=timezone.utc) def test_recent_sync_is_ok(self): r = health._pushed_state(self.T0, None, 1000, now=1060) self.assertEqual((r['state'], r['syncAgeSeconds']), ('ok', 60)) self.assertEqual(r['lastArchivedAt'], self.T0.isoformat()) def test_old_sync_is_stale(self): self.assertEqual(health._pushed_state(self.T0, None, 1000, now=1601)['state'], 'sync_stale') self.assertEqual(health._pushed_state(self.T0, None, 1000, now=1600)['state'], 'ok') def test_no_status_file_is_never_synced(self): self.assertEqual(health._pushed_state(self.T0, None, None, now=1000)['state'], 'never_synced') def test_failure_after_last_success_wins(self): later = self.T0 + timedelta(minutes=1) self.assertEqual(health._pushed_state(self.T0, later, 1000, now=1001)['state'], 'archive_failing') self.assertEqual(health._pushed_state(None, later, 1000, now=1001)['state'], 'archive_failing') def test_old_failure_then_success_is_ok(self): earlier = self.T0 - timedelta(minutes=1) self.assertEqual(health._pushed_state(self.T0, earlier, 1000, now=1001)['state'], 'ok') def test_idle_database_with_no_archive_yet_is_ok(self): self.assertEqual(health._pushed_state(None, None, 1000, now=1001)['state'], 'ok') class OffsiteWarningTests(SimpleTestCase): def test_ok_and_dev_are_silent(self): self.assertEqual(health._offsite_warnings({'state': 'ok', 'lagBytes': 0}), []) self.assertEqual(health._offsite_warnings({'state': 'not_postgres'}), []) def test_every_bad_state_warns(self): for state in ('not_configured', 'slot_missing', 'disconnected', 'lagging', 'lost', 'error', 'archive_failing', 'never_synced', 'sync_stale'): self.assertEqual(len(health._offsite_warnings({'state': state})), 1, state) def test_sqlite_reports_not_postgres(self): # سوئیت روی Postgres هم اجرا می‌شود (پیش از هر تغییرِ دیتابیسی)؛ آن‌جا این حالت معنی ندارد. if health.connection.vendor != 'sqlite': self.skipTest('فقط روی SQLite') self.assertEqual(health._offsite_backup(), {'state': 'not_postgres'})