Skip to content

Commit

Permalink
[uss_qualifier/scenarios/utm/dss/subscription_interactions] Add test …
Browse files Browse the repository at this point in the history
…of requirement DSS0210,A2-7-2,4c
  • Loading branch information
mickmis committed Mar 25, 2024
1 parent e3f3138 commit 1be30d5
Show file tree
Hide file tree
Showing 11 changed files with 216 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

This test step fragment validates that operational intent references can be updated.

## 🛑 Mutate operational intent reference query succeeds check
## [Update query succeeds](./update_query.md)

As per **[astm.f3548.v21.DSS0005,1](../../../../../../../requirements/astm/f3548/v21.md)**, the DSS API must allow callers to mutate an operational intent reference.
Check query succeeds.

## [Response Format](./update_format.md)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Update operational intent reference test step fragment

This test step fragment validates that a query to update an operational intent reference with valid parameters succeeds.

## 🛑 Mutate operational intent reference query succeeds check

As per **[astm.f3548.v21.DSS0005,1](../../../../../../../requirements/astm/f3548/v21.md)**, the DSS API must allow callers to mutate an operational intent reference.
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,40 @@ 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)**.

### Modify an OIR at every DSS in sequence test step

This test step will modify the previously created operational intent reference and assorted subscription at every DSS, in sequence, each time verifying that the DSS
requires notifications for any previously established subscription that intersects with the modified OIR.

Note that this step is run once for each involved DSS (that is, once for the primary DSS and once for every secondary DSS)

#### [Modify OIR](./fragments/oir/crud/update_query.md)

Check that the OIR modification query succeeds

#### 🛑 DSS response contains the expected background subscription check

The response from a DSS to a valid OIR modification request is expected to contain any relevant subscription for the OIR's extents.
This includes one of the subscriptions created earlier, as it is designed to intersect with the OIRs being modified.

If the DSS omits the intersecting subscription, it fails to implement **[astm.f3548.v21.DSS0210,A2-7-2,4c](../../../../requirements/astm/f3548/v21.md)**.

#### 🛑 DSS does not return non-intersecting background subscription check

The response from a DSS to a valid OIR modification request is expected to contain any relevant subscription for the OIR's extents.
This should exclude one of subscriptions created earlier, as it is designed to not intersect with the OIRs being modified.

If the DSS includes the non-intersecting subscription, it fails to implement **[astm.f3548.v21.DSS0210,A2-7-2,4c](../../../../requirements/astm/f3548/v21.md)**.

#### 🛑 DSS returns the implicit subscriptions from intersecting OIRs check

The response from a DSS to a valid OIR modification request is expected to contain any relevant subscription for the OIR's extents.
This includes any implicit subscription previously created on the DSS as part of a previously created OIR.

If the DSS omits any of the implicit subscriptions belonging to an OIR previously created on another DSS (which are designed to all intersect),
any of the DSSes at which an earlier OIR was created, or the DSS at which the current OIR has been modified,
are in violation of **[astm.f3548.v21.DSS0210,A2-7-2,4c](../../../../requirements/astm/f3548/v21.md)**.

## Subscription creation returns relevant OIRs test case

This test case checks that, when a newly created subscription intersects with an existing OIR and that the subscription is intended for operational intent references,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
EntityID,
OperationalIntentReference,
OperationalIntentState,
PutOperationalIntentReferenceParameters,
SubscriberToNotify,
)
from uas_standards.astm.f3548.v21.constants import Scope
Expand All @@ -16,11 +15,11 @@
from monitoring.monitorlib.fetch import QueryError, Query
from monitoring.monitorlib.geotemporal import Volume4D
from monitoring.prober.infrastructure import register_resource_type
from monitoring.uss_qualifier.configurations.configuration import ParticipantID
from monitoring.uss_qualifier.resources.astm.f3548.v21 import PlanningAreaResource
from monitoring.uss_qualifier.resources.astm.f3548.v21.dss import (
DSSInstanceResource,
DSSInstancesResource,
DSSInstance,
)
from monitoring.uss_qualifier.resources.astm.f3548.v21.subscription_params import (
SubscriptionParams,
Expand Down Expand Up @@ -169,72 +168,163 @@ def _step_create_background_subs(self):
def _steps_create_oirs_at_each_dss(self):
"""Creates an OIR at each DSS instance"""

common_params = self._planning_area.get_new_operational_intent_ref_params(
key=[], # Proper key added in each step below
state=OperationalIntentState.Accepted,
uss_base_url="https://example.interuss.org/oir_base_url",
time_start=datetime.utcnow(),
# Cover the first subscription's time, but not the second one
time_end=self._sub_1_end + timedelta(minutes=10),
subscription_id=None,
implicit_sub_base_url="https://example.interuss.org/sub_base_url",
)

existing_oir = None
possible_culprits = []
for i, dss in enumerate([self._dss] + self._secondary_instances):

self.begin_test_step("Create an OIR at every DSS in sequence")

oir_id = self._oir_ids[i]

if existing_oir:
common_params.key.append(existing_oir.ovn)
oir, subs, q = self._put_op_intent(dss, oir_id, common_params)
notification_ids = _to_sub_ids(subs)
possible_culprits.append(dss.participant_id)

def _expected_subs_check(
_participant: ParticipantID,
_notif_ids: set[str],
_query_timestamp: datetime,
):
with self.check(
"DSS response contains the expected background subscription",
dss.participant_id,
) as check:
if self._background_sub_ids[0] not in notification_ids:
check.record_failed(
_participant,
) as _check:
if self._background_sub_ids[0] not in _notif_ids:
_check.record_failed(
summary="DSS did not return the intersecting background subscription",
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],
f" list of subscriptions to notify, but got {_notif_ids}",
query_timestamps=[_query_timestamp],
)

