Skip to content

Commit

Permalink
Fix bugs in allowing config status updates on realtime observation co…
Browse files Browse the repository at this point in the history
…nfiguration statuses
  • Loading branch information
Jon committed Jan 31, 2025
1 parent bfd76e3 commit 6c29cbb
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 18 deletions.
28 changes: 16 additions & 12 deletions observation_portal/common/state_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,18 +249,22 @@ def modify_ipp_time_from_request(ipp_val, request, modification='debit'):

def get_request_state_from_configuration_statuses(old_request_state, request, configuration_statuses):
"""Determine request state from all the configuration statuses associated with one of the request's observations"""
acceptability_threshold = request.acceptability_threshold
observation_state = get_observation_state(configuration_statuses)
completion_percent = exposure_completion_percentage(configuration_statuses)
if isclose(acceptability_threshold, completion_percent) or \
completion_percent >= acceptability_threshold or \
observation_state == 'COMPLETED':
return 'COMPLETED'
# If a nonzero MAX_FAILURES_PER_REQUEST is set and the observation failed, check that condition
if settings.MAX_FAILURES_PER_REQUEST and observation_state == 'FAILED':
failed_observations_count = request.observation_set.filter(state='FAILED').count()
if failed_observations_count >= settings.MAX_FAILURES_PER_REQUEST:
return 'FAILURE_LIMIT_REACHED'
if request.request_group.observation_type == RequestGroup.REAL_TIME:
if configuration_statuses.first().state == 'COMPLETED':
return 'COMPLETED'
else:
acceptability_threshold = request.acceptability_threshold
observation_state = get_observation_state(configuration_statuses)
completion_percent = exposure_completion_percentage(configuration_statuses)
if isclose(acceptability_threshold, completion_percent) or \
completion_percent >= acceptability_threshold or \
observation_state == 'COMPLETED':
return 'COMPLETED'
# If a nonzero MAX_FAILURES_PER_REQUEST is set and the observation failed, check that condition
if settings.MAX_FAILURES_PER_REQUEST and observation_state == 'FAILED':
failed_observations_count = request.observation_set.filter(state='FAILED').count()
if failed_observations_count >= settings.MAX_FAILURES_PER_REQUEST:
return 'FAILURE_LIMIT_REACHED'
return old_request_state


Expand Down
14 changes: 8 additions & 6 deletions observation_portal/observations/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,14 @@ def as_dict(self, no_request=False):
# Returns the current configuration repeat we are within the request for this configuration status
def get_current_repeat(self, configuration_status_id):
num_configurations = self.request.configurations.count()
configuration_status_index = 0
for cs in self.configuration_statuses.all():
if cs.id == configuration_status_id:
break
configuration_status_index += 1
return (configuration_status_index // num_configurations) + 1
if num_configurations:
configuration_status_index = 0
for cs in self.configuration_statuses.all():
if cs.id == configuration_status_id:
break
configuration_status_index += 1
return (configuration_status_index // num_configurations) + 1
return 1

@property
def instrument_types(self):
Expand Down
25 changes: 25 additions & 0 deletions observation_portal/observations/test/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,31 @@ def test_observation_has_configuration_status_created(self, create_downtime):
self.assertEqual(observation['request']['configurations'][0]['configuration_status'],
response.json()['configuration_status_id'])

@patch('observation_portal.common.downtimedb.DowntimeDB.create_downtime_interval')
def test_update_configuration_state_succeeds(self, create_downtime):
response = self.client.post(reverse('api:realtime-list'), data=self.observation)
self.assertEqual(response.status_code, 201)
configuration_status_id = response.json()['configuration_status_id']
configuration_status = ConfigurationStatus.objects.first()
self.assertEqual(configuration_status.id, configuration_status_id)
self.assertEqual(configuration_status.state, 'PENDING')
update_data = {'state': 'ATTEMPTED'}
self.client.force_login(self.user)
self.client.patch(reverse('api:configurationstatus-detail', args=(configuration_status_id,)), update_data)
configuration_status.refresh_from_db()
self.assertEqual(configuration_status.state, 'ATTEMPTED')

@patch('observation_portal.common.downtimedb.DowntimeDB.create_downtime_interval')
def test_update_configuration_state_completed_makes_observation_complete(self, create_downtime):
response = self.client.post(reverse('api:realtime-list'), data=self.observation)
self.assertEqual(response.status_code, 201)
configuration_status_id = response.json()['configuration_status_id']
update_data = {'state': 'COMPLETED'}
self.client.force_login(self.user)
self.client.patch(reverse('api:configurationstatus-detail', args=(configuration_status_id,)), update_data)
observation = Observation.objects.first()
self.assertEqual(observation.state, 'COMPLETED')

@patch('observation_portal.common.downtimedb.DowntimeDB.create_downtime_interval')
def test_observation_has_no_configurations(self, create_downtime):
response = self.client.post(reverse('api:realtime-list'), data=self.observation)
Expand Down

0 comments on commit 6c29cbb

Please sign in to comment.