diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/adapters/reports.py b/SAS/TMSS/backend/src/tmss/tmssapp/adapters/reports.py index 35fd7f42c1a476c2cc26c7e43e26cf82f5a22856..d491a5ecc8e18c1e4d4d0114269b885741eb602d 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/adapters/reports.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/adapters/reports.py @@ -326,31 +326,36 @@ def _get_subs_and_durations_from_project(project_pk: int) -> ({}, {}): """ from lofar.sas.tmss.tmss.workflowapp.models.schedulingunitflow import SchedulingUnitProcess - durations = {'total': 0, 'total_succeeded': 0, 'total_not_cancelled': 0, 'total_failed': 0} + durations = {'total': 0, 'total_not_cancelled': 0, 'total_observed': 0, 'total_observed_succeeded': 0, + 'total_observed_failed': 0} # Get SUBs related to the project project_subs = models.SchedulingUnitBlueprint.objects.filter(draft__scheduling_set__project__pk=project_pk) subs_succeeded, subs_failed = [], [] for prio in models.PriorityQueueType.Choices: - durations[f'total_succeeded_{prio.name}'] = 0 + durations[f'total_observed_succeeded_{prio.name}'] = 0 subs = project_subs.filter(priority_queue=prio.value) for sub in subs: - # TODO: Maybe also add generic durations. + # TODO: Does it make any sense to consider generic successful and failed? + durations['total'] += sub.duration.total_seconds() + if sub.status != 'cancelled': # Not cancelled SUBs + durations['total_not_cancelled'] += sub.duration.total_seconds() + # Observations if sub.observed_duration: - durations['total'] += sub.observed_duration.total_seconds() + durations['total_observed'] += sub.observed_duration.total_seconds() sup = SchedulingUnitProcess.objects.filter(su=sub).first() if sup and sup.results_accepted: # Succeeded SUBs - durations[f'total_succeeded_{prio.name}'] += sub.observed_duration.total_seconds() - subs_succeeded.append({'id': sub.pk, 'name': sub.name, 'observed_duration': sub.duration.total_seconds()}) + durations[f'total_observed_succeeded_{prio.name}'] += sub.observed_duration.total_seconds() + subs_succeeded.append({'id': sub.pk, 'name': sub.name, 'duration': sub.duration.total_seconds(), + 'observed_duration': sub.observed_duration.total_seconds()}) elif sup and sup.results_accepted is False: # Failed SUBs - durations['total_duration_failed'] += sub.observed_duration.total_seconds() - subs_failed.append({'id': sub.pk, 'name': sub.name, 'observed_duration': sub.duration.total_seconds()}) - if sub.status != 'cancelled': # Not cancelled SUBs - durations['total_not_cancelled'] += sub.observed_duration.total_seconds() - durations['total_succeeded'] += durations[f'total_succeeded_{prio.name}'] + durations['total_observed_failed'] += sub.observed_duration.total_seconds() + subs_failed.append({'id': sub.pk, 'name': sub.name, 'duration': sub.duration.total_seconds(), + 'observed_duration': sub.observed_duration.total_seconds()}) + durations['total_observed_succeeded'] += durations[f'total_observed_succeeded_{prio.name}'] - subs = {'finished': subs_succeeded, 'failed': subs_failed} + subs = {'successful': subs_succeeded, 'failed': subs_failed} return subs, durations diff --git a/SAS/TMSS/backend/test/t_adapter.py b/SAS/TMSS/backend/test/t_adapter.py index c329397cda8f749f94f30a5b0518b98774368dea..f2c45cd6c7461cd35bda7051645121703154f7fa 100755 --- a/SAS/TMSS/backend/test/t_adapter.py +++ b/SAS/TMSS/backend/test/t_adapter.py @@ -591,10 +591,10 @@ class ProjectReportTest(unittest.TestCase): """ Test create project extra action. """ - # Create four SUBs and respectively set their states to: 'finished' (so we can create dataproducts and compare - # their sizes), blank (it may be whatever), 'cancelled' and 'defined' (which means not cancelled). + # Create four SUBs and respectively set their states to: 'finished' x2 (so we can create dataproducts, compare + # their sizes, and have a successful and a failed SUBs), 'cancelled' and 'defined' (which means not cancelled). succeeded_sub, _, succeeded_subtask = self._get_SUB_with_subtask_and_set_status('finished') - failed_sub, _, failed_subtask = self._get_SUB_with_subtask_and_set_status() + failed_sub, _, failed_subtask = self._get_SUB_with_subtask_and_set_status('finished') cancelled_sub, _, cancelled_subtask = self._get_SUB_with_subtask_and_set_status('cancelled') not_cancelled_sub, _, not_cancelled_subtask = self._get_SUB_with_subtask_and_set_status('defined') # Set workflow flags so we have a successful and a failed SUBs @@ -616,16 +616,15 @@ class ProjectReportTest(unittest.TestCase): self.assertEqual(result['quota'][0]['id'], self.project_quota.pk) # Assert durations are well calculated - # NOTE: The four SUBs (successful, failed, cancelled and not cancelled) have a duration of 600s each. - # TODO: Now the APIs consider the observed_duration. Set up these values properly and asserts them. + # The four SUBs (successful, failed, cancelled and not cancelled) have a duration/observed_duration of 600s each self.assertAlmostEqual(result['durations']['total'], 2400, places=4) - self.assertAlmostEqual(result['durations']['total_succeeded'], 600, places=4) + self.assertAlmostEqual(result['durations']['total_observed_succeeded'], 600, places=4) self.assertAlmostEqual(result['durations']['total_not_cancelled'], 1800, places=4) - self.assertAlmostEqual(result['durations']['total_failed'], 600, places=4) + self.assertAlmostEqual(result['durations']['total_observed_failed'], 600, places=4) - # There is only one finished SUB - self.assertEqual(result['SUBs']['finished'][0]['id'], succeeded_sub.pk) - # There is only one cancelled SUB + # There is only one successful SUB + self.assertEqual(result['SUBs']['successful'][0]['id'], succeeded_sub.pk) + # There is only one failed SUB self.assertEqual(result['SUBs']['failed'][0]['id'], failed_sub.pk) # There are just two dataproducts