Skip to content
Snippets Groups Projects
Commit e44f1431 authored by Roy de Goei's avatar Roy de Goei
Browse files

TMSS-475 Move can_run to can_run_anywhere for time constraints and create can_run wrapper

parent 5f4097e1
Branches
Tags
1 merge request!367Resolve TMSS-475
...@@ -152,7 +152,29 @@ def can_run_anywhere_within_timewindow_with_daily_constraints(scheduling_unit: m ...@@ -152,7 +152,29 @@ def can_run_anywhere_within_timewindow_with_daily_constraints(scheduling_unit: m
def can_run_within_timewindow_with_time_constraints(scheduling_unit: models.SchedulingUnitBlueprint, lower_bound: datetime, upper_bound: datetime) -> bool: def can_run_within_timewindow_with_time_constraints(scheduling_unit: models.SchedulingUnitBlueprint, lower_bound: datetime, upper_bound: datetime) -> bool:
""" """
Evaluate the time constraint(s) Checks whether it is possible to run the scheduling unit /somewhere/ in the given time window,
considering the duration of the involved observation.
:return: True if there is at least one possibility to place the scheduling unit in a way that all time
constraints are met over the runtime of the observation, else False.
"""
main_observation_task_name = get_target_observation_task_name_from_requirements_doc(scheduling_unit)
duration = timedelta(
seconds=scheduling_unit.requirements_doc['tasks'][main_observation_task_name]['specifications_doc']['duration'])
window_lower_bound = lower_bound
while window_lower_bound + duration < upper_bound:
window_upper_bound = window_lower_bound + duration
if can_run_anywhere_within_timewindow_with_time_constraints(scheduling_unit, window_lower_bound, window_upper_bound):
return True
window_lower_bound += min(timedelta(hours=1), upper_bound - window_lower_bound)
return False
def can_run_anywhere_within_timewindow_with_time_constraints(scheduling_unit: models.SchedulingUnitBlueprint, lower_bound: datetime, upper_bound: datetime) -> bool:
"""
Checks whether it is possible to place the scheduling unit arbitrarily in the given time window,
i.e. the time constraints must be met over the full time window.
:return: True if all time constraints are met over the entire time window, else False.
""" """
can_run_at = True can_run_at = True
can_run_before = True can_run_before = True
......
...@@ -807,129 +807,129 @@ class TestTimeConstraints(TestCase): ...@@ -807,129 +807,129 @@ class TestTimeConstraints(TestCase):
obs_duration=self.obs_duration) obs_duration=self.obs_duration)
self.scheduling_unit_blueprint = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft) self.scheduling_unit_blueprint = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft)
def test_can_run_after_returns_false(self): def test_can_run_anywhere_after_returns_false(self):
# Set datetime constraints after lower_bound # Set datetime constraints after lower_bound
self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["after"] = datetime(2020, 1, 1, 13, 0, 0).isoformat() self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["after"] = datetime(2020, 1, 1, 13, 0, 0).isoformat()
self.assertFalse(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 12, 0, 0),
datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 2, 12, 0, 0)))
# Set datetime constraints to upper_bound # Set datetime constraints to upper_bound
self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["after"] = datetime(2020, 1, 2, 12, 0, 0).isoformat() self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["after"] = datetime(2020, 1, 2, 12, 0, 0).isoformat()
self.assertFalse(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 12, 0, 0),
datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 2, 12, 0, 0)))
def test_can_run_after_returns_true(self): def test_can_run_anywhere_after_returns_true(self):
# Set datetime constraints before lower_bound # Set datetime constraints before lower_bound
self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["after"] = datetime(2020, 1, 1, 11, 0, 0).isoformat() self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["after"] = datetime(2020, 1, 1, 11, 0, 0).isoformat()
self.assertTrue(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 12, 0, 0),
datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 2, 12, 0, 0)))
# Set datetime constraints equal to lower_bound # Set datetime constraints equal to lower_bound
self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["after"] = datetime(2020, 1, 1, 12, 0, 0).isoformat() self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["after"] = datetime(2020, 1, 1, 12, 0, 0).isoformat()
self.assertTrue(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 12, 0, 0),
datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 2, 12, 0, 0)))
def test_can_run_before_returns_false(self): def test_can_run_anywhere_before_returns_false(self):
# Set datetime constraints after upper_bound # Set datetime constraints after upper_bound
self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["before"] = datetime(2020, 1, 2, 13, 0, 0).isoformat() self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["before"] = datetime(2020, 1, 2, 13, 0, 0).isoformat()
self.assertFalse(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 12, 0, 0),
datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 2, 12, 0, 0)))
# Set datetime constraints equal to upper_bound # Set datetime constraints equal to upper_bound
self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["before"] = datetime(2020, 1, 2, 12, 0, 0).isoformat() self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["before"] = datetime(2020, 1, 2, 12, 0, 0).isoformat()
self.assertFalse(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 12, 0, 0),
datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 2, 12, 0, 0)))
# Set datetime constraints equal to upper_bound - duration + 1 sec # Set datetime constraints equal to upper_bound - duration + 1 sec
self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["before"] = \ self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["before"] = \
(datetime(2020, 1, 2, 12, 0, 0) - self.scheduling_unit_blueprint.duration + timedelta(seconds=1)).isoformat() (datetime(2020, 1, 2, 12, 0, 0) - self.scheduling_unit_blueprint.duration + timedelta(seconds=1)).isoformat()
self.assertFalse(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 12, 0, 0),
datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 2, 12, 0, 0)))
def test_can_run_before_returns_true(self): def test_can_run_anywhere_before_returns_true(self):
# Set datetime constraints far before upper_bound (lower_bound) # Set datetime constraints far before upper_bound (lower_bound)
self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["before"] = datetime(2020, 1, 1, 12, 0, 0).isoformat() self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["before"] = datetime(2020, 1, 1, 12, 0, 0).isoformat()
self.assertTrue(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 12, 0, 0),
datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 2, 12, 0, 0)))
# Set datetime constraints equal to upper_bound - duration # Set datetime constraints equal to upper_bound - duration
self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["before"] = \ self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['time']["before"] = \
(datetime(2020, 1, 2, 12, 0, 0) - self.scheduling_unit_blueprint.duration).isoformat() (datetime(2020, 1, 2, 12, 0, 0) - self.scheduling_unit_blueprint.duration).isoformat()
self.assertTrue(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 12, 0, 0),
datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 2, 12, 0, 0)))
def test_can_run_between_returns_false(self): def test_can_run_anywhere_between_returns_false(self):
""" """
Test 'between' constraint with start/stop datetime constraints 'outside' upper_bound or lower_bound Test 'between' constraint with start/stop datetime constraints 'outside' upper_bound or lower_bound
""" """
# Set datetime constraints start > lower_bound and stop > upper_bound # Set datetime constraints start > lower_bound and stop > upper_bound
self.add_time_between_constraint(datetime(2020, 1, 1, 13, 0, 0), datetime(2020, 1, 2, 15, 0, 0)) self.add_time_between_constraint(datetime(2020, 1, 1, 13, 0, 0), datetime(2020, 1, 2, 15, 0, 0))
self.assertFalse(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0)))
# Set datetime constraints start < lower_bound and stop < upper_bound # Set datetime constraints start < lower_bound and stop < upper_bound
self.add_time_between_constraint(datetime(2020, 1, 1, 8, 0, 0), datetime(2020, 1, 2, 8, 0, 0)) self.add_time_between_constraint(datetime(2020, 1, 1, 8, 0, 0), datetime(2020, 1, 2, 8, 0, 0))
self.assertFalse(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0)))
# Set datetime constraints start > lower_bound and stop > upper_bound (1 second only) # Set datetime constraints start > lower_bound and stop > upper_bound (1 second only)
self.add_time_between_constraint(datetime(2020, 1, 1, 12, 0, 1), datetime(2020, 1, 2, 12, 0, 1)) self.add_time_between_constraint(datetime(2020, 1, 1, 12, 0, 1), datetime(2020, 1, 2, 12, 0, 1))
self.assertFalse(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0)))
def test_can_run_between_returns_true(self): def test_can_run_anywhere_between_returns_true(self):
""" """
Test 'between' constraint with start/stop datetime constraints 'inside' upper_bound and lower_bound Test 'between' constraint with start/stop datetime constraints 'inside' upper_bound and lower_bound
""" """
# Set datetime constraints start > lower_bound and stop < upper_bound # Set datetime constraints start > lower_bound and stop < upper_bound
self.add_time_between_constraint(datetime(2020, 1, 1, 13, 0, 0), datetime(2020, 1, 1, 15, 0, 0)) self.add_time_between_constraint(datetime(2020, 1, 1, 13, 0, 0), datetime(2020, 1, 1, 15, 0, 0))
self.assertTrue(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 16, 0, 0))) datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 16, 0, 0)))
# Set datetime constraints start = lower_bound and stop = upper_bound # Set datetime constraints start = lower_bound and stop = upper_bound
self.add_time_between_constraint(datetime(2020, 1, 1, 13, 0, 0), datetime(2020, 1, 1, 15, 0, 0)) self.add_time_between_constraint(datetime(2020, 1, 1, 13, 0, 0), datetime(2020, 1, 1, 15, 0, 0))
self.assertTrue(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 13, 0, 0), datetime(2020, 1, 1, 15, 0, 0))) datetime(2020, 1, 1, 13, 0, 0), datetime(2020, 1, 1, 15, 0, 0)))
def test_can_run_not_between_returns_false(self): def test_can_run_anywhere_not_between_returns_false(self):
""" """
Test 'not_between' constraint with start/stop datetime constraints 'inside' upper_bound or lower_bound Test 'not_between' constraint with start/stop datetime constraints 'inside' upper_bound or lower_bound
""" """
# Set datetime constraints start > lower_bound and stop > upper_bound # Set datetime constraints start > lower_bound and stop > upper_bound
self.add_time_not_between_constraint(datetime(2020, 1, 1, 13, 0, 0), datetime(2020, 1, 2, 15, 0, 0)) self.add_time_not_between_constraint(datetime(2020, 1, 1, 13, 0, 0), datetime(2020, 1, 2, 15, 0, 0))
self.assertFalse(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0)))
# Set datetime constraints start < lower_bound and stop > lower_bound and < upper_bound # Set datetime constraints start < lower_bound and stop > lower_bound and < upper_bound
self.add_time_not_between_constraint(datetime(2020, 1, 1, 8, 0, 0), datetime(2020, 1, 2, 8, 0, 0)) self.add_time_not_between_constraint(datetime(2020, 1, 1, 8, 0, 0), datetime(2020, 1, 2, 8, 0, 0))
self.assertFalse(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0)))
# Set datetime constraints start > lower_bound and stop < upper_bound # Set datetime constraints start > lower_bound and stop < upper_bound
self.add_time_not_between_constraint(datetime(2020, 1, 1, 16, 0, 0), datetime(2020, 1, 2, 8, 0, 0)) self.add_time_not_between_constraint(datetime(2020, 1, 1, 16, 0, 0), datetime(2020, 1, 2, 8, 0, 0))
self.assertFalse(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0)))
# Set datetime constraints start < lower_bound and stop > upper_bound # Set datetime constraints start < lower_bound and stop > upper_bound
self.add_time_not_between_constraint(datetime(2020, 1, 1, 8, 0, 0), datetime(2020, 1, 2, 14, 0, 0)) self.add_time_not_between_constraint(datetime(2020, 1, 1, 8, 0, 0), datetime(2020, 1, 2, 14, 0, 0))
self.assertFalse(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0))) datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 2, 12, 0, 0)))
def test_can_run_not_between_returns_true(self): def test_can_run_anywhere_not_between_returns_true(self):
""" """
Test 'not_between' constraint with start/stop datetime constraints 'outside' upper_bound and lower_bound Test 'not_between' constraint with start/stop datetime constraints 'outside' upper_bound and lower_bound
""" """
# Set datetime constraints start < lower_bound and stop < lower_bound # Set datetime constraints start < lower_bound and stop < lower_bound
self.add_time_not_between_constraint(datetime(2020, 1, 1, 3, 0, 0), datetime(2020, 1, 1, 11, 0, 0)) self.add_time_not_between_constraint(datetime(2020, 1, 1, 3, 0, 0), datetime(2020, 1, 1, 11, 0, 0))
self.assertTrue(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 16, 0, 0))) datetime(2020, 1, 1, 12, 0, 0), datetime(2020, 1, 1, 16, 0, 0)))
# Set datetime constraints start > upper_bound and stop > upper_bound # Set datetime constraints start > upper_bound and stop > upper_bound
self.add_time_not_between_constraint(datetime(2020, 1, 1, 16, 0, 0), datetime(2020, 1, 1, 20, 0, 0)) self.add_time_not_between_constraint(datetime(2020, 1, 1, 16, 0, 0), datetime(2020, 1, 1, 20, 0, 0))
self.assertTrue(tc1.can_run_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint, self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_time_constraints(self.scheduling_unit_blueprint,
datetime(2020, 1, 1, 13, 0, 0), datetime(2020, 1, 1, 15, 0, 0))) datetime(2020, 1, 1, 13, 0, 0), datetime(2020, 1, 1, 15, 0, 0)))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment