Skip to content

Commit

Permalink
[uss_qualifier] netrid: cover net0260 timestamp accuracy
Browse files Browse the repository at this point in the history
  • Loading branch information
Shastick committed Oct 28, 2024
1 parent ff02058 commit 7e80297
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 6 deletions.
15 changes: 15 additions & 0 deletions monitoring/monitorlib/fetch/rid.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,21 @@ def timestamp(self) -> Optional[StringBasedDateTime]:
f"Cannot retrieve speed using RID version {self.rid_version}"
)

@property
def timestamp_accuracy(self) -> Optional[float]:
if self.rid_version == RIDVersion.f3411_19:
if not self.v19_value.has_field_with_value("current_state"):
return None
return self.v19_value.current_state.timestamp_accuracy
elif self.rid_version == RIDVersion.f3411_22a:
if not self.v22a_value.has_field_with_value("current_state"):
return None
return self.v22a_value.current_state.timestamp_accuracy
else:
raise NotImplementedError(
f"Cannot retrieve speed using RID version {self.rid_version}"
)

def errors(self) -> List[str]:
try:
rid_version = self.rid_version
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ def id(self) -> str:
def most_recent_position(self) -> Optional[Position]:
return self.query.flights[self.flight].most_recent_position

# TODO we may rather want to expose the whole flight object (self.query.flights[self.flight])
# and let callers access subfields directly (will be handled in separate PR)
@property
def timestamp_accuracy(self) -> Optional[float]:
return self.query.flights[self.flight].timestamp_accuracy

@property
def raw_flight(self) -> dict:
return self.query.query.response.json["flights"][self.flight]


ObservationType = Union[Flight, DPObservedFlight]

Expand Down Expand Up @@ -892,13 +902,14 @@ def _evaluate_normal_sp_observation(
participants=[mapping.injected_flight.uss_participant_id],
)

# Check that altitudes match for any observed flights matching injected flights
# Check that required fields are present and match for any observed flights matching injected flights
for mapping in mappings.values():
injected_telemetry = mapping.injected_flight.flight.telemetry[
mapping.telemetry_index
]
observed_position = mapping.observed_flight.most_recent_position
injected_position = injected_telemetry.position

if "alt" in observed_position:
with self._test_scenario.check(
"Service Provider altitude",
Expand All @@ -914,6 +925,44 @@ 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}",
)

# Due to how implicit dicts are deserialized and the timestamp_accuracy is specified in the OpenAPI file, we need to look into
# the raw JSON response to determine if the field is present:
#
# Because the spec requires the field to be present while also specifying a default value, the implicit dict based class derived
# from the spec may not catch that a field is missing at deserialization time (because the RIDAircraftState class specifies a default
# value for the field, no ValueError will be thrown when ImplicitDict.parse() is called).
#
# This means that a missing json field will neither raise an exception nor cause the field to be set to None when we access it,
# meaning this part of the logic cannot rely on the deserialized value to determine if the field was present or not.
raw_flight = mapping.observed_flight.raw_flight
raw_state = (
raw_flight["current_state"] if "current_state" in raw_flight else {}
)
with self._test_scenario.check(
"Service Provider timestamp accuracy is present",
[mapping.injected_flight.uss_participant_id],
) as check:
if "timestamp_accuracy" not in raw_state:
check.record_failed(
"Timestamp accuracy not present in Service Provider response",
details=f"Timestamp accuracy not present in Service Provider {mapping.injected_flight.uss_participant_id}'s response for flight with injection ID {mapping.injected_flight.flight.injection_id} in test {mapping.injected_flight.test_id} with telemetry index {mapping.telemetry_index}",
)

if "timestamp_accuracy" in raw_state:
# From this point on we can use the 'timestamp_accuracy' field of the deserialized object
with self._test_scenario.check(
"Service Provider timestamp accuracy is correct",
[mapping.injected_flight.uss_participant_id],
) as check:
if (
mapping.observed_flight.timestamp_accuracy
!= injected_telemetry.timestamp_accuracy
):
check.record_failed(
"Timestamp accuracy in Service Provider response is incorrect",
details=f"Timestamp accuracy in Service Provider {mapping.injected_flight.uss_participant_id}'s response for flight with injection ID {mapping.injected_flight.flight.injection_id} in test {mapping.injected_flight.test_id} with telemetry index {mapping.telemetry_index} is {mapping.observed_flight.timestamp_accuracy} which is not equal to the injected value of {injected_telemetry.timestamp_accuracy}",
)

# Verify that flight details queries succeeded and returned correctly-formatted data
for mapping in mappings.values():
details_queries = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ 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 timestamp accuracy is present check

