From 137772fb6c666a83883d476d1bdb5c1ec52fdc47 Mon Sep 17 00:00:00 2001 From: Mariem Baccari Date: Tue, 20 Oct 2026 09:25:40 +0200 Subject: [PATCH 1/3] Extend test scenario for put OVN --- .../fragments/sub/unchanged_after_conflict.md | 19 ++++++ .../utm/dss/op_intent_ref_key_validation.md | 15 +++++ .../utm/dss/op_intent_ref_key_validation.py | 65 +++++++++++++++++++ .../suites/astm/utm/dss_probing.md | 2 +- .../uss_qualifier/suites/astm/utm/f3548_21.md | 2 +- .../suites/faa/uft/message_signing.md | 2 +- .../suites/interuss/dss/all_tests.md | 2 +- .../suites/uspace/flight_auth.md | 2 +- .../suites/uspace/required_services.md | 2 +- 9 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md b/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md new file mode 100644 index 0000000000..63d04f5ee7 --- /dev/null +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md @@ -0,0 +1,19 @@ +# Subscriptions unchanged after rejected request test step fragment + +This test step fragment validates that a request to create or mutate an operational intent reference that was rejected +because of a conflict did not create, modify or delete any subscription, including implicit subscriptions. + +The subscriptions owned by the client within the planning area are queried before and after the rejected request, and compared. + +## 🛑 Successful subscription search query check + +**[astm.f3548.v21.DSS0005,5](../../../../../../requirements/astm/f3548/v21.md)** requires the implementation of the DSS endpoint to allow callers to retrieve the subscriptions they created. + +## 🛑 Rejected request did not create or modify subscriptions check + +A request to create or mutate an operational intent reference that is rejected because of missing OVNs is not expected to have any effect. +In particular, the DSS is not expected to create an implicit subscription requested by such a request, nor to expand +an existing implicit subscription to cover the rejected operational intent reference. + +If the subscriptions owned by the client differ before and after the rejected request, the DSS fails to properly manage +implicit subscriptions and 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_key_validation.md b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_key_validation.md index 135667b05f..41ef72772c 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_key_validation.md +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_key_validation.md @@ -94,6 +94,8 @@ This step will validate the response body for the `HTTP 409` error response from Checks that an attempt to create an OIR without specifying the OVNs of the already existing and overlapping OIRs fails. +#### [Subscriptions are unchanged](fragments/sub/unchanged_after_conflict.md) + ### Attempt valid OIR creation overlapping with both OIRs test step This test step will attempt to create an operational intent reference that intersects with both of the previously created OIRs, @@ -141,4 +143,17 @@ The expectation is that the DSS will require the missing OVN. #### [Non de-conflicted mutation request fails](fragments/oir/crud/update_conflict.md) +### Attempt mutation requiring expansion of the implicit subscription test step + +This test step attempts to mutate the third operational intent reference so that it ends 10 minutes later, while: +- specifying, as its subscription, the implicit subscription that was created along with it, and +- omitting the OVNs of the two other operational intent references in the `key` field. + +The mutated operational intent reference would end after its implicit subscription, which the DSS would therefore need to expand. +Because the OVNs are missing, the DSS is expected to reject the request, and to leave the implicit subscription unchanged. + +#### [Non de-conflicted mutation request fails](fragments/oir/crud/update_conflict.md) + +#### [Subscriptions are unchanged](fragments/sub/unchanged_after_conflict.md) + ## [Cleanup](./clean_workspace_op_intents_during_cleanup.md) diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_key_validation.py b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_key_validation.py index 79ba67316e..4d821df700 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_key_validation.py +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_key_validation.py @@ -10,6 +10,7 @@ from monitoring.monitorlib import fetch, schema_validation from monitoring.monitorlib.fetch import QueryError +from monitoring.monitorlib.fetch.scd import FetchedSubscriptions from monitoring.monitorlib.schema_validation import F3548_21 from monitoring.prober.infrastructure import register_resource_type from monitoring.uss_qualifier.resources import PlanningAreaResource @@ -218,6 +219,7 @@ def _attempt_update_expect_conflict( base_url=oir_params.uss_base_url, oi_id=oir_id, ovn=ovn, + subscription_id=oir_params.get("subscription_id"), ) self.record_query(q) check.record_failed( @@ -280,9 +282,11 @@ def _steps_attempt_create_overlapping_oir(self): ) self.begin_test_step("Attempt OIR creation overlapping with both OIRs") + subs_before = self._query_own_subs() self._attempt_creation_expect_conflict( third_oir_id, conflict_both, [first_oir.id, second_oir.id] ) + self._check_subscriptions_unchanged(subs_before) self.end_test_step() # Finally, we create the third OIR with the correct key, so we may try to mutate it at the next step @@ -404,6 +408,67 @@ def _steps_attempt_mutation_to_cause_overlap(self): ) self.end_test_step() + # Try to extend the third OIR beyond the end of the second one without providing the conflicting OVNs + expand_implicit_sub = self._planning_area.get_new_operational_intent_ref_params( + key=[], + state=oir_to_mutate.state, + uss_base_url=oir_to_mutate.uss_base_url, + time_start=oir_to_mutate.time_start.value.datetime, + time_end=oir_to_mutate.time_end.value.datetime + timedelta(minutes=10), + subscription_id=oir_to_mutate.subscription_id, + ) + + self.begin_test_step( + "Attempt mutation requiring expansion of the implicit subscription" + ) + subs_before = self._query_own_subs() + assert oir_to_mutate.ovn is not None + self._attempt_update_expect_conflict( + oir_to_mutate.id, + expand_implicit_sub, + [first_oir.id, second_oir.id], + oir_to_mutate.ovn, + ) + self._check_subscriptions_unchanged(subs_before) + self.end_test_step() + + def _query_own_subs(self) -> FetchedSubscriptions: + """Queries the subscriptions owned by the client in the planning area.""" + query = self._dss.query_subscriptions( + self._planning_area_volume4d.to_f3548v21() + ) + self.record_query(query) + with self.check("Successful subscription search query", self._pid) as check: + if query.status_code != 200: + check.record_failed( + summary="Could not query subscriptions", + details=f"When attempting to query subscriptions from the DSS, received {query.status_code}", + query_timestamps=[query.request.timestamp], + ) + return query + + def _check_subscriptions_unchanged(self, query_before: FetchedSubscriptions): + """Checks that the subscriptions owned by the client are the same as before a rejected request.""" + query = self._query_own_subs() + subs_before = {s.id: s.version for s in query_before.subscriptions.values()} + subs_after = {s.id: s.version for s in query.subscriptions.values()} + with self.check( + "Rejected request did not create or modify subscriptions", self._pid + ) as check: + created = subs_after.keys() - subs_before.keys() + deleted = subs_before.keys() - subs_after.keys() + modified = { + sub_id + for sub_id in subs_before.keys() & subs_after.keys() + if subs_before[sub_id] != subs_after[sub_id] + } + if created or deleted or modified: + check.record_failed( + summary="Subscriptions changed by rejected request", + details=f"The request was rejected because of a conflict, but subscriptions were changed: created {created}, deleted {deleted}, modified {modified}", + query_timestamps=[query.request.timestamp], + ) + def _setup_case(self): self.begin_test_case("Setup") self.begin_test_step("Ensure clean workspace") diff --git a/monitoring/uss_qualifier/suites/astm/utm/dss_probing.md b/monitoring/uss_qualifier/suites/astm/utm/dss_probing.md index e394ca376d..040719f58e 100644 --- a/monitoring/uss_qualifier/suites/astm/utm/dss_probing.md +++ b/monitoring/uss_qualifier/suites/astm/utm/dss_probing.md @@ -59,7 +59,7 @@ DSS0005,5 Implemented - ASTM SCD DSS: Implicit Subscription handling
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Explicit Subscription handling
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity deletion interaction
ASTM SCD DSS: Subscription and entity interaction + ASTM SCD DSS: Implicit Subscription handling
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Explicit Subscription handling
ASTM SCD DSS: Operational Intent Reference Key Validation
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity deletion interaction
ASTM SCD DSS: Subscription and entity interaction DSS0015 diff --git a/monitoring/uss_qualifier/suites/astm/utm/f3548_21.md b/monitoring/uss_qualifier/suites/astm/utm/f3548_21.md index fddc07c0f9..dfd89e20b6 100644 --- a/monitoring/uss_qualifier/suites/astm/utm/f3548_21.md +++ b/monitoring/uss_qualifier/suites/astm/utm/f3548_21.md @@ -63,7 +63,7 @@ DSS0005,5 Implemented - ASTM SCD DSS: Implicit Subscription handling
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Explicit Subscription handling
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity deletion interaction
ASTM SCD DSS: Subscription and entity interaction + ASTM SCD DSS: Implicit Subscription handling
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Explicit Subscription handling
ASTM SCD DSS: Operational Intent Reference Key Validation
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity deletion interaction
ASTM SCD DSS: Subscription and entity interaction DSS0015 diff --git a/monitoring/uss_qualifier/suites/faa/uft/message_signing.md b/monitoring/uss_qualifier/suites/faa/uft/message_signing.md index 69cc3424ff..833a97dc11 100644 --- a/monitoring/uss_qualifier/suites/faa/uft/message_signing.md +++ b/monitoring/uss_qualifier/suites/faa/uft/message_signing.md @@ -41,7 +41,7 @@ DSS0005,5 Implemented - ASTM SCD DSS: Implicit Subscription handling
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Explicit Subscription handling
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity deletion interaction
ASTM SCD DSS: Subscription and entity interaction + ASTM SCD DSS: Implicit Subscription handling
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Explicit Subscription handling
ASTM SCD DSS: Operational Intent Reference Key Validation
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity deletion interaction
ASTM SCD DSS: Subscription and entity interaction DSS0015 diff --git a/monitoring/uss_qualifier/suites/interuss/dss/all_tests.md b/monitoring/uss_qualifier/suites/interuss/dss/all_tests.md index 053762e689..5798b48296 100644 --- a/monitoring/uss_qualifier/suites/interuss/dss/all_tests.md +++ b/monitoring/uss_qualifier/suites/interuss/dss/all_tests.md @@ -461,7 +461,7 @@ DSS0005,5 Implemented - ASTM SCD DSS: Implicit Subscription handling
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Explicit Subscription handling
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity deletion interaction
ASTM SCD DSS: Subscription and entity interaction + ASTM SCD DSS: Implicit Subscription handling
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Explicit Subscription handling
ASTM SCD DSS: Operational Intent Reference Key Validation
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity deletion interaction
ASTM SCD DSS: Subscription and entity interaction DSS0015 diff --git a/monitoring/uss_qualifier/suites/uspace/flight_auth.md b/monitoring/uss_qualifier/suites/uspace/flight_auth.md index 5059532c32..d28d15933a 100644 --- a/monitoring/uss_qualifier/suites/uspace/flight_auth.md +++ b/monitoring/uss_qualifier/suites/uspace/flight_auth.md @@ -42,7 +42,7 @@ DSS0005,5 Implemented - ASTM SCD DSS: Implicit Subscription handling
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Explicit Subscription handling
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity deletion interaction
ASTM SCD DSS: Subscription and entity interaction + ASTM SCD DSS: Implicit Subscription handling
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Explicit Subscription handling
ASTM SCD DSS: Operational Intent Reference Key Validation
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity deletion interaction
ASTM SCD DSS: Subscription and entity interaction DSS0015 diff --git a/monitoring/uss_qualifier/suites/uspace/required_services.md b/monitoring/uss_qualifier/suites/uspace/required_services.md index bc5f7f19f2..febe42bdc9 100644 --- a/monitoring/uss_qualifier/suites/uspace/required_services.md +++ b/monitoring/uss_qualifier/suites/uspace/required_services.md @@ -652,7 +652,7 @@ DSS0005,5 Implemented - ASTM SCD DSS: Implicit Subscription handling
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Explicit Subscription handling
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity deletion interaction
ASTM SCD DSS: Subscription and entity interaction + ASTM SCD DSS: Implicit Subscription handling
ASTM SCD DSS: Interfaces authentication
ASTM SCD DSS: Operational Intent Explicit Subscription handling
ASTM SCD DSS: Operational Intent Reference Key Validation
ASTM SCD DSS: Subscription Simple
ASTM SCD DSS: Subscription Synchronization
ASTM SCD DSS: Subscription Validation
ASTM SCD DSS: Subscription and entity deletion interaction
ASTM SCD DSS: Subscription and entity interaction DSS0015 From 29911fae7e8eecc02e743e890b8b5eef6a81950b Mon Sep 17 00:00:00 2001 From: Mariem Baccari <53703829+MariemBaccari@users.noreply.github.com> Date: Wed, 21 Oct 2026 09:01:19 +0200 Subject: [PATCH 2/3] Update monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md Co-authored-by: Benjamin Pelletier --- .../astm/utm/dss/fragments/sub/unchanged_after_conflict.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md b/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md index 63d04f5ee7..26a84b2749 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md @@ -9,7 +9,7 @@ The subscriptions owned by the client within the planning area are queried befor **[astm.f3548.v21.DSS0005,5](../../../../../../requirements/astm/f3548/v21.md)** requires the implementation of the DSS endpoint to allow callers to retrieve the subscriptions they created. -## 🛑 Rejected request did not create or modify subscriptions check +## ⚠️ Rejected request did not create or modify subscriptions check A request to create or mutate an operational intent reference that is rejected because of missing OVNs is not expected to have any effect. In particular, the DSS is not expected to create an implicit subscription requested by such a request, nor to expand From c5d0845c9c01fc5fe14c70290d1504e425e2cb4f Mon Sep 17 00:00:00 2001 From: Mariem Baccari Date: Wed, 21 Oct 2026 09:34:35 +0200 Subject: [PATCH 3/3] address severity change comment --- .../dss/fragments/sub/unchanged_after_conflict.md | 3 ++- .../astm/utm/dss/op_intent_ref_key_validation.py | 15 +++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md b/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md index 26a84b2749..8765c2b008 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/fragments/sub/unchanged_after_conflict.md @@ -4,8 +4,9 @@ This test step fragment validates that a request to create or mutate an operatio because of a conflict did not create, modify or delete any subscription, including implicit subscriptions. The subscriptions owned by the client within the planning area are queried before and after the rejected request, and compared. +If either query fails, the comparison is skipped. -## 🛑 Successful subscription search query check +## ⚠️ Successful subscription search query check **[astm.f3548.v21.DSS0005,5](../../../../../../requirements/astm/f3548/v21.md)** requires the implementation of the DSS endpoint to allow callers to retrieve the subscriptions they created. diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_key_validation.py b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_key_validation.py index 4d821df700..4481144f95 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_key_validation.py +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/op_intent_ref_key_validation.py @@ -432,8 +432,9 @@ def _steps_attempt_mutation_to_cause_overlap(self): self._check_subscriptions_unchanged(subs_before) self.end_test_step() - def _query_own_subs(self) -> FetchedSubscriptions: - """Queries the subscriptions owned by the client in the planning area.""" + def _query_own_subs(self) -> FetchedSubscriptions | None: + """Queries the subscriptions owned by the client in the planning area. + Returns None if the query failed.""" query = self._dss.query_subscriptions( self._planning_area_volume4d.to_f3548v21() ) @@ -445,11 +446,17 @@ def _query_own_subs(self) -> FetchedSubscriptions: details=f"When attempting to query subscriptions from the DSS, received {query.status_code}", query_timestamps=[query.request.timestamp], ) + return None return query - def _check_subscriptions_unchanged(self, query_before: FetchedSubscriptions): - """Checks that the subscriptions owned by the client are the same as before a rejected request.""" + def _check_subscriptions_unchanged(self, query_before: FetchedSubscriptions | None): + """Checks that the subscriptions owned by the client are the same as before a rejected request. + The check is skipped if the subscriptions could not be queried before or after the request.""" + if query_before is None: + return query = self._query_own_subs() + if query is None: + return subs_before = {s.id: s.version for s in query_before.subscriptions.values()} subs_after = {s.id: s.version for s in query.subscriptions.values()} with self.check(