diff --git a/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py b/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py index 6c1dab6d3eb77fbaf29b61c015a971189019802a..fea11261c34f7522eb3f103567c90f72ca35f880 100755 --- a/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py +++ b/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py @@ -5469,6 +5469,68 @@ class TestTriggers(BaseDynamicSchedulingTestCase): task.refresh_from_db() self.assertEqual(models.TaskStatus.Choices.CANCELLED.value, task.status.value) + @mock.patch("lofar.sas.tmss.tmss.tmssapp.subtasks.kill_observation_subtask") + def test_TMSS_2881_bugfix_unschedulable_trigger_should_not_cancel_running_observations(self, kill_observation_subtask_mock): + scheduling_set = models.SchedulingSet.objects.create(**SchedulingSet_test_data()) + scheduling_set.project.trigger_priority = 0 + scheduling_set.project.project_state = models.ProjectState.objects.get(value=models.ProjectState.Choices.ACTIVE.value) + scheduling_set.project.cycles.add(models.Cycle.objects.create(**Cycle_test_data(start=datetime.utcnow()-timedelta(days=1), + stop=datetime.utcnow()+timedelta(days=1)))) + + strategy_template = models.SchedulingUnitObservingStrategyTemplate.get_latest(name="Simple Observation") + regular_su_draft_past = create_scheduling_unit_draft_from_observing_strategy_template(strategy_template, scheduling_set=scheduling_set) + regular_su_blueprint_past = create_scheduling_unit_blueprint_and_tasks_and_subtasks_from_scheduling_unit_draft(regular_su_draft_past) + regular_su_blueprint_past = set_scheduling_unit_blueprint_start_times(regular_su_blueprint_past, round_to_second_precision(datetime.utcnow() - timedelta(days=1))) + regular_obs_subtask_past = regular_su_blueprint_past.observation_tasks.first().subtasks.first() + set_subtask_state_following_allowed_transitions(regular_obs_subtask_past, 'finished') + + regular_su_draft_running = create_scheduling_unit_draft_from_observing_strategy_template(strategy_template, scheduling_set=scheduling_set) + regular_su_draft_running.scheduling_constraints_doc['scheduler'] = 'fixed_time' + regular_su_draft_running.scheduling_constraints_doc['time']['at'] = round_to_second_precision(datetime.utcnow() + timedelta(minutes=3)).isoformat() + regular_su_draft_running.scheduling_constraints_doc['sky']['transit_offset'] = {'from': -12 * 60 * 60, 'to': 12 * 60 * 60} + regular_su_draft_running.scheduling_constraints_doc['sky']['min_elevation'] = {'target': 0, 'calibrator': 0} + regular_su_draft_running.scheduling_constraints_doc['sky']['min_distance'] = {'target': {'sun': 0, 'moon': 0, 'jupiter': 0}} + regular_su_draft_running.save() + regular_su_blueprint_running = create_scheduling_unit_blueprint_and_tasks_and_subtasks_from_scheduling_unit_draft(regular_su_draft_running) + + scheduled_scheduling_units = self.scheduler.schedule_fixed_time_scheduling_units() + self.assertEqual(1, len(scheduled_scheduling_units)) + self.assertEqual(regular_su_blueprint_running.id, scheduled_scheduling_units[0].id) + + # put first obs to started state + first_obs_subtask = regular_su_blueprint_running.observation_tasks.first().subtasks.first() + set_subtask_state_following_allowed_transitions(first_obs_subtask, 'started') + + # create a triggered observation, erroneously in the past (which was the root cause of the bug, making it unschedulable) + scheduling_set = models.SchedulingSet.objects.create(**SchedulingSet_test_data()) + scheduling_set.project.can_trigger = True + scheduling_set.project.trigger_priority = 10000 + scheduling_set.project.project_state = models.ProjectState.objects.get(value=models.ProjectState.Choices.ACTIVE.value) + models.ProjectQuota.objects.create(project=scheduling_set.project.project, value=1000, resource_type=models.ResourceType.objects.get(quantity__value=models.Quantity.Choices.NUMBER.value, name__icontains='trigger')) + scheduling_set.project.cycles.add(models.Cycle.objects.create(**Cycle_test_data(start=datetime.utcnow()-timedelta(days=3), + stop=datetime.utcnow()+timedelta(days=1)))) + scheduling_unit_draft_trigger = self.create_simple_observation_scheduling_unit("triggered scheduling unit for %s" % self._testMethodName, + obs_duration=60, + scheduling_set=scheduling_set, + interrupts_telescope=True) + triggered_scheduling_unit_blueprint = create_scheduling_unit_blueprint_and_tasks_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_trigger) + triggered_scheduling_unit_blueprint.scheduling_constraints_doc = {'scheduler': 'fixed_time', + 'time': {"at": regular_su_blueprint_past.scheduled_start_time.isoformat()} } + triggered_scheduling_unit_blueprint.save() + + # schedule the triggered observations + scheduled_scheduling_units = self.scheduler.schedule_fixed_time_scheduling_units() + self.assertEqual(0, len(scheduled_scheduling_units)) + + triggered_scheduling_unit_blueprint.refresh_from_db() + self.assertEqual(models.SchedulingUnitStatus.Choices.UNSCHEDULABLE.value, triggered_scheduling_unit_blueprint.status.value) + + # the regular observations should NOT have been cancelled. (in the bug report, the running obs was killed) + kill_observation_subtask_mock.assert_not_called() + + + + logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO)