diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py b/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py index 085dd455eb014832280e6958f22d1fab9474ac18..5ad73a12bce413e269a6adca463ef2759909de62 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py @@ -150,7 +150,7 @@ class Subtask(BasicCommon, ProjectPropertyMixin, TemplateSchemaMixin): state = ForeignKey('SubtaskState', null=False, on_delete=PROTECT, related_name='task_states', help_text='Subtask state (see Subtask State Machine).') primary = BooleanField(default=False, db_index=True, help_text='TRUE if this is the one-and-only primary subtask in a parent TaskBlueprint.') specifications_doc = JSONField(help_text='Final specifications, as input for the controller.') - task_blueprint = ForeignKey('TaskBlueprint', null=True, on_delete=PROTECT, related_name='subtasks', help_text='The parent TaskBlueprint.') #TODO: be more strict with null=False + task_blueprint = ForeignKey('TaskBlueprint', null=False, on_delete=PROTECT, related_name='subtasks', help_text='The parent TaskBlueprint.') specifications_template = ForeignKey('SubtaskTemplate', null=False, on_delete=PROTECT, help_text='Schema used for specifications_doc.') cluster = ForeignKey('Cluster', null=True, on_delete=PROTECT, help_text='Where the Subtask is scheduled to run (NULLable).') # resource_claim = ForeignKey("ResourceClaim", null=False, on_delete=PROTECT) # todo <-- how is this external reference supposed to work? diff --git a/SAS/TMSS/backend/test/t_tasks.py b/SAS/TMSS/backend/test/t_tasks.py index 6b7a37ed9a1d32b74c6d9bc5ef4bbe536ea98c89..c90ddeed7b562ea58cc5347cd18e6392e949c6e4 100755 --- a/SAS/TMSS/backend/test/t_tasks.py +++ b/SAS/TMSS/backend/test/t_tasks.py @@ -429,9 +429,9 @@ class TaskBlueprintStateTest(unittest.TestCase): task_blueprint_data = TaskBlueprint_test_data(name="Task Blueprint With Subtasks") task_blueprint = models.TaskBlueprint.objects.create(**task_blueprint_data) # Create observation and qa subtask related to taskblueprint - subtask_data = Subtask_test_data(subtask_template=models.SubtaskTemplate.objects.get(name='observation control'), task_blueprint=task_blueprint) + subtask_data = Subtask_test_data(subtask_template=models.SubtaskTemplate.objects.get(name='observation control'), task_blueprint=task_blueprint, primary=True) subtask_obs = models.Subtask.objects.create(**subtask_data) - subtask_data = Subtask_test_data(subtask_template=models.SubtaskTemplate.objects.get(name='QA file conversion'), task_blueprint=task_blueprint) + subtask_data = Subtask_test_data(subtask_template=models.SubtaskTemplate.objects.get(name='QA file conversion'), task_blueprint=task_blueprint, primary=False) subtask_qa = models.Subtask.objects.create(**subtask_data) # Do the actual test @@ -476,10 +476,11 @@ class TaskBlueprintStateTest(unittest.TestCase): task_blueprint_data = TaskBlueprint_test_data(name="Task Blueprint With Subtasks") task_blueprint = models.TaskBlueprint.objects.create(**task_blueprint_data) # Create observation and qa subtasks related to taskblueprint - subtask_data = Subtask_test_data(subtask_template=models.SubtaskTemplate.objects.get(name='observation control'), task_blueprint=task_blueprint) + subtask_data = Subtask_test_data(subtask_template=models.SubtaskTemplate.objects.get(name='observation control'), task_blueprint=task_blueprint, primary=True) subtask_obs1 = models.Subtask.objects.create(**subtask_data) + subtask_data['primary'] = False subtask_obs2 = models.Subtask.objects.create(**subtask_data) - subtask_data = Subtask_test_data(subtask_template=models.SubtaskTemplate.objects.get(name='QA file conversion'), task_blueprint=task_blueprint) + subtask_data = Subtask_test_data(subtask_template=models.SubtaskTemplate.objects.get(name='QA file conversion'), task_blueprint=task_blueprint, primary=False) subtask_qa1 = models.Subtask.objects.create(**subtask_data) subtask_qa2 = models.Subtask.objects.create(**subtask_data) diff --git a/SAS/TMSS/backend/test/t_tmssapp_scheduling_REST_API.py b/SAS/TMSS/backend/test/t_tmssapp_scheduling_REST_API.py index 165cbf1e71e02ae6d17955d96a814c77806c20e6..719371acc1748494e209ee190c4bd6ebec7a428c 100755 --- a/SAS/TMSS/backend/test/t_tmssapp_scheduling_REST_API.py +++ b/SAS/TMSS/backend/test/t_tmssapp_scheduling_REST_API.py @@ -286,7 +286,7 @@ class SubtaskTestCase(unittest.TestCase): GET_and_assert_equal_expected_code(self, BASE_URL + '/subtask/1234321/', 404) def test_subtask_POST_and_GET(self): - st_test_data = test_data_creator.Subtask(cluster_url=self.cluster_url, task_blueprint_url=self.task_blueprint_url, specifications_template_url=self.specifications_template_url) + st_test_data = test_data_creator.Subtask(cluster_url=self.cluster_url, specifications_template_url=self.specifications_template_url) # POST and GET a new item and assert correctness r_dict = POST_and_assert_expected_response(self, BASE_URL + '/subtask/', st_test_data, 201, st_test_data) @@ -304,8 +304,8 @@ class SubtaskTestCase(unittest.TestCase): PUT_and_assert_expected_response(self, BASE_URL + '/subtask/9876789876/', st_test_data, 404, {}) def test_subtask_PUT(self): - st_test_data = test_data_creator.Subtask(cluster_url=self.cluster_url, task_blueprint_url=self.task_blueprint_url, specifications_template_url=self.specifications_template_url) - st_test_data2 = test_data_creator.Subtask(cluster_url=self.cluster_url, task_blueprint_url=self.task_blueprint_url, specifications_template_url=self.specifications_template_url) + st_test_data = test_data_creator.Subtask(cluster_url=self.cluster_url, task_blueprint_url=test_data_creator.post_data_and_get_url(test_data_creator.TaskBlueprint(), '/task_blueprint/'), specifications_template_url=self.specifications_template_url, primary=True) + st_test_data2 = test_data_creator.Subtask(cluster_url=self.cluster_url, task_blueprint_url=test_data_creator.post_data_and_get_url(test_data_creator.TaskBlueprint(), '/task_blueprint/'), specifications_template_url=self.specifications_template_url, primary=True) # POST new item, verify r_dict = POST_and_assert_expected_response(self, BASE_URL + '/subtask/', st_test_data, 201, st_test_data) @@ -313,11 +313,13 @@ class SubtaskTestCase(unittest.TestCase): GET_OK_and_assert_equal_expected_response(self, url, st_test_data) # PUT new values, verify + st_test_data2['task_blueprint'] = test_data_creator.post_data_and_get_url(test_data_creator.TaskBlueprint(), '/task_blueprint/') PUT_and_assert_expected_response(self, url, st_test_data2, 200, st_test_data2) GET_OK_and_assert_equal_expected_response(self, url, st_test_data2) def test_subtask_PATCH(self): - st_test_data = test_data_creator.Subtask(cluster_url=self.cluster_url, task_blueprint_url=self.task_blueprint_url, specifications_template_url=self.specifications_template_url) + task_blueprint_url = test_data_creator.post_data_and_get_url(test_data_creator.TaskBlueprint(), '/task_blueprint/') + st_test_data = test_data_creator.Subtask(cluster_url=self.cluster_url, task_blueprint_url=task_blueprint_url, specifications_template_url=self.specifications_template_url) # POST new item, verify r_dict = POST_and_assert_expected_response(self, BASE_URL + '/subtask/', st_test_data, 201, st_test_data) @@ -368,7 +370,8 @@ class SubtaskTestCase(unittest.TestCase): stt_test_data = test_data_creator.SubtaskTemplate() expected_data = test_data_creator.update_schema_from_template("subtasktemplate", stt_test_data) specifications_template_url = test_data_creator.post_data_and_get_url(stt_test_data, '/subtask_template/') - st_test_data = test_data_creator.Subtask(specifications_template_url=specifications_template_url, cluster_url=self.cluster_url, task_blueprint_url=self.task_blueprint_url) + st_test_data = test_data_creator.Subtask(specifications_template_url=specifications_template_url, cluster_url=self.cluster_url, + task_blueprint_url=test_data_creator.post_data_and_get_url(test_data_creator.TaskBlueprint(), '/task_blueprint/')) # POST new item and verify url = POST_and_assert_expected_response(self, BASE_URL + '/subtask/', st_test_data, 201, st_test_data)['url'] @@ -382,7 +385,7 @@ class SubtaskTestCase(unittest.TestCase): GET_OK_and_assert_equal_expected_response(self, specifications_template_url, expected_data) def test_subtask_state_log_records(self): - st_test_data = test_data_creator.Subtask() + st_test_data = test_data_creator.Subtask(task_blueprint_url=test_data_creator.post_data_and_get_url(test_data_creator.TaskBlueprint(), '/task_blueprint/')) # POST new item, verify r_dict = POST_and_assert_expected_response(self, BASE_URL + '/subtask/', st_test_data, 201, st_test_data) @@ -572,6 +575,7 @@ class SubtaskInputTestCase(unittest.TestCase): # make new subtask_url instance, but reuse related data for speed subtask_url = test_data_creator.post_data_and_get_url(test_data_creator.Subtask(cluster_url=self.subtask_data['cluster'], task_blueprint_url=self.subtask_data['task_blueprint'], + primary=False, specifications_template_url=self.subtask_data['specifications_template'], specifications_doc=self.subtask_data['specifications_doc']), '/subtask/') test_patch = {"subtask": subtask_url, @@ -598,7 +602,7 @@ class SubtaskInputTestCase(unittest.TestCase): def test_subtask_input_CASCADE_behavior_on_subtask_deleted(self): # make new subtask_url instance, but reuse related data for speed subtask_url = test_data_creator.post_data_and_get_url(test_data_creator.Subtask(cluster_url=self.subtask_data['cluster'], - task_blueprint_url=self.subtask_data['task_blueprint'], + task_blueprint_url=test_data_creator.post_data_and_get_url(test_data_creator.TaskBlueprint(), '/task_blueprint/'), specifications_template_url=self.subtask_data['specifications_template'], specifications_doc=self.subtask_data['specifications_doc']), '/subtask/') sti_test_data = test_data_creator.SubtaskInput(subtask_url=subtask_url, task_relation_blueprint_url=self.task_relation_blueprint_url, dataproduct_urls=self.dataproduct_urls, subtask_output_url=self.subtask_output_url, task_relation_selection_template_url=self.task_relation_selection_template_url) @@ -671,7 +675,7 @@ class SubtaskInputTestCase(unittest.TestCase): class SubtaskOutputTestCase(unittest.TestCase): @classmethod def setUpClass(cls) -> None: - cls.subtask_data = test_data_creator.Subtask() + cls.subtask_data = test_data_creator.Subtask(task_blueprint_url=test_data_creator.post_data_and_get_url(test_data_creator.TaskBlueprint(), '/task_blueprint/')) cls.subtask_url = test_data_creator.post_data_and_get_url(cls.subtask_data, '/subtask/') def test_subtask_output_list_apiformat(self): @@ -740,8 +744,8 @@ class SubtaskOutputTestCase(unittest.TestCase): DELETE_and_assert_gone(self, url) def test_subtask_output_CASCADE_behavior_on_subtask_deleted(self): - # make new subtask_url instance, but reuse related data for speed - subtask_url = test_data_creator.post_data_and_get_url(self.subtask_data, '/subtask/') + subtask_data = test_data_creator.Subtask(task_blueprint_url=test_data_creator.post_data_and_get_url(test_data_creator.TaskBlueprint(), '/task_blueprint/')) + subtask_url = test_data_creator.post_data_and_get_url(subtask_data, '/subtask/') sto_test_data = test_data_creator.SubtaskOutput(subtask_url=subtask_url) # POST new item, verify @@ -1342,7 +1346,7 @@ class SubtaskQueryTestCase(unittest.TestCase): for day_idx in range(0, total_number): start_time = datetime.now() + timedelta(hours=2, days=day_idx) stop_time = datetime.now() + timedelta(hours=4, days=day_idx) - test_data_creator.post_data_and_get_url(test_data_creator.Subtask(start_time=start_time, stop_time=stop_time, + test_data_creator.post_data_and_get_url(test_data_creator.Subtask(start_time=start_time, stop_time=stop_time, primary=(day_idx==0), cluster_url=cluster_url, task_blueprint_url=task_blueprint_url), '/subtask/') subtasks_test_data_with_start_stop_time = {'clusterB': 50, 'clusterC': 30 } @@ -1363,9 +1367,10 @@ class SubtaskQueryTestCase(unittest.TestCase): models.Dataproduct.objects.all().delete() models.Subtask.objects.all().delete() + task_blueprint_url = test_data_creator.post_data_and_get_url(test_data_creator.TaskBlueprint(), '/task_blueprint/') cluster_url = test_data_creator.post_data_and_get_url(test_data_creator.Cluster(name="clusterA"), '/cluster/') test_data_creator.post_data_and_get_url(test_data_creator.Subtask(start_time=datetime.utcnow(), stop_time=datetime.utcnow(), - cluster_url=cluster_url), '/subtask/') + cluster_url=cluster_url, task_blueprint_url=task_blueprint_url), '/subtask/') for cluster_name, period_length_in_days in SubtaskQueryTestCase.subtasks_test_data_with_start_stop_time.items(): SubtaskQueryTestCase.create_multiple_subtask_object(period_length_in_days, cluster_name) diff --git a/SAS/TMSS/backend/test/t_tmssapp_scheduling_django_API.py b/SAS/TMSS/backend/test/t_tmssapp_scheduling_django_API.py index 90268af04eb07a46e2a86efffb7f1d37f40221ce..a75b17cf5a365246a1bf2f744aa8d64f4fdbb16e 100755 --- a/SAS/TMSS/backend/test/t_tmssapp_scheduling_django_API.py +++ b/SAS/TMSS/backend/test/t_tmssapp_scheduling_django_API.py @@ -229,8 +229,8 @@ class SubtaskTest(unittest.TestCase): self.assertEqual(set(), set(subtask2.successors.all())) def test_Subtask_predecessors_and_successors_simple(self): - subtask1:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(task_blueprint=self.task_blueprint)) - subtask2:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(task_blueprint=self.task_blueprint)) + subtask1:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(task_blueprint=self.task_blueprint, primary=True)) + subtask2:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(task_blueprint=self.task_blueprint, primary=False)) output1 = models.SubtaskOutput.objects.create(subtask=subtask1) models.SubtaskInput.objects.create(**SubtaskInput_test_data(subtask=subtask2, producer=output1)) @@ -239,12 +239,12 @@ class SubtaskTest(unittest.TestCase): self.assertEqual(subtask2, subtask1.successors.all()[0]) def test_Subtask_predecessors_and_successors_complex(self): - subtask1:models.Subtask = models.Subtask.objects.create(**Subtask_test_data()) - subtask2:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(subtask1.task_blueprint)) - subtask3:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(subtask1.task_blueprint)) - subtask4:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(subtask1.task_blueprint)) - subtask5:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(subtask1.task_blueprint)) - subtask6:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(subtask1.task_blueprint)) + subtask1:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(primary=True)) + subtask2:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(subtask1.task_blueprint, primary=False)) + subtask3:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(subtask1.task_blueprint, primary=False)) + subtask4:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(subtask1.task_blueprint, primary=False)) + subtask5:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(subtask1.task_blueprint, primary=False)) + subtask6:models.Subtask = models.Subtask.objects.create(**Subtask_test_data(subtask1.task_blueprint, primary=False)) # ST1 ---> ST3 ---> ST4 # | | diff --git a/SAS/TMSS/backend/test/tmss_test_data_django_models.py b/SAS/TMSS/backend/test/tmss_test_data_django_models.py index d731f84b94501c7761feb998fac825d14dbb06bf..e445780d6f9c4c990310d0f505bf0268eec1f988 100644 --- a/SAS/TMSS/backend/test/tmss_test_data_django_models.py +++ b/SAS/TMSS/backend/test/tmss_test_data_django_models.py @@ -401,9 +401,12 @@ def SubtaskInput_test_data(subtask: models.Subtask=None, producer: models.Subtas "selection_template": selection_template, "tags":[]} -def Subtask_test_data(subtask_template: models.SubtaskTemplate=None, +def Subtask_test_data(task_blueprint: models.TaskBlueprint=None, subtask_template: models.SubtaskTemplate=None, specifications_doc: dict=None, start_time=None, stop_time=None, cluster=None, state=None, - raw_feedback=None, task_blueprint: models.TaskBlueprint=None, primary:bool=True) -> dict: + raw_feedback=None, primary:bool=True) -> dict: + + if task_blueprint is None: + task_blueprint = models.TaskBlueprint.objects.create(**TaskBlueprint_test_data()) if subtask_template is None: subtask_template = models.SubtaskTemplate.objects.create(**SubtaskTemplate_test_data()) diff --git a/SAS/TMSS/backend/test/tmss_test_data_rest.py b/SAS/TMSS/backend/test/tmss_test_data_rest.py index 4f74cf21029867c2f22dd6d432c9d400579f71d1..c698612aea453d7f6e18d2e155cc087388b6f29a 100644 --- a/SAS/TMSS/backend/test/tmss_test_data_rest.py +++ b/SAS/TMSS/backend/test/tmss_test_data_rest.py @@ -686,7 +686,7 @@ class TMSSRESTTestDataCreator(): try: return self._subtask_url except AttributeError: - self._subtask_url = self.post_data_and_get_url(self.Subtask(), '/subtask/') + self._subtask_url = self.post_data_and_get_url(self.Subtask(task_blueprint_url = self.post_data_and_get_url(self.TaskBlueprint(), '/task_blueprint/')), '/subtask/') return self._subtask_url def SubtaskOutput(self, subtask_url=None):