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)'
|
'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:
|
try:
|
||||||
first_event = x[0]
|
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
|
# hourly/minutely rrules with far-past DTSTART values
|
||||||
# are *really* slow to precompute
|
# are *really* slow to precompute
|
||||||
# start *from* one week ago to speed things up drastically
|
# 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 contextlib import contextmanager
|
||||||
|
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
@ -161,6 +161,58 @@ class TestComputedFields:
|
|||||||
assert job_template.next_schedule == expected_schedule
|
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
|
@pytest.mark.django_db
|
||||||
def test_repeats_forever(job_template):
|
def test_repeats_forever(job_template):
|
||||||
s = Schedule(
|
s = Schedule(
|
||||||
|
Loading…
Reference in New Issue
Block a user