mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
When a job is disabled only increase it's _next_fire_time value if th…e job would have run at the current time, eg. the current _next_fire_time == now.
This commit is contained in:
parent
326cb8d35b
commit
8901ff57d9
4 changed files with 208 additions and 12 deletions
1
changelog/63699.fixed.md
Normal file
1
changelog/63699.fixed.md
Normal file
|
@ -0,0 +1 @@
|
|||
When a job is disabled only increase it's _next_fire_time value if the job would have run at the current time, eg. the current _next_fire_time == now.
|
|
@ -217,11 +217,12 @@ class Schedule:
|
|||
|
||||
if remove_hidden:
|
||||
_schedule = copy.deepcopy(schedule)
|
||||
for job in _schedule:
|
||||
if isinstance(_schedule[job], dict):
|
||||
for item in _schedule[job]:
|
||||
for job in schedule:
|
||||
if isinstance(schedule[job], dict):
|
||||
for item in schedule[job]:
|
||||
if item.startswith("_"):
|
||||
del schedule[job][item]
|
||||
del _schedule[job][item]
|
||||
return _schedule
|
||||
return schedule
|
||||
|
||||
def _check_max_running(self, func, data, opts, now):
|
||||
|
@ -1769,9 +1770,10 @@ class Schedule:
|
|||
seconds=data["_seconds"]
|
||||
)
|
||||
elif "_skipped" in data and data["_skipped"]:
|
||||
data["_next_fire_time"] = now + datetime.timedelta(
|
||||
seconds=data["_seconds"]
|
||||
)
|
||||
if data["_next_fire_time"] <= now:
|
||||
data["_next_fire_time"] = now + datetime.timedelta(
|
||||
seconds=data["_seconds"]
|
||||
)
|
||||
elif run:
|
||||
data["_next_fire_time"] = now + datetime.timedelta(
|
||||
seconds=data["_seconds"]
|
||||
|
|
|
@ -502,6 +502,146 @@ def test_eval_disabled(schedule):
|
|||
assert ret == job["schedule"][job_name]
|
||||
|
||||
|
||||
def test_eval_disabled_seconds(schedule):
|
||||
"""
|
||||
verify that scheduled job does not run
|
||||
"""
|
||||
|
||||
job_name = "test_eval_disabled_seconds"
|
||||
job = {
|
||||
"schedule": {
|
||||
"enabled": True,
|
||||
job_name: {"function": "test.ping", "seconds": "30"},
|
||||
}
|
||||
}
|
||||
|
||||
# Add the job to the scheduler
|
||||
schedule.opts.update(job)
|
||||
|
||||
eval_time1 = dateutil.parser.parse("11/29/2017 4:00pm")
|
||||
schedule.eval(now=eval_time1)
|
||||
ret = schedule.job_status(job_name)
|
||||
assert "_next_fire_time" in ret
|
||||
assert ret["_next_fire_time"] == datetime.datetime(2017, 11, 29, 16, 0, 30)
|
||||
|
||||
# Disable the job
|
||||
schedule.opts["schedule"]["enabled"] = False
|
||||
|
||||
# Evaluate 1 second for 29 seconds
|
||||
# Assert that the _next_fire_time does not change
|
||||
# until the _next_fire_time is reached
|
||||
for i in range(1, 30):
|
||||
eval_time = eval_time1 + datetime.timedelta(seconds=i)
|
||||
schedule.eval(now=eval_time)
|
||||
ret = schedule.job_status(job_name)
|
||||
assert "_next_fire_time" in ret
|
||||
assert ret["_next_fire_time"] == datetime.datetime(2017, 11, 29, 16, 0, 30)
|
||||
|
||||
eval_time = eval_time1 + datetime.timedelta(seconds=30)
|
||||
schedule.eval(now=eval_time)
|
||||
ret = schedule.job_status(job_name)
|
||||
assert "_next_fire_time" in ret
|
||||
assert ret["_next_fire_time"] == datetime.datetime(2017, 11, 29, 16, 1, 0)
|
||||
|
||||
|
||||
def test_eval_disabled_minutes(schedule):
|
||||
"""
|
||||
verify that scheduled job does not run
|
||||
"""
|
||||
|
||||
job_name = "test_eval_disabled_minutes"
|
||||
job = {
|
||||
"schedule": {
|
||||
"enabled": True,
|
||||
job_name: {"function": "test.ping", "minutes": "55"},
|
||||
}
|
||||
}
|
||||
|
||||
# Add the job to the scheduler
|
||||
schedule.opts.update(job)
|
||||
|
||||
eval_time1 = dateutil.parser.parse("11/29/2017 4:00pm")
|
||||
schedule.eval(now=eval_time1)
|
||||
ret = schedule.job_status(job_name)
|
||||
assert "_next_fire_time" in ret
|
||||
assert ret["_next_fire_time"] == datetime.datetime(2017, 11, 29, 16, 55, 0)
|
||||
|
||||
# Evaluate 1 minute for 50 minutes
|
||||
# Assert that the _next_fire_time does not change
|
||||
# until the _next_fire_time is reached
|
||||
for i in range(1, 50):
|
||||
eval_time = eval_time1 + datetime.timedelta(minutes=i)
|
||||
schedule.eval(now=eval_time)
|
||||
ret = schedule.job_status(job_name)
|
||||
assert "_next_fire_time" in ret
|
||||
assert ret["_next_fire_time"] == datetime.datetime(2017, 11, 29, 16, 55, 0)
|
||||
|
||||
# Disable the job
|
||||
schedule.opts["schedule"]["enabled"] = False
|
||||
|
||||
for i in range(1, 10):
|
||||
eval_time = eval_time1 + datetime.timedelta(seconds=i)
|
||||
schedule.eval(now=eval_time)
|
||||
ret = schedule.job_status(job_name)
|
||||
assert "_next_fire_time" in ret
|
||||
assert ret["_next_fire_time"] == datetime.datetime(2017, 11, 29, 16, 55, 0)
|
||||
|
||||
eval_time = dateutil.parser.parse("11/29/2017 4:55pm")
|
||||
schedule.eval(now=eval_time)
|
||||
ret = schedule.job_status(job_name)
|
||||
assert "_next_fire_time" in ret
|
||||
assert ret["_next_fire_time"] == datetime.datetime(2017, 11, 29, 17, 50, 0)
|
||||
|
||||
|
||||
def test_eval_disabled_hours(schedule):
|
||||
"""
|
||||
verify that scheduled job does not run
|
||||
"""
|
||||
|
||||
job_name = "test_eval_disabled_hours"
|
||||
job = {
|
||||
"schedule": {
|
||||
"enabled": True,
|
||||
job_name: {"function": "test.ping", "hours": "6"},
|
||||
}
|
||||
}
|
||||
|
||||
# Add the job to the scheduler
|
||||
schedule.opts.update(job)
|
||||
|
||||
eval_time1 = dateutil.parser.parse("11/29/2017 4:00pm")
|
||||
schedule.eval(now=eval_time1)
|
||||
ret = schedule.job_status(job_name)
|
||||
assert "_next_fire_time" in ret
|
||||
assert ret["_next_fire_time"] == datetime.datetime(2017, 11, 29, 22, 0, 0)
|
||||
|
||||
# Evaluate 1 hour for 5 hours
|
||||
# Assert that the _next_fire_time does not change
|
||||
# until the _next_fire_time is reached
|
||||
for i in range(1, 5):
|
||||
eval_time = eval_time1 + datetime.timedelta(hours=i)
|
||||
schedule.eval(now=eval_time)
|
||||
ret = schedule.job_status(job_name)
|
||||
assert "_next_fire_time" in ret
|
||||
assert ret["_next_fire_time"] == datetime.datetime(2017, 11, 29, 22, 0, 0)
|
||||
|
||||
# Disable the job
|
||||
schedule.opts["schedule"]["enabled"] = False
|
||||
|
||||
for i in range(1, 50):
|
||||
eval_time = eval_time1 + datetime.timedelta(minutes=i)
|
||||
schedule.eval(now=eval_time)
|
||||
ret = schedule.job_status(job_name)
|
||||
assert "_next_fire_time" in ret
|
||||
assert ret["_next_fire_time"] == datetime.datetime(2017, 11, 29, 22, 0, 0)
|
||||
|
||||
eval_time = dateutil.parser.parse("11/29/2017 10:00pm")
|
||||
schedule.eval(now=eval_time)
|
||||
ret = schedule.job_status(job_name)
|
||||
assert "_next_fire_time" in ret
|
||||
assert ret["_next_fire_time"] == datetime.datetime(2017, 11, 30, 4, 0, 0)
|
||||
|
||||
|
||||
def test_eval_global_disabled_job_enabled(schedule):
|
||||
"""
|
||||
verify that scheduled job does not run
|
||||
|
|
|
@ -1,24 +1,77 @@
|
|||
import copy
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def test_get_schedule(schedule):
|
||||
def test_get_schedule_remove_hidden_true(schedule):
|
||||
"""
|
||||
verify that the _get_schedule function works
|
||||
when remove_hidden is True and schedule data
|
||||
contains enabled key
|
||||
contains enabled key and that opts["schedule"]
|
||||
is not changed.
|
||||
"""
|
||||
|
||||
job_name = "test_get_schedule"
|
||||
job = {
|
||||
"schedule": {
|
||||
"enabled": True,
|
||||
job_name: {"function": "test.ping", "seconds": 60},
|
||||
job_name: {
|
||||
"function": "test.ping",
|
||||
"seconds": 60,
|
||||
"_next_fire_time": datetime.datetime(2023, 2, 13, 18, 25, 16, 271796),
|
||||
"_splay": None,
|
||||
"_seconds": 3600,
|
||||
"_next_scheduled_fire_time": datetime.datetime(
|
||||
2023, 2, 13, 18, 25, 16, 271796
|
||||
),
|
||||
"_skip_reason": "disabled",
|
||||
"_skipped_time": datetime.datetime(2023, 2, 13, 17, 26, 16, 271381),
|
||||
"_skipped": True,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
expected_ret = {
|
||||
"enabled": True,
|
||||
job_name: {"function": "test.ping", "seconds": 60},
|
||||
}
|
||||
# Add the job to the scheduler
|
||||
schedule.opts.update(copy.deepcopy(job))
|
||||
|
||||
ret = schedule._get_schedule(remove_hidden=True)
|
||||
assert expected_ret == ret
|
||||
assert schedule.opts["schedule"][job_name] == job["schedule"][job_name]
|
||||
|
||||
|
||||
def test_get_schedule_remove_hidden_false(schedule):
|
||||
"""
|
||||
verify that the _get_schedule function works
|
||||
when remove_hidden is False and schedule data
|
||||
contains enabled key and that opts["schedule"]
|
||||
is not changed.
|
||||
"""
|
||||
|
||||
job_name = "test_get_schedule"
|
||||
job = {
|
||||
"schedule": {
|
||||
"enabled": True,
|
||||
job_name: {
|
||||
"function": "test.ping",
|
||||
"seconds": 60,
|
||||
"_next_fire_time": datetime.datetime(2023, 2, 13, 18, 25, 16),
|
||||
"_splay": None,
|
||||
"_seconds": 3600,
|
||||
"_next_scheduled_fire_time": datetime.datetime(2023, 2, 13, 18, 25, 16),
|
||||
"_skip_reason": "disabled",
|
||||
"_skipped_time": datetime.datetime(2023, 2, 13, 17, 26, 16),
|
||||
"_skipped": True,
|
||||
},
|
||||
}
|
||||
}
|
||||
# Add the job to the scheduler
|
||||
schedule.opts.update(job)
|
||||
schedule.opts.update(copy.deepcopy(job))
|
||||
|
||||
ret = schedule._get_schedule(remove_hidden=True)
|
||||
ret = schedule._get_schedule(remove_hidden=False)
|
||||
assert job["schedule"] == ret
|
||||
|
|
Loading…
Add table
Reference in a new issue