From 3c47227d85f350e33e294276889de1c813a56832 Mon Sep 17 00:00:00 2001 From: Julien Perrochet Date: Fri, 11 Oct 2024 23:28:45 +0200 Subject: [PATCH 1/2] [uss_qualifier] oir_simple: check subscription extent needs to cover OIR --- monitoring/prober/infrastructure.py | 2 +- .../oir/oir_has_expected_subscription.md | 10 + .../astm/utm/dss/op_intent_ref_simple.md | 62 +++- .../astm/utm/dss/op_intent_ref_simple.py | 276 +++++++++++++++++- 4 files changed, 334 insertions(+), 16 deletions(-) create mode 100644 monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/oir/oir_has_expected_subscription.md diff --git a/monitoring/prober/infrastructure.py b/monitoring/prober/infrastructure.py index 4598697aa7..9022444a94 100644 --- a/monitoring/prober/infrastructure.py +++ b/monitoring/prober/infrastructure.py @@ -100,7 +100,7 @@ def wrapper_default_scope(*args, **kwargs): resource_type_code_descriptions: Dict[ResourceType, str] = {} -# Next code: 398 +# Next code: 400 def register_resource_type(code: int, description: str) -> ResourceType: """Register that the specified code refers to the described resource. diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/oir/oir_has_expected_subscription.md b/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/oir/oir_has_expected_subscription.md new file mode 100644 index 0000000000..7c8bc15d78 --- /dev/null +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/oir/oir_has_expected_subscription.md @@ -0,0 +1,10 @@ +# OIR is attached to expected subscription test step fragment + +## [Query Success](./crud/read_query.md) + +Check query succeeds + +## 🛑 OIR is attached to expected subscription check + +If the OIR returned by the DSS under test is not attached to the expected subscription, +it is in violation of **[astm.f3548.v21.DSS0005,1](../../../../../../requirements/astm/f3548/v21.md)** diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.md b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.md index e6c98dd7d9..1fe6fc192c 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.md +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.md @@ -28,14 +28,74 @@ Verifies the behavior of a DSS for simple interactions pertaining to operational This step ensures that no entities with the known test IDs exists in the DSS. +### [Create a subscription test step](./fragments/sub/crud/create_query.md) + +Create an explicit subscription to be used in this scenario. + +## Validate explicit subscription on OIR creation test case + +Ensures that the explicit subscription provided upon creation of an OIR is properly validated and attached to the OIR. + +### Provide subscription not covering extent of OIR being created test step + +This step verifies that an OIR cannot be created when an explicit subscription that does not cover the extent of the OIR is specified. + +#### 🛑 Request to create OIR with incorrect subscription fails check + +If the DSS under test allows the qualifier to create an OIR with an explicit subscription that does not cover the extent of the OIR, +it is in violation of **[astm.f3548.v21.DSS0005,1](../../../../requirements/astm/f3548/v21.md)** + ### [Create an operational intent reference test step](./fragments/oir/crud/create_query.md) -Create an operational intent reference to be used in this scenario. +When the provided subscription covers the extent of the OIR, the OIR can be created. + +### [OIR is attached to expected subscription test step](./fragments/oir/oir_has_expected_subscription.md) + +This step verifies that the OIR is attached to the subscription provided upon creation. + +## Validate explicit subscription upon subscription replacement test case + +Ensures that when the explicit subscription tied to an OIR is replaced with another explicit subscription, +this subscription is properly validated and attached to the OIR. + +### [Create a subscription test step](./fragments/sub/crud/create_query.md) + +Create an additional explicit subscription to be used in this test case. + +### Attempt to replace OIR's existing explicit subscription with an insufficient one test step + +This step verifies that an OIR's existing explicit subscription cannot be replaced with an explicit subscription that does not cover the extent of the OIR. + +#### 🛑 Request to mutate OIR while providing an incorrect subscription fails check + +If the DSS under test allows the qualifier to replace an OIR's existing explicit subscription with an explicit subscription that does not cover the extent of the OIR, +it is in violation of **[astm.f3548.v21.DSS0005,1](../../../../requirements/astm/f3548/v21.md)** + +### [OIR is attached to expected subscription test step](./fragments/oir/oir_has_expected_subscription.md) + +This step verifies that the OIR is still attached to the previous, valid, subscription. + +### [Replace the OIR's explicit subscription test step](./fragments/oir/crud/update_query.md) + +This step verifies that an OIR attached to an explicit subscription can be mutated in order to be attached +to another explicit subscription that properly covers the extent of the OIR. + +### [OIR is attached to expected subscription test step](./fragments/oir/oir_has_expected_subscription.md) + +This step verifies that the OIR is attached to the subscription provided upon mutation. ## Deletion requires correct OVN test case Ensures that a DSS will only delete OIRs when the correct OVN is presented. +### [Ensure clean workspace test step](./clean_workspace.md) + +This step resets the workspace for the present and following test cases by ensuring that no entities with the known test IDs exists in the DSS. + +### [Create an operational intent reference test step](./fragments/oir/crud/create_query.md) + +Create an operational intent reference to be used in this and the following test cases. + ### Attempt deletion with missing OVN test step This step verifies that an existing OIR cannot be deleted with a missing OVN. diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.py b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.py index 39b5e3dfac..30631dd50f 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.py +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.py @@ -5,10 +5,14 @@ EntityID, OperationalIntentReference, OperationalIntentState, + SubscriptionID, + Subscription, + PutOperationalIntentReferenceParameters, ) from uas_standards.astm.f3548.v21.constants import Scope from monitoring.monitorlib.fetch import QueryError +from monitoring.monitorlib.fetch.rid import subscription from monitoring.monitorlib.geotemporal import Volume4D from monitoring.prober.infrastructure import register_resource_type from monitoring.uss_qualifier.resources.astm.f3548.v21 import PlanningAreaResource @@ -19,6 +23,9 @@ from monitoring.uss_qualifier.resources.astm.f3548.v21.planning_area import ( PlanningAreaSpecification, ) +from monitoring.uss_qualifier.resources.astm.f3548.v21.subscription_params import ( + SubscriptionParams, +) from monitoring.uss_qualifier.resources.communications import ClientIdentityResource from monitoring.uss_qualifier.resources.interuss.id_generator import IDGeneratorResource from monitoring.uss_qualifier.scenarios.astm.utm.dss import test_step_fragments @@ -38,10 +45,13 @@ class OIRSimple(TestScenario): """ OIR_TYPE = register_resource_type(396, "Operational Intent Reference") - + SUB_TYPE = register_resource_type(398, "Subscription") + EXTRA_SUB_TYPE = register_resource_type(399, "Subscription") _dss: DSSInstance _oir_id: EntityID + _sub_id: SubscriptionID + _extra_sub_id: SubscriptionID # Keep track of the current OIR state _current_oir: Optional[OperationalIntentReference] @@ -49,6 +59,12 @@ class OIRSimple(TestScenario): _planning_area: PlanningAreaSpecification _planning_area_volume4d: Volume4D + # Keep track of the current subscription + _sub_params: Optional[SubscriptionParams] + _current_sub: Optional[Subscription] + + _current_extra_sub: Optional[Subscription] + def __init__( self, dss: DSSInstanceResource, @@ -73,6 +89,8 @@ def __init__( self._pid = [self._dss.participant_id] self._oir_id = id_generator.id_factory.make_id(self.OIR_TYPE) + self._sub_id = id_generator.id_factory.make_id(self.SUB_TYPE) + self._extra_sub_id = id_generator.id_factory.make_id(self.EXTRA_SUB_TYPE) self._expected_manager = client_identity.subject() @@ -84,9 +102,36 @@ def __init__( def run(self, context: ExecutionContext): self.begin_test_scenario(context) - self._setup_case() + self.begin_test_case("Setup") + self._setup_case(create_explicit_sub=True) + self.end_test_case() + + self.begin_test_case("Validate explicit subscription on OIR creation") + self._step_create_oir_insufficient_subscription() + self._step_create_oir( + oir_params=self._planning_area.get_new_operational_intent_ref_params( + key=[], + state=OperationalIntentState.Accepted, + uss_base_url=self._planning_area.get_base_url(), + time_start=datetime.now() - timedelta(seconds=10), + time_end=self._sub_params.end_time, # OIR ends at the same time as subscription + subscription_id=self._sub_id, + ), + ) + self._step_oir_has_correct_subscription(expected_sub_id=self._sub_id) + self.end_test_case() + + self.begin_test_case( + "Validate explicit subscription upon subscription replacement" + ) + self._step_update_oir_with_insufficient_explicit_sub() + self._step_oir_has_correct_subscription(expected_sub_id=self._sub_id) + self._step_update_oir_with_sufficient_explicit_sub() + self._step_oir_has_correct_subscription(expected_sub_id=self._extra_sub_id) + self.end_test_case() self.begin_test_case("Deletion requires correct OVN") + self._setup_case(create_oir=True) self._step_attempt_delete_missing_ovn() self._step_attempt_delete_incorrect_ovn() self.end_test_case() @@ -98,17 +143,35 @@ def run(self, context: ExecutionContext): self.end_test_scenario() - def _step_create_oir(self): - oir_params = self._planning_area.get_new_operational_intent_ref_params( - key=[], - state=OperationalIntentState.Accepted, - uss_base_url=self._planning_area.get_base_url(), - time_start=datetime.now() - timedelta(seconds=10), - time_end=datetime.now() + timedelta(minutes=20), - subscription_id=None, + def _step_create_subscription(self, params: SubscriptionParams) -> Subscription: + self.begin_test_step("Create a subscription") + with self.check("Create subscription query succeeds", self._pid) as check: + try: + mutated_sub = self._dss.upsert_subscription(**params) + self.record_query(mutated_sub) + except QueryError as qe: + self.record_queries(qe.queries) + check.record_failed( + summary="Could not create subscription", + details=f"Failed to create subscription with error code {qe.cause_status_code}: {qe.msg}", + query_timestamps=qe.query_timestamps, + ) + self.end_test_step() + return mutated_sub.subscription + + def _step_create_explicit_sub(self): + self._sub_params = self._planning_area.get_new_subscription_params( + subscription_id=self._sub_id, + start_time=datetime.now() - timedelta(seconds=10), + duration=timedelta(minutes=20), + notify_for_op_intents=True, + notify_for_constraints=False, ) + self._current_sub = self._step_create_subscription(self._sub_params) + def _step_create_oir(self, oir_params: PutOperationalIntentReferenceParameters): self.begin_test_step("Create an operational intent reference") + sub_id = oir_params.subscription_id if "subscription_id" in oir_params else None with self.check( "Create operational intent reference query succeeds", self._pid, @@ -120,6 +183,7 @@ def _step_create_oir(self): state=oir_params.state, base_url=oir_params.uss_base_url, oi_id=self._oir_id, + subscription_id=sub_id, ) self.record_query(query) self._current_oir = new_oir @@ -132,6 +196,172 @@ def _step_create_oir(self): ) self.end_test_step() + def _step_create_oir_insufficient_subscription(self): + self.begin_test_step( + "Provide subscription not covering extent of OIR being created" + ) + + oir_params = self._planning_area.get_new_operational_intent_ref_params( + key=[], + state=OperationalIntentState.Accepted, + uss_base_url=self._planning_area.get_base_url(), + time_start=datetime.now() - timedelta(seconds=10), + time_end=self._sub_params.end_time + + timedelta(seconds=1), # OIR ends 1 sec after subscription + subscription_id=self._sub_id, + ) + + with self.check( + "Request to create OIR with incorrect subscription fails", self._pid + ) as check: + try: + _, _, q = self._dss.put_op_intent( + extents=oir_params.extents, + key=oir_params.key, + state=oir_params.state, + base_url=oir_params.uss_base_url, + oi_id=self._oir_id, + subscription_id=oir_params.subscription_id, + ) + self.record_query(q) + # We don't expect to reach this point: + check.record_failed( + summary="OIR creation with too short subscription was not expected to succeed", + details=f"Was expecting an HTTP 400 response because of an insufficient subscription, but got {q.status_code} instead", + query_timestamps=[q.request.timestamp], + ) + except QueryError as qe: + self.record_queries(qe.queries) + if qe.cause_status_code == 400: + pass + else: + check.record_failed( + summary="OIR creation with too short subscription failed for unexpected reason", + details=f"Was expecting an HTTP 400 response because of an insufficient subscription, but got {qe.cause_status_code} instead", + query_timestamps=qe.query_timestamps, + ) + + self.end_test_step() + + def _step_update_oir_with_insufficient_explicit_sub(self): + # Create another subscription that is a few seconds short of covering the OIR: + oir_duration = ( + self._current_oir.time_end.value.datetime + - self._current_oir.time_start.value.datetime + ) + new_sub_params = self._planning_area.get_new_subscription_params( + subscription_id=self._extra_sub_id, + start_time=datetime.now() - timedelta(seconds=10), + duration=oir_duration - timedelta(seconds=2), + notify_for_op_intents=True, + notify_for_constraints=False, + ) + + self._current_extra_sub = self._step_create_subscription(new_sub_params) + + # Now attempt to mutate the OIR for it to use the invalid subscription: + oir_update_params = self._planning_area.get_new_operational_intent_ref_params( + key=[], + state=OperationalIntentState.Accepted, + uss_base_url=self._planning_area.get_base_url(), + time_start=self._current_oir.time_start.value.datetime, + time_end=self._current_oir.time_end.value.datetime, + subscription_id=self._extra_sub_id, + ) + + self.begin_test_step( + "Attempt to replace OIR's existing explicit subscription with an insufficient one" + ) + with self.check( + "Request to mutate OIR while providing an incorrect subscription fails", + self._pid, + ) as check: + try: + _, _, q = self._dss.put_op_intent( + extents=oir_update_params.extents, + key=oir_update_params.key, + state=oir_update_params.state, + base_url=oir_update_params.uss_base_url, + oi_id=self._oir_id, + subscription_id=oir_update_params.subscription_id, + ovn=self._current_oir.ovn, + ) + self.record_query(q) + # We don't expect to reach this point: + check.record_failed( + summary="OIR mutation with too short subscription was not expected to succeed", + details=f"Was expecting an HTTP 400 response because of an insufficient subscription, but got {q.status_code} instead", + query_timestamps=[q.request.timestamp], + ) + except QueryError as qe: + self.record_queries(qe.queries) + if qe.cause_status_code == 400: + pass + else: + check.record_failed( + summary="OIR mutation with too short subscription failed for unexpected reason", + details=f"Was expecting an HTTP 400 response because of an insufficient subscription, but got {qe.cause_status_code} instead. {qe.msg}", + query_timestamps=qe.query_timestamps, + ) + self.end_test_step() + + def _step_update_oir_with_sufficient_explicit_sub(self): + self.begin_test_step("Replace the OIR's explicit subscription") + oir_update_params = self._planning_area.get_new_operational_intent_ref_params( + key=[], + state=OperationalIntentState.Accepted, + uss_base_url=self._planning_area.get_base_url(), + time_start=self._current_extra_sub.time_start.value.datetime, + time_end=self._current_extra_sub.time_end.value.datetime, + subscription_id=self._extra_sub_id, + ) + with self.check( + "Mutate operational intent reference query succeeds", + self._pid, + ) as check: + try: + mutated_oir, _, q = self._dss.put_op_intent( + extents=oir_update_params.extents, + key=oir_update_params.key, + state=oir_update_params.state, + base_url=oir_update_params.uss_base_url, + oi_id=self._oir_id, + subscription_id=oir_update_params.subscription_id, + ovn=self._current_oir.ovn, + ) + self.record_query(q) + self._current_oir = mutated_oir + except QueryError as qe: + self.record_queries(qe.queries) + check.record_failed( + summary="OIR mutation with correct subscription failed", + details=f"Was expecting an HTTP 200 response for a mutation with valid parameters, but got {qe.cause_status_code} instead. {qe.msg}", + query_timestamps=qe.query_timestamps, + ) + self.end_test_step() + + def _step_oir_has_correct_subscription(self, expected_sub_id: SubscriptionID): + self.begin_test_step("OIR is attached to expected subscription") + with self.check("Get operational intent reference by ID", self._pid) as check: + try: + oir, q = self._dss.get_op_intent_reference(self._oir_id) + self.record_query(q) + except QueryError as qe: + self.record_queries(qe.queries) + check.record_failed( + summary="Could not get OIR", + details=f"Failed to get OIR with error code {qe.cause_status_code}: {qe.msg}", + query_timestamps=qe.query_timestamps, + ) + + with self.check("OIR is attached to expected subscription") as check: + if oir.subscription_id != expected_sub_id: + check.record_failed( + summary="OIR is not attached to the correct subscription", + details=f"Expected OIR to be attached to subscription {expected_sub_id}, but it is attached to {oir.subscription_id}", + ) + self.end_test_step() + def _step_attempt_delete_missing_ovn(self): self.begin_test_step("Attempt deletion with missing OVN") @@ -270,18 +500,24 @@ def _step_attempt_mutation_incorrect_ovn(self): self.end_test_step() - def _setup_case(self): - self.begin_test_case("Setup") + def _setup_case(self, create_oir=False, create_explicit_sub=False): # Multiple runs of the scenario seem to rely on the same instance of it: # thus we need to reset the state of the scenario before running it. self._current_oir = None + self._current_sub = None + self._current_extra_sub = None self.begin_test_step("Ensure clean workspace") self._ensure_clean_workspace_step() self.end_test_step() - self._step_create_oir() + if create_oir: + sub_id = self._sub_id if create_explicit_sub else None + self._step_create_oir( + oir_params=self._default_oir_params(subscription_id=sub_id) + ) - self.end_test_case() + if create_explicit_sub: + self._step_create_explicit_sub() def _ensure_clean_workspace_step(self): @@ -315,3 +551,15 @@ def _test_params_for_current_time(self): time_end=datetime.now() + timedelta(minutes=20), subscription_id=None, ) + + def _default_oir_params( + self, subscription_id: SubscriptionID + ) -> PutOperationalIntentReferenceParameters: + return self._planning_area.get_new_operational_intent_ref_params( + key=[], + state=OperationalIntentState.Accepted, + uss_base_url=self._planning_area.get_base_url(), + time_start=datetime.now() - timedelta(seconds=10), + time_end=datetime.now() + timedelta(minutes=20), + subscription_id=subscription_id, + ) From 712fda58e066d8821ab6beff7e1dd14e04a0ef15 Mon Sep 17 00:00:00 2001 From: Julien Perrochet Date: Wed, 16 Oct 2024 15:05:28 +0200 Subject: [PATCH 2/2] first pass of comments --- .../fragments/oir/oir_subscription_update.md | 15 +++++ .../astm/utm/dss/op_intent_ref_simple.md | 20 +++---- .../astm/utm/dss/op_intent_ref_simple.py | 60 +++++++++++++------ 3 files changed, 65 insertions(+), 30 deletions(-) create mode 100644 monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/oir/oir_subscription_update.md diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/oir/oir_subscription_update.md b/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/oir/oir_subscription_update.md new file mode 100644 index 0000000000..2345ba8998 --- /dev/null +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/oir/oir_subscription_update.md @@ -0,0 +1,15 @@ +# OIR's subscription can be updated test step fragment + +## [Update the OIR's subscription](./crud/update_query.md) + +This step verifies that an OIR attached to an explicit subscription can be mutated in order to be attached +to another explicit subscription that properly covers the extent of the OIR. + +## [Fetch the OIR](./crud/read_query.md) + +To determine if the OIR is attached to the correct subscription, the OIR is directly fetched from the DSS. + +## 🛑 OIR is attached to expected subscription check + +If the OIR returned by the DSS under test is not attached to the expected subscription, +it is in violation of **[astm.f3548.v21.DSS0005,1](../../../../../../requirements/astm/f3548/v21.md)** diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.md b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.md index 1fe6fc192c..f15db922dd 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.md +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.md @@ -40,16 +40,16 @@ Ensures that the explicit subscription provided upon creation of an OIR is prope This step verifies that an OIR cannot be created when an explicit subscription that does not cover the extent of the OIR is specified. -#### 🛑 Request to create OIR with incorrect subscription fails check +#### 🛑 Request to create OIR with too short subscription fails check If the DSS under test allows the qualifier to create an OIR with an explicit subscription that does not cover the extent of the OIR, it is in violation of **[astm.f3548.v21.DSS0005,1](../../../../requirements/astm/f3548/v21.md)** -### [Create an operational intent reference test step](./fragments/oir/crud/create_query.md) +### [Create an OIR with correct explicit subscription test step](./fragments/oir/crud/create_query.md) When the provided subscription covers the extent of the OIR, the OIR can be created. -### [OIR is attached to expected subscription test step](./fragments/oir/oir_has_expected_subscription.md) +#### [OIR is attached to expected subscription](./fragments/oir/oir_has_expected_subscription.md) This step verifies that the OIR is attached to the subscription provided upon creation. @@ -66,24 +66,20 @@ Create an additional explicit subscription to be used in this test case. This step verifies that an OIR's existing explicit subscription cannot be replaced with an explicit subscription that does not cover the extent of the OIR. -#### 🛑 Request to mutate OIR while providing an incorrect subscription fails check +#### 🛑 Request to mutate OIR while providing a too short subscription fails check If the DSS under test allows the qualifier to replace an OIR's existing explicit subscription with an explicit subscription that does not cover the extent of the OIR, it is in violation of **[astm.f3548.v21.DSS0005,1](../../../../requirements/astm/f3548/v21.md)** -### [OIR is attached to expected subscription test step](./fragments/oir/oir_has_expected_subscription.md) +#### [OIR is attached to expected subscription](./fragments/oir/oir_has_expected_subscription.md) -This step verifies that the OIR is still attached to the previous, valid, subscription. +Verify that the OIR is still attached to the previous, valid, subscription. -### [Replace the OIR's explicit subscription test step](./fragments/oir/crud/update_query.md) +### [Replace the OIR's explicit subscription test step](./fragments/oir/oir_subscription_update.md) This step verifies that an OIR attached to an explicit subscription can be mutated in order to be attached to another explicit subscription that properly covers the extent of the OIR. -### [OIR is attached to expected subscription test step](./fragments/oir/oir_has_expected_subscription.md) - -This step verifies that the OIR is attached to the subscription provided upon mutation. - ## Deletion requires correct OVN test case Ensures that a DSS will only delete OIRs when the correct OVN is presented. @@ -94,7 +90,7 @@ This step resets the workspace for the present and following test cases by ensur ### [Create an operational intent reference test step](./fragments/oir/crud/create_query.md) -Create an operational intent reference to be used in this and the following test cases. +Create the operational intent reference that will be used for the deletion attempts that happen in the subsequent steps. ### Attempt deletion with missing OVN test step diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.py b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.py index 30631dd50f..e600381883 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.py +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_simple.py @@ -108,26 +108,14 @@ def run(self, context: ExecutionContext): self.begin_test_case("Validate explicit subscription on OIR creation") self._step_create_oir_insufficient_subscription() - self._step_create_oir( - oir_params=self._planning_area.get_new_operational_intent_ref_params( - key=[], - state=OperationalIntentState.Accepted, - uss_base_url=self._planning_area.get_base_url(), - time_start=datetime.now() - timedelta(seconds=10), - time_end=self._sub_params.end_time, # OIR ends at the same time as subscription - subscription_id=self._sub_id, - ), - ) - self._step_oir_has_correct_subscription(expected_sub_id=self._sub_id) + self._step_create_oir_sufficient_subscription() self.end_test_case() self.begin_test_case( "Validate explicit subscription upon subscription replacement" ) self._step_update_oir_with_insufficient_explicit_sub() - self._step_oir_has_correct_subscription(expected_sub_id=self._sub_id) self._step_update_oir_with_sufficient_explicit_sub() - self._step_oir_has_correct_subscription(expected_sub_id=self._extra_sub_id) self.end_test_case() self.begin_test_case("Deletion requires correct OVN") @@ -212,7 +200,7 @@ def _step_create_oir_insufficient_subscription(self): ) with self.check( - "Request to create OIR with incorrect subscription fails", self._pid + "Request to create OIR with too short subscription fails", self._pid ) as check: try: _, _, q = self._dss.put_op_intent( @@ -243,6 +231,42 @@ def _step_create_oir_insufficient_subscription(self): self.end_test_step() + def _step_create_oir_sufficient_subscription(self): + oir_params = self._planning_area.get_new_operational_intent_ref_params( + key=[], + state=OperationalIntentState.Accepted, + uss_base_url=self._planning_area.get_base_url(), + time_start=datetime.now() - timedelta(seconds=10), + time_end=self._sub_params.end_time, # OIR ends at the same time as subscription + subscription_id=self._sub_id, + ) + + self.begin_test_step("Create an OIR with correct explicit subscription") + with self.check( + "Create operational intent reference query succeeds", + self._pid, + ) as check: + try: + new_oir, subs, query = self._dss.put_op_intent( + extents=oir_params.extents, + key=oir_params.key, + state=oir_params.state, + base_url=oir_params.uss_base_url, + oi_id=self._oir_id, + subscription_id=oir_params.subscription_id, + ) + self.record_query(query) + self._current_oir = new_oir + except QueryError as qe: + self.record_queries(qe.queries) + check.record_failed( + summary="Could not create operational intent reference", + details=f"Failed to create operational intent reference with error code {qe.cause_status_code}: {qe.msg}", + query_timestamps=qe.query_timestamps, + ) + self._check_oir_has_correct_subscription(expected_sub_id=self._sub_id) + self.end_test_step() + def _step_update_oir_with_insufficient_explicit_sub(self): # Create another subscription that is a few seconds short of covering the OIR: oir_duration = ( @@ -273,7 +297,7 @@ def _step_update_oir_with_insufficient_explicit_sub(self): "Attempt to replace OIR's existing explicit subscription with an insufficient one" ) with self.check( - "Request to mutate OIR while providing an incorrect subscription fails", + "Request to mutate OIR while providing a too short subscription fails", self._pid, ) as check: try: @@ -303,6 +327,7 @@ def _step_update_oir_with_insufficient_explicit_sub(self): details=f"Was expecting an HTTP 400 response because of an insufficient subscription, but got {qe.cause_status_code} instead. {qe.msg}", query_timestamps=qe.query_timestamps, ) + self._check_oir_has_correct_subscription(expected_sub_id=self._sub_id) self.end_test_step() def _step_update_oir_with_sufficient_explicit_sub(self): @@ -338,10 +363,10 @@ def _step_update_oir_with_sufficient_explicit_sub(self): details=f"Was expecting an HTTP 200 response for a mutation with valid parameters, but got {qe.cause_status_code} instead. {qe.msg}", query_timestamps=qe.query_timestamps, ) + self._check_oir_has_correct_subscription(expected_sub_id=self._extra_sub_id) self.end_test_step() - def _step_oir_has_correct_subscription(self, expected_sub_id: SubscriptionID): - self.begin_test_step("OIR is attached to expected subscription") + def _check_oir_has_correct_subscription(self, expected_sub_id: SubscriptionID): with self.check("Get operational intent reference by ID", self._pid) as check: try: oir, q = self._dss.get_op_intent_reference(self._oir_id) @@ -360,7 +385,6 @@ def _step_oir_has_correct_subscription(self, expected_sub_id: SubscriptionID): summary="OIR is not attached to the correct subscription", details=f"Expected OIR to be attached to subscription {expected_sub_id}, but it is attached to {oir.subscription_id}", ) - self.end_test_step() def _step_attempt_delete_missing_ovn(self):