diff --git a/selfprivacy_api/backup/__init__.py b/selfprivacy_api/backup/__init__.py index 83ed569..25522a5 100644 --- a/selfprivacy_api/backup/__init__.py +++ b/selfprivacy_api/backup/__init__.py @@ -5,6 +5,7 @@ from typing import List, Optional from selfprivacy_api.utils import ReadUserData, WriteUserData from selfprivacy_api.services import get_service_by_id +from selfprivacy_api.services import get_all_services from selfprivacy_api.services.service import ( Service, ServiceStatus, @@ -480,15 +481,9 @@ class Backups: @staticmethod def _service_ids_to_back_up(time: datetime) -> List[str]: - services = Storage.services_with_autobackup() - return [ - id - for id in services - if Backups.is_time_to_backup_service( - id, - time, - ) - ] + # TODO: simplify in light that we do not use redis for this anymore + service_ids = [service.get_id() for service in get_all_services()] + return [id for id in service_ids if Backups.is_time_to_backup_service(id, time)] # Helpers diff --git a/selfprivacy_api/backup/storage.py b/selfprivacy_api/backup/storage.py index 99a4950..f20bd4f 100644 --- a/selfprivacy_api/backup/storage.py +++ b/selfprivacy_api/backup/storage.py @@ -12,6 +12,7 @@ from selfprivacy_api.utils.redis_model_storage import ( from selfprivacy_api.services.service import Service +from selfprivacy_api.services import get_service_by_id from selfprivacy_api.backup.providers.provider import AbstractBackupProvider from selfprivacy_api.backup.providers import get_kind @@ -130,7 +131,10 @@ class Storage: @staticmethod def is_autobackup_set(service_name: str) -> bool: - return redis.exists(Storage.__autobackup_key(service_name)) + service = get_service_by_id(service_name) + if service is None: + raise ValueError("nonexistent service: ", service_name) + return service.can_be_backed_up() @staticmethod def autobackup_period_minutes() -> Optional[int]: diff --git a/selfprivacy_api/services/test_service/__init__.py b/selfprivacy_api/services/test_service/__init__.py index a0fb02a..d062700 100644 --- a/selfprivacy_api/services/test_service/__init__.py +++ b/selfprivacy_api/services/test_service/__init__.py @@ -24,6 +24,7 @@ class DummyService(Service): folders: List[str] = [] startstop_delay = 0 + backuppable = True def __init_subclass__(cls, folders: List[str]): cls.folders = folders @@ -110,6 +111,17 @@ class DummyService(Service): if delay_sec == 0: handle.communicate() + @classmethod + def set_backuppable(cls, new_value: bool) -> None: + """For tests: because can_be_backed_up is static, + we can only set it up dynamically for tests via a classmethod""" + cls.backuppable = new_value + + @classmethod + def can_be_backed_up(cls) -> bool: + """`True` if the service can be backed up.""" + return cls.backuppable + @classmethod def enable(cls): pass diff --git a/tests/test_graphql/test_backup.py b/tests/test_graphql/test_backup.py index 9f13e52..88bbd53 100644 --- a/tests/test_graphql/test_backup.py +++ b/tests/test_graphql/test_backup.py @@ -8,7 +8,7 @@ from datetime import datetime, timedelta, timezone from subprocess import Popen import selfprivacy_api.services as services -from selfprivacy_api.services import Service +from selfprivacy_api.services import Service, get_all_services from selfprivacy_api.services import get_service_by_id from selfprivacy_api.services.test_service import DummyService @@ -414,16 +414,6 @@ def test_restore_snapshot_task( assert len(snaps) == 1 -def test_autobackup_enable_service(backups, dummy_service): - assert not Backups.is_autobackup_enabled(dummy_service) - - Backups.enable_autobackup(dummy_service) - assert Backups.is_autobackup_enabled(dummy_service) - - Backups.disable_autobackup(dummy_service) - assert not Backups.is_autobackup_enabled(dummy_service) - - def test_autobackup_enable_service_storage(backups, dummy_service): assert len(Storage.services_with_autobackup()) == 0 @@ -463,11 +453,36 @@ def test_no_default_autobackup(backups, dummy_service): 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_back_up(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_autobackup_timer_periods(backups, dummy_service): now = datetime.now(timezone.utc) backup_period = 13 # minutes - Backups.enable_autobackup(dummy_service) assert not Backups.is_time_to_backup_service(dummy_service.get_id(), now) assert not Backups.is_time_to_backup(now) @@ -483,16 +498,21 @@ def test_autobackup_timer_periods(backups, dummy_service): 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.get_id(), now) - assert not Backups.is_time_to_backup(now) - Backups.enable_autobackup(dummy_service) + dummy_service.set_backuppable(True) + assert dummy_service.can_be_backed_up() assert Backups.is_time_to_backup_service(dummy_service.get_id(), now) - assert Backups.is_time_to_backup(now) - Backups.disable_autobackup(dummy_service) + Backups.disable_all_autobackup() assert not Backups.is_time_to_backup_service(dummy_service.get_id(), now) assert not Backups.is_time_to_backup(now) @@ -510,15 +530,12 @@ def test_autobackup_timing(backups, dummy_service): now = datetime.now(timezone.utc) assert not Backups.is_time_to_backup_service(dummy_service.get_id(), now) - assert not Backups.is_time_to_backup(now) past = datetime.now(timezone.utc) - timedelta(minutes=1) assert not Backups.is_time_to_backup_service(dummy_service.get_id(), past) - assert not Backups.is_time_to_backup(past) future = datetime.now(timezone.utc) + timedelta(minutes=backup_period + 2) assert Backups.is_time_to_backup_service(dummy_service.get_id(), future) - assert Backups.is_time_to_backup(future) # Storage @@ -581,18 +598,6 @@ def test_provider_storage(backups_backblaze): assert restored_provider.key == "KEY" -def test_services_to_back_up(backups, dummy_service): - backup_period = 13 # minutes - now = datetime.now(timezone.utc) - - Backups.enable_autobackup(dummy_service) - Backups.set_autobackup_period_minutes(backup_period) - - services = Backups.services_to_back_up(now) - assert len(services) == 1 - assert services[0].get_id() == dummy_service.get_id() - - def test_sync(dummy_service): src = dummy_service.get_folders()[0] dst = dummy_service.get_folders()[1]