mirror of
https://git.selfprivacy.org/SelfPrivacy/selfprivacy-rest-api.git
synced 2024-11-21 19:51:28 +00:00
test(backups): separate autobackup tests to a file (was a bit of a mess)
This commit is contained in:
parent
7ec62a8f79
commit
c38e066507
538
tests/test_autobackup.py
Normal file
538
tests/test_autobackup.py
Normal file
|
@ -0,0 +1,538 @@
|
|||
import pytest
|
||||
from copy import copy
|
||||
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
from selfprivacy_api.jobs import Jobs
|
||||
from selfprivacy_api.services import Service, get_all_services
|
||||
|
||||
from selfprivacy_api.graphql.common_types.backup import (
|
||||
BackupReason,
|
||||
AutobackupQuotas,
|
||||
)
|
||||
|
||||
from selfprivacy_api.backup import Backups, Snapshot
|
||||
from selfprivacy_api.backup.tasks import (
|
||||
prune_autobackup_snapshots,
|
||||
)
|
||||
|
||||
from tests.test_backup import backups
|
||||
|
||||
|
||||
def backuppable_services() -> list[Service]:
|
||||
return [service for service in get_all_services() if service.can_be_backed_up()]
|
||||
|
||||
|
||||
def dummy_snapshot(date: datetime):
|
||||
return Snapshot(
|
||||
id=str(hash(date)),
|
||||
service_name="someservice",
|
||||
created_at=date,
|
||||
reason=BackupReason.EXPLICIT,
|
||||
)
|
||||
|
||||
|
||||
def test_no_default_autobackup(backups, dummy_service):
|
||||
now = datetime.now(timezone.utc)
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, now)
|
||||
assert not Backups.is_time_to_backup(now)
|
||||
|
||||
|
||||
# --------------------- Timing -------------------------
|
||||
|
||||
|
||||
def test_set_autobackup_period(backups):
|
||||
assert Backups.autobackup_period_minutes() is None
|
||||
|
||||
Backups.set_autobackup_period_minutes(2)
|
||||
assert Backups.autobackup_period_minutes() == 2
|
||||
|
||||
Backups.disable_all_autobackup()
|
||||
assert Backups.autobackup_period_minutes() is None
|
||||
|
||||
Backups.set_autobackup_period_minutes(3)
|
||||
assert Backups.autobackup_period_minutes() == 3
|
||||
|
||||
Backups.set_autobackup_period_minutes(0)
|
||||
assert Backups.autobackup_period_minutes() is None
|
||||
|
||||
Backups.set_autobackup_period_minutes(3)
|
||||
assert Backups.autobackup_period_minutes() == 3
|
||||
|
||||
Backups.set_autobackup_period_minutes(-1)
|
||||
assert Backups.autobackup_period_minutes() is None
|
||||
|
||||
|
||||
def test_autobackup_timer_periods(backups, dummy_service):
|
||||
now = datetime.now(timezone.utc)
|
||||
backup_period = 13 # minutes
|
||||
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, now)
|
||||
assert not Backups.is_time_to_backup(now)
|
||||
|
||||
Backups.set_autobackup_period_minutes(backup_period)
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now)
|
||||
assert Backups.is_time_to_backup(now)
|
||||
|
||||
Backups.set_autobackup_period_minutes(0)
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, now)
|
||||
assert not Backups.is_time_to_backup(now)
|
||||
|
||||
|
||||
def test_autobackup_timer_enabling(backups, dummy_service):
|
||||
now = datetime.now(timezone.utc)
|
||||
backup_period = 13 # minutes
|
||||
dummy_service.set_backuppable(False)
|
||||
|
||||
Backups.set_autobackup_period_minutes(backup_period)
|
||||
assert Backups.is_time_to_backup(
|
||||
now
|
||||
) # there are other services too, not just our dummy
|
||||
|
||||
# not backuppable service is not backuppable even if period is set
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, now)
|
||||
|
||||
dummy_service.set_backuppable(True)
|
||||
assert dummy_service.can_be_backed_up()
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now)
|
||||
|
||||
Backups.disable_all_autobackup()
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, now)
|
||||
assert not Backups.is_time_to_backup(now)
|
||||
|
||||
|
||||
def test_autobackup_timing(backups, dummy_service):
|
||||
backup_period = 13 # minutes
|
||||
now = datetime.now(timezone.utc)
|
||||
|
||||
Backups.set_autobackup_period_minutes(backup_period)
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now)
|
||||
assert Backups.is_time_to_backup(now)
|
||||
|
||||
Backups.back_up(dummy_service)
|
||||
|
||||
now = datetime.now(timezone.utc)
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, now)
|
||||
|
||||
past = datetime.now(timezone.utc) - timedelta(minutes=1)
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, past)
|
||||
|
||||
future = datetime.now(timezone.utc) + timedelta(minutes=backup_period + 2)
|
||||
assert Backups.is_time_to_backup_service(dummy_service, future)
|
||||
|
||||
|
||||
# --------------------- What to autobackup and what not to --------------------
|
||||
|
||||
|
||||
def test_services_to_autobackup(backups, dummy_service):
|
||||
backup_period = 13 # minutes
|
||||
now = datetime.now(timezone.utc)
|
||||
|
||||
dummy_service.set_backuppable(False)
|
||||
services = Backups.services_to_back_up(now)
|
||||
assert len(services) == 0
|
||||
|
||||
dummy_service.set_backuppable(True)
|
||||
|
||||
services = Backups.services_to_back_up(now)
|
||||
assert len(services) == 0
|
||||
|
||||
Backups.set_autobackup_period_minutes(backup_period)
|
||||
|
||||
services = Backups.services_to_back_up(now)
|
||||
assert len(services) == len(backuppable_services())
|
||||
assert dummy_service.get_id() in [
|
||||
service.get_id() for service in backuppable_services()
|
||||
]
|
||||
|
||||
|
||||
def test_do_not_autobackup_disabled_services(backups, dummy_service):
|
||||
now = datetime.now(timezone.utc)
|
||||
Backups.set_autobackup_period_minutes(3)
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now) is True
|
||||
|
||||
dummy_service.disable()
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now) is False
|
||||
|
||||
|
||||
def test_failed_autoback_prevents_more_autobackup(backups, dummy_service):
|
||||
backup_period = 13 # minutes
|
||||
now = datetime.now(timezone.utc)
|
||||
|
||||
Backups.set_autobackup_period_minutes(backup_period)
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now)
|
||||
|
||||
# artificially making an errored out backup job
|
||||
dummy_service.set_backuppable(False)
|
||||
with pytest.raises(ValueError):
|
||||
Backups.back_up(dummy_service)
|
||||
dummy_service.set_backuppable(True)
|
||||
|
||||
assert Backups.get_last_backed_up(dummy_service) is None
|
||||
assert Backups.get_last_backup_error_time(dummy_service) is not None
|
||||
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now) is False
|
||||
|
||||
|
||||
# --------------------- Quotas and Pruning -------------------------
|
||||
|
||||
|
||||
unlimited_quotas = AutobackupQuotas(
|
||||
last=-1,
|
||||
daily=-1,
|
||||
weekly=-1,
|
||||
monthly=-1,
|
||||
yearly=-1,
|
||||
)
|
||||
|
||||
zero_quotas = AutobackupQuotas(
|
||||
last=0,
|
||||
daily=0,
|
||||
weekly=0,
|
||||
monthly=0,
|
||||
yearly=0,
|
||||
)
|
||||
|
||||
unlimited_quotas = AutobackupQuotas(
|
||||
last=-1,
|
||||
daily=-1,
|
||||
weekly=-1,
|
||||
monthly=-1,
|
||||
yearly=-1,
|
||||
)
|
||||
|
||||
zero_quotas = AutobackupQuotas(
|
||||
last=0,
|
||||
daily=0,
|
||||
weekly=0,
|
||||
monthly=0,
|
||||
yearly=0,
|
||||
)
|
||||
|
||||
|
||||
def test_get_empty_quotas(backups):
|
||||
quotas = Backups.autobackup_quotas()
|
||||
assert quotas is not None
|
||||
assert quotas == unlimited_quotas
|
||||
|
||||
|
||||
def test_set_quotas(backups):
|
||||
quotas = AutobackupQuotas(
|
||||
last=3,
|
||||
daily=2343,
|
||||
weekly=343,
|
||||
monthly=0,
|
||||
yearly=-34556,
|
||||
)
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
assert Backups.autobackup_quotas() == AutobackupQuotas(
|
||||
last=3,
|
||||
daily=2343,
|
||||
weekly=343,
|
||||
monthly=0,
|
||||
yearly=-1,
|
||||
)
|
||||
|
||||
|
||||
def test_set_zero_quotas(backups):
|
||||
quotas = AutobackupQuotas(
|
||||
last=0,
|
||||
daily=0,
|
||||
weekly=0,
|
||||
monthly=0,
|
||||
yearly=0,
|
||||
)
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
assert Backups.autobackup_quotas() == zero_quotas
|
||||
|
||||
|
||||
def test_set_unlimited_quotas(backups):
|
||||
quotas = AutobackupQuotas(
|
||||
last=-1,
|
||||
daily=-1,
|
||||
weekly=-1,
|
||||
monthly=-1,
|
||||
yearly=-1,
|
||||
)
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
assert Backups.autobackup_quotas() == unlimited_quotas
|
||||
|
||||
|
||||
def test_set_zero_quotas_after_unlimited(backups):
|
||||
quotas = AutobackupQuotas(
|
||||
last=-1,
|
||||
daily=-1,
|
||||
weekly=-1,
|
||||
monthly=-1,
|
||||
yearly=-1,
|
||||
)
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
assert Backups.autobackup_quotas() == unlimited_quotas
|
||||
|
||||
quotas = AutobackupQuotas(
|
||||
last=0,
|
||||
daily=0,
|
||||
weekly=0,
|
||||
monthly=0,
|
||||
yearly=0,
|
||||
)
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
assert Backups.autobackup_quotas() == zero_quotas
|
||||
|
||||
|
||||
def test_autobackup_snapshots_pruning(backups):
|
||||
# Wednesday, fourth week
|
||||
now = datetime(year=2023, month=1, day=25, hour=10)
|
||||
|
||||
snaps = [
|
||||
dummy_snapshot(now),
|
||||
dummy_snapshot(now - timedelta(minutes=5)),
|
||||
dummy_snapshot(now - timedelta(hours=2)),
|
||||
dummy_snapshot(now - timedelta(hours=5)),
|
||||
dummy_snapshot(now - timedelta(days=1)),
|
||||
dummy_snapshot(now - timedelta(days=1, hours=2)),
|
||||
dummy_snapshot(now - timedelta(days=1, hours=3)),
|
||||
dummy_snapshot(now - timedelta(days=2)),
|
||||
dummy_snapshot(now - timedelta(days=7)),
|
||||
dummy_snapshot(now - timedelta(days=12)),
|
||||
dummy_snapshot(now - timedelta(days=23)),
|
||||
dummy_snapshot(now - timedelta(days=28)),
|
||||
dummy_snapshot(now - timedelta(days=32)),
|
||||
dummy_snapshot(now - timedelta(days=47)),
|
||||
dummy_snapshot(now - timedelta(days=64)),
|
||||
dummy_snapshot(now - timedelta(days=84)),
|
||||
dummy_snapshot(now - timedelta(days=104)),
|
||||
dummy_snapshot(now - timedelta(days=365 * 2)),
|
||||
]
|
||||
old_len = len(snaps)
|
||||
|
||||
quotas = copy(unlimited_quotas)
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
assert Backups._prune_snaps_with_quotas(snaps) == snaps
|
||||
|
||||
quotas = copy(zero_quotas)
|
||||
quotas.last = 2
|
||||
quotas.daily = 2
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(now),
|
||||
dummy_snapshot(now - timedelta(minutes=5)),
|
||||
# dummy_snapshot(now - timedelta(hours=2)),
|
||||
# dummy_snapshot(now - timedelta(hours=5)),
|
||||
dummy_snapshot(now - timedelta(days=1)),
|
||||
# dummy_snapshot(now - timedelta(days=1, hours=2)),
|
||||
# dummy_snapshot(now - timedelta(days=1, hours=3)),
|
||||
# dummy_snapshot(now - timedelta(days=2)),
|
||||
# dummy_snapshot(now - timedelta(days=7)),
|
||||
# dummy_snapshot(now - timedelta(days=12)),
|
||||
# dummy_snapshot(now - timedelta(days=23)),
|
||||
# dummy_snapshot(now - timedelta(days=28)),
|
||||
# dummy_snapshot(now - timedelta(days=32)),
|
||||
# dummy_snapshot(now - timedelta(days=47)),
|
||||
# dummy_snapshot(now - timedelta(days=64)),
|
||||
# dummy_snapshot(now - timedelta(days=84)),
|
||||
# dummy_snapshot(now - timedelta(days=104)),
|
||||
# dummy_snapshot(now - timedelta(days=365 * 2)),
|
||||
]
|
||||
|
||||
# checking that this function does not mutate the argument
|
||||
assert snaps != snaps_to_keep
|
||||
assert len(snaps) == old_len
|
||||
|
||||
quotas = copy(zero_quotas)
|
||||
quotas.weekly = 4
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(now),
|
||||
# dummy_snapshot(now - timedelta(minutes=5)),
|
||||
# dummy_snapshot(now - timedelta(hours=2)),
|
||||
# dummy_snapshot(now - timedelta(hours=5)),
|
||||
# dummy_snapshot(now - timedelta(days=1)),
|
||||
# dummy_snapshot(now - timedelta(days=1, hours=2)),
|
||||
# dummy_snapshot(now - timedelta(days=1, hours=3)),
|
||||
# dummy_snapshot(now - timedelta(days=2)),
|
||||
dummy_snapshot(now - timedelta(days=7)),
|
||||
dummy_snapshot(now - timedelta(days=12)),
|
||||
dummy_snapshot(now - timedelta(days=23)),
|
||||
# dummy_snapshot(now - timedelta(days=28)),
|
||||
# dummy_snapshot(now - timedelta(days=32)),
|
||||
# dummy_snapshot(now - timedelta(days=47)),
|
||||
# dummy_snapshot(now - timedelta(days=64)),
|
||||
# dummy_snapshot(now - timedelta(days=84)),
|
||||
# dummy_snapshot(now - timedelta(days=104)),
|
||||
# dummy_snapshot(now - timedelta(days=365 * 2)),
|
||||
]
|
||||
|
||||
quotas = copy(zero_quotas)
|
||||
quotas.monthly = 7
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(now),
|
||||
# dummy_snapshot(now - timedelta(minutes=5)),
|
||||
# dummy_snapshot(now - timedelta(hours=2)),
|
||||
# dummy_snapshot(now - timedelta(hours=5)),
|
||||
# dummy_snapshot(now - timedelta(days=1)),
|
||||
# dummy_snapshot(now - timedelta(days=1, hours=2)),
|
||||
# dummy_snapshot(now - timedelta(days=1, hours=3)),
|
||||
# dummy_snapshot(now - timedelta(days=2)),
|
||||
# dummy_snapshot(now - timedelta(days=7)),
|
||||
# dummy_snapshot(now - timedelta(days=12)),
|
||||
# dummy_snapshot(now - timedelta(days=23)),
|
||||
dummy_snapshot(now - timedelta(days=28)),
|
||||
# dummy_snapshot(now - timedelta(days=32)),
|
||||
# dummy_snapshot(now - timedelta(days=47)),
|
||||
dummy_snapshot(now - timedelta(days=64)),
|
||||
# dummy_snapshot(now - timedelta(days=84)),
|
||||
dummy_snapshot(now - timedelta(days=104)),
|
||||
dummy_snapshot(now - timedelta(days=365 * 2)),
|
||||
]
|
||||
|
||||
|
||||
def test_autobackup_snapshots_pruning_yearly(backups):
|
||||
snaps = [
|
||||
dummy_snapshot(datetime(year=2055, month=3, day=1)),
|
||||
dummy_snapshot(datetime(year=2055, month=2, day=1)),
|
||||
dummy_snapshot(datetime(year=2023, month=4, day=1)),
|
||||
dummy_snapshot(datetime(year=2023, month=3, day=1)),
|
||||
dummy_snapshot(datetime(year=2023, month=2, day=1)),
|
||||
dummy_snapshot(datetime(year=2021, month=2, day=1)),
|
||||
]
|
||||
quotas = copy(zero_quotas)
|
||||
quotas.yearly = 2
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(datetime(year=2055, month=3, day=1)),
|
||||
dummy_snapshot(datetime(year=2023, month=4, day=1)),
|
||||
]
|
||||
|
||||
|
||||
def test_autobackup_snapshots_pruning_bottleneck(backups):
|
||||
now = datetime(year=2023, month=1, day=25, hour=10)
|
||||
snaps = [
|
||||
dummy_snapshot(now),
|
||||
dummy_snapshot(now - timedelta(minutes=5)),
|
||||
dummy_snapshot(now - timedelta(hours=2)),
|
||||
dummy_snapshot(now - timedelta(hours=3)),
|
||||
dummy_snapshot(now - timedelta(hours=4)),
|
||||
]
|
||||
|
||||
yearly_quota = copy(zero_quotas)
|
||||
yearly_quota.yearly = 2
|
||||
|
||||
monthly_quota = copy(zero_quotas)
|
||||
monthly_quota.monthly = 2
|
||||
|
||||
weekly_quota = copy(zero_quotas)
|
||||
weekly_quota.weekly = 2
|
||||
|
||||
daily_quota = copy(zero_quotas)
|
||||
daily_quota.daily = 2
|
||||
|
||||
last_quota = copy(zero_quotas)
|
||||
last_quota.last = 1
|
||||
last_quota.yearly = 2
|
||||
|
||||
for quota in [last_quota, yearly_quota, monthly_quota, weekly_quota, daily_quota]:
|
||||
print(quota)
|
||||
Backups.set_autobackup_quotas(quota)
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(now),
|
||||
# If there is a vacant quota, we should keep the last snapshot even if it doesn't fit
|
||||
dummy_snapshot(now - timedelta(hours=4)),
|
||||
]
|
||||
|
||||
|
||||
def test_autobackup_snapshots_pruning_edgeweek(backups):
|
||||
# jan 1 2023 is Sunday
|
||||
snaps = [
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=6)),
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=1)),
|
||||
dummy_snapshot(datetime(year=2022, month=12, day=31)),
|
||||
dummy_snapshot(datetime(year=2022, month=12, day=30)),
|
||||
]
|
||||
quotas = copy(zero_quotas)
|
||||
quotas.weekly = 2
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=6)),
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=1)),
|
||||
]
|
||||
|
||||
|
||||
def test_autobackup_snapshots_pruning_big_gap(backups):
|
||||
snaps = [
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=6)),
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=2)),
|
||||
dummy_snapshot(datetime(year=2022, month=10, day=31)),
|
||||
dummy_snapshot(datetime(year=2022, month=10, day=30)),
|
||||
]
|
||||
quotas = copy(zero_quotas)
|
||||
quotas.weekly = 2
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=6)),
|
||||
dummy_snapshot(datetime(year=2022, month=10, day=31)),
|
||||
]
|
||||
|
||||
|
||||
def test_quotas_exceeded_with_too_many_autobackups(backups, dummy_service):
|
||||
assert Backups.autobackup_quotas()
|
||||
quota = copy(zero_quotas)
|
||||
quota.last = 2
|
||||
Backups.set_autobackup_quotas(quota)
|
||||
assert Backups.autobackup_quotas().last == 2
|
||||
|
||||
snap = Backups.back_up(dummy_service, BackupReason.AUTO)
|
||||
assert len(Backups.get_snapshots(dummy_service)) == 1
|
||||
snap2 = Backups.back_up(dummy_service, BackupReason.AUTO)
|
||||
assert len(Backups.get_snapshots(dummy_service)) == 2
|
||||
snap3 = Backups.back_up(dummy_service, BackupReason.AUTO)
|
||||
assert len(Backups.get_snapshots(dummy_service)) == 2
|
||||
|
||||
snaps = Backups.get_snapshots(dummy_service)
|
||||
assert snap2 in snaps
|
||||
assert snap3 in snaps
|
||||
assert snap not in snaps
|
||||
|
||||
quota.last = -1
|
||||
Backups.set_autobackup_quotas(quota)
|
||||
snap4 = Backups.back_up(dummy_service, BackupReason.AUTO)
|
||||
|
||||
snaps = Backups.get_snapshots(dummy_service)
|
||||
assert len(snaps) == 3
|
||||
assert snap4 in snaps
|
||||
|
||||
# Retroactivity
|
||||
quota.last = 1
|
||||
Backups.set_autobackup_quotas(quota)
|
||||
job = Jobs.add("trimming", "test.autobackup_trimming", "trimming the snaps!")
|
||||
handle = prune_autobackup_snapshots(job)
|
||||
handle(blocking=True)
|
||||
snaps = Backups.get_snapshots(dummy_service)
|
||||
assert len(snaps) == 1
|
||||
|
||||
snap5 = Backups.back_up(dummy_service, BackupReason.AUTO)
|
||||
snaps = Backups.get_snapshots(dummy_service)
|
||||
assert len(snaps) == 1
|
||||
assert snap5 in snaps
|
||||
|
||||
# Explicit snaps are not affected
|
||||
snap6 = Backups.back_up(dummy_service, BackupReason.EXPLICIT)
|
||||
|
||||
snaps = Backups.get_snapshots(dummy_service)
|
||||
assert len(snaps) == 2
|
||||
assert snap5 in snaps
|
||||
assert snap6 in snaps
|
|
@ -7,25 +7,17 @@ from os import listdir
|
|||
from os import urandom
|
||||
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from copy import copy
|
||||
import tempfile
|
||||
|
||||
from selfprivacy_api.utils.huey import huey
|
||||
|
||||
import tempfile
|
||||
|
||||
from selfprivacy_api.utils.huey import huey
|
||||
|
||||
from selfprivacy_api.services import Service, get_all_services
|
||||
from selfprivacy_api.services import get_service_by_id
|
||||
from selfprivacy_api.services.service import ServiceStatus
|
||||
from selfprivacy_api.services.test_service import DummyService
|
||||
|
||||
from selfprivacy_api.graphql.queries.providers import BackupProvider
|
||||
from selfprivacy_api.graphql.common_types.backup import (
|
||||
RestoreStrategy,
|
||||
BackupReason,
|
||||
AutobackupQuotas,
|
||||
)
|
||||
|
||||
from selfprivacy_api.jobs import Jobs, JobStatus
|
||||
|
@ -43,7 +35,6 @@ from selfprivacy_api.backup.tasks import (
|
|||
start_backup,
|
||||
restore_snapshot,
|
||||
reload_snapshot_cache,
|
||||
prune_autobackup_snapshots,
|
||||
)
|
||||
from selfprivacy_api.backup.storage import Storage
|
||||
|
||||
|
@ -218,16 +209,6 @@ def test_reinit_after_purge(backups):
|
|||
assert len(Backups.get_all_snapshots()) == 0
|
||||
|
||||
|
||||
def test_backup_simple_file(raw_dummy_service, file_backup):
|
||||
# temporarily incomplete
|
||||
service = raw_dummy_service
|
||||
assert service is not None
|
||||
assert file_backup is not None
|
||||
|
||||
name = service.get_id()
|
||||
file_backup.backupper.init()
|
||||
|
||||
|
||||
def test_backup_service(dummy_service, backups):
|
||||
id = dummy_service.get_id()
|
||||
assert_job_finished(f"services.{id}.backup", count=0)
|
||||
|
@ -281,360 +262,6 @@ def test_backup_reasons(backups, dummy_service):
|
|||
assert snaps[0].reason == BackupReason.AUTO
|
||||
|
||||
|
||||
unlimited_quotas = AutobackupQuotas(
|
||||
last=-1,
|
||||
daily=-1,
|
||||
weekly=-1,
|
||||
monthly=-1,
|
||||
yearly=-1,
|
||||
)
|
||||
|
||||
zero_quotas = AutobackupQuotas(
|
||||
last=0,
|
||||
daily=0,
|
||||
weekly=0,
|
||||
monthly=0,
|
||||
yearly=0,
|
||||
)
|
||||
|
||||
|
||||
def test_get_empty_quotas(backups):
|
||||
quotas = Backups.autobackup_quotas()
|
||||
assert quotas is not None
|
||||
assert quotas == unlimited_quotas
|
||||
|
||||
|
||||
def test_set_quotas(backups):
|
||||
quotas = AutobackupQuotas(
|
||||
last=3,
|
||||
daily=2343,
|
||||
weekly=343,
|
||||
monthly=0,
|
||||
yearly=-34556,
|
||||
)
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
assert Backups.autobackup_quotas() == AutobackupQuotas(
|
||||
last=3,
|
||||
daily=2343,
|
||||
weekly=343,
|
||||
monthly=0,
|
||||
yearly=-1,
|
||||
)
|
||||
|
||||
|
||||
def test_set_zero_quotas(backups):
|
||||
quotas = AutobackupQuotas(
|
||||
last=0,
|
||||
daily=0,
|
||||
weekly=0,
|
||||
monthly=0,
|
||||
yearly=0,
|
||||
)
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
assert Backups.autobackup_quotas() == zero_quotas
|
||||
|
||||
|
||||
def test_set_unlimited_quotas(backups):
|
||||
quotas = AutobackupQuotas(
|
||||
last=-1,
|
||||
daily=-1,
|
||||
weekly=-1,
|
||||
monthly=-1,
|
||||
yearly=-1,
|
||||
)
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
assert Backups.autobackup_quotas() == unlimited_quotas
|
||||
|
||||
|
||||
def test_set_zero_quotas_after_unlimited(backups):
|
||||
quotas = AutobackupQuotas(
|
||||
last=-1,
|
||||
daily=-1,
|
||||
weekly=-1,
|
||||
monthly=-1,
|
||||
yearly=-1,
|
||||
)
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
assert Backups.autobackup_quotas() == unlimited_quotas
|
||||
|
||||
quotas = AutobackupQuotas(
|
||||
last=0,
|
||||
daily=0,
|
||||
weekly=0,
|
||||
monthly=0,
|
||||
yearly=0,
|
||||
)
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
assert Backups.autobackup_quotas() == zero_quotas
|
||||
|
||||
|
||||
def dummy_snapshot(date: datetime):
|
||||
return Snapshot(
|
||||
id=str(hash(date)),
|
||||
service_name="someservice",
|
||||
created_at=date,
|
||||
reason=BackupReason.EXPLICIT,
|
||||
)
|
||||
|
||||
|
||||
def test_autobackup_snapshots_pruning(backups):
|
||||
# Wednesday, fourth week
|
||||
now = datetime(year=2023, month=1, day=25, hour=10)
|
||||
|
||||
snaps = [
|
||||
dummy_snapshot(now),
|
||||
dummy_snapshot(now - timedelta(minutes=5)),
|
||||
dummy_snapshot(now - timedelta(hours=2)),
|
||||
dummy_snapshot(now - timedelta(hours=5)),
|
||||
dummy_snapshot(now - timedelta(days=1)),
|
||||
dummy_snapshot(now - timedelta(days=1, hours=2)),
|
||||
dummy_snapshot(now - timedelta(days=1, hours=3)),
|
||||
dummy_snapshot(now - timedelta(days=2)),
|
||||
dummy_snapshot(now - timedelta(days=7)),
|
||||
dummy_snapshot(now - timedelta(days=12)),
|
||||
dummy_snapshot(now - timedelta(days=23)),
|
||||
dummy_snapshot(now - timedelta(days=28)),
|
||||
dummy_snapshot(now - timedelta(days=32)),
|
||||
dummy_snapshot(now - timedelta(days=47)),
|
||||
dummy_snapshot(now - timedelta(days=64)),
|
||||
dummy_snapshot(now - timedelta(days=84)),
|
||||
dummy_snapshot(now - timedelta(days=104)),
|
||||
dummy_snapshot(now - timedelta(days=365 * 2)),
|
||||
]
|
||||
old_len = len(snaps)
|
||||
|
||||
quotas = copy(unlimited_quotas)
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
assert Backups._prune_snaps_with_quotas(snaps) == snaps
|
||||
|
||||
quotas = copy(zero_quotas)
|
||||
quotas.last = 2
|
||||
quotas.daily = 2
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(now),
|
||||
dummy_snapshot(now - timedelta(minutes=5)),
|
||||
# dummy_snapshot(now - timedelta(hours=2)),
|
||||
# dummy_snapshot(now - timedelta(hours=5)),
|
||||
dummy_snapshot(now - timedelta(days=1)),
|
||||
# dummy_snapshot(now - timedelta(days=1, hours=2)),
|
||||
# dummy_snapshot(now - timedelta(days=1, hours=3)),
|
||||
# dummy_snapshot(now - timedelta(days=2)),
|
||||
# dummy_snapshot(now - timedelta(days=7)),
|
||||
# dummy_snapshot(now - timedelta(days=12)),
|
||||
# dummy_snapshot(now - timedelta(days=23)),
|
||||
# dummy_snapshot(now - timedelta(days=28)),
|
||||
# dummy_snapshot(now - timedelta(days=32)),
|
||||
# dummy_snapshot(now - timedelta(days=47)),
|
||||
# dummy_snapshot(now - timedelta(days=64)),
|
||||
# dummy_snapshot(now - timedelta(days=84)),
|
||||
# dummy_snapshot(now - timedelta(days=104)),
|
||||
# dummy_snapshot(now - timedelta(days=365 * 2)),
|
||||
]
|
||||
|
||||
# checking that this function does not mutate the argument
|
||||
assert snaps != snaps_to_keep
|
||||
assert len(snaps) == old_len
|
||||
|
||||
quotas = copy(zero_quotas)
|
||||
quotas.weekly = 4
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(now),
|
||||
# dummy_snapshot(now - timedelta(minutes=5)),
|
||||
# dummy_snapshot(now - timedelta(hours=2)),
|
||||
# dummy_snapshot(now - timedelta(hours=5)),
|
||||
# dummy_snapshot(now - timedelta(days=1)),
|
||||
# dummy_snapshot(now - timedelta(days=1, hours=2)),
|
||||
# dummy_snapshot(now - timedelta(days=1, hours=3)),
|
||||
# dummy_snapshot(now - timedelta(days=2)),
|
||||
dummy_snapshot(now - timedelta(days=7)),
|
||||
dummy_snapshot(now - timedelta(days=12)),
|
||||
dummy_snapshot(now - timedelta(days=23)),
|
||||
# dummy_snapshot(now - timedelta(days=28)),
|
||||
# dummy_snapshot(now - timedelta(days=32)),
|
||||
# dummy_snapshot(now - timedelta(days=47)),
|
||||
# dummy_snapshot(now - timedelta(days=64)),
|
||||
# dummy_snapshot(now - timedelta(days=84)),
|
||||
# dummy_snapshot(now - timedelta(days=104)),
|
||||
# dummy_snapshot(now - timedelta(days=365 * 2)),
|
||||
]
|
||||
|
||||
quotas = copy(zero_quotas)
|
||||
quotas.monthly = 7
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(now),
|
||||
# dummy_snapshot(now - timedelta(minutes=5)),
|
||||
# dummy_snapshot(now - timedelta(hours=2)),
|
||||
# dummy_snapshot(now - timedelta(hours=5)),
|
||||
# dummy_snapshot(now - timedelta(days=1)),
|
||||
# dummy_snapshot(now - timedelta(days=1, hours=2)),
|
||||
# dummy_snapshot(now - timedelta(days=1, hours=3)),
|
||||
# dummy_snapshot(now - timedelta(days=2)),
|
||||
# dummy_snapshot(now - timedelta(days=7)),
|
||||
# dummy_snapshot(now - timedelta(days=12)),
|
||||
# dummy_snapshot(now - timedelta(days=23)),
|
||||
dummy_snapshot(now - timedelta(days=28)),
|
||||
# dummy_snapshot(now - timedelta(days=32)),
|
||||
# dummy_snapshot(now - timedelta(days=47)),
|
||||
dummy_snapshot(now - timedelta(days=64)),
|
||||
# dummy_snapshot(now - timedelta(days=84)),
|
||||
dummy_snapshot(now - timedelta(days=104)),
|
||||
dummy_snapshot(now - timedelta(days=365 * 2)),
|
||||
]
|
||||
|
||||
|
||||
def test_autobackup_snapshots_pruning_yearly(backups):
|
||||
snaps = [
|
||||
dummy_snapshot(datetime(year=2055, month=3, day=1)),
|
||||
dummy_snapshot(datetime(year=2055, month=2, day=1)),
|
||||
dummy_snapshot(datetime(year=2023, month=4, day=1)),
|
||||
dummy_snapshot(datetime(year=2023, month=3, day=1)),
|
||||
dummy_snapshot(datetime(year=2023, month=2, day=1)),
|
||||
dummy_snapshot(datetime(year=2021, month=2, day=1)),
|
||||
]
|
||||
quotas = copy(zero_quotas)
|
||||
quotas.yearly = 2
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(datetime(year=2055, month=3, day=1)),
|
||||
dummy_snapshot(datetime(year=2023, month=4, day=1)),
|
||||
]
|
||||
|
||||
|
||||
def test_autobackup_snapshots_pruning_bottleneck(backups):
|
||||
now = datetime(year=2023, month=1, day=25, hour=10)
|
||||
snaps = [
|
||||
dummy_snapshot(now),
|
||||
dummy_snapshot(now - timedelta(minutes=5)),
|
||||
dummy_snapshot(now - timedelta(hours=2)),
|
||||
dummy_snapshot(now - timedelta(hours=3)),
|
||||
dummy_snapshot(now - timedelta(hours=4)),
|
||||
]
|
||||
|
||||
yearly_quota = copy(zero_quotas)
|
||||
yearly_quota.yearly = 2
|
||||
|
||||
monthly_quota = copy(zero_quotas)
|
||||
monthly_quota.monthly = 2
|
||||
|
||||
weekly_quota = copy(zero_quotas)
|
||||
weekly_quota.weekly = 2
|
||||
|
||||
daily_quota = copy(zero_quotas)
|
||||
daily_quota.daily = 2
|
||||
|
||||
last_quota = copy(zero_quotas)
|
||||
last_quota.last = 1
|
||||
last_quota.yearly = 2
|
||||
|
||||
for quota in [last_quota, yearly_quota, monthly_quota, weekly_quota, daily_quota]:
|
||||
print(quota)
|
||||
Backups.set_autobackup_quotas(quota)
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(now),
|
||||
# If there is a vacant quota, we should keep the last snapshot even if it doesn't fit
|
||||
dummy_snapshot(now - timedelta(hours=4)),
|
||||
]
|
||||
|
||||
|
||||
def test_autobackup_snapshots_pruning_edgeweek(backups):
|
||||
# jan 1 2023 is Sunday
|
||||
snaps = [
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=6)),
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=1)),
|
||||
dummy_snapshot(datetime(year=2022, month=12, day=31)),
|
||||
dummy_snapshot(datetime(year=2022, month=12, day=30)),
|
||||
]
|
||||
quotas = copy(zero_quotas)
|
||||
quotas.weekly = 2
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=6)),
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=1)),
|
||||
]
|
||||
|
||||
|
||||
def test_autobackup_snapshots_pruning_big_gap(backups):
|
||||
snaps = [
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=6)),
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=2)),
|
||||
dummy_snapshot(datetime(year=2022, month=10, day=31)),
|
||||
dummy_snapshot(datetime(year=2022, month=10, day=30)),
|
||||
]
|
||||
quotas = copy(zero_quotas)
|
||||
quotas.weekly = 2
|
||||
Backups.set_autobackup_quotas(quotas)
|
||||
|
||||
snaps_to_keep = Backups._prune_snaps_with_quotas(snaps)
|
||||
assert snaps_to_keep == [
|
||||
dummy_snapshot(datetime(year=2023, month=1, day=6)),
|
||||
dummy_snapshot(datetime(year=2022, month=10, day=31)),
|
||||
]
|
||||
|
||||
|
||||
def test_too_many_auto(backups, dummy_service):
|
||||
assert Backups.autobackup_quotas()
|
||||
quota = copy(zero_quotas)
|
||||
quota.last = 2
|
||||
Backups.set_autobackup_quotas(quota)
|
||||
assert Backups.autobackup_quotas().last == 2
|
||||
|
||||
snap = Backups.back_up(dummy_service, BackupReason.AUTO)
|
||||
assert len(Backups.get_snapshots(dummy_service)) == 1
|
||||
snap2 = Backups.back_up(dummy_service, BackupReason.AUTO)
|
||||
assert len(Backups.get_snapshots(dummy_service)) == 2
|
||||
snap3 = Backups.back_up(dummy_service, BackupReason.AUTO)
|
||||
assert len(Backups.get_snapshots(dummy_service)) == 2
|
||||
|
||||
snaps = Backups.get_snapshots(dummy_service)
|
||||
assert snap2 in snaps
|
||||
assert snap3 in snaps
|
||||
assert snap not in snaps
|
||||
|
||||
quota.last = -1
|
||||
Backups.set_autobackup_quotas(quota)
|
||||
snap4 = Backups.back_up(dummy_service, BackupReason.AUTO)
|
||||
|
||||
snaps = Backups.get_snapshots(dummy_service)
|
||||
assert len(snaps) == 3
|
||||
assert snap4 in snaps
|
||||
|
||||
# Retroactivity
|
||||
quota.last = 1
|
||||
Backups.set_autobackup_quotas(quota)
|
||||
job = Jobs.add("trimming", "test.autobackup_trimming", "trimming the snaps!")
|
||||
handle = prune_autobackup_snapshots(job)
|
||||
handle(blocking=True)
|
||||
snaps = Backups.get_snapshots(dummy_service)
|
||||
assert len(snaps) == 1
|
||||
|
||||
snap5 = Backups.back_up(dummy_service, BackupReason.AUTO)
|
||||
snaps = Backups.get_snapshots(dummy_service)
|
||||
assert len(snaps) == 1
|
||||
assert snap5 in snaps
|
||||
|
||||
# Explicit snaps are not affected
|
||||
snap6 = Backups.back_up(dummy_service, BackupReason.EXPLICIT)
|
||||
|
||||
snaps = Backups.get_snapshots(dummy_service)
|
||||
assert len(snaps) == 2
|
||||
assert snap5 in snaps
|
||||
assert snap6 in snaps
|
||||
|
||||
|
||||
def folder_files(folder):
|
||||
return [
|
||||
path.join(folder, filename)
|
||||
|
@ -857,127 +484,6 @@ def test_restore_snapshot_task(
|
|||
assert len(snaps) == 1
|
||||
|
||||
|
||||
def test_set_autobackup_period(backups):
|
||||
assert Backups.autobackup_period_minutes() is None
|
||||
|
||||
Backups.set_autobackup_period_minutes(2)
|
||||
assert Backups.autobackup_period_minutes() == 2
|
||||
|
||||
Backups.disable_all_autobackup()
|
||||
assert Backups.autobackup_period_minutes() is None
|
||||
|
||||
Backups.set_autobackup_period_minutes(3)
|
||||
assert Backups.autobackup_period_minutes() == 3
|
||||
|
||||
Backups.set_autobackup_period_minutes(0)
|
||||
assert Backups.autobackup_period_minutes() is None
|
||||
|
||||
Backups.set_autobackup_period_minutes(3)
|
||||
assert Backups.autobackup_period_minutes() == 3
|
||||
|
||||
Backups.set_autobackup_period_minutes(-1)
|
||||
assert Backups.autobackup_period_minutes() is None
|
||||
|
||||
|
||||
def test_no_default_autobackup(backups, dummy_service):
|
||||
now = datetime.now(timezone.utc)
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, now)
|
||||
assert not Backups.is_time_to_backup(now)
|
||||
|
||||
|
||||
def backuppable_services() -> list[Service]:
|
||||
return [service for service in get_all_services() if service.can_be_backed_up()]
|
||||
|
||||
|
||||
def test_services_to_autobackup(backups, dummy_service):
|
||||
backup_period = 13 # minutes
|
||||
now = datetime.now(timezone.utc)
|
||||
|
||||
dummy_service.set_backuppable(False)
|
||||
services = Backups.services_to_back_up(now)
|
||||
assert len(services) == 0
|
||||
|
||||
dummy_service.set_backuppable(True)
|
||||
|
||||
services = Backups.services_to_back_up(now)
|
||||
assert len(services) == 0
|
||||
|
||||
Backups.set_autobackup_period_minutes(backup_period)
|
||||
|
||||
services = Backups.services_to_back_up(now)
|
||||
assert len(services) == len(backuppable_services())
|
||||
assert dummy_service.get_id() in [
|
||||
service.get_id() for service in backuppable_services()
|
||||
]
|
||||
|
||||
|
||||
def test_do_not_autobackup_disabled_services(backups, dummy_service):
|
||||
now = datetime.now(timezone.utc)
|
||||
Backups.set_autobackup_period_minutes(3)
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now) is True
|
||||
|
||||
dummy_service.disable()
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now) is False
|
||||
|
||||
|
||||
def test_autobackup_timer_periods(backups, dummy_service):
|
||||
now = datetime.now(timezone.utc)
|
||||
backup_period = 13 # minutes
|
||||
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, now)
|
||||
assert not Backups.is_time_to_backup(now)
|
||||
|
||||
Backups.set_autobackup_period_minutes(backup_period)
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now)
|
||||
assert Backups.is_time_to_backup(now)
|
||||
|
||||
Backups.set_autobackup_period_minutes(0)
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, now)
|
||||
assert not Backups.is_time_to_backup(now)
|
||||
|
||||
|
||||
def test_autobackup_timer_enabling(backups, dummy_service):
|
||||
now = datetime.now(timezone.utc)
|
||||
backup_period = 13 # minutes
|
||||
dummy_service.set_backuppable(False)
|
||||
|
||||
Backups.set_autobackup_period_minutes(backup_period)
|
||||
assert Backups.is_time_to_backup(
|
||||
now
|
||||
) # there are other services too, not just our dummy
|
||||
|
||||
# not backuppable service is not backuppable even if period is set
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, now)
|
||||
|
||||
dummy_service.set_backuppable(True)
|
||||
assert dummy_service.can_be_backed_up()
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now)
|
||||
|
||||
Backups.disable_all_autobackup()
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, now)
|
||||
assert not Backups.is_time_to_backup(now)
|
||||
|
||||
|
||||
def test_autobackup_timing(backups, dummy_service):
|
||||
backup_period = 13 # minutes
|
||||
now = datetime.now(timezone.utc)
|
||||
|
||||
Backups.set_autobackup_period_minutes(backup_period)
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now)
|
||||
assert Backups.is_time_to_backup(now)
|
||||
|
||||
Backups.back_up(dummy_service)
|
||||
|
||||
now = datetime.now(timezone.utc)
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, now)
|
||||
|
||||
past = datetime.now(timezone.utc) - timedelta(minutes=1)
|
||||
assert not Backups.is_time_to_backup_service(dummy_service, past)
|
||||
|
||||
future = datetime.now(timezone.utc) + timedelta(minutes=backup_period + 2)
|
||||
assert Backups.is_time_to_backup_service(dummy_service, future)
|
||||
|
||||
|
||||
def test_backup_unbackuppable(backups, dummy_service):
|
||||
dummy_service.set_backuppable(False)
|
||||
assert dummy_service.can_be_backed_up() is False
|
||||
|
@ -985,25 +491,6 @@ def test_backup_unbackuppable(backups, dummy_service):
|
|||
Backups.back_up(dummy_service)
|
||||
|
||||
|
||||
def test_failed_autoback_prevents_more_autobackup(backups, dummy_service):
|
||||
backup_period = 13 # minutes
|
||||
now = datetime.now(timezone.utc)
|
||||
|
||||
Backups.set_autobackup_period_minutes(backup_period)
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now)
|
||||
|
||||
# artificially making an errored out backup job
|
||||
dummy_service.set_backuppable(False)
|
||||
with pytest.raises(ValueError):
|
||||
Backups.back_up(dummy_service)
|
||||
dummy_service.set_backuppable(True)
|
||||
|
||||
assert Backups.get_last_backed_up(dummy_service) is None
|
||||
assert Backups.get_last_backup_error_time(dummy_service) is not None
|
||||
|
||||
assert Backups.is_time_to_backup_service(dummy_service, now) is False
|
||||
|
||||
|
||||
# Storage
|
||||
def test_snapshots_caching(backups, dummy_service):
|
||||
Backups.back_up(dummy_service)
|
||||
|
|
Loading…
Reference in a new issue