**[astm.f3411.v19.NET0260,Table1,5](../../../../requirements/astm/f3411/v19.md)** requires that relevant Remote ID data, consistent with the common data dictionary, be reported by the Service Provider. Timestamp accuracy is a required field, but it was not present.

#### ⚠️ Service Provider timestamp accuracy is correct check

**[astm.f3411.v19.NET0260,Table1,5](../../../../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 timestamp accuracy, but the accuracy reported by the Service Provider did not match it.

#### 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ 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 timestamp accuracy is present check

**[astm.f3411.v22a.NET0260,Table1,5](../../../../requirements/astm/f3411/v22a.md)** requires that relevant Remote ID data, consistent with the common data dictionary, be reported by the Service Provider. Timestamp accuracy is a required field, but it was not present.

#### ⚠️ Service Provider timestamp accuracy is correct check

**[astm.f3411.v22a.NET0260,Table1,5](../../../../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 timestamp accuracy, but the accuracy reported by the Service Provider did not match it.

#### 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.
Expand Down
6 changes: 6 additions & 0 deletions monitoring/uss_qualifier/suites/astm/netrid/f3411_19.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,12 @@
<td>Implemented</td>
<td><a href="../../../scenarios/astm/netrid/v19/dss/heavy_traffic_concurrent.md">ASTM NetRID DSS: Concurrent Requests</a><br><a href="../../../scenarios/astm/netrid/v19/dss/isa_expiry.md">ASTM NetRID DSS: ISA Expiry</a><br><a href="../../../scenarios/astm/netrid/v19/dss/isa_subscription_interactions.md">ASTM NetRID DSS: ISA Subscription Interactions</a><br><a href="../../../scenarios/astm/netrid/v19/dss/isa_simple.md">ASTM NetRID DSS: Simple ISA</a><br><a href="../../../scenarios/astm/netrid/v19/dss/isa_validation.md">ASTM NetRID DSS: Submitted ISA Validations</a><br><a href="../../../scenarios/astm/netrid/v19/dss/subscription_simple.md">ASTM NetRID DSS: Subscription Simple</a><br><a href="../../../scenarios/astm/netrid/v19/dss/subscription_validation.md">ASTM NetRID DSS: Subscription Validation</a><br><a href="../../../scenarios/astm/netrid/v19/dss/token_validation.md">ASTM NetRID DSS: Token Validation</a></td>
</tr>
<tr>
<td rowspan="1" style="vertical-align:top;"><a href="../../../requirements/astm/f3411/v22a.md">astm<br>.f3411<br>.v22a</a></td>
<td><a href="../../../requirements/astm/f3411/v22a.md">NET0260,Table1,5</a></td>
<td>Implemented</td>
<td><a href="../../../scenarios/astm/netrid/v19/nominal_behavior.md">ASTM NetRID nominal behavior</a></td>
</tr>
<tr>
<td rowspan="4" style="vertical-align:top;"><a href="../../../requirements/interuss/automated_testing/rid/injection.md">interuss<br>.automated_testing<br>.rid<br>.injection</a></td>
<td><a href="../../../requirements/interuss/automated_testing/rid/injection.md">DeleteTestSuccess</a></td>
Expand Down
11 changes: 8 additions & 3 deletions monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

## [Actions](../../README.md#actions)

1. Action generator: [`action_generators.astm.f3411.ForEachDSS`](../../../action_generators/astm/f3411/for_each_dss.py)
1. Scenario: [ASTM NetRID nominal behavior](../../../scenarios/astm/netrid/v22a/nominal_behavior.md) ([`scenarios.astm.netrid.v22a.NominalBehavior`](../../../scenarios/astm/netrid/v22a/nominal_behavior.py))
2. Action generator: [`action_generators.astm.f3411.ForEachDSS`](../../../action_generators/astm/f3411/for_each_dss.py)
1. Suite: [DSS testing for ASTM NetRID F3411-22a](f3411_22a/dss_probing.md) ([`suites.astm.netrid.f3411_22a.dss_probing`](f3411_22a/dss_probing.yaml))
2. Scenario: [ASTM NetRID nominal behavior](../../../scenarios/astm/netrid/v22a/nominal_behavior.md) ([`scenarios.astm.netrid.v22a.NominalBehavior`](../../../scenarios/astm/netrid/v22a/nominal_behavior.py))
3. Scenario: [ASTM NetRID SP clients misbehavior handling](../../../scenarios/astm/netrid/v22a/misbehavior.md) ([`scenarios.astm.netrid.v22a.Misbehavior`](../../../scenarios/astm/netrid/v22a/misbehavior.py))
4. Scenario: [ASTM NetRID: Operator interactions](../../../scenarios/astm/netrid/v22a/operator_interactions.md) ([`scenarios.astm.netrid.v22a.OperatorInteractions`](../../../scenarios/astm/netrid/v22a/operator_interactions.py))
5. Scenario: [ASTM F3411-22a NetRID aggregate checks](../../../scenarios/astm/netrid/v22a/aggregate_checks.md) ([`scenarios.astm.netrid.v22a.AggregateChecks`](../../../scenarios/astm/netrid/v22a/aggregate_checks.py))
Expand All @@ -21,7 +21,7 @@
<th><a href="../../README.md#checked-in">Checked in</a></th>
</tr>
<tr>
<td rowspan="87" style="vertical-align:top;"><a href="../../../requirements/astm/f3411/v22a.md">astm<br>.f3411<br>.v22a</a></td>
<td rowspan="88" style="vertical-align:top;"><a href="../../../requirements/astm/f3411/v22a.md">astm<br>.f3411<br>.v22a</a></td>
<td><a href="../../../requirements/astm/f3411/v22a.md">DSS0010</a></td>
<td>Implemented</td>
<td><a href="../../../scenarios/astm/netrid/v22a/dss/token_validation.md">ASTM NetRID DSS: Token Validation</a></td>
Expand Down Expand Up @@ -291,6 +291,11 @@
<td>Implemented</td>
<td><a href="../../../scenarios/astm/netrid/v22a/nominal_behavior.md">ASTM NetRID nominal behavior</a></td>
</tr>
<tr>
<td><a href="../../../requirements/astm/f3411/v22a.md">NET0260,Table1,5</a></td>
<td>Implemented</td>
<td><a href="../../../scenarios/astm/netrid/v22a/nominal_behavior.md">ASTM NetRID nominal behavior</a></td>
</tr>
<tr>
<td><a href="../../../requirements/astm/f3411/v22a.md">NET0260,Table1,7</a></td>
<td>Implemented</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<th><a href="../README.md#checked-in">Checked in</a></th>
</tr>
<tr>
<td rowspan="87" style="vertical-align:top;"><a href="../../requirements/astm/f3411/v22a.md">astm<br>.f3411<br>.v22a</a></td>
<td rowspan="88" style="vertical-align:top;"><a href="../../requirements/astm/f3411/v22a.md">astm<br>.f3411<br>.v22a</a></td>
<td><a href="../../requirements/astm/f3411/v22a.md">DSS0010</a></td>
<td>Implemented</td>
<td><a href="../../scenarios/astm/netrid/v22a/dss/token_validation.md">ASTM NetRID DSS: Token Validation</a></td>
Expand Down Expand Up @@ -287,6 +287,11 @@
<td>Implemented</td>
<td><a href="../../scenarios/astm/netrid/v22a/nominal_behavior.md">ASTM NetRID nominal behavior</a></td>
</tr>
<tr>
<td><a href="../../requirements/astm/f3411/v22a.md">NET0260,Table1,5</a></td>
<td>Implemented</td>
<td><a href="../../scenarios/astm/netrid/v22a/nominal_behavior.md">ASTM NetRID nominal behavior</a></td>
</tr>
<tr>
<td><a href="../../requirements/astm/f3411/v22a.md">NET0260,Table1,7</a></td>
<td>Implemented</td>
Expand Down
7 changes: 6 additions & 1 deletion monitoring/uss_qualifier/suites/uspace/required_services.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<th><a href="../README.md#checked-in">Checked in</a></th>
</tr>
<tr>
<td rowspan="87" style="vertical-align:top;"><a href="../../requirements/astm/f3411/v22a.md">astm<br>.f3411<br>.v22a</a></td>
<td rowspan="88" style="vertical-align:top;"><a href="../../requirements/astm/f3411/v22a.md">astm<br>.f3411<br>.v22a</a></td>
<td><a href="../../requirements/astm/f3411/v22a.md">DSS0010</a></td>
<td>Implemented</td>
<td><a href="../../scenarios/astm/netrid/v22a/dss/token_validation.md">ASTM NetRID DSS: Token Validation</a></td>
Expand Down Expand Up @@ -288,6 +288,11 @@
<td>Implemented</td>
<td><a href="../../scenarios/astm/netrid/v22a/nominal_behavior.md">ASTM NetRID nominal behavior</a></td>
</tr>
<tr>
<td><a href="../../requirements/astm/f3411/v22a.md">NET0260,Table1,5</a></td>
<td>Implemented</td>
<td><a href="../../scenarios/astm/netrid/v22a/nominal_behavior.md">ASTM NetRID nominal behavior</a></td>
</tr>
<tr>
<td><a href="../../requirements/astm/f3411/v22a.md">NET0260,Table1,7</a></td>
<td>Implemented</td>
Expand Down

0 comments on commit 7e80297

Please sign in to comment.