diff --git a/monitoring/monitorlib/mutate/rid.py b/monitoring/monitorlib/mutate/rid.py index 851df074aa..8bf9ec979f 100644 --- a/monitoring/monitorlib/mutate/rid.py +++ b/monitoring/monitorlib/mutate/rid.py @@ -1,19 +1,15 @@ import datetime from typing import Dict, List, Optional, Union, Set -from implicitdict import ImplicitDict import s2sphere -from uas_standards import Operation - -from monitoring.monitorlib.fetch import QueryType -from monitoring.monitorlib.fetch.rid import RIDQuery, Subscription, ISA -from monitoring.monitorlib.rid import RIDVersion -from uas_standards.astm.f3411 import v19, v22a import uas_standards.astm.f3411.v19.api import uas_standards.astm.f3411.v19.constants import uas_standards.astm.f3411.v22a.api import uas_standards.astm.f3411.v22a.constants import yaml +from implicitdict import ImplicitDict +from uas_standards import Operation +from uas_standards.astm.f3411 import v19, v22a from yaml.representer import Representer from monitoring.monitorlib import ( @@ -22,6 +18,9 @@ rid_v1, rid_v2, ) +from monitoring.monitorlib.fetch import QueryType +from monitoring.monitorlib.fetch.rid import RIDQuery, Subscription, ISA +from monitoring.monitorlib.rid import RIDVersion class ChangedSubscription(RIDQuery): @@ -450,6 +449,11 @@ class ISAChange(ImplicitDict): notifications: Dict[str, ISAChangeNotification] """Mapping from USS base URL to change notification query""" + @property + def subscribers(self) -> Optional[List[SubscriberToNotify]]: + """List of subscribers that required a notification for the change.""" + return self.dss_query.subscribers + def build_isa_request_body( area_vertices: List[s2sphere.LatLng], diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/display_data_evaluator.py b/monitoring/uss_qualifier/scenarios/astm/netrid/display_data_evaluator.py index 93946e08db..0ded4dc8a4 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/display_data_evaluator.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/display_data_evaluator.py @@ -49,18 +49,25 @@ def _rect_str(rect) -> str: ) +VERTICAL_SPEED_PRECISION = 0.1 + + @dataclass class DPObservedFlight(object): query: FetchedUSSFlights - flight: int + flight_index: int @property def id(self) -> str: - return self.query.flights[self.flight].id + return self.query.flights[self.flight_index].id @property def most_recent_position(self) -> Optional[Position]: - return self.query.flights[self.flight].most_recent_position + return self.query.flights[self.flight_index].most_recent_position + + @property + def flight(self) -> fetch.rid.Flight: + return self.query.flights[self.flight_index] ObservationType = Union[Flight, DPObservedFlight] @@ -156,7 +163,7 @@ def map_fetched_to_injected_flights( observed_flights = [] for uss_query in fetched_flights: for f in range(len(uss_query.flights)): - observed_flights.append(DPObservedFlight(query=uss_query, flight=f)) + observed_flights.append(DPObservedFlight(query=uss_query, flight_index=f)) tel_mapping = map_observations_to_injected_flights( injected_flights, observed_flights @@ -914,6 +921,23 @@ def _evaluate_normal_sp_observation( details=f"{mapping.injected_flight.uss_participant_id}'s flight with injection ID {mapping.injected_flight.flight.injection_id} in test {mapping.injected_flight.test_id} had telemetry index {mapping.telemetry_index} at {injected_telemetry.timestamp} with lat={injected_telemetry.position.lat}, lng={injected_telemetry.position.lng}, alt={injected_telemetry.position.alt}, but Service Provider reported lat={observed_position.lat}, lng={observed_position.lng}, alt={observed_position.alt} at {mapping.observed_flight.query.query.request.initiated_at}", ) + if mapping.observed_flight.flight.raw.current_state is not None: + with self._test_scenario.check( + "Service Provider vertical speed", + [mapping.injected_flight.uss_participant_id], + ) as check: + if ( + abs( + injected_telemetry.vertical_speed + - mapping.observed_flight.flight.raw.current_state.vertical_speed + ) + > VERTICAL_SPEED_PRECISION + ): + check.record_failed( + "Vertical speed reported by Service Provider does not match injected vertical speed", + details=f"{mapping.injected_flight.uss_participant_id}'s flight with injection ID {mapping.injected_flight.flight.injection_id} in test {mapping.injected_flight.test_id} had telemetry index {mapping.telemetry_index} at {injected_telemetry.timestamp} with vertical speed {injected_telemetry.vertical_speed}, but Service Provider reported vertical speed {mapping.observed_flight.flight.raw.current_state.vertical_speed} at {mapping.observed_flight.query.query.request.initiated_at}", + ) + # Verify that flight details queries succeeded and returned correctly-formatted data for mapping in mappings.values(): details_queries = [ diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/v19/nominal_behavior.md b/monitoring/uss_qualifier/scenarios/astm/netrid/v19/nominal_behavior.md index 1795378ab3..6b71b56513 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/v19/nominal_behavior.md +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/v19/nominal_behavior.md @@ -88,6 +88,10 @@ The identity of flights is determined by precisely matching the known injected p **[astm.f3411.v19.NET0260,Table1,11](../../../../requirements/astm/f3411/v19.md)** requires that relevant Remote ID data, consistent with the common data dictionary, be reported by the Service Provider. Injected flight data had known altitudes, but the altitude reported by the Service Provider did not match those known altitudes. +#### ⚠️ Service Provider vertical speed check + +**[astm.f3411.v19.NET0260,Table1,20](../../../../requirements/astm/f3411/v19.md)** requires that relevant Remote ID data, consistent with the common data dictionary, be reported by the Service Provider. Injected flight data had a specified vertical speed that was different from the reported one. + #### Successful flight details query check **[astm.f3411.v19.NET0710,2](../../../../requirements/astm/f3411/v19.md)** and **[astm.f3411.v19.NET0340](../../../../requirements/astm/f3411/v19.md)** require a Service Provider to implement the GET flight details endpoint. This check will fail if uss_qualifier cannot query that endpoint (specified in the ISA present in the DSS) successfully. diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/nominal_behavior.md b/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/nominal_behavior.md index f7a1c174e7..6b728bf9a3 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/nominal_behavior.md +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/nominal_behavior.md @@ -88,6 +88,10 @@ The identity of flights is determined by precisely matching the known injected p **[astm.f3411.v22a.NET0260,Table1,12](../../../../requirements/astm/f3411/v22a.md)** requires that relevant Remote ID data, consistent with the common data dictionary, be reported by the Service Provider. Injected flight data had known altitudes, but the altitude reported by the Service Provider did not match those known altitudes. +#### ⚠️ Service Provider vertical speed check + +**[astm.f3411.v22a.NET0260,Table1,21](../../../../requirements/astm/f3411/v22a.md)** requires that relevant Remote ID data, consistent with the common data dictionary, be reported by the Service Provider. Injected flight data had a specified vertical speed that was different from the reported one. + #### Successful flight details query check **[astm.f3411.v22a.NET0710,2](../../../../requirements/astm/f3411/v22a.md)** and **[astm.f3411.v22a.NET0340](../../../../requirements/astm/f3411/v22a.md) require a Service Provider to implement the GET flight details endpoint. This check will fail if uss_qualifier cannot query that endpoint (specified in the ISA present in the DSS) successfully. diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/oir_implicit_sub_handling.py b/monitoring/uss_qualifier/scenarios/astm/utm/dss/oir_implicit_sub_handling.py index 2c02b4bf8c..64cce2b085 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/oir_implicit_sub_handling.py +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/oir_implicit_sub_handling.py @@ -221,7 +221,8 @@ def _case_2_step_create_overlapping_oir_no_sub(self): ) with self.check( - "New OIR creation response contains previous implicit subscription to notify" + "New OIR creation response contains previous implicit subscription to notify", + self._pid, ) as check: if self._implicit_sub_2.id not in to_sub_ids(subs): check.record_failed( diff --git a/monitoring/uss_qualifier/scenarios/astm/utm/dss/test_step_fragments.py b/monitoring/uss_qualifier/scenarios/astm/utm/dss/test_step_fragments.py index b7fa8f7134..86f10a8903 100644 --- a/monitoring/uss_qualifier/scenarios/astm/utm/dss/test_step_fragments.py +++ b/monitoring/uss_qualifier/scenarios/astm/utm/dss/test_step_fragments.py @@ -166,6 +166,7 @@ def cleanup_active_oirs( ) as check: try: oirs, query = dss.find_op_intent(volume) + scenario.record_query(query) except QueryError as qe: scenario.record_queries(qe.queries) check.record_failed( @@ -190,6 +191,7 @@ def cleanup_op_intent( ) as check: try: oir, q = dss.get_op_intent_reference(oi_id) + scenario.record_query(q) except fetch.QueryError as e: scenario.record_queries(e.queries) if e.cause_status_code != 404: diff --git a/monitoring/uss_qualifier/suites/astm/netrid/f3411_19.md b/monitoring/uss_qualifier/suites/astm/netrid/f3411_19.md index 89bab93543..b211863f2f 100644 --- a/monitoring/uss_qualifier/suites/astm/netrid/f3411_19.md +++ b/monitoring/uss_qualifier/suites/astm/netrid/f3411_19.md @@ -21,7 +21,7 @@ Checked in - astm
.f3411
.v19
+ astm
.f3411
.v19
DSS0010 Implemented ASTM NetRID DSS: Token Validation @@ -251,6 +251,11 @@ Implemented ASTM NetRID nominal behavior + + NET0260,Table1,20 + Implemented + ASTM NetRID nominal behavior + NET0260,Table1,9 Implemented diff --git a/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.md b/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.md index 3066d6a267..d4fab3ad42 100644 --- a/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.md +++ b/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.md @@ -21,7 +21,7 @@ Checked in - astm
.f3411
.v22a
+ astm
.f3411
.v22a
DSS0010 Implemented ASTM NetRID DSS: Token Validation @@ -271,6 +271,11 @@ Implemented ASTM NetRID nominal behavior + + NET0260,Table1,21 + Implemented + ASTM NetRID nominal behavior + NET0260,Table1,23 Implemented diff --git a/monitoring/uss_qualifier/suites/uspace/network_identification.md b/monitoring/uss_qualifier/suites/uspace/network_identification.md index 6d17e3c0e2..264d2265eb 100644 --- a/monitoring/uss_qualifier/suites/uspace/network_identification.md +++ b/monitoring/uss_qualifier/suites/uspace/network_identification.md @@ -17,7 +17,7 @@ Checked in - astm
.f3411
.v22a
+ astm
.f3411
.v22a
DSS0010 Implemented ASTM NetRID DSS: Token Validation @@ -267,6 +267,11 @@ Implemented ASTM NetRID nominal behavior + + NET0260,Table1,21 + Implemented + ASTM NetRID nominal behavior + NET0260,Table1,23 Implemented diff --git a/monitoring/uss_qualifier/suites/uspace/required_services.md b/monitoring/uss_qualifier/suites/uspace/required_services.md index 4e201b2411..39486aee44 100644 --- a/monitoring/uss_qualifier/suites/uspace/required_services.md +++ b/monitoring/uss_qualifier/suites/uspace/required_services.md @@ -18,7 +18,7 @@ Checked in - astm
.f3411
.v22a
+ astm
.f3411
.v22a
DSS0010 Implemented ASTM NetRID DSS: Token Validation @@ -268,6 +268,11 @@ Implemented ASTM NetRID nominal behavior + + NET0260,Table1,21 + Implemented + ASTM NetRID nominal behavior + NET0260,Table1,23 Implemented