mirror of
https://github.com/ansible/awx.git
synced 2024-10-27 00:55:06 +03:00
fix an rrule bug that causes improper HOURLY/MINUTELY calculation
see: https://github.com/ansible/awx/issues/8071
This commit is contained in:
parent
56c5a39087
commit
bf1d93168b
@ -205,10 +205,15 @@ class Schedule(PrimordialModel, LaunchTimeConfig):
|
||||
'A valid TZID must be provided (e.g., America/New_York)'
|
||||
)
|
||||
|
||||
if fast_forward and ('MINUTELY' in rrule or 'HOURLY' in rrule):
|
||||
if (
|
||||
fast_forward and
|
||||
('MINUTELY' in rrule or 'HOURLY' in rrule) and
|
||||
'COUNT=' not in rrule
|
||||
):
|
||||
try:
|
||||
first_event = x[0]
|
||||
if first_event < now():
|
||||
# If the first event was over a week ago...
|
||||
if (now() - first_event).days > 7:
|
||||
# hourly/minutely rrules with far-past DTSTART values
|
||||
# are *really* slow to precompute
|
||||
# start *from* one week ago to speed things up drastically
|
||||
|
@ -1,4 +1,4 @@
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from contextlib import contextmanager
|
||||
|
||||
from django.utils.timezone import now
|
||||
@ -161,6 +161,58 @@ class TestComputedFields:
|
||||
assert job_template.next_schedule == expected_schedule
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize('freq, delta', (
|
||||
('MINUTELY', 1),
|
||||
('HOURLY', 1)
|
||||
))
|
||||
def test_past_week_rrule(job_template, freq, delta):
|
||||
# see: https://github.com/ansible/awx/issues/8071
|
||||
recent = (datetime.utcnow() - timedelta(days=3))
|
||||
recent = recent.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
recent_dt = recent.strftime('%Y%m%d')
|
||||
rrule = f'DTSTART;TZID=America/New_York:{recent_dt}T000000 RRULE:FREQ={freq};INTERVAL={delta};COUNT=5' # noqa
|
||||
sched = Schedule.objects.create(
|
||||
name='example schedule',
|
||||
rrule=rrule,
|
||||
unified_job_template=job_template
|
||||
)
|
||||
first_event = sched.rrulestr(sched.rrule)[0]
|
||||
assert first_event.replace(tzinfo=None) == recent
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize('freq, delta', (
|
||||
('MINUTELY', 1),
|
||||
('HOURLY', 1)
|
||||
))
|
||||
def test_really_old_dtstart(job_template, freq, delta):
|
||||
# see: https://github.com/ansible/awx/issues/8071
|
||||
# If an event is per-minute/per-hour and was created a *really long*
|
||||
# time ago, we should just bump forward to start counting "in the last week"
|
||||
rrule = f'DTSTART;TZID=America/New_York:20150101T000000 RRULE:FREQ={freq};INTERVAL={delta}' # noqa
|
||||
sched = Schedule.objects.create(
|
||||
name='example schedule',
|
||||
rrule=rrule,
|
||||
unified_job_template=job_template
|
||||
)
|
||||
last_week = (datetime.utcnow() - timedelta(days=7)).date()
|
||||
first_event = sched.rrulestr(sched.rrule)[0]
|
||||
assert last_week == first_event.date()
|
||||
|
||||
# the next few scheduled events should be the next minute/hour incremented
|
||||
next_five_events = list(sched.rrulestr(sched.rrule).xafter(now(), count=5))
|
||||
|
||||
assert next_five_events[0] > now()
|
||||
last = None
|
||||
for event in next_five_events:
|
||||
if last:
|
||||
assert event == last + (
|
||||
timedelta(minutes=1) if freq == 'MINUTELY' else timedelta(hours=1)
|
||||
)
|
||||
last = event
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_repeats_forever(job_template):
|
||||
s = Schedule(
|
||||
|
Loading…
Reference in New Issue
Block a user