Skip to content

Commit 1c5ff36

Browse files
committed
tests: for backup schedules
1 parent 456482b commit 1c5ff36

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ testpaths = [
9090
"tests/test_projects.py",
9191
"tests/test_resources.py",
9292
"tests/branches",
93+
"tests/test_backup_schedules.py",
9394
]
9495

9596
[tool.ruff]

tests/test_backup_schedules.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import time
2+
from datetime import datetime
3+
4+
import pytest
5+
6+
pytestmark = pytest.mark.backup
7+
8+
_state: dict = {}
9+
10+
_BACKUP_POLL_SEC = 15
11+
_BACKUP_TIMEOUT_SEC = 300
12+
13+
14+
@pytest.fixture(scope="module")
15+
def org(make_org):
16+
return make_org("test-org-schedules", max_backups=10)
17+
18+
19+
@pytest.fixture(scope="module")
20+
def project(make_project, org):
21+
return make_project(org, "test-project-schedules", max_backups=10)
22+
23+
24+
@pytest.fixture(scope="module")
25+
def branch_id(make_branch, org, project):
26+
return make_branch(org, project, "test-branch-schedules")
27+
28+
29+
def test_scheduled_backup_created_on_time(client, branch_id):
30+
"""Create a 1-min schedule, wait for the backup monitor to fire,
31+
and verify the backup arrives on time with a valid PVC snapshot."""
32+
r = client.post(
33+
f"backup/branches/{branch_id}/schedule",
34+
json={"rows": [{"row_index": 0, "interval": 1, "unit": "min", "retention": 3}]},
35+
)
36+
assert r.status_code == 200
37+
_state["sched_id"] = r.json()["schedule_id"]
38+
39+
# Wait for the backup monitor to initialise NextBackup records
40+
deadline = time.monotonic() + _BACKUP_TIMEOUT_SEC
41+
info = None
42+
while time.monotonic() < deadline:
43+
r = client.get(f"backup/branches/{branch_id}/info")
44+
if r.status_code == 200:
45+
info = r.json()
46+
break
47+
time.sleep(_BACKUP_POLL_SEC)
48+
assert info is not None, "Backup info endpoint never became available"
49+
expected_next = datetime.fromisoformat(info["next_backup"])
50+
51+
# Poll until a scheduled backup (row_index == 0) appears
52+
backup = None
53+
while time.monotonic() < deadline:
54+
r = client.get(f"backup/branches/{branch_id}/")
55+
assert r.status_code == 200
56+
scheduled = [b for b in r.json() if b["row_index"] == 0]
57+
if scheduled:
58+
backup = scheduled[0]
59+
break
60+
time.sleep(_BACKUP_POLL_SEC)
61+
62+
assert backup is not None, "Scheduled backup was not created within timeout"
63+
assert backup["size_bytes"] > 0, "PVC snapshot was not created (size_bytes is 0)"
64+
65+
created_at = datetime.fromisoformat(backup["created_at"])
66+
drift = abs((created_at - expected_next).total_seconds())
67+
assert drift < 180, f"Backup created {drift:.0f}s from expected time ({expected_next})"
68+
69+
_state["scheduled_backup_id"] = backup["id"]
70+
71+
72+
def test_scheduled_backup_cleanup(client):
73+
r = client.delete(f"backup/{_state['scheduled_backup_id']}", timeout=120)
74+
assert r.status_code == 200
75+
76+
r = client.delete(f"backup/schedule/{_state['sched_id']}/")
77+
assert r.status_code == 200
78+
assert r.json()["status"] == "success"

0 commit comments

Comments
 (0)