diff --git a/SAS/TMSS/src/tmss/tmssapp/tasks.py b/SAS/TMSS/src/tmss/tmssapp/tasks.py index 84cd542871c03b8b88f0cd258ba6ce606d26191a..d7e747154c014a26d89f5a9932ef3e40e1b1fa37 100644 --- a/SAS/TMSS/src/tmss/tmssapp/tasks.py +++ b/SAS/TMSS/src/tmss/tmssapp/tasks.py @@ -27,20 +27,24 @@ def create_scheduling_unit_blueprint_from_scheduling_unit_draft(scheduling_unit_ return scheduling_unit_blueprint -def create_tasks_draft_from_scheduling_unit_draft(scheduling_unit_draft: models.SchedulingUnitDraft) -> [TaskDraft]: +def create_task_drafts_from_scheduling_unit_draft(scheduling_unit_draft: models.SchedulingUnitDraft) -> [TaskDraft]: """ Generic create-method for tasks draft. Calls the appropriate create method based on the scheduling_unit_blueprint specifications_template name. """ - list_tasks = scheduling_unit_draft.requirements_doc["tasks"] - list_task_relations = scheduling_unit_draft.requirements_doc["task_relations"] - list_task_scheduling_relations = scheduling_unit_draft.requirements_doc["task_scheduling_relations"] + list_created_task_object = [] + + try: + list_tasks = scheduling_unit_draft.requirements_doc["tasks"] + logger.info("create_task_drafts_from_scheduling_unit_draft with scheduling_unit_draft.id=%s, nbr_tasks=%d" % + (scheduling_unit_draft.pk, len(list_tasks))) + except KeyError: + logger.info("create_task_drafts_from_scheduling_unit_draft -> NO tasks to process from requirements_doc") + list_tasks = [] - print("create_tasks_draft_from_scheduling_unit_draft with scheduling_unit_draft.id=%s, nbr_tasks=%d" % - (scheduling_unit_draft.pk, len(list_tasks))) for task in list_tasks: task_template_name = task["specifications_template"] - print("task name is '%s', task_template_name '%s'" % (task["name"], task_template_name)) + logger.info("task name is '%s', task_template_name '%s'" % (task["name"], task_template_name)) task_template = models.TaskTemplate.objects.get(name=task_template_name) task_draft = models.TaskDraft.objects.create( name=task["name"], @@ -51,10 +55,16 @@ def create_tasks_draft_from_scheduling_unit_draft(scheduling_unit_draft: models. copies=None, scheduling_unit_draft=scheduling_unit_draft, specifications_template=task_template) - print("task draft with id %s created succesfully" % task_draft.id) + logger.info("task draft with id %s created successfully" % task_draft.id) + list_created_task_object.append(task_draft) # Now create task relation - print("create_tasks_draft_from_scheduling_unit_draft, nbr of task relations=%d" % len(list_task_relations)) + try: + list_task_relations = scheduling_unit_draft.requirements_doc["task_relations"] + logger.info("create_task_drafts_from_scheduling_unit_draft, nbr of task relations=%d" % len(list_task_relations)) + except KeyError: + logger.info("create_task_drafts_from_scheduling_unit_draft -> NO task relations to process from requirements_doc") + list_task_relations = [] for task_relation in list_task_relations: task_rel_obj = models.TaskRelationDraft.objects.create( tags=task_relation["tags"], @@ -65,11 +75,19 @@ def create_tasks_draft_from_scheduling_unit_draft(scheduling_unit_draft: models. input=models.TaskConnector.objects.get(role=task_relation["input"]["role"]), output=models.TaskConnector.objects.get(role=task_relation["output"]["role"]), selection_template=models.TaskRelationSelectionTemplate.objects.get(name=task_relation["selection_template"])) - print("task relation draft object with id %s created successfully" % task_rel_obj.id) + logger.info("task relation draft object with id %s created successfully" % task_rel_obj.id) # TODO task_scheduling_relation ?? + try: + list_task_scheduling_relations = scheduling_unit_draft.requirements_doc["task_scheduling_relations"] + logger.info("create_task_drafts_from_scheduling_unit_draft, nbr of task relations=%d" % len(list_task_relations)) + except KeyError: + logger.info("create_task_drafts_from_scheduling_unit_draft -> NO tasks scheduling relations to process from requirements_doc") + list_task_scheduling_relations = [] # Apparently a task scheduling relation draft and a task scheduling relation blueprint table must be created - # Also have to get the QA properties and maybe more from Target Observation before and after + # Also have to get the QA properties and maybe more from Target Observation 'before' and 'after' + + return list_created_task_object def create_task_blueprint_from_task_draft(task_draft: models.TaskDraft) -> models.TaskBlueprint: diff --git a/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py b/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py index d5febba4edd187a6bb2349707a4de2652103739e..840e91866459aa87fe3e389730f46862d295819c 100644 --- a/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py +++ b/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py @@ -204,13 +204,13 @@ class SchedulingUnitDraftViewSet(LOFARViewSet): @swagger_auto_schema(responses={201: 'The Created Task Draft, see Location in Response header', 403: 'forbidden'}, - operation_description="Create Tasks Draft from SchedulingUnitDraft.") - @action(methods=['get'], detail=True, url_name="create_tasks_draft", name="Create Tasks Draft from Requirement doc") + operation_description="Create Task Drafts from SchedulingUnitDraft.") + @action(methods=['get'], detail=True, url_name="create_task_drafts", name="Create Task Drafts from Requirement doc") def create_tasks_draft(self, request, pk=None): scheduling_unit_draft = get_object_or_404(models.SchedulingUnitDraft, pk=pk) - create_tasks_draft_from_scheduling_unit_draft(scheduling_unit_draft) + create_task_drafts_from_scheduling_unit_draft(scheduling_unit_draft) - # return a response with the new serialized scheduling_unit_blueprint (with references to the created task_blueprint(s) and (scheduled) subtasks) + # just return as a response the serialized scheduling_unit_draft (with references to the created task_draft(s) return Response(serializers.SchedulingUnitDraftSerializer(scheduling_unit_draft, context={'request':request}).data, status=status.HTTP_201_CREATED) diff --git a/SAS/TMSS/test/CMakeLists.txt b/SAS/TMSS/test/CMakeLists.txt index f3ff1838d84942847f77ed41e89bfb3ac6f7160a..a5aca55b3248799d21f9373f1d7ca51a924bc960 100644 --- a/SAS/TMSS/test/CMakeLists.txt +++ b/SAS/TMSS/test/CMakeLists.txt @@ -17,6 +17,7 @@ if(BUILD_TESTING) tmss_test_environment_unittest_setup.py tmss_test_data_django_models.py tmss_test_data_rest.py + testdata/example_CTC_scheduling_block.json DESTINATION lofar/sas/tmss/test) lofar_add_test(t_tmss_test_database) diff --git a/SAS/TMSS/test/t_specify_observation.py b/SAS/TMSS/test/t_specify_observation.py index 2a3c16918870e30f6725e8000e08b45dbcfa57f7..cab775f025a094fad149256f85462dcd4f017c4d 100755 --- a/SAS/TMSS/test/t_specify_observation.py +++ b/SAS/TMSS/test/t_specify_observation.py @@ -39,27 +39,165 @@ from lofar.sas.tmss.test.tmss_test_data_rest import TMSSRESTTestDataCreator rest_data_creator = TMSSRESTTestDataCreator(BASE_URL, AUTH) from lofar.sas.tmss.tmss.tmssapp import models -from lofar.sas.tmss.tmss.tmssapp.tasks import create_task_blueprint_from_task_draft_and_instantiate_subtasks_from_template +from lofar.sas.tmss.tmss.tmssapp.tasks import * -class SpecifyObservationFromTaskDraftTest(unittest.TestCase): +class CreationFromSchedulingUnitDraft(unittest.TestCase): + """ + From scheduling_unit_draft should test: + 1. create_scheduling_unit_blueprint_from_scheduling_unit_draft(scheduling_unit_draft: models.SchedulingUnitDraft) -> models.SchedulingUnitBlueprint: + 6. create_task_drafts_from_scheduling_unit_draft(scheduling_unit_draft: models.SchedulingUnitDraft) -> [TaskDraft]: + 3. create_task_blueprints_and_subtasks_and_schedule_subtasks_from_scheduling_unit_draft(scheduling_unit_draft: models.SchedulingUnitDraft) -> models.SchedulingUnitBlueprint: + """ + @staticmethod + def create_scheduling_unit_draft_object(scheduling_unit_draft_name, requirements_doc=None): + """ + Helper function to create a scheduling unit object for testing + """ + scheduling_unit_draft_data = SchedulingUnitDraft_test_data(name=scheduling_unit_draft_name) + draft_obj = models.SchedulingUnitDraft.objects.create(**scheduling_unit_draft_data) + return draft_obj + + def test_create_scheduling_unit_blueprint_from_scheduling_unit_draft(self): + """ + Create Scheduling Unit Draft + Check if the name draft (specified) is equal to name blueprint (created) + Check with REST-call if NO tasks are created + """ + scheduling_unit_draft = self.create_scheduling_unit_draft_object("Test Scheduling Unit 1") + + res_scheduling_unit_draft = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/' + str(scheduling_unit_draft.id), 200) + scheduling_unit_blueprint = create_scheduling_unit_blueprint_from_scheduling_unit_draft(scheduling_unit_draft) + self.assertEqual(scheduling_unit_draft.name, scheduling_unit_blueprint.draft.name) + res_scheduling_unit_blueprint = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/' + str(scheduling_unit_draft.id), 200) + self.assertEqual(res_scheduling_unit_blueprint['requirements_template'], res_scheduling_unit_draft['requirements_template']) + self.assertEqual(res_scheduling_unit_blueprint['requirements_doc'], res_scheduling_unit_draft['requirements_doc']) + self.assertEqual(0, len(res_scheduling_unit_blueprint['task_blueprints'])) + + def test_create_task_drafts_from_scheduling_unit_draft(self): + """ + Create Scheduling Unit Draft (with empty requirements_doc) + Check if NO tasks are created + Check with REST-call if NO tasks are created + """ + scheduling_unit_draft = self.create_scheduling_unit_draft_object("Test Scheduling Unit 2") + + res_scheduling_unit_draft = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/' + str(scheduling_unit_draft.id), 200) + list_tasks = create_task_drafts_from_scheduling_unit_draft(scheduling_unit_draft) + self.assertEqual(0, len(list_tasks)) + self.assertEqual(0, len(res_scheduling_unit_draft['task_drafts'])) + + def test_create_task_drafts_from_scheduling_unit_draft_with_UC1_requirements(self): + """ + Create Scheduling Unit Draft with requirements_doc (read from file) + Check if tasks (7) are created + Check with REST-call if tasks are created + """ + working_dir = os.path.dirname(os.path.abspath(__file__)) + with open(os.path.join(working_dir, "testdata/example_CTC_scheduling_block.json")) as json_file: + json_requirements_doc = json.loads(json_file.read()) + + scheduling_unit_draft = models.SchedulingUnitDraft.objects.create( + name="Test Scheduling Unit UC1", + requirements_doc=json_requirements_doc, + requirements_template=models.SchedulingUnitTemplate.objects.get(name="scheduling unit schema"), + copy_reason=models.CopyReason.objects.get(value='template'), + generator_instance_doc="para", + copies=None, + scheduling_set=models.SchedulingSet.objects.create(**SchedulingSet_test_data())) + + res_scheduling_unit_draft = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/' + str(scheduling_unit_draft.id), 200) + list_tasks = create_task_drafts_from_scheduling_unit_draft(scheduling_unit_draft) + self.assertEqual(7, len(list_tasks)) + # TODO: check why rest api is not updated? self.assertEqual(7, len(res_scheduling_unit_draft['task_drafts'])) + + def test_create_task_blueprints_and_subtasks_and_schedule_subtasks_from_scheduling_unit_draft(self): + """ + Create Scheduling Unit Draft + Check if the name draft (specified) is equal to name blueprint (created) + Check with REST-call if NO tasks are created + """ + scheduling_unit_draft = self.create_scheduling_unit_draft_object("Test Scheduling Unit 3") + + res_scheduling_unit_draft = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/' + str(scheduling_unit_draft.id), 200) + scheduling_unit_blueprint = create_task_blueprints_and_subtasks_and_schedule_subtasks_from_scheduling_unit_draft(scheduling_unit_draft) + self.assertEqual(scheduling_unit_draft.name, scheduling_unit_blueprint.draft.name) + res_scheduling_unit_blueprint = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/' + str(scheduling_unit_blueprint.id), 200) + self.assertEqual(res_scheduling_unit_blueprint['requirements_template'], res_scheduling_unit_draft['requirements_template']) + self.assertEqual(res_scheduling_unit_blueprint['requirements_doc'], res_scheduling_unit_draft['requirements_doc']) + self.assertEqual(0, len(res_scheduling_unit_blueprint['task_blueprints'])) + + +class CreationFromSchedulingUnitBluePrint(unittest.TestCase): + """ + From scheduling_unit_blueprint should test: + 5. create_task_blueprints_and_subtasks_and_schedule_subtasks_from_scheduling_unit_blueprint(scheduling_unit_blueprint: models.SchedulingUnitBlueprint) -> models.SchedulingUnitBlueprint: + """ + + def test_create_task_blueprints_and_subtasks_and_schedule_subtasks_from_scheduling_unit_blueprint(self): + """ + Create Scheduling Unit BluePrint + Check with REST-call if NO tasks are created + """ + scheduling_unit_blueprint_data = SchedulingUnitBlueprint_test_data(name="Test Scheduling Unit BluePrint") + scheduling_unit_blueprint = models.SchedulingUnitBlueprint.objects.create(**scheduling_unit_blueprint_data) + + scheduling_unit_blueprint_after_creation = create_task_blueprints_and_subtasks_and_schedule_subtasks_from_scheduling_unit_blueprint(scheduling_unit_blueprint) + res_scheduling_unit_blueprint = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/' + str(scheduling_unit_blueprint.id), 200) + self.assertEqual(0, len(res_scheduling_unit_blueprint['task_blueprints'])) + + +class CreationFromTaskDraft(unittest.TestCase): + """ + From task draft should test: + 2. create_task_blueprint_from_task_draft(task_draft: models.TaskDraft) -> models.TaskBlueprint: + 5. create_task_blueprint_and_subtasks_and_schedule_subtasks_from_task_draft(task_draft: models.TaskDraft) -> models.TaskBlueprint: + """ + @staticmethod + def create_task_object(task_draft_name): + """ + Helper function to create a task object for testing + TODO change schema to observation schema, correlator schema wil be removed + """ + obs_task_template = models.TaskTemplate.objects.get(name='correlator schema') + task_draft_data = TaskDraft_test_data(name=task_draft_name, specifications_template=obs_task_template) + models.TaskDraft.objects.create(**task_draft_data) + + def test_create_task_blueprint_and_subtasks_and_schedule_subtasks(self): + """ + Create task draft + Check if the name draft (specified) is equal to name blueprint (created) + Check with REST-call if 3 subtasks are created and if these subtasks have state value 'defined' + """ + self.create_task_object("Test Target Observation 1") + + task_draft = models.TaskDraft.objects.get(name="Test Target Observation 1") + rest_task_draft = GET_and_assert_equal_expected_code(self, BASE_URL + '/task_draft/' + str(task_draft.id), 200) + task_blueprint = create_task_blueprint_and_subtasks_and_schedule_subtasks_from_task_draft(task_draft) + self.assertEqual(task_draft.name, task_blueprint.draft.name) + rest_task_blueprint = GET_and_assert_equal_expected_code(self, BASE_URL + '/task_blueprint/' + str(task_blueprint.id), 200) + self.assertEqual(3, len(rest_task_blueprint['subtasks'])) + self.assertEqual(rest_task_blueprint['specifications_template'], rest_task_draft['specifications_template']) + for subtask_url in rest_task_blueprint['subtasks']: + res_subtask = GET_and_assert_equal_expected_code(self, subtask_url, 200) + state_value = GET_and_assert_equal_expected_code(self, res_subtask['state'], 200)['value'] + # TODO not all scheduled??? self.assertEqual(state_value, "defined") + def test_create_task_blueprint(self): """ - Use the 'default' task draft (ID=1) to specify observation + Create task draft Check if the task draft name is equal to the task draft name specified in the created task blueprint - Check with REST-call if 4 subtasks are created and if these subtaskshave state value 'defined' + Check with REST-call if NO subtasks are created """ - task_draft = models.TaskDraft.objects.get(id=1) - res_task_draft = GET_and_assert_equal_expected_code(self, BASE_URL + '/task_draft/1/', 200) - task_blueprint = create_task_blueprint_from_task_draft_and_instantiate_subtasks_from_template(task_draft) + self.create_task_object("Test Target Observation 2") + + task_draft = models.TaskDraft.objects.get(name="Test Target Observation 2") + res_task_draft = GET_and_assert_equal_expected_code(self, BASE_URL + '/task_draft/' + str(task_draft.id), 200) + task_blueprint = create_task_blueprint_from_task_draft(task_draft) self.assertEqual(task_draft.name, task_blueprint.draft.name) - res_task_blueprint = GET_and_assert_equal_expected_code(self, BASE_URL + '/task_blueprint/1/', 200) - self.assertEqual(len(res_task_blueprint['subtasks']), 3) + res_task_blueprint = GET_and_assert_equal_expected_code(self, BASE_URL + '/task_blueprint/' + str(task_blueprint.id), 200) + self.assertEqual(0, len(res_task_blueprint['subtasks'])) self.assertEqual(res_task_blueprint['specifications_template'], res_task_draft['specifications_template']) - for subtask_url in res_task_blueprint['subtasks']: - res_subtask = GET_and_assert_equal_expected_code(self, subtask_url, 200) - state_value = GET_and_assert_equal_expected_code(self, res_subtask['state'], 200)['value'] - self.assertEqual(state_value, "defined") if __name__ == "__main__": diff --git a/SAS/TMSS/src/tmss/tmssapp/schemas/example_CTC_observation.json b/SAS/TMSS/test/testdata/example_CTC_scheduling_block.json similarity index 100% rename from SAS/TMSS/src/tmss/tmssapp/schemas/example_CTC_observation.json rename to SAS/TMSS/test/testdata/example_CTC_scheduling_block.json