Skip to content

Commit

Permalink
[uss_qualifier] Call flight planner from general flight authorization…
Browse files Browse the repository at this point in the history
… scenario (#297)

* Call flight planner from general flight authorization scenario

* Fix import location
  • Loading branch information
BenjaminPelletier authored Oct 31, 2023
1 parent 7f528d5 commit ea07fd9
Show file tree
Hide file tree
Showing 19 changed files with 730 additions and 135 deletions.
5 changes: 5 additions & 0 deletions github_pages/static/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ These reports were generated during continuous integration for the most recent P

* [Sequence view](./artifacts/uss_qualifier/reports/dss_probing/sequence)
* [Tested requirements](./artifacts/uss_qualifier/reports/dss_probing/requirements)

### [General flight authorization configuration](https://github.com/interuss/monitoring/blob/main/monitoring/uss_qualifier/configurations/dev/general_flight_auth.yaml)

* [Sequence view](./artifacts/uss_qualifier/reports/general_flight_auth/sequence)
* [Tested requirements](./artifacts/uss_qualifier/reports/general_flight_auth/requirements)
39 changes: 33 additions & 6 deletions monitoring/monitorlib/clients/flight_planning/client_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,22 @@
from monitoring.monitorlib.clients.flight_planning.planning import (
PlanningActivityResponse,
)
from monitoring.monitorlib.fetch import query_and_describe
from monitoring.monitorlib.fetch import query_and_describe, QueryType
from monitoring.monitorlib.geotemporal import Volume4D
from monitoring.monitorlib.infrastructure import UTMClientSession
from monitoring.uss_qualifier.configurations.configuration import ParticipantID

from uas_standards.interuss.automated_testing.flight_planning.v1 import api
from uas_standards.interuss.automated_testing.flight_planning.v1.constants import Scope


class V1FlightPlannerClient(FlightPlannerClient):
_session: UTMClientSession
_participant_id: ParticipantID

def __init__(self, session: UTMClientSession):
def __init__(self, session: UTMClientSession, participant_id: ParticipantID):
self._session = session
self._participant_id = participant_id

def _inject(
self,
Expand All @@ -53,7 +56,13 @@ def _inject(
op = api.OPERATIONS[api.OperationID.UpsertFlightPlan]
url = op.path.format(flight_plan_id=flight_plan_id)
query = query_and_describe(
self._session, op.verb, url, json=req, scope=Scope.Plan
self._session,
op.verb,
url,
json=req,
scope=Scope.Plan,
participant_id=self._participant_id,
query_type=QueryType.InterUSSFlightPlanningV1UpsertFlightPlan,
)
if query.status_code != 200 and query.status_code != 201:
raise PlanningActivityError(
Expand Down Expand Up @@ -108,7 +117,14 @@ def try_end_flight(
)
op = api.OPERATIONS[api.OperationID.DeleteFlightPlan]
url = op.path.format(flight_plan_id=flight_id)
query = query_and_describe(self._session, op.verb, url, scope=Scope.Plan)
query = query_and_describe(
self._session,
op.verb,
url,
scope=Scope.Plan,
participant_id=self._participant_id,
query_type=QueryType.InterUSSFlightPlanningV1DeleteFlightPlan,
)
if query.status_code != 200:
raise PlanningActivityError(
f"Attempt to delete flight plan returned status {query.status_code} rather than 200 as expected",
Expand All @@ -134,7 +150,12 @@ def try_end_flight(
def report_readiness(self) -> TestPreparationActivityResponse:
op = api.OPERATIONS[api.OperationID.GetStatus]
query = query_and_describe(
self._session, op.verb, op.path, scope=Scope.DirectAutomatedTest
self._session,
op.verb,
op.path,
scope=Scope.DirectAutomatedTest,
participant_id=self._participant_id,
query_type=QueryType.InterUSSFlightPlanningV1GetStatus,
)
if query.status_code != 200:
raise PlanningActivityError(
Expand Down Expand Up @@ -166,7 +187,13 @@ def clear_area(self, area: Volume4D) -> TestPreparationActivityResponse:

op = api.OPERATIONS[api.OperationID.ClearArea]
query = query_and_describe(
self._session, op.verb, op.path, json=req, scope=Scope.DirectAutomatedTest
self._session,
op.verb,
op.path,
json=req,
scope=Scope.DirectAutomatedTest,
participant_id=self._participant_id,
query_type=QueryType.InterUSSFlightPlanningV1ClearArea,
)
if query.status_code != 200:
raise PlanningActivityError(
Expand Down
14 changes: 14 additions & 0 deletions monitoring/monitorlib/fetch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,20 @@ class QueryType(str, Enum):
# InterUSS automated testing versioning interface
InterUSSVersioningGetVersion = "interuss.automated_testing.versioning.GetVersion"

# InterUSS automated testing flight_planning interface
InterUSSFlightPlanningV1GetStatus = (
"interuss.automated_testing.flight_planning.v1.GetStatus"
)
InterUSSFlightPlanningV1ClearArea = (
"interuss.automated_testing.flight_planning.v1.ClearArea"
)
InterUSSFlightPlanningV1UpsertFlightPlan = (
"interuss.automated_testing.flight_planning.v1.UpsertFlightPlan"
)
InterUSSFlightPlanningV1DeleteFlightPlan = (
"interuss.automated_testing.flight_planning.v1.DeleteFlightPlan"
)

@staticmethod
def flight_details(rid_version: RIDVersion):
if rid_version == RIDVersion.f3411_19:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,34 @@ v1:
resources:
resource_declarations:
example_flight_check_table: {$ref: 'library/resources.yaml#/example_flight_check_table'}

utm_auth: {$ref: 'library/environment.yaml#/utm_auth'}
uss1_flight_planner: {$ref: 'library/environment.yaml#/uss1_flight_planner'}
non_baseline_inputs:
- v1.test_run.resources.resource_declarations.utm_auth
- v1.test_run.resources.resource_declarations.uss1_flight_planner
action:
test_scenario:
scenario_type: scenarios.interuss.flight_authorization.GeneralFlightAuthorization
resources:
table: example_flight_check_table
planner: uss1_flight_planner
artifacts:
output_path: output/general_flight_auth
raw_report: {}
sequence_view: {}
tested_requirements:
- report_name: requirements
requirement_collections:
example:
requirement_collections:
- requirements:
- REQ_001
- REQ_002
- REQ_003
- REQ_004
- REQ_007
participant_requirements:
uss1: example
validation:
$ref: ./library/validation.yaml#/normal_test
158 changes: 99 additions & 59 deletions monitoring/uss_qualifier/configurations/dev/library/resources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -151,73 +151,113 @@ example_flight_check_table:
- REQ_002
- REQ_007
description: The first test step defined by the test designer
additional_information:
new_jurisdiction_x:
operation_rule_set: Rules1
volumes:
- outline_circle:
center:
lng: 7.4774
lat: 46.9749
radius:
value: 100
units: M
altitude_lower:
value: 0
units: M
reference: SFC
altitude_upper:
value: 100
units: M
reference: SFC
start_time:
start_of_test: { }
use_timezone: Europe/Berlin
end_time:
offset_from:
starting_from:
next_day:
time_zone: Europe/Zurich
starting_from:
start_of_test: { }
days_of_the_week: [ "Tu", "Th" ]
offset: 12h
acceptance_expectation: MustBeAccepted
flight_info:
basic_information:
usage_state: Planned
uas_state: Nominal
area:
- outline_circle:
center:
lng: 7.4774
lat: 46.9749
radius:
value: 100
units: M
altitude_lower:
value: 550
units: M
# TODO: Change to SFC once mock_uss can process that datum
reference: W84
altitude_upper:
value: 650
units: M
# TODO: Change to SFC once mock_uss can process that datum
reference: W84
start_time:
start_of_test: { }
use_timezone: Europe/Berlin
end_time:
offset_from:
starting_from:
next_day:
time_zone: Europe/Zurich
starting_from:
start_of_test: { }
days_of_the_week: [ "Tu", "Th" ]
offset: 12h
additional_information:
new_jurisdiction_x:
operation_rule_set: Rules1
# TODO: Remove once mock_uss is fixed to not require U-space flight auth
uspace_flight_authorisation:
uas_serial_number: 1AF49UL5CC5J6K
operation_category: Open
operation_mode: Vlos
uas_class: C0
identification_technologies:
- ASTMNetRID
connectivity_methods:
- cellular
endurance_minutes: 30
emergency_procedure_url: https://example.interussplatform.org/emergency
operator_id: CHEo5kut30e0mt01-qwe
uas_id: ''
uas_type_certificate: ''
- flight_check_id: TEST_002
requirement_ids:
- REQ_001
- REQ_003
- REQ_004
description: The second test step defined by the test designer
additional_information:
new_jurisdiction_x:
operation_rule_set: Rules1
volumes:
- outline_circle:
center:
lng: 7.4774
lat: 46.9749
radius:
value: 100
units: M
altitude_lower:
value: 50
units: M
reference: SFC
altitude_upper:
value: 5000
units: FT
reference: W84
start_time:
next_day:
time_zone: +02:00
starting_from:
offset_from:
acceptance_expectation: MustBeAccepted
flight_info:
basic_information:
usage_state: Planned
uas_state: Nominal
area:
- outline_circle:
center:
lng: 7.4774
lat: 46.9749
radius:
value: 100
units: M
altitude_lower:
value: 1424
units: M
reference: W84
altitude_upper:
value: 5000
units: FT
reference: W84
start_time:
next_day:
time_zone: +02:00
starting_from:
start_of_test: { }
offset: 12h
duration: 5m
conditions_expectation: MustBePresent
offset_from:
starting_from:
start_of_test: { }
offset: 12h
duration: 5m
additional_information:
new_jurisdiction_x:
operation_rule_set: Rules1
# TODO: Remove once mock_uss is fixed to not require U-space flight auth
uspace_flight_authorisation:
uas_serial_number: 1AF49UL5CC5J6K
operation_category: Open
operation_mode: Vlos
uas_class: C0
identification_technologies:
- ASTMNetRID
connectivity_methods:
- cellular
endurance_minutes: 30
emergency_procedure_url: https://example.interussplatform.org/emergency
operator_id: CHEo5kut30e0mt01-qwe
uas_id: ''
uas_type_certificate: ''

# ===== Geospatial feature comprehension =====

Expand Down
6 changes: 4 additions & 2 deletions monitoring/uss_qualifier/reports/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ def query_passed_checks(

def query_failed_checks(
self, participant_id: Optional[str] = None
) -> Iterator[Tuple[JSONPathExpression, PassedCheck]]:
) -> Iterator[Tuple[JSONPathExpression, FailedCheck]]:
test_suite, test_scenario, action_generator = self.get_applicable_report()
if test_suite:
report = self.test_suite
Expand Down Expand Up @@ -486,7 +486,9 @@ def start_time(self) -> Optional[StringBasedDateTime]:

@property
def end_time(self) -> Optional[StringBasedDateTime]:
return self._conditional(lambda report: report.end_time)
return self._conditional(
lambda report: report.end_time if "end_time" in report else None
)


class AllConditionsEvaluationReport(ImplicitDict):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,28 @@

## Overview

TODO: Link to API YAML and provide overview
When a USS implements the [InterUSS flight_planning automated testing API](https://github.com/interuss/automated_testing_interfaces/tree/main/flight_planning) (or [legacy scd automated testing API](https://github.com/interuss/automated_testing_interfaces/tree/main/scd)), they are expected to respond to requests to that API as defined in the API. Specific requirements are below.

## Requirements

TODO: Describe requirements
### <tt>ImplementAPI</tt>

A USS must implement the endpoints defined in the API, accept requests in the data format prescribed in the API, and respond in the data format prescribed in the API. If there is a problem using the API such as a connection error, invalid response code, or invalid data, the USS will have failed to meet this requirement.

### <tt>ClearArea</tt>

In order to conduct automated tests effectively, the USS must remove all of their existing flights from a particular area when instructed by the test director. This is not an action performed on behalf of an emulated user, but rather an action performed in any way appropriate to support automated testing -- therefore, fulfilling this request may cause actions on the implementing USS's system that no normal user would be able to perform.

### <tt>ExpectedBehavior</tt>

When the test director (client of the flight planning API; usually uss_qualifier) requests that a flight planning activity be performed, the API implementer must act as if this request is coming from a normal user attempting to use the USS's system normally. The USS must fulfill this request as it would for a normal user, and these actions are generally expected to succeed (allowing the user to fly) when a UTM rule does not prohibit them.

### <tt>FlightCoveredByOperationalIntent</tt>

For InterUSS to effectively test the requirements of ASTM F3548-21, a USS under test must act as if there is a
regulatory requirement requiring all flights it manages to provide operational intents according to ASTM F3548-21 at all
times for all flights it manages.

### <tt>DeleteFlightSuccess</tt>

In order to conduct automated tests effectively, the USS must remove a particular flight when instructed by the test director. This is not an action performed on behalf of an emulated user, but rather an action performed in any way appropriate to support automated testing -- therefore, fulfilling this request may cause actions on the implementing USS's system that no normal user would be able to perform.
Loading

0 comments on commit ea07fd9

Please sign in to comment.