2026-05-19 11:39:10 +02:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from datetime import datetime, timezone
|
|
|
|
|
|
|
|
|
|
from django.contrib.admin.sites import AdminSite
|
|
|
|
|
from django.test import TestCase
|
|
|
|
|
|
2026-05-21 02:24:55 +02:00
|
|
|
from pobsync_backend.admin import BackupRunAdmin, GlobalConfigAdmin, HostConfigAdmin, SnapshotRecordAdmin
|
|
|
|
|
from pobsync_backend.models import BackupRun, GlobalConfig, HostConfig, ScheduleConfig, SnapshotRecord
|
2026-05-19 11:39:10 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class AdminDisplayTests(TestCase):
|
2026-05-21 02:46:09 +02:00
|
|
|
def test_admin_hides_old_global_state_fields_and_labels_host_runtime_state(self) -> None:
|
2026-05-21 02:24:55 +02:00
|
|
|
site = AdminSite()
|
|
|
|
|
global_admin = GlobalConfigAdmin(GlobalConfig, site)
|
|
|
|
|
host_admin = HostConfigAdmin(HostConfig, site)
|
|
|
|
|
|
|
|
|
|
global_fieldsets = list(global_admin.fieldsets)
|
|
|
|
|
host_fieldsets = list(host_admin.fieldsets)
|
|
|
|
|
global_fields = [field for _name, options in global_fieldsets for field in options["fields"]]
|
|
|
|
|
fieldset_names = [name for name, _options in [*global_fieldsets, *host_fieldsets]]
|
|
|
|
|
|
|
|
|
|
self.assertNotIn("pobsync_home", global_fields)
|
2026-05-21 02:46:09 +02:00
|
|
|
self.assertNotIn("data", global_fields)
|
|
|
|
|
self.assertIn("Runtime state", fieldset_names)
|
|
|
|
|
self.assertNotIn("Compatibility data", fieldset_names)
|
2026-05-21 02:24:55 +02:00
|
|
|
self.assertNotIn("Legacy JSON", fieldset_names)
|
|
|
|
|
|
2026-05-19 11:39:10 +02:00
|
|
|
def test_host_admin_links_to_related_snapshots_and_runs(self) -> None:
|
|
|
|
|
site = AdminSite()
|
|
|
|
|
admin = HostConfigAdmin(HostConfig, site)
|
|
|
|
|
host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
|
|
|
|
|
snapshot = SnapshotRecord.objects.create(
|
|
|
|
|
host=host,
|
|
|
|
|
kind="scheduled",
|
|
|
|
|
dirname="20260519-021500Z__ABCDEFGH",
|
|
|
|
|
path="/backups/web-01/scheduled/20260519-021500Z__ABCDEFGH",
|
|
|
|
|
)
|
|
|
|
|
BackupRun.objects.create(host=host, status=BackupRun.Status.SUCCESS, snapshot=snapshot)
|
|
|
|
|
|
|
|
|
|
snapshot_link = str(admin.snapshot_count_link(host))
|
|
|
|
|
run_link = str(admin.backup_run_count_link(host))
|
|
|
|
|
|
|
|
|
|
self.assertIn("/admin/pobsync_backend/snapshotrecord/", snapshot_link)
|
|
|
|
|
self.assertIn(f"host__id__exact={host.pk}", snapshot_link)
|
|
|
|
|
self.assertIn(">1<", snapshot_link)
|
|
|
|
|
self.assertIn("/admin/pobsync_backend/backuprun/", run_link)
|
|
|
|
|
self.assertIn(f"host__id__exact={host.pk}", run_link)
|
|
|
|
|
self.assertIn(">1<", run_link)
|
|
|
|
|
|
|
|
|
|
def test_host_admin_summarizes_schedule_and_latest_run(self) -> None:
|
|
|
|
|
site = AdminSite()
|
|
|
|
|
admin = HostConfigAdmin(HostConfig, site)
|
|
|
|
|
host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
|
|
|
|
|
|
|
|
|
|
self.assertEqual(admin.schedule_state(host), "none")
|
|
|
|
|
|
|
|
|
|
ScheduleConfig.objects.create(host=host, cron_expr="15 2 * * *", enabled=True)
|
|
|
|
|
host.refresh_from_db()
|
|
|
|
|
BackupRun.objects.create(
|
|
|
|
|
host=host,
|
|
|
|
|
status=BackupRun.Status.SUCCESS,
|
|
|
|
|
started_at=datetime(2026, 5, 19, 2, 15, tzinfo=timezone.utc),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
self.assertEqual(admin.schedule_state(host), "15 2 * * *")
|
|
|
|
|
self.assertEqual(admin.latest_run_state(host), "success 2026-05-19 02:15")
|
|
|
|
|
|
|
|
|
|
def test_snapshot_admin_links_to_base_and_backup_runs(self) -> None:
|
|
|
|
|
site = AdminSite()
|
|
|
|
|
admin = SnapshotRecordAdmin(SnapshotRecord, site)
|
|
|
|
|
host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
|
|
|
|
|
base = SnapshotRecord.objects.create(
|
|
|
|
|
host=host,
|
|
|
|
|
kind="scheduled",
|
|
|
|
|
dirname="20260518-021500Z__BASESNAP",
|
|
|
|
|
path="/backups/web-01/scheduled/20260518-021500Z__BASESNAP",
|
|
|
|
|
)
|
|
|
|
|
child = SnapshotRecord.objects.create(
|
|
|
|
|
host=host,
|
|
|
|
|
kind="scheduled",
|
|
|
|
|
dirname="20260519-021500Z__CHILDSNP",
|
|
|
|
|
path="/backups/web-01/scheduled/20260519-021500Z__CHILDSNP",
|
|
|
|
|
base=base,
|
|
|
|
|
)
|
|
|
|
|
BackupRun.objects.create(host=host, status=BackupRun.Status.SUCCESS, snapshot=child)
|
|
|
|
|
|
|
|
|
|
base_link = str(admin.base_link(child))
|
|
|
|
|
run_link = str(admin.backup_run_count_link(child))
|
|
|
|
|
|
|
|
|
|
self.assertIn(f"/admin/pobsync_backend/snapshotrecord/{base.pk}/change/", base_link)
|
|
|
|
|
self.assertIn(base.dirname, base_link)
|
|
|
|
|
self.assertIn("/admin/pobsync_backend/backuprun/", run_link)
|
|
|
|
|
self.assertIn(f"snapshot__id__exact={child.pk}", run_link)
|
|
|
|
|
self.assertIn(">1<", run_link)
|
|
|
|
|
|
|
|
|
|
def test_backup_run_admin_links_to_snapshot(self) -> None:
|
|
|
|
|
site = AdminSite()
|
|
|
|
|
admin = BackupRunAdmin(BackupRun, site)
|
|
|
|
|
host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
|
|
|
|
|
snapshot = SnapshotRecord.objects.create(
|
|
|
|
|
host=host,
|
|
|
|
|
kind="scheduled",
|
|
|
|
|
dirname="20260519-021500Z__ABCDEFGH",
|
|
|
|
|
path="/backups/web-01/scheduled/20260519-021500Z__ABCDEFGH",
|
|
|
|
|
)
|
|
|
|
|
run = BackupRun.objects.create(host=host, status=BackupRun.Status.SUCCESS, snapshot=snapshot)
|
|
|
|
|
|
|
|
|
|
snapshot_link = str(admin.snapshot_link(run))
|
|
|
|
|
|
|
|
|
|
self.assertIn(f"/admin/pobsync_backend/snapshotrecord/{snapshot.pk}/change/", snapshot_link)
|
|
|
|
|
self.assertIn(snapshot.dirname, snapshot_link)
|