From fb65c3b7662b12967fb75bb64015a38faa256779 Mon Sep 17 00:00:00 2001 From: Elisabeth Heinrich-Josties Date: Fri, 24 Jan 2020 20:00:33 +0000 Subject: [PATCH 1/3] Use the repeat_duration to figure out percent completed for repeat type configurations --- .../common/test_state_changes.py | 59 +++++++++++++++++++ .../requestgroups/request_utils.py | 10 +++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/observation_portal/common/test_state_changes.py b/observation_portal/common/test_state_changes.py index 161fe23a..f31d32a7 100644 --- a/observation_portal/common/test_state_changes.py +++ b/observation_portal/common/test_state_changes.py @@ -703,6 +703,65 @@ def test_request_state_configuration_status_failed_2(self): self.assertFalse(state_changed) self.assertEqual(self.request.state, 'PENDING') + def test_request_state_repeat_configuration_failed_and_threshold_failed(self): + with disconnect_signal(post_save, cb_configurationstatus_post_save, ConfigurationStatus): + self.request.state = 'PENDING' + self.request.save() + repeat_configuration = self.request.configurations.first() + repeat_configuration.type = 'REPEAT_EXPOSE' + repeat_configuration.repeat_duration = 2000 + repeat_configuration.save() + + observation = dmixer.blend( + Observation, request=self.request, start=self.now - timedelta(minutes=30), + end=self.now - timedelta(minutes=20) + ) + for configuration in self.request.configurations.all(): + if configuration.id == repeat_configuration.id: + cs = dmixer.blend( + ConfigurationStatus, observation=observation, configuration=configuration, state='FAILED', + ) + dmixer.blend(Summary, configuration_status=cs, time_completed=1000) + else: + cs = dmixer.blend( + ConfigurationStatus, observation=observation, configuration=configuration, state='FAILED', + ) + dmixer.blend(Summary, configuration_status=cs, time_completed=0) + state_changed = update_request_state(self.request, observation.configuration_statuses.all(), False) + self.request.refresh_from_db() + self.assertFalse(state_changed) + self.assertEqual(self.request.state, 'PENDING') + + def test_request_state_repeat_configuration_failed_but_threshold_reached(self): + with disconnect_signal(post_save, cb_configurationstatus_post_save, ConfigurationStatus): + self.request.state = 'PENDING' + self.request.acceptability_threshold = 90 + self.request.save() + repeat_configuration = self.request.configurations.last() + repeat_configuration.type = 'REPEAT_EXPOSE' + repeat_configuration.repeat_duration = 2000 + repeat_configuration.save() + + observation = dmixer.blend( + Observation, request=self.request, start=self.now - timedelta(minutes=30), + end=self.now - timedelta(minutes=20) + ) + for configuration in self.request.configurations.all(): + if configuration.id == repeat_configuration.id: + cs = dmixer.blend( + ConfigurationStatus, observation=observation, configuration=configuration, state='FAILED', + ) + dmixer.blend(Summary, configuration_status=cs, time_completed=1999) + else: + cs = dmixer.blend( + ConfigurationStatus, observation=observation, configuration=configuration, state='COMPLETED', + ) + dmixer.blend(Summary, configuration_status=cs, time_completed=100) + state_changed = update_request_state(self.request, observation.configuration_statuses.all(), False) + self.request.refresh_from_db() + self.assertTrue(state_changed) + self.assertEqual(self.request.state, 'COMPLETED') + class TestAggregateRequestStates(TestCase): def test_many_all_complete(self): diff --git a/observation_portal/requestgroups/request_utils.py b/observation_portal/requestgroups/request_utils.py index 2cf503f2..6bb78b54 100644 --- a/observation_portal/requestgroups/request_utils.py +++ b/observation_portal/requestgroups/request_utils.py @@ -128,8 +128,14 @@ def exposure_completion_percentage(configuration_statuses): if hasattr(configuration_status, 'summary'): completed_exposure_time += configuration_status.summary.time_completed configuration_exposure_time = 0 - for instrument_config in configuration_status.configuration.instrument_configs.all(): - configuration_exposure_time += instrument_config.exposure_count * instrument_config.exposure_time + if ( + 'REPEAT' in configuration_status.configuration.type + and configuration_status.configuration.repeat_duration is not None + ): + configuration_exposure_time = configuration_status.configuration.repeat_duration + else: + for instrument_config in configuration_status.configuration.instrument_configs.all(): + configuration_exposure_time += instrument_config.exposure_count * instrument_config.exposure_time total_exposure_time += configuration_exposure_time if float(total_exposure_time) == 0: From 478558e4babdae517dcd96045bef945569ab876e Mon Sep 17 00:00:00 2001 From: Elisabeth Heinrich-Josties Date: Sat, 25 Jan 2020 00:13:32 +0000 Subject: [PATCH 2/3] Used summary end and start times for time completed for repeats --- .../common/test_state_changes.py | 7 ++-- .../requestgroups/request_utils.py | 34 +++++++++++-------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/observation_portal/common/test_state_changes.py b/observation_portal/common/test_state_changes.py index f31d32a7..43588b0b 100644 --- a/observation_portal/common/test_state_changes.py +++ b/observation_portal/common/test_state_changes.py @@ -721,7 +721,8 @@ def test_request_state_repeat_configuration_failed_and_threshold_failed(self): cs = dmixer.blend( ConfigurationStatus, observation=observation, configuration=configuration, state='FAILED', ) - dmixer.blend(Summary, configuration_status=cs, time_completed=1000) + dmixer.blend(Summary, configuration_status=cs, time_completed=1000, start=observation.start, + end=observation.start + timedelta(seconds=1000)) else: cs = dmixer.blend( ConfigurationStatus, observation=observation, configuration=configuration, state='FAILED', @@ -746,12 +747,14 @@ def test_request_state_repeat_configuration_failed_but_threshold_reached(self): Observation, request=self.request, start=self.now - timedelta(minutes=30), end=self.now - timedelta(minutes=20) ) + repeat_starts = observation.start + timedelta(seconds=300) for configuration in self.request.configurations.all(): if configuration.id == repeat_configuration.id: cs = dmixer.blend( ConfigurationStatus, observation=observation, configuration=configuration, state='FAILED', ) - dmixer.blend(Summary, configuration_status=cs, time_completed=1999) + dmixer.blend(Summary, configuration_status=cs, time_completed=1999, + start=repeat_starts, end=repeat_starts + timedelta(seconds=1999)) else: cs = dmixer.blend( ConfigurationStatus, observation=observation, configuration=configuration, state='COMPLETED', diff --git a/observation_portal/requestgroups/request_utils.py b/observation_portal/requestgroups/request_utils.py index 6bb78b54..2ab7c678 100644 --- a/observation_portal/requestgroups/request_utils.py +++ b/observation_portal/requestgroups/request_utils.py @@ -122,26 +122,32 @@ def get_airmasses_for_request_at_sites(request_dict, is_staff=False): def exposure_completion_percentage(configuration_statuses): - total_exposure_time = 0 - completed_exposure_time = 0 + total_time = 0 + completed_time = 0 for configuration_status in configuration_statuses: - if hasattr(configuration_status, 'summary'): - completed_exposure_time += configuration_status.summary.time_completed - configuration_exposure_time = 0 - if ( - 'REPEAT' in configuration_status.configuration.type - and configuration_status.configuration.repeat_duration is not None - ): - configuration_exposure_time = configuration_status.configuration.repeat_duration + is_repeat_type = ( + 'REPEAT' in configuration_status.configuration.type and + configuration_status.configuration.repeat_duration is not None + ) + has_summary = hasattr(configuration_status, 'summary') + configuration_total_time = 0 + if is_repeat_type: + if has_summary: + completed_time += ( + configuration_status.summary.end - configuration_status.summary.start + ).total_seconds() + configuration_total_time = configuration_status.configuration.repeat_duration else: + if has_summary: + completed_time += configuration_status.summary.time_completed for instrument_config in configuration_status.configuration.instrument_configs.all(): - configuration_exposure_time += instrument_config.exposure_count * instrument_config.exposure_time - total_exposure_time += configuration_exposure_time + configuration_total_time += instrument_config.exposure_count * instrument_config.exposure_time + total_time += configuration_total_time - if float(total_exposure_time) == 0: + if float(total_time) == 0: return 100.0 - return (completed_exposure_time / total_exposure_time) * 100.0 + return (completed_time / total_time) * 100.0 def return_paginated_results(collection, url): From 36c44f6519a2e5e96dd1a196daf222f3abaa9a4e Mon Sep 17 00:00:00 2001 From: Elisabeth Heinrich-Josties Date: Sat, 25 Jan 2020 01:39:32 +0000 Subject: [PATCH 3/3] Get rid of unecessary variable --- observation_portal/requestgroups/request_utils.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/observation_portal/requestgroups/request_utils.py b/observation_portal/requestgroups/request_utils.py index 2ab7c678..f6678873 100644 --- a/observation_portal/requestgroups/request_utils.py +++ b/observation_portal/requestgroups/request_utils.py @@ -130,19 +130,17 @@ def exposure_completion_percentage(configuration_statuses): configuration_status.configuration.repeat_duration is not None ) has_summary = hasattr(configuration_status, 'summary') - configuration_total_time = 0 if is_repeat_type: if has_summary: completed_time += ( - configuration_status.summary.end - configuration_status.summary.start + configuration_status.summary.end - configuration_status.summary.start ).total_seconds() - configuration_total_time = configuration_status.configuration.repeat_duration + total_time += configuration_status.configuration.repeat_duration else: if has_summary: completed_time += configuration_status.summary.time_completed for instrument_config in configuration_status.configuration.instrument_configs.all(): - configuration_total_time += instrument_config.exposure_count * instrument_config.exposure_time - total_time += configuration_total_time + total_time += instrument_config.exposure_count * instrument_config.exposure_time if float(total_time) == 0: return 100.0