def _non_intersecting_subs_check(
_participant: ParticipantID,
_notif_ids: set[str],
_query_timestamp: datetime,
):
with self.check(
"DSS does not return non-intersecting background subscription",
dss.participant_id,
) as check:
if self._background_sub_ids[1] in notification_ids:
check.record_failed(
_participant,
) as _check:
if self._background_sub_ids[1] in _notif_ids:
_check.record_failed(
summary="DSS returned the non-intersecting background subscription",
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],
f" list of subscriptions to notify, but got {_notif_ids}",
query_timestamps=[_query_timestamp],
)

def _implicit_subs_check(
_participants: List[ParticipantID],
_notif_ids: set[str],
_query_timestamp: datetime,
):
with self.check(
"DSS returns the implicit subscriptions from intersecting OIRs",
possible_culprits,
) as check:
_participants,
) as _check:
# Previously created OIRs have subscriptions that should be triggered:
for existing_oir_id, existing_oir in self._current_oirs.items():
if existing_oir.subscription_id not in notification_ids:
check.record_failed(
if existing_oir.subscription_id not in _notif_ids:
_check.record_failed(
summary="Missing subscription to notify",
details=f"Expected subscription {existing_oir.subscription_id} to be notified for "
f"freshly created OIR {existing_oir_id}",
query_timestamps=[q.request.timestamp],
query_timestamps=[_query_timestamp],
)

existing_oir = oir
self.begin_test_step("Create an OIR at every DSS in sequence")
possible_culprits: List[ParticipantID] = []
for i, dss in enumerate([self._dss] + self._secondary_instances):
oir_id = self._oir_ids[i]
oir = self._planning_area.get_new_operational_intent_ref_params(
key=[current_oir.ovn for current_oir in self._current_oirs.values()],
state=OperationalIntentState.Accepted,
uss_base_url="https://example.interuss.org/oir_base_url",
time_start=datetime.utcnow(),
# Cover the first subscription's time, but not the second one
time_end=self._sub_1_end + timedelta(minutes=10),
subscription_id=None,
implicit_sub_base_url="https://example.interuss.org/sub_base_url",
)

with self.check(
"Create operational intent reference query succeeds",
[dss.participant_id],
) as check:
try:
oir, subs, q = dss.put_op_intent(
extents=oir.extents,
key=oir.key,
state=oir.state,
base_url=oir.uss_base_url,
oi_id=oir_id,
)
self.record_query(q)
except QueryError as qe:
self.record_queries(qe.queries)
check.record_failed(
summary="Failed to create operational intent reference",
details=f"Failed to create operational intent reference: {qe}",
query_timestamps=qe.query_timestamps,
)

notification_ids = _to_sub_ids(subs)
possible_culprits.append(dss.participant_id)

_expected_subs_check(
dss.participant_id, notification_ids, q.request.timestamp
)
_non_intersecting_subs_check(
dss.participant_id, notification_ids, q.request.timestamp
)
_implicit_subs_check(
possible_culprits, notification_ids, q.request.timestamp
)

self._current_oirs[oir_id] = oir
self.end_test_step()
self.end_test_step()

self.begin_test_step("Modify an OIR at every DSS in sequence")
possible_culprits = []
for i, dss in enumerate([self._dss] + self._secondary_instances):
oir_id = self._oir_ids[i]
oir = self._planning_area.get_new_operational_intent_ref_params(
key=[current_oir.ovn for current_oir in self._current_oirs.values()],
state=OperationalIntentState.Accepted,
uss_base_url="https://example.interuss.org/oir_base_url_bis", # dummy modification of the OIR
time_start=datetime.utcnow(),
# Cover the first subscription's time, but not the second one
time_end=self._sub_1_end + timedelta(minutes=10),
subscription_id=None,
implicit_sub_base_url="https://example.interuss.org/sub_base_url",
)

with self.check(
"Mutate operational intent reference query succeeds",
[dss.participant_id],
) as check:
try:
oir, subs, q = dss.put_op_intent(
extents=oir.extents,
key=oir.key,
state=oir.state,
base_url=oir.uss_base_url,
oi_id=oir_id,
ovn=self._current_oirs[oir_id].ovn,
)
self.record_query(q)
except QueryError as qe:
self.record_queries(qe.queries)
check.record_failed(
summary="Failed to mutate operational intent reference",
details=f"Failed to mutate operational intent reference: {qe}",
query_timestamps=qe.query_timestamps,
)

notification_ids = _to_sub_ids(subs)
possible_culprits.append(dss.participant_id)

_expected_subs_check(
dss.participant_id, notification_ids, q.request.timestamp
)
_non_intersecting_subs_check(
dss.participant_id, notification_ids, q.request.timestamp
)
_implicit_subs_check(
possible_culprits, notification_ids, q.request.timestamp
)

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"""
Expand Down Expand Up @@ -301,36 +391,6 @@ def _steps_create_subs_at_each_dss(self):

self.end_test_step()

def _put_op_intent(
self,
dss: DSSInstance,
oir_id: EntityID,
params: PutOperationalIntentReferenceParameters,
) -> Tuple[OperationalIntentReference, List[SubscriberToNotify], Query]:

with self.check(
"Create operational intent reference query succeeds", [dss.participant_id]
) as check:
try:
oir, subs, q = dss.put_op_intent(
extents=params.extents,
key=params.key,
state=params.state,
base_url=params.uss_base_url,
oi_id=oir_id,
ovn=None,
)
self.record_query(q)
except QueryError as qe:
self.record_queries(qe.queries)
check.record_failed(
summary="Failed to create operational intent reference",
details=f"Failed to create operational intent reference: {qe}",
query_timestamps=qe.query_timestamps,
)

return oir, subs, q

def _create_sub_with_params(
self, params: SubscriptionParams
) -> Tuple[Subscription, List[OperationalIntentReference], fetch.Query]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Verify that the operational intent reference's version fields are as expected.
This test step mutates the previously created operational intent reference to verify that the DSS reacts properly: notably, it checks that the operational intent reference version is updated,
including for changes that are not directly visible, such as changing the operational intent reference's footprint.

#### [Update OIR](../fragments/oir/crud/update.md)
#### [Update OIR](../fragments/oir/crud/update_correct.md)

Confirm that the operational intent reference can be mutated.

Expand Down
7 changes: 6 additions & 1 deletion monitoring/uss_qualifier/suites/astm/utm/dss_probing.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<th><a href="../../README.md#checked-in">Checked in</a></th>
</tr>
<tr>
<td rowspan="30" style="vertical-align:top;"><a href="../../../requirements/astm/f3548/v21.md">astm<br>.f3548<br>.v21</a></td>
<td rowspan="31" style="vertical-align:top;"><a href="../../../requirements/astm/f3548/v21.md">astm<br>.f3548<br>.v21</a></td>
<td><a href="../../../requirements/astm/f3548/v21.md">DSS0005,1</a></td>
<td>Implemented</td>
<td><a href="../../../scenarios/astm/utm/dss/op_intent_ref_access_control.md">ASTM F3548-21 UTM DSS Operational Intent Reference Access Control</a><br><a href="../../../scenarios/astm/utm/dss/authentication/authentication_validation.md">ASTM SCD DSS: Interfaces authentication</a><br><a href="../../../scenarios/astm/utm/dss/op_intent_ref_key_validation.md">ASTM SCD DSS: Operational Intent Reference Key Validation</a><br><a href="../../../scenarios/astm/utm/dss/synchronization/op_intent_ref_synchronization.md">ASTM SCD DSS: Operational Intent Reference Synchronization</a><br><a href="../../../scenarios/astm/utm/dss/subscription_simple.md">ASTM SCD DSS: Subscription Simple</a><br><a href="../../../scenarios/astm/utm/dss/synchronization/subscription_synchronization.md">ASTM SCD DSS: Subscription Synchronization</a><br><a href="../../../scenarios/astm/utm/dss/subscription_validation.md">ASTM SCD DSS: Subscription Validation</a><br><a href="../../../scenarios/astm/utm/dss/subscription_interactions.md">ASTM SCD DSS: Subscription and entity interaction</a></td>
Expand Down Expand Up @@ -156,6 +156,11 @@
<td>Implemented</td>
<td><a href="../../../scenarios/astm/utm/dss/subscription_interactions.md">ASTM SCD DSS: Subscription and entity interaction</a></td>
</tr>
<tr>
<td><a href="../../../requirements/astm/f3548/v21.md">DSS0210,A2-7-2,4c</a></td>
<td>Implemented</td>
<td><a href="../../../scenarios/astm/utm/dss/subscription_interactions.md">ASTM SCD DSS: Subscription and entity interaction</a></td>
</tr>
<tr>
<td><a href="../../../requirements/astm/f3548/v21.md">DSS0210,A2-7-2,7</a></td>
<td>Implemented</td>
Expand Down
Loading

0 comments on commit 1be30d5

Please sign in to comment.