From 91f3c76fd668903799233f88c511b8b6aca21bff Mon Sep 17 00:00:00 2001 From: Julien Perrochet Date: Wed, 13 Mar 2024 16:33:57 +0100 Subject: [PATCH] DSS0210 prepare sub interactions scenario: oir creation --- monitoring/monitorlib/mutate/scd.py | 17 +++ .../astm/utm/dss/subscription_interactions.md | 22 ++++ .../astm/utm/dss/subscription_interactions.py | 101 ++++++++++++++---- .../suites/astm/utm/dss_probing.md | 7 +- .../uss_qualifier/suites/astm/utm/f3548_21.md | 7 +- .../suites/faa/uft/message_signing.md | 7 +- .../suites/interuss/dss/all_tests.md | 7 +- .../suites/uspace/flight_auth.md | 7 +- .../suites/uspace/required_services.md | 7 +- 9 files changed, 153 insertions(+), 29 deletions(-) diff --git a/monitoring/monitorlib/mutate/scd.py b/monitoring/monitorlib/mutate/scd.py index 3543fe2c58..818f27470c 100644 --- a/monitoring/monitorlib/mutate/scd.py +++ b/monitoring/monitorlib/mutate/scd.py @@ -9,6 +9,7 @@ OperationID, Subscription, PutSubscriptionParameters, + OperationalIntentReference, ) from yaml.representer import Representer @@ -51,6 +52,22 @@ def subscription(self) -> Optional[Subscription]: except ValueError: return None + @property + def operational_intent_references(self) -> List[OperationalIntentReference]: + if self.json_result is None: + return [] + try: + if "operational_intent_references" not in self.json_result: + return [] + oirs_json = self.json_result["operational_intent_references"] + if not isinstance(oirs_json, list): + return [] + return [ + ImplicitDict.parse(oir, OperationalIntentReference) for oir in oirs_json + ] + except ValueError: + return [] + yaml.add_representer(MutatedSubscription, Representer.represent_dict) diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/subscription_interactions.md b/monitoring/uss_qualifier/scenarios/astm/utm/dss/subscription_interactions.md index eab95740e3..a7faf6a084 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/subscription_interactions.md +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/subscription_interactions.md @@ -79,4 +79,26 @@ If the DSS omits any of the implicit subscriptions belonging to an OIR previousl any of the DSSes at which an earlier OIR was created, or the DSS at which the current OIR has been created, are in violation of **[astm.f3548.v21.DSS0210,A2-7-2,4b](../../../../requirements/astm/f3548/v21.md)**. +## Subscription creation returns relevant OIRs test case + +This test case checks that, when a newly crete subscription intersects with an existing OIR and that the subscription is intended for operational intent references, +the DSS includes the relevant OIRs in the response to the creation. + +### Create a subscription at every DSS in sequence test step + +This test step will create a new subscription at every DSS, in sequence, each time verifying that the DSS +returns any OIRs that intersect with the newly created subscription. + +Note that this step is run once for each involved DSS (that is, once for the primary DSS and once for every secondary DSS) + +#### [Create subscription](./fragments/sub/crud/create_query.md) + +Check that the subscription creation succeeds + +#### 🛑 DSS response contains the expected OIRs check + +The response from a DSS to a valid subscription creation request is expected to contain any relevant OIRs for the subscription's extents if the subscription had the `notify_for_op_intents` flag set to `true`. + +If the DSS omits the intersecting OIR, it fails to comply with **[astm.f3548.v21.DSS0210,A2-7-2,4a](../../../../requirements/astm/f3548/v21.md)**. + ## [Cleanup](./clean_workspace.md) diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/subscription_interactions.py b/monitoring/uss_qualifier/scenarios/astm/utm/dss/subscription_interactions.py index 67f8ddcebe..73c54a49e0 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/subscription_interactions.py +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/subscription_interactions.py @@ -12,10 +12,9 @@ ) from uas_standards.astm.f3548.v21.constants import Scope -from monitoring.monitorlib.delay import sleep +from monitoring.monitorlib import fetch from monitoring.monitorlib.fetch import QueryError, Query from monitoring.monitorlib.geotemporal import Volume4D -from monitoring.monitorlib.mutate.scd import MutatedSubscription from monitoring.prober.infrastructure import register_resource_type from monitoring.uss_qualifier.resources.astm.f3548.v21 import PlanningAreaResource from monitoring.uss_qualifier.resources.astm.f3548.v21.dss import ( @@ -31,7 +30,6 @@ from monitoring.uss_qualifier.scenarios.astm.utm.dss import test_step_fragments from monitoring.uss_qualifier.scenarios.scenario import ( TestScenario, - PendingCheck, ) from monitoring.uss_qualifier.suites.suite import ExecutionContext @@ -44,14 +42,19 @@ class SubscriptionInteractions(TestScenario): A scenario that tests interactions between subscriptions and entities across a DSS cluster. """ - SUB_TYPES = [ - register_resource_type(386, "First Subscription"), - register_resource_type(387, "Second Subscription"), + BG_SUB_TYPES = [ + register_resource_type(386, "Background subscription 1"), + register_resource_type(387, "Background subscription 2"), ] - OIR_TYPE = register_resource_type(388, "Operational Intent References") + PER_DSS_OIR_TYPE = register_resource_type( + 388, "Multiple Operational Intent References" + ) + PER_DSS_SUB_TYPE = register_resource_type(389, "Multiple Subscriptions") + + _background_sub_ids: List[SubscriptionID] - _sub_ids: List[SubscriptionID] _oir_ids: List[EntityID] + _sub_ids: List[SubscriptionID] _current_subs: Dict[SubscriptionID, Subscription] _current_oirs: Dict[EntityID, OperationalIntentReference] @@ -92,17 +95,23 @@ def __init__( dss.get_instance(scopes) for dss in other_instances.dss_instances ] - # Prepare the two subscription ids: - self._sub_ids = [ - id_generator.id_factory.make_id(sub_type) for sub_type in self.SUB_TYPES + # Prepare the two background subscription ids: + self._background_sub_ids = [ + id_generator.id_factory.make_id(sub_type) for sub_type in self.BG_SUB_TYPES ] # Prepare one OIR id for each DSS we will interact with (one for the main and one for each secondary) - base_oir_id = id_generator.id_factory.make_id(self.OIR_TYPE) + base_oir_id = id_generator.id_factory.make_id(self.PER_DSS_OIR_TYPE) self._oir_ids = [ f"{base_oir_id[:-3]}{i:03d}" for i in range(len(self._secondary_instances) + 1) ] + # Prepare one subscription id for each DSS we will interact with (one for the main and one for each secondary) + base_sub_id = id_generator.id_factory.make_id(self.PER_DSS_SUB_TYPE) + self._sub_ids = [ + f"{base_sub_id[:-3]}{i:03d}" + for i in range(len(self._secondary_instances) + 1) + ] self._manager = utm_client_identity.subject() @@ -115,6 +124,10 @@ def run(self, context: ExecutionContext): self._steps_create_oirs_at_each_dss() self.end_test_case() + self.begin_test_case("Subscription creation returns relevant OIRs") + self._steps_create_subs_at_each_dss() + self.end_test_case() + self.end_test_scenario() def _step_create_background_subs(self): @@ -125,7 +138,7 @@ def _step_create_background_subs(self): self.begin_test_step("Create first background subscription") sub_now_params = self._planning_area.get_new_subscription_params( - subscription_id=self._sub_ids[0], + subscription_id=self._background_sub_ids[0], start_time=self._sub_1_start, duration=self._sub_1_end - self._sub_1_start, # This is a planning area without constraint processing @@ -133,7 +146,7 @@ def _step_create_background_subs(self): notify_for_constraints=False, ) - sub_now = self._create_sub_with_params(sub_now_params) + sub_now, _, _ = self._create_sub_with_params(sub_now_params) self._current_subs[sub_now_params.sub_id] = sub_now self.end_test_step() @@ -141,7 +154,7 @@ def _step_create_background_subs(self): self.begin_test_step("Create second background subscription") sub_later_params = self._planning_area.get_new_subscription_params( - subscription_id=self._sub_ids[1], + subscription_id=self._background_sub_ids[1], start_time=self._sub_2_start, duration=self._sub_2_end - self._sub_2_start, # This is a planning area without constraint processing @@ -149,7 +162,7 @@ def _step_create_background_subs(self): notify_for_constraints=False, ) - sub_later = self._create_sub_with_params(sub_later_params) + sub_later, _, _ = self._create_sub_with_params(sub_later_params) self._current_subs[sub_later_params.sub_id] = sub_later self.end_test_step() @@ -185,10 +198,10 @@ def _steps_create_oirs_at_each_dss(self): "DSS response contains the expected background subscription", dss.participant_id, ) as check: - if self._sub_ids[0] not in notification_ids: + if self._background_sub_ids[0] not in notification_ids: check.record_failed( summary="DSS did not return the intersecting background subscription", - details=f"Expected subscription {self._sub_ids[0]} (first background subscription) in the" + details=f"Expected subscription {self._background_sub_ids[0]} (first background subscription) in the" f" list of subscriptions to notify, but got {notification_ids}", query_timestamps=[q.request.timestamp], ) @@ -197,10 +210,10 @@ def _steps_create_oirs_at_each_dss(self): "DSS does not return non-intersecting background subscription", dss.participant_id, ) as check: - if self._sub_ids[1] in notification_ids: + if self._background_sub_ids[1] in notification_ids: check.record_failed( summary="DSS returned the non-intersecting background subscription", - details=f"Expected subscription {self._sub_ids[1]} (second background subscription) to not be in the" + details=f"Expected subscription {self._background_sub_ids[1]} (second background subscription) to not be in the" f" list of subscriptions to notify, but got {notification_ids}", query_timestamps=[q.request.timestamp], ) @@ -223,6 +236,46 @@ def _steps_create_oirs_at_each_dss(self): self._current_oirs[oir_id] = oir self.end_test_step() + def _steps_create_subs_at_each_dss(self): + """Creates a subscription at each DSS instance""" + + # The new subscriptions use the same parameters as the first background subscription + common_params = self._planning_area.get_new_subscription_params( + subscription_id="", + start_time=self._sub_1_start, + duration=self._sub_1_end - self._sub_1_start, + notify_for_op_intents=True, + notify_for_constraints=False, + ) + + # All previously created OIRs are relevant to each subscription + expected_oir_ids = set(self._oir_ids) + + for i, dss in enumerate([self._dss] + self._secondary_instances): + self.begin_test_step("Create a subscription at every DSS in sequence") + + sub_id = self._sub_ids[i] + common_params.sub_id = sub_id + sub, oirs, r = self._create_sub_with_params(common_params) + self._current_subs[sub_id] = sub + + returned_oir_ids = set(oir.id for oir in oirs) + + with self.check( + "DSS response contains the expected OIRs", + dss.participant_id, + ) as check: + if not expected_oir_ids.issubset(returned_oir_ids): + missing_oirs = expected_oir_ids - returned_oir_ids + check.record_failed( + summary="DSS did not return the expected OIRs", + details=f"Expected OIRs {expected_oir_ids} in the list of OIRs to notify, but got {returned_oir_ids}. " + f"Missing: {missing_oirs}", + query_timestamps=[r.request.timestamp], + ) + + self.end_test_step() + def _put_op_intent( self, dss: DSSInstance, @@ -253,7 +306,9 @@ def _put_op_intent( return oir, subs, q - def _create_sub_with_params(self, params: SubscriptionParams) -> Subscription: + def _create_sub_with_params( + self, params: SubscriptionParams + ) -> Tuple[Subscription, List[OperationalIntentReference], fetch.Query]: """Create a subscription with the given parameters via the primary DSS instance""" with self.check("Create subscription query succeeds") as check: r = self._dss.upsert_subscription(**params) @@ -263,7 +318,7 @@ def _create_sub_with_params(self, params: SubscriptionParams) -> Subscription: details=f"Failed to create a subscription on primary DSS with code {r.status_code}: {r.error_message}", query_timestamps=[r.request.timestamp], ) - return r.subscription + return r.subscription, r.operational_intent_references, r def _setup_case(self): self.begin_test_case("Setup") @@ -305,7 +360,7 @@ def _clean_workspace(self): self._dss, extents, ) - for sub_id in self._sub_ids: + for sub_id in self._background_sub_ids: test_step_fragments.cleanup_sub(self, self._dss, sub_id) def cleanup(self): diff --git a/monitoring/uss_qualifier/suites/astm/utm/dss_probing.md b/monitoring/uss_qualifier/suites/astm/utm/dss_probing.md index 9876becfbc..9d1b87c15c 100644 --- a/monitoring/uss_qualifier/suites/astm/utm/dss_probing.md +++ b/monitoring/uss_qualifier/suites/astm/utm/dss_probing.md @@ -26,7 +26,7 @@ Checked in - astm
.f3548
.v21
+ astm
.f3548
.v21
DSS0005,1 Implemented ASTM F3548-21 UTM DSS Operational Intent Reference Access Control
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Reference Key Validation
ASTM SCD DSS: Operational Intent Reference Synchronization
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity interaction @@ -146,6 +146,11 @@ Implemented ASTM SCD DSS: Operational Intent Reference Key Validation + + DSS0210,A2-7-2,4a + Implemented + ASTM SCD DSS: Subscription and entity interaction + DSS0210,A2-7-2,4b Implemented diff --git a/monitoring/uss_qualifier/suites/astm/utm/f3548_21.md b/monitoring/uss_qualifier/suites/astm/utm/f3548_21.md index 8291245a05..1867d64e65 100644 --- a/monitoring/uss_qualifier/suites/astm/utm/f3548_21.md +++ b/monitoring/uss_qualifier/suites/astm/utm/f3548_21.md @@ -35,7 +35,7 @@ Checked in - astm
.f3548
.v21
+ astm
.f3548
.v21
DSS0005,1 Implemented ASTM F3548 flight planners preparation
ASTM F3548-21 UTM DSS Operational Intent Reference Access Control
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Reference Key Validation
ASTM SCD DSS: Operational Intent Reference Synchronization
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity interaction
Off-Nominal planning: down USS
Off-Nominal planning: down USS with equal priority conflicts not permitted @@ -160,6 +160,11 @@ Implemented ASTM SCD DSS: Operational Intent Reference Key Validation + + DSS0210,A2-7-2,4a + Implemented + ASTM SCD DSS: Subscription and entity interaction + DSS0210,A2-7-2,4b Implemented diff --git a/monitoring/uss_qualifier/suites/faa/uft/message_signing.md b/monitoring/uss_qualifier/suites/faa/uft/message_signing.md index 1463da5f8e..237770b8a3 100644 --- a/monitoring/uss_qualifier/suites/faa/uft/message_signing.md +++ b/monitoring/uss_qualifier/suites/faa/uft/message_signing.md @@ -18,7 +18,7 @@ Checked in - astm
.f3548
.v21
+ astm
.f3548
.v21
DSS0005,1 Implemented ASTM F3548 flight planners preparation
ASTM F3548-21 UTM DSS Operational Intent Reference Access Control
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Reference Key Validation
ASTM SCD DSS: Operational Intent Reference Synchronization
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity interaction
Off-Nominal planning: down USS
Off-Nominal planning: down USS with equal priority conflicts not permitted @@ -143,6 +143,11 @@ Implemented ASTM SCD DSS: Operational Intent Reference Key Validation + + DSS0210,A2-7-2,4a + Implemented + ASTM SCD DSS: Subscription and entity interaction + DSS0210,A2-7-2,4b Implemented diff --git a/monitoring/uss_qualifier/suites/interuss/dss/all_tests.md b/monitoring/uss_qualifier/suites/interuss/dss/all_tests.md index 16b353e717..e3105d59ed 100644 --- a/monitoring/uss_qualifier/suites/interuss/dss/all_tests.md +++ b/monitoring/uss_qualifier/suites/interuss/dss/all_tests.md @@ -408,7 +408,7 @@ ASTM NetRID DSS: Concurrent Requests
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Subscription Simple
ASTM NetRID DSS: Subscription Validation
ASTM NetRID DSS: Token Validation - astm
.f3548
.v21
+ astm
.f3548
.v21
DSS0005,1 Implemented ASTM F3548-21 UTM DSS Operational Intent Reference Access Control
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Reference Key Validation
ASTM SCD DSS: Operational Intent Reference Synchronization
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity interaction @@ -528,6 +528,11 @@ Implemented ASTM SCD DSS: Operational Intent Reference Key Validation + + DSS0210,A2-7-2,4a + Implemented + ASTM SCD DSS: Subscription and entity interaction + DSS0210,A2-7-2,4b Implemented diff --git a/monitoring/uss_qualifier/suites/uspace/flight_auth.md b/monitoring/uss_qualifier/suites/uspace/flight_auth.md index d20362a78e..4060930579 100644 --- a/monitoring/uss_qualifier/suites/uspace/flight_auth.md +++ b/monitoring/uss_qualifier/suites/uspace/flight_auth.md @@ -19,7 +19,7 @@ Checked in - astm
.f3548
.v21
+ astm
.f3548
.v21
DSS0005,1 Implemented ASTM F3548 flight planners preparation
ASTM F3548-21 UTM DSS Operational Intent Reference Access Control
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Reference Key Validation
ASTM SCD DSS: Operational Intent Reference Synchronization
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity interaction
Off-Nominal planning: down USS
Off-Nominal planning: down USS with equal priority conflicts not permitted @@ -144,6 +144,11 @@ Implemented ASTM SCD DSS: Operational Intent Reference Key Validation + + DSS0210,A2-7-2,4a + Implemented + ASTM SCD DSS: Subscription and entity interaction + DSS0210,A2-7-2,4b Implemented diff --git a/monitoring/uss_qualifier/suites/uspace/required_services.md b/monitoring/uss_qualifier/suites/uspace/required_services.md index faa2760205..0fbe86148b 100644 --- a/monitoring/uss_qualifier/suites/uspace/required_services.md +++ b/monitoring/uss_qualifier/suites/uspace/required_services.md @@ -454,7 +454,7 @@ ASTM NetRID DSS: Concurrent Requests
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Subscription Simple
ASTM NetRID DSS: Subscription Validation
ASTM NetRID DSS: Token Validation - astm
.f3548
.v21
+ astm
.f3548
.v21
DSS0005,1 Implemented ASTM F3548 flight planners preparation
ASTM F3548-21 UTM DSS Operational Intent Reference Access Control
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Reference Key Validation
ASTM SCD DSS: Operational Intent Reference Synchronization
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity interaction
Off-Nominal planning: down USS
Off-Nominal planning: down USS with equal priority conflicts not permitted @@ -579,6 +579,11 @@ Implemented ASTM SCD DSS: Operational Intent Reference Key Validation + + DSS0210,A2-7-2,4a + Implemented + ASTM SCD DSS: Subscription and entity interaction + DSS0210,A2-7-2,4b Implemented