1
0
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:
Ryan Petrello 2020-09-18 10:29:46 -04:00
parent 56c5a39087
commit bf1d93168b
No known key found for this signature in database
GPG Key ID: F2AA5F2122351777
2 changed files with 60 additions and 3 deletions

View File

@ -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

View File

@ -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(