def _parse_schedules(cls, data): schedule = None restrict_schedule = None if "schedule" in data and not data["auto"]: raise ValueError( "You can't have schedule for replication that does not run automatically" ) if data["direction"] == ReplicationDirection.PUSH: if "schedule" in data: if data["periodic-snapshot-tasks"]: raise ValueError( "Push replication can't be bound to periodic snapshot task and have " "schedule at the same time") schedule = CronSchedule.from_data(data["schedule"]) else: if data["auto"] and not data["periodic-snapshot-tasks"]: raise ValueError( "Push replication that runs automatically must be either bound to periodic " "snapshot task or have schedule") if "restrict-schedule" in data: if not data["auto"]: raise ValueError( "You can only have restrict-schedule for replication that runs " "automatically") if not data["periodic-snapshot-tasks"]: raise ValueError( "You can only have restrict-schedule for replication that is bound to " "periodic snapshot tasks") restrict_schedule = CronSchedule.from_data( data["restrict-schedule"]) if data["direction"] == ReplicationDirection.PULL: if "schedule" in data: schedule = CronSchedule.from_data(data["schedule"]) if "restrict-schedule" in data: raise ValueError( "Pull replication can't have restrict-schedule") if data["periodic-snapshot-tasks"]: raise ValueError( "Pull replication can't be bound to periodic snapshot task" ) return schedule, restrict_schedule
def from_data(cls, data: dict): if data["retention-policy"] == "source": return SameAsSourceSnapshotRetentionPolicy() if data["retention-policy"] == "custom": if "lifetime" not in data: raise ValueError( "lifetime is required for custom retention policy") return CustomSnapshotRetentionPolicy( isodate.parse_duration(data["lifetime"]), sorted( [ CustomSnapshotRetentionPolicyLifetime( CronSchedule.from_data(lifetime["schedule"]), isodate.parse_duration(lifetime["lifetime"]), ) for lifetime in data.get("lifetimes", {}).values() ], key=lambda lifetime: lifetime.lifetime, reverse=True, ), ) if data["retention-policy"] == "none": return NoneSnapshotRetentionPolicy() raise ValueError( f"Unknown retention policy: {data['retention-policy']!r}")
def test__get_snapshot_to_send__restrict_schedule(): assert get_snapshots_to_send( ["2018-09-02_17-45", "2018-09-02_17-46", "2018-09-02_17-47"], ["2018-09-02_17-45"], Mock(periodic_snapshot_tasks=[Mock(naming_schema="%Y-%m-%d_%H-%M")], also_include_naming_schema=[], restrict_schedule=CronSchedule("*/2", "*", "*", "*", "*", time(0, 0), time(23, 59)), only_matching_schedule=False, retention_policy=Mock(calculate_delete_snapshots=Mock(return_value=[]))), ) == ("2018-09-02_17-45", ["2018-09-02_17-46"])
def _parse_schedules(cls, data): if "schedule" in data: schedule = CronSchedule.from_data(data["schedule"]) else: schedule = None if "restrict-schedule" in data: restrict_schedule = CronSchedule.from_data( data["restrict-schedule"]) else: restrict_schedule = None if data["direction"] == ReplicationDirection.PUSH: if schedule is None and data[ "auto"] and not data["periodic-snapshot-tasks"]: raise ValueError( "Push replication that runs automatically must be either bound to a periodic " "snapshot task or have a schedule") if data["direction"] == ReplicationDirection.PULL: if schedule is None and data["auto"]: raise ValueError( "Pull replication that runs automatically must have a schedule" ) if data["periodic-snapshot-tasks"]: raise ValueError( "Pull replication can't be bound to a periodic snapshot task" ) if schedule: if not data["auto"]: raise ValueError( "You can't have schedule for replication that does not run automatically" ) else: if data["only-matching-schedule"]: raise ValueError( "You can't have only-matching-schedule without schedule") return schedule, restrict_schedule
def from_data(cls, data): periodic_snapshot_task_validator.validate(data) data.setdefault("exclude", []) data.setdefault("allow-empty", True) if "lifetime" in data: lifetime = isodate.parse_duration(data["lifetime"]) else: # timedelta.max is not good here because operations with it would result in # OverflowError: date value out of range lifetime = timedelta(days=36500) return cls(data["id"], data["dataset"], data["recursive"], data["exclude"], lifetime, data["naming-schema"], CronSchedule.from_data(data["schedule"]), data["allow-empty"])
# -*- coding=utf-8 -*- from datetime import datetime, time import pytest from zettarepl.scheduler.cron import CronSchedule @pytest.mark.parametrize("schedule,datetime,result", [ (CronSchedule(0, "*", "*", "*", "*", time(0, 0), time( 23, 59)), datetime(2018, 8, 31, 16, 0, 5, 54412), True), (CronSchedule(0, "*", "*", "*", "*", time(9, 0), time( 15, 00)), datetime(2018, 8, 31, 16, 0, 5, 54412), False), (CronSchedule(0, "*", "*", "*", "*", time(15, 0), time( 9, 00)), datetime(2018, 8, 31, 16, 0, 5, 54412), True), (CronSchedule(0, "*", "*", "*", "*", time(15, 0), time( 9, 00)), datetime(2018, 8, 31, 8, 0, 5, 54412), True), (CronSchedule(0, "*", "*", "*", "*", time(15, 0), time( 9, 00)), datetime(2018, 8, 31, 12, 0, 5, 54412), False), ]) def test__cron(schedule, datetime, result): assert schedule.should_run(datetime) == result