Skip to content

Commit

Permalink
[uss_qualifier] new constraint ref validator, based on the OIR validator
Browse files Browse the repository at this point in the history
  • Loading branch information
Shastick committed May 30, 2024
1 parent 58d636e commit 7304995
Show file tree
Hide file tree
Showing 24 changed files with 1,038 additions and 39 deletions.
8 changes: 8 additions & 0 deletions monitoring/monitorlib/schema_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ class F3548_21(str, Enum):
)
AirspaceConflictResponse = "components.schemas.AirspaceConflictResponse"

ChangeConstraintReferenceResponse = (
"components.schemas.ChangeConstraintReferenceResponse"
)
GetConstraintReferenceResponse = "components.schemas.GetConstraintReferenceResponse"
QueryConstraintReferenceResponse = (
"components.schemas.QueryConstraintReferenceResponse"
)


_openapi_content_cache: Dict[str, dict] = {}

Expand Down
2 changes: 1 addition & 1 deletion monitoring/prober/infrastructure.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def wrapper_default_scope(*args, **kwargs):
resource_type_code_descriptions: Dict[ResourceType, str] = {}


# Next code: 390
# Next code: 391
def register_resource_type(code: int, description: str) -> ResourceType:
"""Register that the specified code refers to the described resource.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ v1:
# ASTM F3548-21 USS emulation roles
- utm.strategic_coordination
- utm.availability_arbitration
- utm.constraint_management
# For authentication test purposes.
# Remove if the authentication provider pointed to by AUTH_SPEC does not support it.
- ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ utm_auth:
- utm.strategic_coordination
- utm.conformance_monitoring_sa
- utm.availability_arbitration
- utm.constraint_management
# InterUSS versioning automated testing
- interuss.versioning.read_system_versions
- interuss.geospatial_map.query
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ utm_auth:
- utm.strategic_coordination
- utm.conformance_monitoring_sa
- utm.availability_arbitration
- utm.constraint_management
# InterUSS versioning automated testing
- interuss.versioning.read_system_versions
- interuss.geospatial_map.query
Expand Down
138 changes: 138 additions & 0 deletions monitoring/uss_qualifier/resources/astm/f3548/v21/dss.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
ExchangeRecord,
ErrorReport,
AirspaceConflictResponse,
PutConstraintReferenceParameters,
ChangeConstraintReferenceResponse,
ConstraintReference,
QueryConstraintReferenceParameters,
QueryConstraintReferencesResponse,
)
from uas_standards.astm.f3548.v21.constants import Scope

Expand Down Expand Up @@ -457,6 +462,139 @@ def set_uss_availability(
result = query.parse_json_result(UssAvailabilityStatusResponse)
return result.version, query

def put_constraint_ref(
self,
cr_id: str,
extents: List[Volume4D],
uss_base_url: UssBaseURL,
ovn: Optional[str] = None,
) -> Tuple[ConstraintReference, List[SubscriberToNotify], Query]:
"""
Create or update a constraint reference.
Returns:
the constraint reference created or updated, the subscribers to notify, the query
Raises:
* QueryError if request failed, if HTTP status code is different than 200 or 201, or if the parsing of the response failed.
"""
self._uses_scope(Scope.ConstraintManagement)
create = ovn is None
if create:
op = OPERATIONS[OperationID.CreateConstraintReference]
url = op.path.format(entityid=cr_id)
query_type = QueryType.F3548v21DSSCreateConstraintReference
else:
op = OPERATIONS[OperationID.UpdateConstraintReference]
url = op.path.format(entityid=cr_id, ovn=ovn)
query_type = QueryType.F3548v21DSSUpdateConstraintReference

req = PutConstraintReferenceParameters(
extents=extents,
uss_base_url=uss_base_url,
)
query = query_and_describe(
self.client,
op.verb,
url,
query_type,
self.participant_id,
scope=Scope.ConstraintManagement,
json=req,
)
if (create and query.status_code == 201) or (
not create and query.status_code == 200
):
result = query.parse_json_result(ChangeConstraintReferenceResponse)
return result.constraint_reference, result.subscribers, query
else:
err_msg = query.error_message if query.error_message is not None else ""
raise QueryError(
f"Received code {query.status_code} when attempting to {'create' if create else 'update'} constraint reference with ID {cr_id}; error message: `{err_msg}`",
query,
)

def get_constraint_ref(self, id: str) -> Tuple[ConstraintReference, Query]:
"""
Retrieve a constraint reference from the DSS, using only its ID
Raises:
* QueryError: if request failed, if HTTP status code is different than 200, or if the parsing of the response failed.
"""
self._uses_scope(Scope.ConstraintManagement)
op = OPERATIONS[OperationID.GetConstraintReference]
query = query_and_describe(
self.client,
op.verb,
op.path.format(entityid=id),
QueryType.F3548v21DSSGetConstraintReference,
self.participant_id,
scope=Scope.ConstraintManagement,
)
if query.status_code != 200:
raise QueryError(
f"Received code {query.status_code} when attempting to retrieve constraint reference {id}{f'; error message: `{query.error_message}`' if query.error_message is not None else ''}",
query,
)
else:
result = query.parse_json_result(ChangeConstraintReferenceResponse)
return result.constraint_reference, query

def find_constraint_ref(
self, extent: Volume4D
) -> Tuple[List[ConstraintReference], Query]:
"""
Find constraint references overlapping with a given volume 4D.
Raises:
* QueryError: if request failed, if HTTP status code is different than 200, or if the parsing of the response failed.
"""
self._uses_scope(Scope.ConstraintManagement)
op = OPERATIONS[OperationID.QueryConstraintReferences]
req = QueryConstraintReferenceParameters(area_of_interest=extent)
query = query_and_describe(
self.client,
op.verb,
op.path,
QueryType.F3548v21DSSQueryConstraintReferences,
self.participant_id,
scope=Scope.ConstraintManagement,
json=req,
)
if query.status_code != 200:
raise QueryError(
f"Received code {query.status_code} when attempting to find operational intents in {extent}{f'; error message: `{query.error_message}`' if query.error_message is not None else ''}",
query,
)
else:
result = query.parse_json_result(QueryConstraintReferencesResponse)
return result.constraint_references, query

def delete_constraint_ref(
self,
id: str,
ovn: str,
) -> Tuple[ConstraintReference, List[SubscriberToNotify], Query]:
"""
Delete a constraint reference.
Raises:
* QueryError: if request failed, if HTTP status code is different than 200, or if the parsing of the response failed.
"""
self._uses_scope(Scope.ConstraintManagement)
op = OPERATIONS[OperationID.DeleteConstraintReference]
query = query_and_describe(
self.client,
op.verb,
op.path.format(entityid=id, ovn=ovn),
QueryType.F3548v21DSSDeleteConstraintReference,
self.participant_id,
scope=Scope.ConstraintManagement,
)
if query.status_code != 200:
raise QueryError(
f"Received code {query.status_code} when attempting to delete constraint reference {id}{f'; error message: `{query.error_message}`' if query.error_message is not None else ''}",
query,
)
else:
result = query.parse_json_result(ChangeConstraintReferenceResponse)
return result.constraint_reference, result.subscribers, query

def make_report(
self,
exchange: ExchangeRecord,
Expand Down
24 changes: 24 additions & 0 deletions monitoring/uss_qualifier/resources/astm/f3548/v21/planning_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
EntityID,
PutOperationalIntentReferenceParameters,
ImplicitSubscriptionParameters,
PutConstraintReferenceParameters,
)

from monitoring.monitorlib.geo import make_latlng_rect, Volume3D
Expand Down Expand Up @@ -101,6 +102,29 @@ def get_new_operational_intent_ref_params(
else None,
)

def get_new_constraint_ref_params(
self,
time_start: datetime.datetime,
time_end: datetime.datetime,
) -> PutConstraintReferenceParameters:
"""
Builds a PutConstraintReferenceParameters object that can be used against the DSS OCR API.
The extents contained in these parameters contain a single 4DVolume, which may not be entirely realistic,
but is sufficient in situations where the content of the CR is irrelevant as long as it is valid, such
as for testing authentication or parameter validation.
"""
return PutConstraintReferenceParameters(
extents=[
Volume4D(
volume=self.volume,
time_start=Time(time_start),
time_end=Time(time_end),
).to_f3548v21()
],
uss_base_url=self.base_url,
)


class PlanningAreaResource(Resource[PlanningAreaSpecification]):
specification: PlanningAreaSpecification
Expand Down
15 changes: 15 additions & 0 deletions monitoring/uss_qualifier/scenarios/astm/utm/dss/clean_workspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,18 @@ If the DSS cannot be queried for the existing test ID, the DSS is likely not imp
## 🛑 Subscription can be deleted check

**[astm.f3548.v21.DSS0005,5](../../../../requirements/astm/f3548/v21.md)** requires the implementation of the DSS endpoint to allow callers to delete subscriptions they created.

## 🛑 Constraint references can be queried by ID check

If an existing constraint reference cannot directly be queried by its ID, or if for a non-existing one the DSS replies with a status code different than 404,
the DSS implementation is in violation of **[astm.f3548.v21.DSS0005,3](../../../../requirements/astm/f3548/v21.md)**.

## 🛑 Constraint references can be searched for check

A client with valid credentials should be allowed to search for constraint references in a given area.
Otherwise, the DSS is not in compliance with **[astm.f3548.v21.DSS0005,4](../../../../requirements/astm/f3548/v21.md)**.

## 🛑 Constraint reference removed check

If an existing constraint cannot be deleted by its manager when providing the proper ID and OVN, the DSS implementation is in violation of
**[astm.f3548.v21.DSS0005,3](../../../../requirements/astm/f3548/v21.md)**.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Create constraint reference test step fragment

This test step fragment validates that:
- a query to create a constraint reference with valid parameters succeeds
- the response to the query conforms to the OpenAPI specification
- the content of the response reflects the created constraint reference

## [Query Success](./create_query.md)

Check query succeeds

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

Check response format

## 🛑 Create constraint reference response content is correct check

A successful constraint reference creation query is expected to return a body, the content of which reflects the created constraint reference.
If the content of the response does not correspond to what was requested, the DSS is failing to implement **[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)**.

This check will usually be performing a series of sub-checks from the [validate](../validate) fragments.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Create constraint reference response format test step fragment

This test step fragment validates that a constraint references creation returns a body in the correct format.

## 🛑 Create constraint reference response format conforms to spec check

The response to a successful constraint reference creation query is expected to conform to the format defined by the OpenAPI specification under the `A3.1` Annex of ASTM F3548−21.

If it does not, the DSS is failing to implement **[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)**.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Create constraint reference test step fragment

This test step fragment validates that a query to create a constraint reference with valid parameters succeeds

## 🛑 Create constraint reference query succeeds check

As per **[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)**, the DSS API must allow callers to create a constraint reference with either one or both of the
start and end time missing, provided all the required parameters are valid.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Validate the content of a constraint reference test step fragment

This test step fragment attempts to validate the content of a single constraint reference returned by the DSS.

The code for these checks lives in the [cr_validator.py](../../../validators/cr_validator.py) class.

## ⚠️ Returned constraint reference ID is correct check

If the returned constraint reference ID does not correspond to the one specified in the creation parameters,
**[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)** is not respected.

## ⚠️ Returned constraint reference has a manager check

If the returned constraint reference has no manager defined, **[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)** is not respected.

## ⚠️ Returned constraint reference manager is correct check

The returned manager must correspond to the identity of the client that created the constraint at the DSS,
otherwise the DSS is in violation of **[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)**.

## ⚠️ Returned constraint reference has an USS base URL check

If the returned constraint reference has no USS base URL defined, **[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)** is not respected.

## ⚠️ Returned constraint reference base URL is correct check

The returned USS base URL must be prefixed with the USS base URL that was provided at constraint reference creation, otherwise the DSS is in violation of **[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)**.

## ⚠️ Returned constraint reference has a start time check

If the returned constraint reference has no start time defined, **[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)** is not respected.

## ⚠️ Returned start time is correct check

The returned start time must be the same as the provided one, otherwise the DSS is in violation of **[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)**.

## ⚠️ Returned constraint reference has an end time check

constraint references need a defined end time in order to limit their duration: if the DSS omits to set the end time, it will be in violation of **[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)**.

## ⚠️ Returned end time is correct check

The returned end time must be the same as the provided one, otherwise the DSS is in violation of **[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)**.

## ⚠️ Returned constraint reference has a version check

If the returned constraint reference has no version defined, **[astm.f3548.v21.DSS0005,3](../../../../../../../requirements/astm/f3548/v21.md)** is not respected.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .subscription_synchronization import SubscriptionSynchronization
from .op_intent_ref_synchronization import OIRSynchronization
from .uss_availability_synchronization import USSAvailabilitySynchronization
from .constraint_ref_synchronization import CRSynchronization
Loading

0 comments on commit 7304995

Please sign in to comment.